--- phase: 14.2.1-translate-plugin reviewed: 2026-10-06T14:35:40Z depth: standard files_reviewed: 18 files_reviewed_list: - modules/cabana/schema_types.go - modules/cabana/field_ml.go - modules/cabana/crud.go - modules/cabana/http.go - modules/cabana/relation.go - modules/cabana/relation_child.go - modules/cabana/ml_test.go - modules/cabana/ml_smoke_test.go - modules/cabana/relation_child_ml_test.go - 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/tests/form/MLFields.test.ts - admin/tests/form/formState.test.ts - ../sm-translate-plugin/classes/admin_writer.go findings: critical: 0 warning: 0 info: 0 total: 0 status: clean --- # Phase 14.2.1: Code Review Report **Reviewed:** 2026-10-06T14:35:40Z **Depth:** standard **Files Reviewed:** 18 **Status:** clean ## Summary Standard-depth re-review of the Plan 05/06 gap closure (CR-01 hydration + WR-02 relation-child lift). Source was read directly; plan SUMMARYs were not treated as evidence. `classes.TranslatedExact` in the plugin (callee of `AdminWriter.TranslatedExact`) was traced for D-11 only. All reviewed files meet quality standards. No issues found. The eight look-fors from this pass are closed in code: | Look-for | Result | |---|---| | D-11 fallback leaking into `TranslatedExact` / `hydrateMLRecord` | Closed. `hydrateMLRecord` calls `TranslationWriter.TranslatedExact` only for non-default codes and writes `""` when `ok` is false. `AdminWriter.TranslatedExact` delegates to `classes.TranslatedExact`, which returns the stored key or `ok=false` and never the host column. `classes.Translated` (D-11) is not on this path. `TestMLHydration` english-only row yields `pl: ""`. | | Nested maps dropped on `fillChild` | Closed. `CreateChild` / `UpdateChild` call `liftMLValues` on `in.Body` before `fillChild`, so the default locale is a host scalar by the time `projectOperation` → `ProjectWritableFields` runs. `applyMLTranslations` runs after the child PK. `TestRelationChildMLNestedSave` asserts host `Hello`, Polish attrs, and `de` 422 with no insert. `fillChild` itself is only used from those two callers. | | List-row hydration leaking translations | Closed. `hydrateMLRecord` is called from `CRUDService.ShowRecord` / `save` and `RelationService` Create/Update/Show child only. `ExecuteList` → `projectRow` is unchanged. `listSchema` Localize sets `FormMeta{Locale: locale}` with no `EnabledLocales`. Relation linked/candidate queries select host columns. | | Cabana importing the plugin | Closed. Cabana has no `sm-translate` import. `crud()` and `relations()` both `Lookup[TranslationWriter]()`. Plugin `AdminWriter` implements the framework interface. | | New routes | Closed. Plan 05/06 reuse existing form/relation-schema, record, and child record routes. No translate-read or translate-write endpoint. | | Locale validation bypass | Closed. `liftMLValues` still rejects unknown codes, non-strings, and a missing default locale as 422 before Fill. Child saves use the same helper inside the child transaction. | | SPA selector not using `FORM_ENABLED_LOCALES` | Closed. `MLTextField` / `MLMarkdownField` inject `FORM_ENABLED_LOCALES` and list those codes. They no longer derive options from `Object.keys(value)` or hardcode `['en']` as the option list. `FormView` provides the inject from `schema.meta.enabledLocales`; `RelationChildModal` re-provides the parent inject. | | `adopt` wiping sibling locales | Closed. `FormView.adopt` and `RelationChildModal.adopt` call `mergeMLValue`. A map overlays the seeded `{code: ""}` object. A leftover host string becomes the first enabled code and keeps sibling keys. Create seeds via `initialValues(fields, enabledLocales)`. | WR-01, WR-03, and IN-01..IN-04 were out of scope for this closure and were not re-opened. Host CRUD still calls `liftMLValues` on `s.DB` before `s.transaction` (same as the prior WR-01 note); the child path now reads locales on `tx`, which is not a regression. ## Prior findings resolved ### CR-01 (resolved): Admin ML fields never surface enabled locales on create, load, or save Fixed in Plan 05, confirmed in source: - `FormMeta.EnabledLocales` (`schema_types.go`) is copied onto protect()'d form schema `view.Meta` and the envelope, and onto relation-schema envelope meta (`http.go` `formSchema` / `relationSchema` / `enabledContentLocales`). - `CRUDService.ShowRecord` and `save` run `hydrateMLRecord` after `projectFullRecord` (`crud.go`). - SPA create seeds `{[code]: ""}`; selectors read `FORM_ENABLED_LOCALES`; `adopt` merges through `mergeMLValue` (`formState.ts`, `FormView.vue`, both ML field components, `RelationChildModal.vue`). ### WR-02 (resolved): Relation-child saves drop nested ML maps Fixed in Plan 06, confirmed in source: - `RelationService.writer` is the same unexported `TranslationWriter` Lookup as `CRUDService` (`relation.go`, `http.go` `relations()`). - `CreateChild` / `UpdateChild`: `liftMLValues` → `fillChild` → row write → `applyMLTranslations` → `hydrateMLRecord`. - `ShowChild` hydrates with op `"update"`. - `TestRelationChildMLNestedSave` covers create, update, show, and undeclared `de`. ## Narrative Findings (AI reviewer) None. --- _Reviewed: 2026-10-06T14:35:40Z_ _Reviewer: the agent (gsd-code-reviewer)_ _Depth: standard_