docs(14.2.1-01): complete translate plugin repository and locale seam plan
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
200
.planning/phases/14.2.1-translate-plugin/14.2.1-01-SUMMARY.md
Normal file
200
.planning/phases/14.2.1-translate-plugin/14.2.1-01-SUMMARY.md
Normal file
@@ -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*
|
||||
Reference in New Issue
Block a user