Files
summercms/.planning/quick/261006-t5r-make-spa-slug-preset-follow-mltext-sourc/261006-t5r-SUMMARY.md
2026-10-06 21:21:15 +02:00

7.0 KiB

phase, plan, subsystem, tags, status, requires, provides, affects, tech-stack, key-files, decisions, metrics, estimate, actuals, plan_head_before, plan_head_after
phase plan subsystem tags status requires provides affects tech-stack key-files decisions metrics estimate actuals plan_head_before plan_head_after
quick-261006-t5r 01 cabana forms / admin SPA
preset
mltext
slug
admin-spa
forms
complete
fields.yaml preset on text and mltext targets with text or mltext sources
SPA preset follow per locale (formState.presetUpdates, changedLocales)
sm-journal-plugin (post and category slug presets; YAML snippet below, not applied here)
added patterns
Pure preset-follow rules in formState.ts; FormView only tracks edits and the active ML locale
created modified
modules/cabana/preset_ml_test.go
modules/cabana/form_schema.go
modules/cabana/phase121_form_test.go
modules/cabana/phase121_schema_boot_test.go
admin/src/components/form/formState.ts
admin/src/views/FormView.vue
admin/tests/form/formState.test.ts
admin/tests/form/FormView.test.ts
modules/boardwalk/dist/index.html
modules/boardwalk/dist/assets/index-DPCIeFlT.js
modules/cabana/schema_types.go
modules/cabana/admin_openapi.go
admin/openapi/admin.json
admin/src/api/schema.d.ts
modules/cabana/README.md
docs/backend/forms.md
ML -> ML presets follow per locale: only locales whose source text changed are rewritten, each from its own locale
Hand edits of an ML preset target are tracked per locale; editing locale L stops only L
A preset never writes a locale the administrator neither typed in nor sees: text -> mltext writes only the active locale
mltext -> text follows the source's active-locale string (FormView tracks the active ML locale via ML_LOCALE_CHANGE)
mlmarkdown stays out: server admits only text/mltext targets and sources
duration completed
~13 min 2026-10-06
tokens tasks
70000 3
tokens tasks commits
13500 3 3
7e2b1a909b 5932172148

Quick 261006-t5r: Make SPA slug preset follow mltext source Summary

fields.yaml preset now works on mltext fields: cabana accepts text/mltext targets and sources, and the admin SPA follows an mltext title into an mltext slug per locale, stopping only the locale the administrator edits by hand.

What changed

Task 1 - cabana (7afad73, feat(cabana): accept preset on mltext fields)

  • compilePresetKey admits type: text or type: mltext; anything else fails with preset is only valid on type: text or mltext.
  • checkPresets admits a text or mltext source; otherwise field %s: preset field %s must be a text or mltext field.
  • New DB-free TestPresetML (RED confirmed before the change) covers mltext->mltext (mapping, short form, exact), text->mltext, mltext->text, and the refusals (mlmarkdown and markdown targets, mlmarkdown source). The Journal-shaped field serializes with "type":"mltext" and "preset":{"field":"title","type":"slug"}.
  • TestPresetSchema / TestPhase121BootErrors rows updated to the new messages (testcontainers Postgres, green). Settings and relation forms still refuse preset.

Task 2 - admin SPA (b5d8506, feat(admin): follow presets on mltext fields per locale)

  • formState.ts: changedLocales(previous, next) and presetUpdates(fields, source, previous, next, values, activeLocale, isEdited) (plus PresetEdited type) hold every preset-follow rule; all values still go through presetValue, so slug/exact remain one implementation.
  • FormView.vue: update() reads the previous value, records per-locale hand edits of ML fields in editedLocales, and on create merges presetUpdates into the next values. mlLocale follows the window ML_LOCALE_CHANGE event, starts on the first enabled locale after load, and resets to it when activeTab changes. Update mode unchanged.
  • Tests: 6 new formState unit cases, 4 new FormView cases (Journal ML->ML per-locale with POST body check, update mode, mltext->text, text->mltext). The existing text preset test is unchanged and green. Full Vitest: 1064 passed; vue-tsc clean.
  • modules/boardwalk/dist rebuilt (old index-7UEAlsFO.js removed, index-DPCIeFlT.js added; intentional hashed-bundle swap); check-admin-dist.sh reports a match.

Task 3 - docs (5932172, docs(cabana): document preset on mltext fields)

  • schema_types.go Preset/FieldPreset comments and the form-schema swag description in admin_openapi.go name text or mltext; admin.json and schema.d.ts regenerated with scripts/check-admin-openapi.sh (the --check gate passes).
  • modules/cabana/README.md (Features bullet, cabana.FieldPreset row) and docs/backend/forms.md (Field options list, preset paragraph, new multilingual-rules paragraph, start-up refusal sentence, and a pointer from the Markdown and multilingual fields section to #field-options).
  • TestDocsTree, go vet ./... and go test ./... green.

Discretion choices (from the plan)

  • ML -> ML follows per locale: only the locales whose source text changed in this update are rewritten, each from its own locale.
  • Edits of an ML target are tracked per locale: a hand edit of locale L stops L only.
  • A preset never writes a locale the administrator neither typed in (source side) nor is looking at (target side): text -> mltext writes only the active locale; untouched locales stay empty so the server's translation fallback applies, and no unseen duplicate translations get saved.
  • mltext -> text follows the source's active-locale string (FormView tracks the active ML locale).
  • mlmarkdown stays out: the server admits text/mltext targets and text/mltext sources only.

Plugin follow-up (sm-journal-plugin, NOT edited in this task)

sm-journal-plugin was not edited. Apply in that repo:

models/post/fields.yaml, the slug field gains a preset:

    slug:
        label: golem15.journal::lang.post.slug
        type: mltext
        span: right
        tab: golem15.journal::lang.post.tab_edit
        required: true
        preset:
            field: title
            type: slug

models/category/fields.yaml, the slug field gains preset: { field: name, type: slug } the same way (its source name is mltext). models/tag/fields.yaml already has a text -> text preset and needs nothing.

Deviations from Plan

None - plan executed exactly as written. (Process note: the formState helpers were written just before their tests; RED was then demonstrated by running the new tests against the committed formState.ts/FormView.vue — 9 failures — before restoring the implementation.)

Known Stubs

None.

Threat Flags

None. No new routes or trust-boundary surface; the server-side widening admits exactly text and mltext (pinned by TestPresetML), and preset output remains client convenience validated by the normal save path.

Self-Check: PASSED

  • FOUND: modules/cabana/preset_ml_test.go
  • FOUND: commits 7afad73, b5d8506, 5932172 (no co-author trailers, no .planning files)
  • Gates: check-admin-dist, check-admin-openapi --check, TestDocsTree, go vet ./..., go test ./..., Vitest full suite, vue-tsc