@ai-matrx/records 0.57.3 → 0.58.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,127 @@
1
1
  # Changelog — @ai-matrx/records
2
2
 
3
+ ## 0.58.1
4
+
5
+ Automatic changed-only republish (docs/metadata drift since the last tag — see
6
+ `git diff npm/records/v0.58.0..npm/records/v0.58.1 -- apps/shared/records`).
7
+ No source changes intended and no consumer action required.
8
+
9
+ ## 0.58.0 (2026-09-24 — published by PUBLISH-SWEEP-5; folds every section below down to 0.57.3)
10
+
11
+ * **`src/store.generated.ts` is regenerated from the LIVE main database at publish time** (608 doors).
12
+ The integrator sweep `79b505cfa5` had committed a catalogue generated against a rehearsal copy,
13
+ claiming 30 doors production does not have (`form_preview_asks`, `table_row_counts`,
14
+ `agg_*`, `pipeline_move_many`, `work_decide_many` …); `real-doors` refused it. Those doors answer
15
+ `door_absent` naming their file until the chair's production window applies them and
16
+ `pnpm records:generate` runs again. Some sections below reached main through integrator sweeps
17
+ (`79b505cfa5`, `4bf803c452`) rather than their lanes' own commits.
18
+ * S2-PRIME's `StoreFilter` (`isRuleFilter`, `stableFilterKey`; `e7e53d3269`) and S6's client/door
19
+ hunks (`4bf803c452`) ride in this release.
20
+
21
+ ### Lane S3 PERIODS (2026-09-24)
22
+
23
+ * **A target read from a goal column.** `DashboardTarget` is a fixed `value` OR a `field` (a Field
24
+ key of the block's Table) with `op` `sum | avg | min | max` (default `sum`): the store adds that
25
+ column up over exactly the records the block's own number read — same filter, same current window,
26
+ same reader. `DashboardTargetResult.value` is now `number | null` and carries `field`, `op` and
27
+ `refused` (the store's sentence when this reader may not read the goal column; the block still
28
+ answers its number). Store side: matrx-frontend
29
+ `uichamp_s3_a_target_can_be_read_from_a_goal_column.sql` (chair applies after the S3 files).
30
+
31
+ ### Lane S4 BATCH-DOORS (2026-09-24)
32
+
33
+ * **Two batch doors, one transaction each, one answer per item.**
34
+ `pipelineMoveMany({moves: [{record_id, stage, expected_version, also?}]})` over
35
+ `custom.pipeline_move_many`, and `workDecideMany({decisions: [{item, decision: "approve" | "decline",
36
+ note?}]})` over `custom.work_decide_many`. Every item is judged exactly as the single door judges it
37
+ (`pipeline_move` / `work_approval_decide`), in its own savepoint, so a refused item writes nothing and
38
+ the rest still land. `expected_version` is required per card: a card somebody changed after the board
39
+ loaded answers `changed_since_loaded` and is never overwritten. Verdicts: moves
40
+ `moved | needs_approval | needs_fields | changed_since_loaded | no_right | refused`; decisions
41
+ `approved | declined | already_decided | no_right | refused`. Cap: knob `custom/batch_items_max` (500).
42
+ Types `PipelineMoveMany*`, `WorkDecideMany*`. Until the chair's production apply and
43
+ `records:generate`, both answer `door_absent` naming lane S4.
44
+
45
+ ### Lane DEFAULT-GRID-PARITY (2026-09-24)
46
+
47
+ * `NewFieldDeclaration.formula_text` and `FieldPatch.formula_text`: a formula in the language a
48
+ person types (GRID-PRIMITIVES G3). The store parses it and keeps both the text and the expression.
49
+ * `FieldTypeWord` gains `autonumber`, `created_time` and `modified_time`, the words
50
+ `custom.field_declare` takes for the store's own stamps (G5).
51
+ * For lane SC-R: `NewFieldDeclaration.allowed_types` and the `entity_reference` word on `FieldTypeWord`.
52
+
53
+ ### Lane SC-R (2026-09-24)
54
+
55
+ * **A new field kind, `entity_reference`** — a column that points at a PLATFORM thing (a note, a web
56
+ site, an agent, a workbook, a dataset, a conversation …) rather than at a record of one of your
57
+ Tables. In the store it is a relation whose `config.target_mode` is `any`, restricted by
58
+ `config.allowed_types` (entity tokens); each value is `{token, id}`, and every read door answers
59
+ `{token, id, label}` with the label withheld from a reader who may not open the thing. Declare it
60
+ with `fieldDeclare({ type: "entity_reference", allowed_types: ["note"] })`. `FIELD_KINDS` and
61
+ `fieldKindFor` know it; `coerceTypedAnswer` takes `note:<id>` (or a bare id when the column allows one
62
+ kind) and refuses words. File and Person stay `attachment` / `member`.
63
+ * **Helpers**: `isEntityReferenceConfig`, `entityReferenceKindsOf`, `entityRefsOf` (read a cell in any
64
+ shape), `entityRefsToWrite` (what to send — `{token, id}` only, each thing once, the label dropped),
65
+ and the two doors `entityReferenceKinds(source)` (`custom.entity_reference_kinds`, for the kind
66
+ picker) and `entityReferenceWords(source, organizationId, refs)` (`custom.entity_reference_words`,
67
+ the words of a chip before it is saved). Types `EntityRef`, `EntityRefWithWords`,
68
+ `EntityReferenceKind`. Both doors are on the dev clone and the rehearsal branch;
69
+ `pnpm records:generate` after the chair's production apply.
70
+
71
+ ### Lane S3 (2026-09-24)
72
+
73
+ * **`recordAggregate({ …, compare })`** — `custom.record_aggregate(…, p_compare)`: the same question
74
+ over a prior window (`previous_period`, `same_period_last_year`, or a fixed `range` baseline),
75
+ answered under the same principal. Each row carries `prior_groups`, `prior_measures`,
76
+ `prior_row_count`, `delta` ({current, prior, change, change_pct} per measure), `position` and the
77
+ two `compare` windows as local ISO moments. Buckets are cut in the organization's calendar (knobs
78
+ `custom/time_zone`, `custom/week_start`) and answer ISO 8601 with the organization's offset.
79
+ * **`dashboardRun({ …, compare, grain })`** — `custom.dashboard_run(…, p_compare, p_grain)`; blocks
80
+ carry `compare` and `target` (`DashboardTarget`), and each block's answer adds `compare` (the
81
+ windows), `totals`, `target` (current, progress, pace) and `compare_refused`.
82
+ * New types: `AggregateCompare`, `AggregateCompareKind`, `AggregateDelta`, `AggregateCompareWindows`,
83
+ `DashboardTarget`, `DashboardTotals`, `DashboardTargetResult`. Both doors are on the dev clone and
84
+ the rehearsal branch; `pnpm records:generate` after the chair's production apply.
85
+
86
+ ### Lane FORMS-FIX-1 (2026-09-24)
87
+
88
+ * **`client.formPreviewAsks({ table_id, questions, values })`** — `custom.form_preview_asks`, the
89
+ owner's form-preview door: which questions of a draft form are asked given the answers so far,
90
+ answered by the same store loop as the public form (`custom._form_questions_asked` →
91
+ `custom.rule_eval`), behind the organization wall and the caller's own viewer rung on the Table.
92
+ It replaces `records-ui`'s direct `ruleEval` call from the browser, which every real database
93
+ refuses. On the rehearsal branch; listed in `OWED_BY` until the chair's production apply and
94
+ `pnpm records:generate`.
95
+
96
+ ### Lane GRID-PRIMITIVES G9–G11 (2026-09-23)
97
+
98
+ * **Three cutover doors** (CUTOVER-PLAN.md F1, A3, F11/D5), on the rehearsal branch and waiting for
99
+ the chair's production apply; until `pnpm records:generate` lists them each call answers
100
+ `door_absent` naming its file. `tableListEverywhere()` — every table a picker may offer, from BOTH
101
+ stores, in `get_user_tables`' shape plus `store` (`TableListEntry`). `tableSync({home_id, spec})`
102
+ — refresh a sheet tab into ONE Table: new rows added, changed rows updated, dropped rows archived,
103
+ columns the person added kept (`TableSyncSpec`, `TableSyncResult`). Pure `sheetSyncSpec()` turns a
104
+ tab's cells into that spec and refuses repeated column names or row ids.
105
+ `scopeTableProvision({home_id, item_id, scope_id})` — a context scope's template-bound Table in
106
+ the store, one per item and scope. Tests: `grid.test.ts` (sheetSyncSpec).
107
+ * **G12** `tableRowCounts({table_ids})` (`TableRowCount`) and pure `withRowCounts(tables, counts)` —
108
+ one call counts the rows each Table's reader may see, so a list never shows `row_count: null`;
109
+ `recordHeaders({ids})` (`RecordHeader`) — created / updated / version of live rows the read door
110
+ does not answer, `created_by` only as the caller's own id. Tests: `grid.test.ts` (withRowCounts).
111
+ * **G13** `viewRecordOrderSet({view_id, record_ids})` (`ViewOrderSet`) keeps a hand-set row order
112
+ on a saved view; `readInViewOrder({view_id, limit, offset})` reads it back (placed rows by
113
+ position, then the rest by created time); pure `moveInOrder(order, moved, toIndex)` builds the
114
+ order a drag sends. Tests: `grid.test.ts` (moveInOrder).
115
+ * **Headless `declareTable`** (asked by INTEG-CLIENTS): `declareTable`, `addFields`,
116
+ `fieldDeclarationFor`, `tokenFor`, `DEFAULT_FIELDS` and their types now live in
117
+ `@ai-matrx/records/core` — no React, no host — so the extension's service worker and server-side
118
+ births walk the one birth. `@ai-matrx/records-ui` re-exports them from here, unchanged for its
119
+ callers. Tests: `declare-table.test.ts`.
120
+ * **G11 amended**: `scopeTableProvision({item_id, scope_id, home_id?})` — the Home is optional (the
121
+ organization's own), and a scope provisioned before the move answers with its moved Table.
122
+ * **G14** `tableShareOutsideGrant({table_id, person, level})` (`OutsideShareAnswer`): an existing
123
+ account outside the organization is granted at once and notified; no account → the invitation.
124
+
3
125
  ## 0.57.3 (unpublished — lane HUB-FIX)
4
126
 
5
127
  * **The lane facts are their own call.** 0.57.2 folded `custom.table_facts` into every