From 5b1d8b01fb52697b6f733dbe5ca6ad2e9b3d248c Mon Sep 17 00:00:00 2001 From: Jakub Zych Date: Tue, 6 Oct 2026 16:36:03 +0200 Subject: [PATCH] docs(14.2.1): code review after gap closure Co-authored-by: Cursor --- .../14.2.1-translate-plugin/14.2.1-REVIEW.md | 86 +++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 .planning/phases/14.2.1-translate-plugin/14.2.1-REVIEW.md diff --git a/.planning/phases/14.2.1-translate-plugin/14.2.1-REVIEW.md b/.planning/phases/14.2.1-translate-plugin/14.2.1-REVIEW.md new file mode 100644 index 0000000..cba989d --- /dev/null +++ b/.planning/phases/14.2.1-translate-plugin/14.2.1-REVIEW.md @@ -0,0 +1,86 @@ +--- +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_