|
| 1 | +// Copyright (c) 2026 ObjectStack. Licensed under the Apache-2.0 license. |
| 2 | + |
| 3 | +import type { SemanticMigration } from '../../types.js'; |
| 4 | + |
| 5 | +// #20901 — the form-view carrier of the inline grid column. `subforms[].columns` |
| 6 | +// was `z.array(z.any())` while the other carrier, a relationship field's |
| 7 | +// `inlineColumns`, has been the strict `InlineGridColumnSchema` since #9227; the |
| 8 | +// carrier now REFERENCES that schema, so both carriers are judged by one |
| 9 | +// contract. D3 only, deliberately: the one mechanical respelling the family |
| 10 | +// had (`field` → `name`, conversion `field-column-lists-canonicalized`) is |
| 11 | +// already retired from the load path, and every other refused shape is a |
| 12 | +// judgment only the author can make. A stored view whose column fails is |
| 13 | +// refused with the column schema's own prescription, never stripped. |
| 14 | +export const entry: SemanticMigration = { |
| 15 | + id: 'form-view-subform-columns-closed', |
| 16 | + surface: 'view.form.subforms[].columns[] and view.formViews.<key>.subforms[].columns[] — the ' |
| 17 | + + 'form view\'s inline grid columns, which used to accept any value', |
| 18 | + replacement: 'each entry is the strict, name-keyed inline grid column a relationship field\'s ' |
| 19 | + + '`inlineColumns` takes — `{ name, label?, type?, … }`, where `{ name }` alone hydrates the rest ' |
| 20 | + + 'from the child object\'s field. Write `name` where a column said `field` (or `fieldName`, ' |
| 21 | + + '`key`); delete `scale` from a column declaring `type: \'currency\'`; delete any key the ' |
| 22 | + + 'column schema does not declare.', |
| 23 | + reason: 'Both carriers feed the one console grid, which reads only the keys the column schema ' |
| 24 | + + 'declares and keys a column by `name` alone. On the form view the columns were never judged, ' |
| 25 | + + 'so a mis-keyed column published clean and drew a blank grid column, and a key the other ' |
| 26 | + + 'carrier refuses — `scale` on a currency column, under the maintainer\'s ruling of 2026-09-23 ' |
| 27 | + + '(option B, `scale` retired from the currency type) and the remedy ruled on 2026-09-24 ' |
| 28 | + + '(option 乙 — a currency\'s ISO 4217 minor unit decides its display) — published green here. ' |
| 29 | + + 'The carrier now references the column schema, so every rule it holds applies here too, with ' |
| 30 | + + 'its own prescription. NOT mechanically converted: the `field` → `name` respelling this family ' |
| 31 | + + 'had is already retired from the load path, and which column an unknown key or a mixed ' |
| 32 | + + '`field`/`name` entry meant is the author\'s call — a conversion that dropped the key would ' |
| 33 | + + 'accept on every load what the parse now refuses. Population measured at the change, on ' |
| 34 | + + 'origin/main cb4c31dd52: zero authored `subforms` in the repository (the showcase derives its ' |
| 35 | + + 'master-detail grids from the data model instead), against one authored `inlineColumns` block ' |
| 36 | + + 'as the control. Deployed metadata NOT MEASURED.', |
| 37 | + acceptanceCriteria: 'Every view in the stack parses: `objectstack validate` and a view parse report ' |
| 38 | + + 'no issue on a `subforms[].columns[]` path. Every column entry is an object carrying `name`, ' |
| 39 | + + 'no entry carries `field`, `fieldName` or `key`, and no column declaring `type: \'currency\'` ' |
| 40 | + + 'carries `scale`. Each column `name` names a field of the subform\'s `childObject`, and the ' |
| 41 | + + 'master-detail grid renders a value — not a blank cell — in each column for a row that has one.', |
| 42 | +}; |
0 commit comments