- mltextarea compiles (with size), binds as a writable scalar and goes
through the mltext lift, translation write and hydrate paths
- preset on or from an mltextarea field stays refused
- tests: compile, Postgres round trip over a nullable host column with
multi-line text, invalid locale maps, preset refusals
- schema_types.go and the form-schema swag description name text or mltext
- regenerated admin/openapi/admin.json and admin/src/api/schema.d.ts
- README and docs/backend/forms.md describe the per-locale rules
- formState: changedLocales and presetUpdates hold the preset-follow rules
for text and mltext pairs
- FormView applies presetUpdates on create, tracks per-locale hand edits of
ML fields and follows the active ML locale
- rebuilt modules/boardwalk/dist
- compilePresetKey admits a text or mltext target
- checkPresets admits a text or mltext source
- TestPresetML pins every text/mltext pairing and the refusals
- check-phase10, 12.1, 12.2 and 14.2.1 drop only the exact
MarkdownField.vue line binding sanitizedHtml (server-rendered by
cabana.RenderMarkdown); every other raw-HTML sink is still refused
- MarkdownField posts the source to POST /markdown/preview when Preview
opens and again 300 ms after a change while open; stale answers dropped
- the pane binds only data.html of a 2xx answer; a refusal is a text notice
- mlmarkdown previews the active locale and follows a locale switch
- .summer-markdown style kit restores headings, lists, code and tables
- vitest coverage, forms.md and rebuilt modules/boardwalk/dist
- POST {prefix}/api/v1/markdown/preview renders {markdown} through
cabana.RenderMarkdown in the backend-guarded group behind requireAjax
- refused output is a 422 validation_failed on markdown with a fixed message
- swag annotation, regenerated admin.json and schema.d.ts
- route inventories, CSRF walk (26) and OpenAPI conformance learn the route
- README and docs/backend/forms.md document the route
- table-driven hostScalarString cases for nil and live pointers to string, ints, uint, float, bool, []byte, named string and double pointers
- DB-free hydrateMLRecord cases for nil, empty and filled *string hosts
- hostScalarString walks pointers via reflect; nil at any depth is ""
- string kinds return raw text, byte slices decode, other kinds format the dereferenced value
- Postgres round-trip regression for an mltext field on a *string column
Copy overwrote the active locale with the other locale's often-empty string, so the editor went blank. Keep a single synchronized locale picker.
Co-authored-by: Cursor <cursoragent@cursor.com>
WR-02 proofs and T-14.2.1-19..23 must fail the phase closed if hydration or child locale validation is removed.
Co-authored-by: Cursor <cursoragent@cursor.com>
UpdateChild and ShowChild now lift, apply, and hydrate nested locales the same way as host CRUD, so a child form keeps English on the column and Polish through the writer.
Co-authored-by: Cursor <cursoragent@cursor.com>
RelationService looks up TranslationWriter like CRUDService so CreateChild can lift locale maps before fillChild, write Polish after the child PK, and return a hydrated title map.
Co-authored-by: Cursor <cursoragent@cursor.com>
MLMarkdownField and relation-child forms share the enabled-locale
inject and adopt merge; OpenAPI, types, docs, and boardwalk dist match.
Co-authored-by: Cursor <cursoragent@cursor.com>
Form schema meta lists enabled locales, Show/save expand mltext maps
without D-11 fallback, and the SPA seeds and adopt-merges every locale.
Co-authored-by: Cursor <cursoragent@cursor.com>
Require named PASS lines, real Postgres, sibling go -C, and a closed high-threat review before the phase gate can pass.
Co-authored-by: Cursor <cursoragent@cursor.com>
- Document markdown, mltext, and mlmarkdown plus TranslationWriter save semantics
- Extend the SPA registry tests and rebuild committed boardwalk dist
Co-authored-by: Cursor <cursoragent@cursor.com>
Lift locale maps before ProjectWritableFields so a Journal-shaped save can persist the default host scalar and non-default locales through TranslationWriter without dropping nested JSON.
Co-authored-by: Cursor <cursoragent@cursor.com>
Look up a backpack-published resolver so a compiled translate plugin can
strip an enabled URL prefix and write a validated locale onto context.
Co-authored-by: Cursor <cursoragent@cursor.com>