8.2 KiB
phase, plan, status, subsystem, tags, requires, provides, affects, tech-stack, key-files, decisions, metrics, actuals, plan_head_before, plan_head_after
| phase | plan | status | subsystem | tags | requires | provides | affects | tech-stack | key-files | decisions | metrics | actuals | plan_head_before | plan_head_after | ||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| quick-261001-ddh | 01 | complete | lagoon (data layer), application genre list |
|
|
|
|
|
|
|
|
565ce982d9 |
026ce74234 |
Quick 261001-ddh: Per-query collation replaces lagoon's ICU pl-PL database requirement
lagoon.OrderBy(db, col, dir, allowed, lagoon.Collate("pl-x-icu")) now emits a validated, double-quoted COLLATE clause. lagoon no longer checks the database locale, and the framework's tests and docs use plain PostgreSQL. The application's genre list sorts with pl-x-icu, so it returns the recorded Polish order on any database. A libc C database test proves it.
Commits
| Task | Repo | Commit | Message |
|---|---|---|---|
| 1 | summercms.go | 037dc53 |
feat(lagoon): per-query collation for OrderBy, drop the database locale check |
| 2 | fonoteka.go | 2da9482 |
fix(genres): sort genre names with a per-query Polish collation |
| 3 | summercms.go | 026ce74 |
docs(quick-261001-ddh): record per-query collation decision superseding D-06 |
commits: 2 counts summercms.go only (measured with git rev-list --count 565ce98..HEAD). The fonoteka.go commit 2da9482 sits on top of 1c88199 in the sibling repo. actuals.tokens is chars/4 over both repos' diffs (53422 + 7458 bytes).
What changed
Task 1, framework (037dc53):
modules/lagoon/order.go:- Adds
OrderOptionandCollate(name).OrderBynow has the signatureOrderBy(db, column, dir, allowed, opts ...OrderOption), so existing callers compile unchanged. - Checks run in order: column allow-list, then direction, then collation. The collation check accepts 1-63 bytes, starting with an ASCII letter, digit or
_and continuing with letters, digits,_,-,.or@. - The name is emitted through a single
quoteCollationhelper. When the lastCollateoption wins, the clause is<col> COLLATE "<name>" ASC|DESC.
- Adds
modules/lagoon/connection.go: removes theCheckLocale/checkLocalefunctions, their constants and both call sites. The Open/Use doc comments are rewritten.- New tests:
- The clause tests now use neutral table names.
- Tables of accepted and rejected collation names. The rejected list includes injection-shaped names, NUL, non-ASCII, a 64-byte name, and names with a leading
-or.. Each rejection comes back fromOrderByas(nil, err)and leaves the GORM handle untouched. - The last
Collateoption wins, and the check order is pinned. ExampleCollate.- Integration test
TestCollatePolishOrderOnLibcDatabase: Open and Use succeed on a libcCdatabase. The plain order is[Lis Mysz Zebra Łoś]and thepl-x-icuorder is[Lis Łoś Mysz Zebra]. An unknown collation reaches Postgres as an identifier (SQLSTATE 42704).
- Deleted tests:
TestCheckLocaleRejectsNilSQL,TestWrongICULocaleFailsOpen,TestCheckLocaleMessage. - Removed the ICU initdb args and ICU
CREATE DATABASEfrom the lagoon, lagoon/attach, cabana, beachcomber, lighthouse, bouncer and conga harnesses and from docs/examples/blog (icuDatabasewas renamed totestDatabase). The testcontainers imports that became unused were dropped in the bouncer and cabana tests. - Updated the lagoon README, root README, installation, models, queries-and-pagination (new "Sorting with a collation" section with an
ExampleCollatesnippet filled bydocs:sync) and plugin testing docs. The comment inscripts/check-phase8.shis corrected; its initdb args are kept.
Task 2, application (2da9482):
polishCollation = "pl-x-icu"is passed at the PolishOrder call site. The response shape is unchanged.- The source check now also requires
lagoon.Collate(. TestGenrePolishOrderOnLibcDatabasereplacesTestGenreQueryFailsOnWrongLocale. Before the controller change it failed (RED), withŁódź Beatsorted last. After the change it passes:Łódź Beatcomes afterLatin, while the plainORDER BYon the same database still puts it last.TestMigrateRejectsNonPolishLocaleis deleted.- README: ICU pl-PL is now a recommendation. The section explains the explicit collation on the genre list and that the framework no longer checks the locale.
Task 3, decision note (026ce74): .planning/notes/lagoon-per-query-collation.md supersedes D-06, and D-06 in 03-CONTEXT.md points to it.
Verification
- summercms.go:
go vet ./...is clean.- Full
go test -count=1 ./...with Docker passed (35 packages ok, exit 0). - The targeted lagoon tests pass, including the libc integration test.
go test ./cmd/summer -run TestDocsTreepasses, andgo run ./cmd/summer docs:build --checkreports "no problems found".grep -rnE 'CheckLocale|ICU_LOCALE|icu-locale|ICU .?pl-PL' modules docs examples README.mdand thefonotekagrep on order_test.go and example_test.go both print nothing.
- fonoteka.go:
go vet ./...is clean in the root module and in both plugin modules.- Full
go test -count=1 ./...passes in the root module and inplugins/golem15/userandplugins/golem15/fonoteka. go test ./parity -run Genrepasses.gofmt -lon the touched packages is empty.
- None of the three commits has a co-author trailer, and all files were staged by explicit path.
Deviations from Plan
1. [Scope boundary] gofmt drift in files this task did not touch. gofmt -l modules docs/examples (part of the plan's automated verify) prints 6 files that were already in that state at 565ce98: modules/compass/config_test.go, modules/compass/persist_test.go, modules/party/registry_test.go, modules/tide/flow_test.go, modules/tide/headers_test.go, modules/wristband/server.go. The drift is method-alignment whitespace from the newer gofmt. None of the files this task changed are listed. I did not fix them because they are out of scope; they need a separate gofmt -w commit.
2. [Verification scope] fonoteka.go workspace. In fonoteka.go, go vet ./... and go test ./... from the repo root cover only the root module (5 packages) under go.work. I also ran both inside plugins/golem15/user and plugins/golem15/fonoteka, and all passed.
3. [Rule 3 - Blocking] Unused imports. After the WithEnv option was removed, the testcontainers import was unused in modules/bouncer/phase07_coverage_test.go and modules/cabana/auth_test.go, so I removed it. The plan anticipated this.
Commits were made directly on master, as the plan says (branching_strategy: none).
Known Stubs
None.
Threat Flags
None. The only new raw-SQL surface is the collation name. It is covered by T-ddh-01: byte validation, one quoting helper, and unit tests with injection-shaped names.
Self-Check: PASSED
- FOUND: modules/lagoon/order.go (contains
func Collate() - FOUND: docs/database/queries-and-pagination.md (contains
src=modules/lagoon/example_test.go#ExampleCollate) - FOUND: ../fonoteka.go/plugins/golem15/fonoteka/controllers/genre_controller.go (contains
lagoon.Collate() - FOUND: .planning/notes/lagoon-per-query-collation.md (contains
Supersedes) - FOUND: commits
037dc53,026ce74(summercms.go), 2da9482 (fonoteka.go)