Files
summercms/.planning/phases/14.2.1-translate-plugin/14.2.1-01-SUMMARY.md
2026-10-06 11:56:36 +02:00

10 KiB

phase, plan, subsystem, tags, requires, provides, affects, actuals, plan_head_before, plan_head_after, plugin_repo_head_after, tech-stack, key-files, key-decisions, patterns-established, requirements-completed, coverage, duration, completed, status
phase plan subsystem tags requires provides affects actuals plan_head_before plan_head_after plugin_repo_head_after tech-stack key-files key-decisions patterns-established requirements-completed coverage duration completed status
14.2.1-translate-plugin 01 i18n
translate
sm-translate-plugin
gormigrate
LocaleResolver
towel.WithLocale
golem15_translate
phase provides
01-framework-kernel-foundation compiled party.Register plugins, backpack Publish/Lookup
phase provides
04-cli-scaffolding-i18n-and-mail towel.WithLocale request locale bag
phase provides
06-http-middleware-and-openapi surf wrap locale() house middleware and BuildRouter
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
14.2.1-02 Translatable API and Locales admin
14.2.1-03 proof host mount
15-journal-plugin
tokens tasks commits
29734 3 3
e88007aa76 b2ce986604 f6cf99c00b2d2b1951d2971e574acf0ff724daad
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
created modified
../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
modules/surf/router.go
modules/surf/README.md
docs/architecture/request-lifecycle.md
docs/services/localization.md
docs/services/routing.md
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.
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
D-01
D-02
D-03
D-04
D-07
D-08
D-10
D-12
D-15
D-16
id description verification human_judgment
D1 Compiled sm-translate-plugin module with ID golem15.translate publishes surf.LocaleResolver at Boot
kind ref status
unit sm-translate-plugin#TestPluginID pass
kind ref status
other go -C ../sm-translate-plugin vet ./... && go -C ../sm-translate-plugin test ./... -short -count=1 pass
false
id description verification human_judgment
D2 Four golem15_translate_* tables plus empty messages and idempotent en/pl seed via gormigrate
kind ref status
other rg golem15_translate_ updates/202610060001..004; seed file has English/Polski and no Deutsch pass
false
id description verification human_judgment
D3 Optional surf LocaleResolver seam writes a validated code with towel.WithLocale and keeps Accept-Language when unpublished
kind ref status
unit modules/surf#TestLocaleResolverWritesValidatedCodeAndStripsPrefix pass
kind ref status
unit modules/surf#TestLocaleAbsentResolverKeepsAcceptLanguage pass
kind ref status
other go vet ./modules/surf/... && go test ./modules/surf -short -count=1 pass
false
id description verification human_judgment
D4 PHP translate tree at SHA 725d547 is unchanged
kind ref status
other git -C /media/nvme/dev/golem15/fonoteka/plugins/golem15/translate status --short (empty) and rev-parse HEAD pass
false
16min 2026-10-06 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