From de202fcb03f31c9951eac445e68105135f76ecc8 Mon Sep 17 00:00:00 2001 From: Jakub Zych Date: Tue, 6 Oct 2026 11:56:36 +0200 Subject: [PATCH] docs(14.2.1-01): complete translate plugin repository and locale seam plan Co-authored-by: Cursor --- .planning/ROADMAP.md | 4 +- .planning/STATE.md | 19 +- .../14.2.1-01-SUMMARY.md | 200 ++++++++++++++++++ 3 files changed, 213 insertions(+), 10 deletions(-) create mode 100644 .planning/phases/14.2.1-translate-plugin/14.2.1-01-SUMMARY.md diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index 634f77f..8ccca35 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -843,12 +843,12 @@ Plans: 3. Cabana `markdown`/`mltext`/`mlmarkdown` compose; nested locale writes are not dropped; docs, OpenAPI, TS types and `boardwalk` `dist/` update in the same change. 4. Proof host `sm-grzybyfunkcjonalne-app` boots with user+translate; unit tests are the last plan. -**Plans:** 4 plans +**Plans:** 1/4 plans executed Plans: **Wave 1** -- [ ] 14.2.1-01-PLAN.md — Plugin repo, `golem15_translate_*` schema, Locale, en/pl seed, Translator, surf Resolver +- [x] 14.2.1-01-PLAN.md — Plugin repo, `golem15_translate_*` schema, Locale, en/pl seed, Translator, surf Resolver **Wave 2** *(blocked on Wave 1 completion)* - [ ] 14.2.1-02-PLAN.md — Translatable API, Locales admin, fixture save/read diff --git a/.planning/STATE.md b/.planning/STATE.md index 4f8c33a..cdb730b 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -4,16 +4,16 @@ milestone: v1.0 current_phase: 14.2.1 current_phase_name: Translate plugin status: executing -stopped_at: 14.2.1-01 Task 1 complete; Task 2 awaiting Winter table contract decision -last_updated: "2026-10-06T09:29:56.278Z" +stopped_at: Completed 14.2.1-01-PLAN.md +last_updated: "2026-10-06T09:56:25.260Z" last_activity: 2026-10-06 last_activity_desc: 14.2.1-01 Task 1 sibling checkouts created; Task 2 Winter table contract pending -state_head: e88007aa7620c8c5067d0276e8a1a9fc6dcdd97c +state_head: b2ce986604521234140adcc3d02226676435ee1e progress: total_phases: 26 completed_phases: 12 total_plans: 129 - completed_plans: 125 + completed_plans: 126 milestone_name: milestone --- @@ -29,7 +29,7 @@ See: .planning/PROJECT.md (updated 2026-09-16) ## Current Position Phase: 14.2.1 (Translate plugin) — EXECUTING -Plan: 1 of 4 (14.2.1-01 Task 1 complete; Task 2 checkpoint) +Plan: 2 of 4 (14.2.1-01 Task 1 complete; Task 2 checkpoint) Status: Paused at Task 2 Winter table contract decision Last activity: 2026-10-06 — created sibling sm-translate-plugin and sm-grzybyfunkcjonalne-app checkouts @@ -180,6 +180,7 @@ Progress: [███████░░░] 67% | Phase 12.1 P05 | 103min | 3 tasks | 56 files | | Phase 14.1 P01 | 90 | 4 tasks | 20 files | | Phase 14.1 P02 | 8 min | 3 tasks | 3 files | +| Phase 14.2.1 P01 | 16 min | 3 tasks | 23 files | ## Accumulated Context @@ -574,6 +575,8 @@ Recent decisions affecting current work: - [Phase 14.1]: sessionApp does not phrasebook.Activate; EN/PL 409 tests activate catalogs and set locale with towel.WithLocale — sessionApp Boots the plugin only; Get would return the raw last_method_blocked key - [Phase 14.1]: Unique (provider, provider_id) is table-global; EN/PL 409 seeds use provider_id fb-only- — oauth_identities_provider_identity_unique is not per-user - [Phase 14.1]: Task 3 needed no parity_test.go change: 14.1-01 already set expectedPortedRoutes 175 and rewrote assertPortedMismatch — Corpus already recorded 175/175 passing 175 failing 0 unrecorded 0 pending 0 +- [Phase 14.2.1]: Task 2 locked golem15-prefix: Go tables are golem15_translate_*; PHP pin keeps winter_translate_* out of Go DDL. +- [Phase 14.2.1]: Sibling plugin go.mod replace is ../summercms.go so isolated D-16 go test passes; host mounts replace via go.work. ### Pending Todos @@ -626,6 +629,6 @@ Items acknowledged and carried forward from previous milestone close: ## Session Continuity -Last session: 2026-10-06T09:29:55.747Z -Stopped at: 14.2.1-01 Task 1 complete; Task 2 awaiting Winter table contract decision -Resume file: .planning/phases/14.2.1-translate-plugin/14.2.1-01-PLAN.md +Last session: 2026-10-06T09:56:24.657Z +Stopped at: Completed 14.2.1-01-PLAN.md +Resume file: None diff --git a/.planning/phases/14.2.1-translate-plugin/14.2.1-01-SUMMARY.md b/.planning/phases/14.2.1-translate-plugin/14.2.1-01-SUMMARY.md new file mode 100644 index 0000000..b16b7b5 --- /dev/null +++ b/.planning/phases/14.2.1-translate-plugin/14.2.1-01-SUMMARY.md @@ -0,0 +1,200 @@ +--- +phase: 14.2.1-translate-plugin +plan: 01 +subsystem: i18n +tags: [translate, sm-translate-plugin, gormigrate, LocaleResolver, towel.WithLocale, golem15_translate] + +requires: + - phase: 01-framework-kernel-foundation + provides: "compiled party.Register plugins, backpack Publish/Lookup" + - phase: 04-cli-scaffolding-i18n-and-mail + provides: "towel.WithLocale request locale bag" + - phase: 06-http-middleware-and-openapi + provides: "surf wrap locale() house middleware and BuildRouter" +provides: + - "Module git.golem15.com/golem15/sm-translate-plugin, package translate, plugin ID golem15.translate" + - "gormigrate tables golem15_translate_locales, golem15_translate_attributes, golem15_translate_indexes, empty golem15_translate_messages" + - "Idempotent en/pl Locale seed (en default sort_order 1, pl Polski enabled non-default sort_order 2)" + - "classes.Translator context-only Locale(ctx); surf.LocaleResolver published at Boot" + - "Optional surf resolver seam: URL prefix rewrite before routing, validated towel.WithLocale; Accept-Language fallback when unpublished" +affects: [14.2.1-02 Translatable API and Locales admin, 14.2.1-03 proof host mount, 15-journal-plugin] + +actuals: + tokens: 29734 + tasks: 3 + commits: 3 +plan_head_before: e88007aa7620c8c5067d0276e8a1a9fc6dcdd97c +plan_head_after: b2ce986604521234140adcc3d02226676435ee1e +plugin_repo_head_after: f6cf99c00b2d2b1951d2971e574acf0ff724daad + +tech-stack: + added: [] + patterns: + - "Go translate tables are golem15_translate_*; PHP pin keeps winter_translate_* and is not copied into Go DDL" + - "surf.LocaleResolver lives in the framework; the plugin Boot-publishes it; hosts without translate keep Accept-Language" + - "Request locale is context-only (KERN-07); locale_manually_set is a flag cookie with value 1" + +key-files: + created: + - ../sm-translate-plugin/go.mod + - ../sm-translate-plugin/plugin.go + - ../sm-translate-plugin/README.md + - ../sm-translate-plugin/config/config.yaml + - ../sm-translate-plugin/models/registry.go + - ../sm-translate-plugin/models/locale.go + - ../sm-translate-plugin/updates/registry.go + - ../sm-translate-plugin/updates/202610060001_create_golem15_translate_locales.go + - ../sm-translate-plugin/updates/202610060002_create_golem15_translate_attributes.go + - ../sm-translate-plugin/updates/202610060003_create_golem15_translate_indexes.go + - ../sm-translate-plugin/updates/202610060004_create_golem15_translate_messages.go + - ../sm-translate-plugin/updates/202610060005_seed_en_pl_locales.go + - ../sm-translate-plugin/classes/translator.go + - modules/surf/locale_resolver.go + - modules/surf/locale_resolver_test.go + modified: + - modules/surf/router.go + - modules/surf/README.md + - docs/architecture/request-lifecycle.md + - docs/services/localization.md + - docs/services/routing.md + +key-decisions: + - "Task 2 locked golem15-prefix: Go tables are golem15_translate_locales, golem15_translate_attributes, golem15_translate_indexes, golem15_translate_messages. PHP at SHA 725d547 still uses winter_translate_*; those names are not copied into Go DDL. No rainlab_translate_* tables. No JSON-column storage." + - "Sibling plugin go.mod replaces the framework with ../summercms.go so isolated go test in the D-16 checkout passes; a host mount supplies its own go.work replace." + +patterns-established: + - "Squashed gormigrate files named 202610060001_create_golem15_translate_* through 005 seed; never AutoMigrate" + - "Translator.Rewrite strips an enabled first path segment before ServeMux; Resolve order is URL, principal, remembered cookie, cookie-gated Accept-Language, default" + - "surf stores app on Router at BuildRouter and Lookup[LocaleResolver] without importing the plugin" + +requirements-completed: [D-01, D-02, D-03, D-04, D-07, D-08, D-10, D-12, D-15, D-16] + +coverage: + - id: D1 + description: "Compiled sm-translate-plugin module with ID golem15.translate publishes surf.LocaleResolver at Boot" + verification: + - kind: unit + ref: "sm-translate-plugin#TestPluginID" + status: pass + - kind: other + ref: "go -C ../sm-translate-plugin vet ./... && go -C ../sm-translate-plugin test ./... -short -count=1" + status: pass + human_judgment: false + - id: D2 + description: "Four golem15_translate_* tables plus empty messages and idempotent en/pl seed via gormigrate" + verification: + - kind: other + ref: "rg golem15_translate_ updates/202610060001..004; seed file has English/Polski and no Deutsch" + status: pass + human_judgment: false + - id: D3 + description: "Optional surf LocaleResolver seam writes a validated code with towel.WithLocale and keeps Accept-Language when unpublished" + verification: + - kind: unit + ref: "modules/surf#TestLocaleResolverWritesValidatedCodeAndStripsPrefix" + status: pass + - kind: unit + ref: "modules/surf#TestLocaleAbsentResolverKeepsAcceptLanguage" + status: pass + - kind: other + ref: "go vet ./modules/surf/... && go test ./modules/surf -short -count=1" + status: pass + human_judgment: false + - id: D4 + description: "PHP translate tree at SHA 725d547 is unchanged" + verification: + - kind: other + ref: "git -C /media/nvme/dev/golem15/fonoteka/plugins/golem15/translate status --short (empty) and rev-parse HEAD" + status: pass + human_judgment: false + +duration: 16min +completed: 2026-10-06 +status: complete +--- + +# Phase 14.2.1 Plan 01: Translate plugin repository, schema, and locale seam Summary + +**Sibling `sm-translate-plugin` with squashed `golem15_translate_*` tables, en/pl Locale seed, context-only Translator, and an optional surf `LocaleResolver` seam** + +## Performance + +- **Duration:** 16 min +- **Started:** 2026-10-06T09:37:49Z +- **Completed:** 2026-10-06T09:54:21Z +- **Tasks:** 3 +- **Files modified:** 23 + +## Accomplishments + +- Created the compiled plugin module `git.golem15.com/golem15/sm-translate-plugin` (package `translate`, ID `golem15.translate`) in the D-16 sibling checkout, with config, Locale model, five gormigrate steps, and Boot publication of `surf.LocaleResolver`. +- Squashed the PHP pin's columns and indexes onto `golem15_translate_locales`, `golem15_translate_attributes`, `golem15_translate_indexes`, and empty `golem15_translate_messages`. Seeded enabled default `en` at sort_order 1 and enabled non-default `pl` (Polski) at sort_order 2. No Deutsch row. No AutoMigrate. No `winter_translate_*` or `rainlab_translate_*` in Go source. +- Implemented `classes.Translator` with D-07 order (URL prefix → principal preferred_locale → remembered `golem15.translate.locale` → cookie-gated Accept-Language → default), `ResolveAPI` without persistence, and `Translator.Locale(ctx)` only. `locale_manually_set` is a flag with value `1`. +- Added framework `surf.LocaleResolver`; `BuildRouter` stores the app; prefix rewrite runs before CORS/routing; `locale()` writes `towel.WithLocale`. Hosts without the plugin keep raw Accept-Language. + +## Task Commits + +Each task was committed atomically: + +1. **Task 1: Create the public Gitea remote and authorize local repository setup** - `d878a67` (sm-translate-plugin, chore) / `28bd45f` (summercms.go, docs) +2. **Task 2: Confirm the one-way table contract** - recorded in this summary (`golem15-prefix`); no code commit +3. **Task 3: Resolve one URL-prefixed request through the plugin, enabled Locale row, surf, and context** - `f6cf99c` (sm-translate-plugin, feat) / `b2ce986` (summercms.go, feat) + +**Plan metadata:** (this commit) + +_Note: Task 2 was a checkpoint:decision. The locked answer `golem15-prefix` was applied before Task 3._ + +## Files Created/Modified + +- `../sm-translate-plugin/plugin.go` - compiled Plugin, HasConfig/HasMigrations/HasModels, Boot publishes LocaleResolver +- `../sm-translate-plugin/models/locale.go` - Locale, no timestamps, Fillable code/name/is_enabled +- `../sm-translate-plugin/updates/202610060001_create_golem15_translate_locales.go` through `004` messages and `005` en/pl seed +- `../sm-translate-plugin/classes/translator.go` - Rewrite, Resolve, ResolveAPI, Locale(ctx) +- `../sm-translate-plugin/README.md` - application-neutral plugin contract +- `modules/surf/locale_resolver.go` - framework LocaleResolver interface +- `modules/surf/router.go` - app on Router, prefix strip, resolver lookup +- `modules/surf/README.md`, `docs/services/routing.md`, `docs/services/localization.md`, `docs/architecture/request-lifecycle.md` - exported seam + +## Decisions Made + +- **golem15-prefix (Task 2, locked):** Go persistent tables are `golem15_translate_locales`, `golem15_translate_attributes`, `golem15_translate_indexes`, `golem15_translate_messages`. PHP SHA `725d547ec839f02b5fdc0f0a6faaed601a414d50` still uses `winter_translate_*`; those names are not copied into Go DDL. `winter-final` and `host-json` were not implemented. +- Sibling `go.mod` replace is `../summercms.go` so `go -C ../sm-translate-plugin test` works in the D-16 checkout. A host that mounts the plugin at `plugins/golem15/translate` should replace the framework from the host `go.work`. + +## Deviations from Plan + +### Auto-fixed Issues + +**1. [Rule 3 - Blocking] Sibling go.mod replace path** +- **Found during:** Task 3 (module init) +- **Issue:** PATTERNS copies the submodule replace `../../../../summercms.go`, which does not resolve from `/media/nvme/dev/golem15/summercms.io/summercms/sm-translate-plugin`. The plan's verify command is `go -C ../sm-translate-plugin vet ./...`. +- **Fix:** `replace git.golem15.com/golem15/summercms => ../summercms.go`, documented in the plugin README. +- **Files modified:** `../sm-translate-plugin/go.mod`, `../sm-translate-plugin/README.md` +- **Verification:** `go -C ../sm-translate-plugin vet ./...` and `go test ./... -short` pass +- **Committed in:** `f6cf99c` (Task 3 plugin commit) + +--- + +**Total deviations:** 1 auto-fixed (1 blocking) +**Impact on plan:** Required for the isolated sibling verify command. No schema or resolver-order change. + +## Issues Encountered + +None beyond the replace-path deviation. + +## Authentication Gates + +None. + +## User Setup Required + +None - no external service configuration required. + +## Next Phase Readiness + +Ready for 14.2.1-02 (Translatable API, Locales admin, fixture). Schema names and the request-locale seam are the import contract. Messages admin, CMS components, and cabana ML fields stay later plans. + +## Self-Check: PASSED + +--- +*Phase: 14.2.1-translate-plugin* +*Completed: 2026-10-06*