Repository navigation
Conversation
Upd4ting
force-pushed
the
fix/interface-dms-stored-row
branch
3 times, most recently
from
November 13, 2026 17:54
1a95aba to
36f5d06
Compare
Upd4ting
force-pushed
the
fix/interface-dms-stored-row
branch
from
November 13, 2026 19:11
36f5d06 to
b672b01
Compare
Upd4ting
added a commit
that referenced
this pull request
Nov 13, 2026
…ements them and break the table-view/data-types cycle (#904) Part of ANT-1088: every suppression in `guardrails.suppressions.json` goes, by fixing the code it hides. Some suppressions existed only because a **published** type said something the runtime does not do. Antony decided to fix those types in one **breaking** PR, together with the last interface-dms import cycle (cycle A, table-view ↔ data-types). ⚠ sensitive: it changes the interface-dms contract (published declarations, a required export-ownership schema) and module evaluation order. Export access now refuses a stored context its schema rejects. Every break is listed with its TypeScript error and migration in `packages/interface-dms/UPGRADING.md` (Unreleased) and `packages/dms/docs/02.building/18.migration-0-13-to-0-14.md`. ## Summary | Change | Before | After | Suppression removed | | --- | --- | --- | --- | | Table-view data function receivers: `listWithSearch`, `countWithSearch`, `summarizeWithSearch`, `startExport`, `getExportStatus`, `downloadExport`, `validateRowsAgainstRule`, `fetchRowForGuard`, `RowBulkOperationParams` | `DataControllerCallback \| DataControllerCallbackWithOptions` | `DataControllerInstance` (what every route passes as `this`) | nav-badges `SAFETY:` cast | | `ExportJobGenerateContext.context` | `TContext` | `TContext \| undefined` (a job may start without one) | `export-jobs-run.ts` `SAFETY:` cast | | Export ownership | `isOwnedBy(record, context: TContext)` on unparsed stored JSON | `isOwnedBy` must come with `contextSchema` (zod); the stored context is parsed through it, and a refused one answers 403 | `export-jobs-run.ts` `no-unsafe-assignment` | | `TableViewRoutes.ExportRoutes` | `Record<string, DataControllerCallback \| …>` | its three typed routes, carried by `TableViewRoutes.All`, members and roles | `no-known-value-widening` | | `TableViewMeta.footerSummary` | `TableViewFooterSummary<any> \| undefined` | `TableViewFooterSummary \| undefined`, checked when declared | `routes.ts` `no-unsafe-assignment` | | `DmsCascader` props, and the Cascader `fallback` option | six props declared, never read; `fallback` forwarded to the picker | removed | — | | Cycle A | `table-view/meta` ↔ data-types barrel ↔ `default-types`, plus a lazy `require` in `relation-endpoints` | `default-types` no longer imports `table-view/meta`; `relation-endpoints` reads the class from a slot that `TableViewMeta` fills from its static block | 3 `import/no-cycle`, 1 `no-unsafe-assignment` | ```diff base/data-types/default-types - -> table-view/meta (the cycle edge) base/data-types/internal/relation-endpoints - require("table-view/meta") (lazy require) + -> internal/table-view-meta-slot (new @internal leaf, filled by TableViewMeta's static block) ``` Budget against main: - `import/no-cycle` 3 → 0 - `typescript/no-unsafe-assignment` 5 → 2 - `anti-slop/no-known-value-widening` 2 → 1 - `SAFETY:` 37 → 35 Nothing rises. ## Evidence - **Break forms, compiled.** A scratch consumer compiled against main and against this branch confirms each break and its error code in the upgrade notes: TS2345, TS2322, TS2558, TS2739, TS7053, TS18048, TS2312, TS2422, TS2416, TS2425, TS2353. - **Every new test fails on a wrong implementation**, each broken once on purpose: - `export-job-access.test.mjs` (interface-dms): fails when the schema is skipped, and when raw JSON is read instead of the parsed context. - `table-view-export-access.test.ts` (integration): - status and download refuse another table view's job with 403 and serve the job's own table view; - it fails with `isOwnedBy` always true, when the controller key is ignored, and when `downloadExport` drops the access check. - `built-in-data-type-registration.test.mjs` loads 11 entries, each in a fresh process, and serializes 23 built-ins. - **Before:** with `table-view/meta` importing `data-types/core` instead of the barrel, 2 of 11 entries fail. - **After:** 11 of 11 pass. - Emptying the slot makes 3 existing dms relation tests fail. - **Cycle A evaluation order.** A built probe runs the 34 entries that reach the cycle, each in its own process. - Proxy insertions, event proxies and identities are identical in all 34. - 31 half-evaluated reads disappear, and none appear. - The module moves are listed under Attention. - The only registry change is that `default-types`, loaded alone, no longer registers `status`. - An independent check loaded all 337 dist modules alone on base and head and found the same single change. - **Suites:** - `pnpm run checks` 11 passed. - interface-dms tests 194. - `test:unit` 2627, integration 420. - frontend-vue typecheck passes; vitest 3506 passed, 1 skipped. The playground typechecks. - **api-diff** `origin/main --allow-added '**/internal/**'` exits 1 by design. The declaration differences are the changes in the table above, in 24 subpath declaration files. - Auto-imports: 944 entries unchanged. - Added (allowed): `base/data-types/internal/table-view-meta-slot`. - `readExportJobContext`, a new `@internal` function in the existing internal module `base/internal/export-jobs`, shows as a runtime addition rather than an allowed one; api-diff allows only additions in new modules. - `KeyValueType$1` moves between two declarations in the bundled `base/index`: a bundler alias artefact, with the same exported type. - The dms runtime comparison cannot complete: api-diff builds base's dms against this branch's interface, which base's export options no longer satisfy. That is the break itself. - The output is 158 KB, too large for this body, so it is summarised here. - **Independent review** (claude-sonnet-5-5): no blocker. Its findings are fixed here: the Cascader `fallback` option, the download test, and the TS2422/TS2312 and `json_context` notes. The 500 for an untyped caller is stated under Attention. ## Attention - **Cascader attributes.** `FormFieldControl` still passes `initialValue`, `loading`, `componentId`, `pageId` and `routeParams` to every field component. On `DmsCascader` they now land on its root `<div>` as attributes (`route-params="[object Object]"` among them), as they already do on sibling field components that do not declare them. The root cause, `FormFieldControl` passing them to everything, is a follow-up. - **`status` registration.** `base/data-types/default-types`, loaded alone, no longer registers `status`. Every entry that serializes a type (the barrel, any table-view entry) still registers all built-ins. - **Evaluation order.** `base/index`, `data-controllers/*` and the dms runtime now load `table-view/meta` inside `table-view/factory`. Some `base/data-types` and `table-view/internal` entries no longer load `table-view/meta` at all. Where `table-view/meta` finishes loading, every built-in is now registered; on main, most were not yet. - **Ownership check.** - A job started without a context is stored as `"null"` and is now refused under an object schema. The upgrade notes state this. - A JavaScript caller that passes `isOwnedBy` without `contextSchema` gets a 500 (`TypeError`) before its check runs. It still fails closed; the types forbid that call. - `json_context` is now parsed only when an ownership check runs. - **Not in this PR:** - `RelationType`'s `fallback` option is never read either. It is the same kind of lie, but outside this scope. - The `runExportJobProxy` `SAFETY:` and the `authorizeAction(thisObj: unknown)` directive could now take `DataControllerInstance`: a follow-up. - The `archiveFilter` cast went into #888, since it needs data-api 0.8. - **Migration guide name.** It is named for the next interface release line (0.13 → 0.14), following the existing guides' naming. ## Merge Danger **Door:** one-way once released. Modules that implement export ownership, type against the table-view data functions, `ExportRoutes` or `footerSummary`, or pass the Cascader `fallback` must migrate. In the repo it is two-way. **Blast Radius:** wide. Every module on interface-dms that touches table-view data functions, exports, footer summaries or Cascader fields, plus the load order of interface-dms entries.
Upd4ting
force-pushed
the
fix/interface-dms-stored-row
branch
from
November 13, 2026 19:30
b672b01 to
ca837f0
Compare
interface-data-api 0.7 removed RowFields, which interface-dms 0.13.3 names in its published declarations, so a project that resolves data-api 0.7 fails tsc. interface-dms and dms now build against data-api 0.7 and name StoredRow. The guard-row read in column-conditions is typed from the published fetchRowForGuard, and dms reads a row id as text through rowIdText, which refuses an id holding a row, a list or a document.
…tarball interface-data-api main (d70049c, #129) declares the decorators-0.5 ContainerModifier fix, packed as 0.7.2. The tarball stands in for the release until it ships; interface-dms requires >=0.7.2 <0.8.0.
interface-data-api 0.7.2 declares its modifier keys as Class<ContainerModifier> and requires decorators >=0.5.0; decorators 0.3.1's LocalizationModifier does not satisfy it. dms, the playground and interface-dms's development build move to decorators >=0.5.2.
… run every query interface-data-api #133 runs each DefaultRoutes query through .run(), which interface-database 0.4 needs. Packed as 0.7.2 like the tarball it replaces.
…terValue holds a boolean interface-data-api 0.8 types a filter value as string | boolean (ANT-2463). DataType.filter takes that value and hands its compare mode String(value), which the value parser reads back as the same boolean; the date type's override reads it as text. interface-dms and dms require data-api >=0.8.0 <0.9.0.
interface-data-api 0.8 types a filter value as string | boolean, so archiveFilter returns [true, mode] as typed and the SAFETY comment and chained assertion go.
Upd4ting
force-pushed
the
fix/interface-dms-stored-row
branch
from
November 13, 2026 20:10
ca837f0 to
42b25e5
Compare
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
ANT-2384. interface-data-api 0.7.0 replaced the published
RowFieldswithStoredRow.@antelopejs/interface-dms0.13.3 still namesRowFieldsin its published declarations and accepts data-api>=0.6.0 <1.0.0. A fresh project resolves data-api 0.7, so a module the Builder's Connect generates failstsc.⚠ sensitive: this changes the interface-dms contract (its published declarations and peer range).
tgz-pending: interface-data-api 0.8.0 is not released. It comes from data-api main (170f079: #129 decorators-0.5 declarations, #133 every DefaultRoutes query through
.run(), #134FilterValueholds a boolean) through.tgz-deps/antelopejs-interface-data-api-170f079.tgz, packed as 0.8.0.swap-tgz.shrestores>=0.8.0 <0.9.0once 0.8.0 ships.Summary
Why decorators move: data-api 0.8 declares its modifier keys as
Class<ContainerModifier>and requires decorators>=0.5.0. Decorators 0.3.1'sLocalizationModifierdoes not satisfy that type (TS2345 insrc/test/attachment-host/native.ts). With decorators 0.5.2 the workspace typechecks on interface-database 0.3.1, and the unit suite passes on mongodb 1.6.2. The interface-database 0.4.0 move stays in its own PR (ANT-2382).The
ContainerModifierTS2635 in the task comes from data-api's own declarations: data-api 0.7.1 and 0.6.3 writetypeof ContainerModifier<any>, which decorators 0.5.x refuses. data-api 0.8 fixes it, so the new floor covers it.Why
DataType.filterwidens: data-api 0.8 types a filter value asstring | boolean, because the archive filter hands its field's filter the booleantrue.DataType.filtertakes that type and hands its compare modeString(value), which the value parser reads back as the same boolean; the date type's override reads it as text. With the type honest,archiveFilterreturns[true, mode], and itsSAFETY:comment andtrue as unknown as stringgo (SAFETY:37 → 36,no-chained-type-assertions1 → 0).packages/interface-dms/UPGRADING.mdhas an Unreleased section with these changes.Evidence
Consumer typecheck of a module the Builder generates. It is produced by the engine (
MapResourceson a two-table catalog with a relation, thenscaffoldLocalModule) with the Builder's default compiler options and no hand edit. It is installed from public npm with interface-database 0.4.0, decorators 0.5.2, interface-core 0.5.1 and interface-api 0.3.2. Thennpx tsc --noEmit -p .:tscexits 0 with no output.StoredRowat the same four lines, so the floor is needed.pnpm run typecheckpasses.pnpm --dir packages/dms test:unit(backend-checks included) passes 2629 and integration 419 on data-api 0.8.0, including the newrowIdTexttests.node --test tests/*.test.mjspassed 180/180 before the decorators bump. After it, 179/180, with the one failure being the time-bound testpayloads: 200000 fields in the body itself are accepted in time and in memory(2893 ms, under a host load average of 62).Merge Danger
Door: two-way in the repo. The published contract is one-way once released: interface-dms requires data-api
>=0.8.0 <0.9.0, so a module on data-api 0.6 must move with it.Blast Radius: wide. It covers every module that types against
TableViewRoutes.GetorEdit, and every project's data-api and decorators versions. dms-saas and dms-database consume this branch.