docs(14.2.1-05): complete hydrate enabled locales on admin ML forms plan
This commit is contained in:
218
.planning/phases/14.2.1-translate-plugin/14.2.1-05-SUMMARY.md
Normal file
218
.planning/phases/14.2.1-translate-plugin/14.2.1-05-SUMMARY.md
Normal file
@@ -0,0 +1,218 @@
|
||||
---
|
||||
phase: 14.2.1-translate-plugin
|
||||
plan: 05
|
||||
subsystem: i18n
|
||||
tags: [translate, cabana, mltext, mlmarkdown, TranslatedExact, hydrateMLRecord, FORM_ENABLED_LOCALES, CR-01]
|
||||
|
||||
requires:
|
||||
- phase: 14.2.1-04
|
||||
provides: "ML nested save, TranslationWriter adapter, TestMLNestedSave, SPA MLFields, phase gate"
|
||||
provides:
|
||||
- "FormMeta.EnabledLocales on protect()'d form and relation schemas"
|
||||
- "TranslationWriter.TranslatedExact plus hydrateMLRecord on Show/save record maps"
|
||||
- "SPA FORM_ENABLED_LOCALES inject, create seed maps, and adopt merge"
|
||||
- "Regenerated OpenAPI, schema.d.ts, docs, and boardwalk dist"
|
||||
affects: [14.2.1-06, 15-journal-plugin]
|
||||
|
||||
actuals:
|
||||
tokens: 12147
|
||||
tasks: 3
|
||||
commits: 2
|
||||
plan_head_before: ed81f2a0c164d775ff6ee6ad122aecd4a153e16e
|
||||
plan_head_after: 424fe9ccc06d34436e148add6334d1c2206723c2
|
||||
plugin_repo_head_after: 11ac3288d2f6775bfc22598c94ffe7dacf3c3dd1
|
||||
|
||||
tech-stack:
|
||||
added: []
|
||||
patterns:
|
||||
- "Admin GET/save hydrates declared ML fields through TranslationWriter.TranslatedExact; missing non-default locales stay empty (no D-11 fallback)"
|
||||
- "SPA ML selectors read FORM_ENABLED_LOCALES from schema meta; adopt merges maps instead of replacing with a host scalar"
|
||||
|
||||
key-files:
|
||||
created: []
|
||||
modified:
|
||||
- modules/cabana/schema_types.go
|
||||
- modules/cabana/field_ml.go
|
||||
- modules/cabana/crud.go
|
||||
- modules/cabana/http.go
|
||||
- modules/cabana/ml_test.go
|
||||
- modules/cabana/ml_smoke_test.go
|
||||
- modules/cabana/README.md
|
||||
- docs/backend/forms.md
|
||||
- docs/backend/admin-controllers.md
|
||||
- admin/src/components/form/formContext.ts
|
||||
- admin/src/components/form/formState.ts
|
||||
- admin/src/views/FormView.vue
|
||||
- admin/src/components/form/fields/MLTextField.vue
|
||||
- admin/src/components/form/fields/MLMarkdownField.vue
|
||||
- admin/src/components/relation/RelationChildModal.vue
|
||||
- admin/src/components/relation/RelationPickerModal.vue
|
||||
- admin/tests/form/MLFields.test.ts
|
||||
- admin/tests/form/formState.test.ts
|
||||
- admin/openapi/admin.json
|
||||
- admin/src/api/schema.d.ts
|
||||
- modules/boardwalk/dist/
|
||||
- ../sm-translate-plugin/classes/admin_writer.go
|
||||
|
||||
key-decisions:
|
||||
- "writer-exact: add TranslatedExact to cabana.TranslationWriter; AdminWriter delegates to classes.TranslatedExact"
|
||||
- "hydrateMLRecord runs after projectFullRecord on Show/save only; list rows stay host scalars"
|
||||
- "FORM_ENABLED_LOCALES is SPA-only; docs name cabana identifiers EnabledLocales, TranslatedExact, hydrateMLRecord"
|
||||
|
||||
patterns-established:
|
||||
- "Exact admin reads go through TranslationWriter.TranslatedExact on the same Lookup as WriteTranslated; cabana never imports sm-translate-plugin"
|
||||
- "Create seeds {code: \"\"} for every enabled locale; adopt overlays localeRecord and places a host string on the default locale without dropping siblings"
|
||||
|
||||
requirements-completed: [D-06, D-17]
|
||||
|
||||
coverage:
|
||||
- id: D1
|
||||
description: "Show/save RecordResult.Data for declared mltext/mlmarkdown is a locale map; missing pl is empty, not D-11 English; host column stays the default scalar"
|
||||
requirement: D-17
|
||||
verification:
|
||||
- kind: unit
|
||||
ref: "modules/cabana#TestMLHydration"
|
||||
status: pass
|
||||
- kind: unit
|
||||
ref: "modules/cabana#TestMLNestedSave"
|
||||
status: pass
|
||||
human_judgment: false
|
||||
- id: D2
|
||||
description: "Create seeds empty maps for every enabled locale; FormView.adopt merges a GET host string without dropping sibling keys; MLTextField options equal FORM_ENABLED_LOCALES"
|
||||
requirement: D-06
|
||||
verification:
|
||||
- kind: automated_ui
|
||||
ref: "admin/tests/form/MLFields.test.ts"
|
||||
status: pass
|
||||
- kind: unit
|
||||
ref: "admin/tests/form/formState.test.ts"
|
||||
status: pass
|
||||
human_judgment: false
|
||||
- id: D3
|
||||
description: "MLMarkdownField and RelationChildModal share the inject/seed/adopt path; OpenAPI FormMeta.enabledLocales, docs, and boardwalk dist stay in sync"
|
||||
requirement: D-06
|
||||
verification:
|
||||
- kind: automated_ui
|
||||
ref: "admin/tests/form/MLFields.test.ts"
|
||||
status: pass
|
||||
- kind: other
|
||||
ref: "bash scripts/check-admin-openapi.sh --check"
|
||||
status: pass
|
||||
- kind: other
|
||||
ref: "go test ./cmd/summer -run TestDocsTree"
|
||||
status: pass
|
||||
- kind: unit
|
||||
ref: "sm-translate-plugin/classes#TestTranslatableGetSet"
|
||||
status: pass
|
||||
human_judgment: false
|
||||
|
||||
duration: 11min
|
||||
completed: 2026-10-06
|
||||
status: complete
|
||||
---
|
||||
|
||||
# Phase 14.2.1 Plan 05: Hydrate enabled locales on admin ML forms Summary
|
||||
|
||||
**Admin ML create/GET/save hydrates every enabled locale through `TranslationWriter.TranslatedExact` so the SPA lists en+pl together and posts full locale maps (CR-01)**
|
||||
|
||||
## Performance
|
||||
|
||||
- **Duration:** 11 min
|
||||
- **Started:** 2026-10-06T13:32:15Z
|
||||
- **Completed:** 2026-10-06T13:43:26Z
|
||||
- **Tasks:** 3
|
||||
- **Files modified:** 24
|
||||
|
||||
## Accomplishments
|
||||
|
||||
- Task 1 locked **writer-exact**: `TranslatedExact` is a required method on `cabana.TranslationWriter`. Cabana does not import the plugin. `classes.TranslatedExact` still skips D-11 fallback.
|
||||
- Show/save record payloads expand declared `mltext`/`mlmarkdown` fields to `{locale: value}` via `hydrateMLRecord`. Default locale comes from the host column; other codes come from exact stored values; missing non-default codes are empty strings. List rows stay scalars.
|
||||
- Protect()'d `formSchema` and `relationSchema` copy `TranslationWriter.EnabledLocales` onto `FormMeta.enabledLocales`. Create seeds `{en: "", pl: ""}`. `FormView` / `RelationChildModal` adopt merges maps so a host string cannot wipe sibling locales. ML selectors read `FORM_ENABLED_LOCALES`.
|
||||
- OpenAPI, `schema.d.ts`, cabana README, forms/admin-controllers docs, and `modules/boardwalk/dist/` regenerated. WR-02 `fillChild` is unchanged (Plan 06).
|
||||
|
||||
## Task Commits
|
||||
|
||||
Each task was committed atomically:
|
||||
|
||||
1. **Task 1: Confirm TranslationWriter.TranslatedExact as the hydration contract** — decision `writer-exact` (no code commit)
|
||||
2. **Task 2: Hydrate one mltext create/GET/save path and show en+pl on the SPA**
|
||||
- `0f8d137` (feat) summercms.go — hydrate ML create/GET/save through TranslatedExact
|
||||
- `11ac328` (feat) sm-translate-plugin — AdminWriter.TranslatedExact delegates to classes.TranslatedExact
|
||||
3. **Task 3: Cover mlmarkdown, relation-child adopt, and regenerate docs/OpenAPI/TS/dist**
|
||||
- `424fe9c` (feat) summercms.go — mlmarkdown, child adopt, docs/OpenAPI/dist
|
||||
|
||||
**Plan metadata:** this SUMMARY commit
|
||||
|
||||
Nothing was pushed. Dist replacement deleted `modules/boardwalk/dist/assets/index-CT96jdWe.js` and added `index-B08bxLq5.js` (intentional Vite hash).
|
||||
|
||||
## Files Created/Modified
|
||||
|
||||
- `modules/cabana/schema_types.go` — `FormMeta.EnabledLocales` (`json:"enabledLocales,omitempty"`)
|
||||
- `modules/cabana/field_ml.go` — `TranslationWriter.TranslatedExact`, `hydrateMLRecord`, recordingWriter exact reads
|
||||
- `modules/cabana/crud.go` — hydrate after `projectFullRecord` on Show and save
|
||||
- `modules/cabana/http.go` — form/relation schema Lookup copies enabled locales onto envelope meta
|
||||
- `modules/cabana/ml_test.go` — `TestMLHydration`; `TestMLNestedSave` projected title is the hydrated map
|
||||
- `modules/cabana/ml_smoke_test.go` — nested-save smoke expects the hydrated title map
|
||||
- `admin/src/components/form/formContext.ts` — `FORM_ENABLED_LOCALES`
|
||||
- `admin/src/components/form/formState.ts` — `initialValues(fields, enabledLocales)`, `mergeMLValue`
|
||||
- `admin/src/views/FormView.vue` — provide inject; create seed; adopt merge
|
||||
- `admin/src/components/form/fields/MLTextField.vue` / `MLMarkdownField.vue` — selector options from inject
|
||||
- `admin/src/components/relation/RelationChildModal.vue` — re-provide inject; seed and adopt merge
|
||||
- `admin/src/components/relation/RelationPickerModal.vue` — pivot `initialValues(..., [])`
|
||||
- `admin/tests/form/MLFields.test.ts` — create-empty and GET-string merge for mltext and mlmarkdown
|
||||
- `admin/tests/form/formState.test.ts` — seed maps and merge helper
|
||||
- `admin/openapi/admin.json`, `admin/src/api/schema.d.ts` — `enabledLocales?: string[]`
|
||||
- `modules/boardwalk/dist/` — Vite build matching the SPA change
|
||||
- `modules/cabana/README.md`, `docs/backend/forms.md`, `docs/backend/admin-controllers.md` — hydration contract
|
||||
- `../sm-translate-plugin/classes/admin_writer.go` — `AdminWriter.TranslatedExact`
|
||||
|
||||
## Decisions Made
|
||||
|
||||
- **writer-exact** (Task 1, user-selected): add `TranslatedExact` to the published `cabana.TranslationWriter` interface; `AdminWriter` delegates to `classes.TranslatedExact`. Rejected optional-reader (hydration would silently no-op) and import-plugin (cabana must not import sm-translate-plugin).
|
||||
- Hydration is Show/save only; `Localize` stays cache/no-DB; list Meta stays locale-only.
|
||||
- `FORM_ENABLED_LOCALES` is documented as SPA-only so the docs identifier checker does not treat it as a Go ident.
|
||||
|
||||
## Deviations from Plan
|
||||
|
||||
### Auto-fixed Issues
|
||||
|
||||
**1. [Rule 3 - Blocking] Vitest `--run` path vs include glob**
|
||||
- **Found during:** Task 2 verify
|
||||
- **Issue:** `npm --prefix admin test -- --run admin/tests/form/MLFields.test.ts` finds no files because Vitest include is `tests/**` under `admin/`.
|
||||
- **Fix:** Ran `tests/form/MLFields.test.ts` (and the same relative paths in Task 3). Same pattern as 14.2.1-04.
|
||||
- **Files modified:** none (verify command only)
|
||||
- **Verification:** Task 2 then Task 3 Vitest PASS
|
||||
- **Committed in:** n/a
|
||||
|
||||
**2. [Rule 1 - Bug] vue-tsc rejected MLFields mount props**
|
||||
- **Found during:** Task 3 `npm --prefix admin run typecheck`
|
||||
- **Issue:** `mlMount` passed `Record<string, unknown>` into Vue `props` (TS2322).
|
||||
- **Fix:** Cast mount props `as never`.
|
||||
- **Files modified:** `admin/tests/form/MLFields.test.ts`
|
||||
- **Verification:** `npm --prefix admin run typecheck` PASS
|
||||
- **Committed in:** `424fe9c`
|
||||
|
||||
---
|
||||
|
||||
**Total deviations:** 2 auto-fixed (1 blocking verify path, 1 typecheck)
|
||||
**Impact on plan:** Required for green Task 2/3 gates. No scope creep. `fillChild` untouched. No gormigrate file. No npm pin change (T-14.2.1-SC).
|
||||
|
||||
## Issues Encountered
|
||||
|
||||
- Task 3 combined gate used the Vitest relative paths above; plugin `TestTranslatableGetSet` still PASS after `AdminWriter.TranslatedExact`.
|
||||
- Unrelated dirty `.planning/` files from other sessions were left unstaged.
|
||||
- `requirements.mark-complete D-06 D-17` was a no-op: those IDs are CONTEXT.md decisions, not rows in REQUIREMENTS.md (`not_found`). They remain recorded on this SUMMARY's `requirements-completed`.
|
||||
|
||||
## User Setup Required
|
||||
|
||||
None - no external service configuration required.
|
||||
|
||||
## Next Phase Readiness
|
||||
|
||||
CR-01 is closed on the admin form path (D-06, D-17). Plan 06 still owns WR-02 (`fillChild` must lift nested ML maps on relation-child saves) and named tests last. Journal (Phase 15) can keep translatable fields once WR-02 lands.
|
||||
|
||||
---
|
||||
*Phase: 14.2.1-translate-plugin*
|
||||
*Completed: 2026-10-06*
|
||||
|
||||
## Self-Check: PASSED
|
||||
Reference in New Issue
Block a user