@ai-matrx/records 0.51.0 → 0.53.0
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 +69 -0
- package/dist/core/index.cjs +112 -3
- package/dist/core/index.cjs.map +1 -1
- package/dist/core/index.d.cts +95 -9
- package/dist/core/index.d.ts +95 -9
- package/dist/core/index.js +112 -3
- package/dist/core/index.js.map +1 -1
- package/dist/{field-C6_QKP1G.d.cts → field-ddMymGEI.d.cts} +28 -3
- package/dist/{field-C6_QKP1G.d.ts → field-ddMymGEI.d.ts} +28 -3
- package/dist/index.cjs +33 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +129 -3
- package/dist/index.d.ts +129 -3
- package/dist/index.js +33 -3
- package/dist/index.js.map +1 -1
- package/dist/react/index.cjs +192 -3
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +302 -8
- package/dist/react/index.d.ts +302 -8
- package/dist/react/index.js +192 -3
- package/dist/react/index.js.map +1 -1
- package/dist/use-cases/index.cjs.map +1 -1
- package/dist/use-cases/index.d.cts +1 -1
- package/dist/use-cases/index.d.ts +1 -1
- package/dist/use-cases/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,74 @@
|
|
|
1
1
|
# Changelog — @ai-matrx/records
|
|
2
2
|
|
|
3
|
+
## 0.53.0
|
|
4
|
+
|
|
5
|
+
**Archiving a table is a job, not a statement.** (lane FIX-11A, VERIFIER-11 finding F3.)
|
|
6
|
+
|
|
7
|
+
An admin of Greenline Landscaping Crew opened Settings on "Riverside Yard season tickets"
|
|
8
|
+
— 1,430 records the product's own import had just written — pressed **Delete this table**
|
|
9
|
+
and waited twelve seconds for `57014`, "canceling statement due to statement timeout …
|
|
10
|
+
Nothing was changed. Try a smaller page." There is no page. `custom.record_delete` aimed at
|
|
11
|
+
a Table recurses through everything the Table contains inside ONE transaction: a delete
|
|
12
|
+
rule, an access check, a history capture and an outbox row per record. That is unbounded by
|
|
13
|
+
construction — no timeout is long enough — and a store whose write path is batched and
|
|
14
|
+
whose delete path is not has one honest shape available to it.
|
|
15
|
+
|
|
16
|
+
* New client method `tableArchive({ table_id, chunk, includeTable })` over
|
|
17
|
+
`custom.table_archive`, typed as `TableArchiveProgress`: `archived`, `remaining`,
|
|
18
|
+
`total`, `archived_total`, `table_archived`, `done`, `chunk` and the store's own
|
|
19
|
+
`message`. `chunk: 0` reports and changes nothing, so a screen can say how many records
|
|
20
|
+
will be archived BEFORE a person commits to it.
|
|
21
|
+
* New hook `useTableArchive(tableId, { chunk, includeTable })` — it owns the loop, the
|
|
22
|
+
numbers, the stop and the resume, so every screen that ever gets rid of a table inherits
|
|
23
|
+
one behaviour instead of each re-deriving it. Resumable because it is STATELESS: what
|
|
24
|
+
remains is read off the records themselves every pass, so a refused pass, a `stop()`, a
|
|
25
|
+
closed tab or a deploy mid-run leave `interrupted` true and a `carryOn()` that continues
|
|
26
|
+
from exactly where it stopped. It must never be reported as "nothing happened":
|
|
27
|
+
`archived_total` is what actually landed.
|
|
28
|
+
* **The pass size is 50, measured, and it backs off.** One record costs about 35ms to
|
|
29
|
+
archive on the live store, so a pass of 200 is ~7s against an 8s statement timeout — it
|
|
30
|
+
died on `57014` on the first real table it was pointed at, which is the original defect
|
|
31
|
+
one level up. When the store does run out of time the loop HALVES the pass and carries
|
|
32
|
+
on (floor 10, `slowedDown` true so a screen can say so), because a pass that timed out
|
|
33
|
+
changed nothing and retrying it smaller repeats no work.
|
|
34
|
+
* Nothing is hard-deleted: every row still goes through `custom.record_delete`, so every
|
|
35
|
+
guard, history capture and outbox row happens and `recordRestore` still brings it back.
|
|
36
|
+
|
|
37
|
+
Proven on the main database on 2026-09-22 from the admin seat, through this package's own
|
|
38
|
+
client: 1,430 records archived in 25 passes across a deliberate cut and a resume (450 at
|
|
39
|
+
the cut, 1,430 at the end), then 312 more in 7 passes. Consumer action: a screen that
|
|
40
|
+
deletes a whole Table must call `useTableArchive`, never `useRecordMutation().remove`;
|
|
41
|
+
matrx-frontend's `pnpm check:table-archive-is-chunked` fails on the old shape.
|
|
42
|
+
|
|
43
|
+
## 0.52.0
|
|
44
|
+
|
|
45
|
+
**The portal archive doors are reachable.** (lane PUBLISH-SWEEP, closing ORG-CLEANUP's
|
|
46
|
+
own "left behind, named".)
|
|
47
|
+
|
|
48
|
+
* `custom.portal_archive`, `custom.portal_restore` and the archive-aware
|
|
49
|
+
`custom.list_portals(org, 'active'|'archived'|'all')` landed on the main database on
|
|
50
|
+
2026-09-22, and nine of Rincon Plumbing Co's ten identical portals were archived through
|
|
51
|
+
them FROM A SCRIPT. This package knew none of them, so from every client those nine simply
|
|
52
|
+
ceased to exist: `custom.portals` hides archived portals by design and there was no other
|
|
53
|
+
reader, no restore, and no archive.
|
|
54
|
+
* New client methods: `listPortals({ archived })`, `portalArchive({ portal_id, confirm_title,
|
|
55
|
+
reason })`, `portalRestore({ portal_id, confirm_title })`, over the three new door names.
|
|
56
|
+
* New vocabulary and words, so every screen says the same thing: `PORTAL_ARCHIVE_FILTERS` /
|
|
57
|
+
`PortalArchiveFilter` / `isPortalArchiveFilter` (three values, no fourth — the door refuses
|
|
58
|
+
a fourth `22023`), `PortalArchiveAnswer`, `portalArchiveConsequence`, `portalConfirmLine`,
|
|
59
|
+
`portalTitleTypedBack` and `emptyPortalArchiveLine`. The typed-title confirmation is the
|
|
60
|
+
DOOR's rule, not a screen's ceremony: ten portals can carry one title, so the title is not
|
|
61
|
+
what picks this one and `23514` is what says so.
|
|
62
|
+
* `src/store.generated.ts` regenerated from the live store (570 doors), which also picks up
|
|
63
|
+
IMPORT-2's `custom.io_import_declare_columns`.
|
|
64
|
+
|
|
65
|
+
**The import wizard adds the columns as its own step.** (lane IMPORT-2.)
|
|
66
|
+
|
|
67
|
+
* `importDeclareColumns` over `custom.io_import_declare_columns`, and the batch size the store
|
|
68
|
+
itself sizes, so a wide file stops being one statement the store refuses.
|
|
69
|
+
|
|
70
|
+
**Consumer action:** none — everything here is additive.
|
|
71
|
+
|
|
3
72
|
## 0.51.0
|
|
4
73
|
|
|
5
74
|
**The seal is asked through its own door.** (lane FIX-10B, from VERIFIER-10 finding F6.)
|
package/dist/core/index.cjs
CHANGED
|
@@ -41,6 +41,7 @@ __export(core_exports, {
|
|
|
41
41
|
DEFAULT_ARCHIVE_LANE: () => DEFAULT_ARCHIVE_LANE,
|
|
42
42
|
DEFAULT_DOCUMENT_MAX_BYTES: () => DEFAULT_DOCUMENT_MAX_BYTES,
|
|
43
43
|
DEFAULT_PAGE_SIZE: () => DEFAULT_PAGE_SIZE,
|
|
44
|
+
DEFAULT_PORTAL_ARCHIVE_FILTER: () => DEFAULT_PORTAL_ARCHIVE_FILTER,
|
|
44
45
|
DEFAULT_VALUE_MAX_BYTES: () => DEFAULT_VALUE_MAX_BYTES,
|
|
45
46
|
DELIVERIES: () => DELIVERIES,
|
|
46
47
|
DOORS: () => DOORS,
|
|
@@ -60,6 +61,7 @@ __export(core_exports, {
|
|
|
60
61
|
PERMISSION_LEVELS: () => PERMISSION_LEVELS,
|
|
61
62
|
PER_VALUE_ACCESS_WORDS: () => PER_VALUE_ACCESS_WORDS,
|
|
62
63
|
PIPELINE_RULE_KINDS: () => PIPELINE_RULE_KINDS,
|
|
64
|
+
PORTAL_ARCHIVE_FILTERS: () => PORTAL_ARCHIVE_FILTERS,
|
|
63
65
|
REFUSALS_WORTH_REPEATING: () => REFUSALS_WORTH_REPEATING,
|
|
64
66
|
RELATION_BINDINGS: () => RELATION_BINDINGS,
|
|
65
67
|
RELATION_CARDINALITIES: () => RELATION_CARDINALITIES,
|
|
@@ -96,6 +98,7 @@ __export(core_exports, {
|
|
|
96
98
|
doorCensus: () => doorCensus,
|
|
97
99
|
doorExists: () => doorExists,
|
|
98
100
|
emptyArchiveLine: () => emptyArchiveLine,
|
|
101
|
+
emptyPortalArchiveLine: () => emptyPortalArchiveLine,
|
|
99
102
|
err: () => err,
|
|
100
103
|
exportCsv: () => exportCsv,
|
|
101
104
|
exportXlsx: () => exportXlsx,
|
|
@@ -110,6 +113,7 @@ __export(core_exports, {
|
|
|
110
113
|
isArchiveLane: () => isArchiveLane,
|
|
111
114
|
isDecided: () => isDecided,
|
|
112
115
|
isOwnOp: () => isOwnOp,
|
|
116
|
+
isPortalArchiveFilter: () => isPortalArchiveFilter,
|
|
113
117
|
isRecordsErr: () => isRecordsErr,
|
|
114
118
|
isTheChosen: () => isTheChosen,
|
|
115
119
|
looksLikeAnId: () => looksLikeAnId,
|
|
@@ -125,7 +129,10 @@ __export(core_exports, {
|
|
|
125
129
|
optionLabel: () => optionLabel,
|
|
126
130
|
parseCsv: () => parseCsv,
|
|
127
131
|
planQuery: () => planQuery,
|
|
132
|
+
portalArchiveConsequence: () => portalArchiveConsequence,
|
|
133
|
+
portalConfirmLine: () => portalConfirmLine,
|
|
128
134
|
portalPath: () => portalPath,
|
|
135
|
+
portalTitleTypedBack: () => portalTitleTypedBack,
|
|
129
136
|
predictEnvelopeRefusal: () => predictEnvelopeRefusal,
|
|
130
137
|
predictSizeRefusal: () => predictSizeRefusal,
|
|
131
138
|
predictValueRefusals: () => predictValueRefusals,
|
|
@@ -530,6 +537,24 @@ function publicFormPath(formId) {
|
|
|
530
537
|
function portalPath(slug) {
|
|
531
538
|
return `/portal/c/${slug}`;
|
|
532
539
|
}
|
|
540
|
+
var PORTAL_ARCHIVE_FILTERS = ["active", "archived", "all"];
|
|
541
|
+
var DEFAULT_PORTAL_ARCHIVE_FILTER = "active";
|
|
542
|
+
function isPortalArchiveFilter(word) {
|
|
543
|
+
return typeof word === "string" && PORTAL_ARCHIVE_FILTERS.includes(word);
|
|
544
|
+
}
|
|
545
|
+
function portalArchiveConsequence(title, signedIn, invited) {
|
|
546
|
+
const people = invited === 0 ? "Nobody is invited to it" : signedIn === 0 ? `The ${invited} ${invited === 1 ? "person" : "people"} invited to it will not be able to sign in` : `The ${signedIn} ${signedIn === 1 ? "person" : "people"} signed in to it, and the ${invited - signedIn} still invited, will not be able to sign in`;
|
|
547
|
+
return `\u201C${title}\u201D will leave your portal list. ${people}, and their invitation links will say this portal was archived and can be restored. Nothing is deleted \u2014 every Table it shows and everyone invited to it is kept exactly as it is, and you can restore it at any time.`;
|
|
548
|
+
}
|
|
549
|
+
function portalConfirmLine(title) {
|
|
550
|
+
return `Type the portal\u2019s title \u2014 ${title} \u2014 to confirm you mean this one.`;
|
|
551
|
+
}
|
|
552
|
+
function portalTitleTypedBack(typed, title) {
|
|
553
|
+
return typed.trim() === (title ?? "").trim();
|
|
554
|
+
}
|
|
555
|
+
function emptyPortalArchiveLine() {
|
|
556
|
+
return "No portal of this organization has been archived. A portal you put away waits here until somebody restores it, and nothing is ever destroyed.";
|
|
557
|
+
}
|
|
533
558
|
|
|
534
559
|
// src/aggregate.ts
|
|
535
560
|
function measureKey(measure) {
|
|
@@ -1205,6 +1230,7 @@ var STORE_DOORS = [
|
|
|
1205
1230
|
{ name: "io_export", args: "p_organization_id uuid, p_table_id uuid, p_columns text[] DEFAULT NULL::text[], p_limit integer DEFAULT 10000, p_required text DEFAULT 'viewer'::text", returns: "jsonb", security: "definer" },
|
|
1206
1231
|
{ name: "io_export_csv", args: "p_organization_id uuid, p_table_id uuid, p_columns text[] DEFAULT NULL::text[], p_limit integer DEFAULT 10000, p_delimiter text DEFAULT chr(44), p_required text DEFAULT 'viewer'::text", returns: "text", security: "definer" },
|
|
1207
1232
|
{ name: "io_import_begin", args: "p_organization_id uuid, p_table_id uuid, p_format text DEFAULT 'csv'::text, p_source_name text DEFAULT NULL::text, p_source_columns jsonb DEFAULT '[]'::jsonb, p_file_hash text DEFAULT NULL::text, p_policy jsonb DEFAULT '{}'::jsonb, p_dedupe_key text DEFAULT NULL::text, p_file_bytes bigint DEFAULT NULL::bigint, p_force boolean DEFAULT false", returns: "jsonb", security: "definer" },
|
|
1233
|
+
{ name: "io_import_declare_columns", args: "p_organization_id uuid, p_table_id uuid, p_rows jsonb, p_mapping jsonb DEFAULT '{}'::jsonb", returns: "jsonb", security: "definer" },
|
|
1208
1234
|
{ name: "io_import_finish", args: "p_organization_id uuid, p_import_id uuid, p_unmapped text DEFAULT NULL::text", returns: "jsonb", security: "definer" },
|
|
1209
1235
|
{ name: "io_import_forget", args: "p_organization_id uuid, p_import_id uuid", returns: "boolean", security: "definer" },
|
|
1210
1236
|
{ name: "io_import_open", args: "p_organization_id uuid, p_table_id uuid, p_format text DEFAULT 'csv'::text, p_source_name text DEFAULT NULL::text, p_source_columns jsonb DEFAULT '[]'::jsonb", returns: "uuid", security: "definer" },
|
|
@@ -1238,6 +1264,7 @@ var STORE_DOORS = [
|
|
|
1238
1264
|
{ name: "levels_raised_by_a_less_specific_rung", args: "", returns: "TABLE(organization_id uuid, organization_name text, member_id uuid, member_email text, record_id uuid, addressed_level permission_level, answered_level permission_level)", security: "definer" },
|
|
1239
1265
|
{ name: "list_door_disagreements", args: "p_pretend text DEFAULT NULL::text, p_only_organization uuid DEFAULT NULL::uuid, p_sample integer DEFAULT 200", returns: "TABLE(organization_id uuid, organization_name text, member_id uuid, table_id uuid, record_id uuid, door text, why text)", security: "invoker" },
|
|
1240
1266
|
{ name: "list_door_disagreements", args: "p_pretend text, p_only_organization uuid, p_sample integer, p_exhaustive boolean", returns: "TABLE(organization_id uuid, organization_name text, member_id uuid, table_id uuid, record_id uuid, door text, why text)", security: "invoker" },
|
|
1267
|
+
{ name: "list_portals", args: "p_organization_id uuid, p_archived text DEFAULT 'active'::text", returns: "TABLE(portal_id uuid, title text, slug text, client_table_id uuid, client_table text, is_active boolean, tables integer, invited integer, signed_in integer, sign_in_method text, opened_at timestamp with time zone)", security: "definer" },
|
|
1241
1268
|
{ name: "lookup_value", args: "p_organization_id uuid, p_record_id uuid, p_field_data jsonb", returns: "jsonb", security: "invoker" },
|
|
1242
1269
|
{ name: "mask_document", args: "p_document jsonb, p_visible_keys text[], p_notices jsonb, p_by_id boolean DEFAULT false, p_key_ids jsonb DEFAULT '{}'::jsonb", returns: "jsonb", security: "invoker" },
|
|
1243
1270
|
{ name: "mask_document", args: "p_document jsonb, p_visible_keys text[], p_notices jsonb, p_by_id boolean DEFAULT false, p_key_ids jsonb DEFAULT '{}'::jsonb, p_declared_keys text[] DEFAULT NULL::text[]", returns: "jsonb", security: "invoker" },
|
|
@@ -1287,6 +1314,7 @@ var STORE_DOORS = [
|
|
|
1287
1314
|
{ name: "pipeline_read", args: "p_organization_id uuid, p_table_id uuid", returns: "jsonb", security: "definer" },
|
|
1288
1315
|
{ name: "pipeline_transition_refusal", args: "p_organization_id uuid, p_record_id uuid, p_to text", returns: "jsonb", security: "definer" },
|
|
1289
1316
|
{ name: "portal_admits", args: "p_organization_id uuid, p_user_id uuid DEFAULT NULL::uuid", returns: "boolean", security: "definer" },
|
|
1317
|
+
{ name: "portal_archive", args: "p_organization_id uuid, p_portal_id uuid, p_confirm_title text, p_reason text DEFAULT NULL::text", returns: "jsonb", security: "definer" },
|
|
1290
1318
|
{ name: "portal_card", args: "p_organization_id uuid, p_portal_id uuid", returns: "jsonb", security: "definer" },
|
|
1291
1319
|
{ name: "portal_declare", args: "p_organization_id uuid, p_title text, p_client_table_id uuid, p_tables jsonb, p_portal_id uuid DEFAULT NULL::uuid, p_slug text DEFAULT NULL::text, p_sign_in_method text DEFAULT 'magic_link'::text", returns: "uuid", security: "definer" },
|
|
1292
1320
|
{ name: "portal_field_map", args: "p_organization_id uuid, p_table_id uuid", returns: "TABLE(field_id uuid, field_key text, field_type text, points_at uuid)", security: "definer" },
|
|
@@ -1298,6 +1326,7 @@ var STORE_DOORS = [
|
|
|
1298
1326
|
{ name: "portal_principal_bind", args: "p_organization_id uuid, p_principal_id uuid, p_user_id uuid", returns: "jsonb", security: "definer" },
|
|
1299
1327
|
{ name: "portal_public", args: "p_slug text", returns: "jsonb", security: "definer" },
|
|
1300
1328
|
{ name: "portal_record_title", args: "p_organization_id uuid, p_record_id uuid", returns: "text", security: "definer" },
|
|
1329
|
+
{ name: "portal_restore", args: "p_organization_id uuid, p_portal_id uuid, p_confirm_title text", returns: "jsonb", security: "definer" },
|
|
1301
1330
|
{ name: "portal_revoke", args: "p_organization_id uuid, p_portal_id uuid, p_principal_id uuid", returns: "jsonb", security: "definer" },
|
|
1302
1331
|
{ name: "portal_slug", args: "p_organization_id uuid, p_title text, p_portal_id uuid DEFAULT NULL::uuid", returns: "text", security: "definer" },
|
|
1303
1332
|
{ name: "portal_tables", args: "p_organization_id uuid", returns: "TABLE(portal_id uuid, table_id uuid, name text)", security: "definer" },
|
|
@@ -1440,6 +1469,7 @@ var STORE_DOORS = [
|
|
|
1440
1469
|
{ name: "stamp_value_envelopes", args: "p_data jsonb, p_actor text, p_on_behalf_of text, p_at timestamp with time zone", returns: "jsonb", security: "invoker" },
|
|
1441
1470
|
{ name: "storage_modes", args: "", returns: "text[]", security: "invoker" },
|
|
1442
1471
|
{ name: "store_is_open", args: "p_organization_id uuid DEFAULT NULL::uuid", returns: "boolean", security: "invoker" },
|
|
1472
|
+
{ name: "store_off_sentence", args: "p_organization_id uuid", returns: "text", security: "invoker" },
|
|
1443
1473
|
{ name: "subscription_cadences", args: "p_organization_id uuid", returns: "text[]", security: "definer" },
|
|
1444
1474
|
{ name: "subscription_declare", args: "p_organization_id uuid, p_table_id uuid, p_spec jsonb", returns: "uuid", security: "definer" },
|
|
1445
1475
|
{ name: "subscription_mute", args: "p_organization_id uuid, p_rule_id uuid, p_muted boolean DEFAULT true", returns: "boolean", security: "definer" },
|
|
@@ -1578,16 +1608,16 @@ var STORE_KNOBS = [
|
|
|
1578
1608
|
{ key: "world_publish_enabled", value: "false", type: "boolean" }
|
|
1579
1609
|
];
|
|
1580
1610
|
var STORE_REFUSAL_CODES = [
|
|
1581
|
-
{ code: "02000", raised_by: "_checklist_instantiate,_portal_invite_payload,_share_write_person,_table_share_invite_payload,checklist_declare,checklist_run,checklist_step_complete,checklist_step_refusal,checklist_template_shape,conversation_scope_bind,dashboard_delete,dashboard_run,doc_letterhead,doc_render_body,doc_render_document,doc_render_read,doc_sign,doc_signature_intact,doc_signature_read,doc_template_delete,doc_template_read,doc_template_save,enrich_pin,entity_field_retire,entity_field_update,entity_record_read,entity_value_write,external_history_event,external_rows,external_stub_upsert,external_writes_set,io_restore,migrate_delete,migrate_extract_parent,migrate_merge,migrate_reclass,migrate_rename,migrate_reparent,migrate_retype,migrate_split,migrate_undo,organization_clear,portal_card,portal_declare,portal_invite,portal_invite_accept,portal_preview,portal_principal_bind,portal_revoke,read_record,record_delete,record_restore,record_restore_preview,record_table,record_update,relation_uncarry,share_access,share_grant,share_lane_set,share_people,share_revoke,sign_request_cancel,sign_request_create,sign_request_remind,sign_request_unchanged,table_archive,table_share_outside_accept,table_share_outside_invite,table_share_outside_resend,table_share_outside_revoke,visibility_as_of,work_approval_decide,work_approval_read,work_approval_request,work_assign,work_record_states,work_set_state" },
|
|
1611
|
+
{ code: "02000", raised_by: "_checklist_instantiate,_portal_invite_payload,_share_write_person,_table_share_invite_payload,checklist_declare,checklist_run,checklist_step_complete,checklist_step_refusal,checklist_template_shape,conversation_scope_bind,dashboard_delete,dashboard_run,doc_letterhead,doc_render_body,doc_render_document,doc_render_read,doc_sign,doc_signature_intact,doc_signature_read,doc_template_delete,doc_template_read,doc_template_save,enrich_pin,entity_field_retire,entity_field_update,entity_record_read,entity_value_write,external_history_event,external_rows,external_stub_upsert,external_writes_set,io_restore,migrate_delete,migrate_extract_parent,migrate_merge,migrate_reclass,migrate_rename,migrate_reparent,migrate_retype,migrate_split,migrate_undo,organization_clear,portal_archive,portal_card,portal_declare,portal_invite,portal_invite_accept,portal_preview,portal_principal_bind,portal_restore,portal_revoke,read_record,record_delete,record_restore,record_restore_preview,record_table,record_update,relation_uncarry,share_access,share_grant,share_lane_set,share_people,share_revoke,sign_request_cancel,sign_request_create,sign_request_remind,sign_request_unchanged,table_archive,table_share_outside_accept,table_share_outside_invite,table_share_outside_resend,table_share_outside_revoke,visibility_as_of,work_approval_decide,work_approval_read,work_approval_request,work_assign,work_record_states,work_set_state" },
|
|
1582
1612
|
{ code: "0A000", raised_by: "checklist_step_complete,external_rows,external_source_declare,external_write_through,promote_field,promoted_index_expr,promoted_query_sql,promoted_read,rule_eval,work_assign" },
|
|
1583
1613
|
{ code: "22003", raised_by: "context_resolve" },
|
|
1584
1614
|
{ code: "22004", raised_by: "_entity_custom_fields_guard,_share_write_person,_value_envelope,actor_word,agg_assert_key,agg_sql,anon_capture,anon_token_issue,anon_write,assert_client_may_reach,booking_declare,capture_submit,checklist_declare,context_resolve,dashboard_block_normalize,dashboard_declare,dashboard_window_sql,doc_render_write,doc_sign,doc_signature_write,doc_template_save,enrich_land,enrich_normalize,external_history_event,external_rows,external_source_declare,external_stub_upsert,external_write_through,external_writes_set,field_history,form_declare,form_submit,home_add,io_comment_write,io_import_begin,io_infer_column,io_outbox_drain,io_restore,migrate_choice_keys,migrate_purge,migrate_reclass,migrate_split,migrate_undo,organization_clear,organization_contents,pipeline_declare,pipeline_gate_preview,portal_declare,portal_invite,portal_principal_bind,provenance_retention_days,provenance_write,query_across_homes,query_by_coordinates,query_rollup,record_delete,record_reparent,record_resolve,record_restore,record_update,record_write,record_write_many,relation_carry,relation_own,rule_declare,share_grant,sign_request_create,sign_request_sign,subscription_declare,table_archive,table_declare,table_share_outside_invite,value_restore,view_declare,work_approval_decide,work_approval_request,work_template_declare" },
|
|
1585
1615
|
{ code: "22007", raised_by: "dashboard_window_sql" },
|
|
1586
1616
|
{ code: "22012", raised_by: "rule_eval" },
|
|
1587
|
-
{ code: "22023", raised_by: "_booking_availability,_entity_custom_fields_guard,_take_op_id,_value_envelope,_work_shape_guard,actor_word,agg_assert_key,agg_sql,anon_token_issue,booking_declare,containment_parent,dashboard_block_normalize,dashboard_window_sql,doc_render_body,doc_render_write,doc_signature_write,enrich_declare,enrich_land,enrich_normalize,enrich_pin,entity_value_write,external_history_event,external_source_declare,external_stub_upsert,external_write_through,field_history,field_update,io_export,io_import_begin,io_import_finish,io_import_plan,io_import_report,io_proposal_accept,migrate_merge,migrate_reclass,my_levels,organization_clear,page_size,pin_agent_cells,pipeline_move,portal_declare,provenance_write,query_by_coordinates,query_rollup,read_records_archived,record_update,record_write_many,relation_carry,rule_eval,rule_members,share_grant,share_lane_set,sign_request_create,sign_request_sign,subscription_declare,table_rules,visibility_as_of,work_approval_request,work_list,work_slot_hold" },
|
|
1617
|
+
{ code: "22023", raised_by: "_booking_availability,_entity_custom_fields_guard,_take_op_id,_value_envelope,_work_shape_guard,actor_word,agg_assert_key,agg_sql,anon_token_issue,booking_declare,containment_parent,dashboard_block_normalize,dashboard_window_sql,doc_render_body,doc_render_write,doc_signature_write,enrich_declare,enrich_land,enrich_normalize,enrich_pin,entity_value_write,external_history_event,external_source_declare,external_stub_upsert,external_write_through,field_history,field_update,io_export,io_import_begin,io_import_finish,io_import_plan,io_import_report,io_proposal_accept,list_portals,migrate_merge,migrate_reclass,my_levels,organization_clear,page_size,pin_agent_cells,pipeline_move,portal_declare,provenance_write,query_by_coordinates,query_rollup,read_records_archived,record_update,record_write_many,relation_carry,rule_eval,rule_members,share_grant,share_lane_set,sign_request_create,sign_request_sign,subscription_declare,table_rules,visibility_as_of,work_approval_request,work_list,work_slot_hold" },
|
|
1588
1618
|
{ code: "23503", raised_by: "_booking_availability,_checklist_instantiate,_containment_guard,_display_spec_for,_field_document_for,_field_type_parity_guard,_pipeline_stage_key,_record_rule_uses,agg_digest_assemble,anon_publish,anon_rate_take,anon_token_issue,anon_write,assert_organization_wall,booking_cancel,booking_confirm,booking_declare,booking_hold,booking_reschedule,capture_publish,checklist_declare,checklist_steps_table,comment_write,dashboard_declare,delete_rule,doc_sign,doc_template_save,enrich_declare,enrich_due,enrich_land,form_declare,form_submit,home_add,inbound_declare,inbound_mail_land,inbound_set,io_comment_write,io_import_begin,io_import_finish,io_import_report,io_import_rows,io_proposal_accept,migrate_demote,migrate_promote,pipeline_board,pipeline_declare,pipeline_move,pipeline_read,pipeline_transition_refusal,promote_field,promote_table,record_applicability,record_reparent,relation_carry,relation_own,resolve_first_match,rule_applies,rule_declare,rule_eval,rule_members,rule_run,sign_request_create,subscription_mute,subscription_preview,view_declare,work_set_state,work_take_assignment,work_template_instantiate" },
|
|
1589
1619
|
{ code: "23505", raised_by: "_share_write_person,_unique_rule_holds,doc_sign,doc_signature_write,entity_field_declare,field_declare,home_add,inbound_declare,io_proposal_accept,relation_carry,relation_own,sign_request_cancel,sign_request_create,table_share_outside_resend,work_approval_decide,work_slot_hold" },
|
|
1590
|
-
{ code: "23514", raised_by: "_checklist_instantiate,_checklist_step_guard,_containment_guard,_dated_values_guard,_derived_fields,_display_spec_for,_entity_custom_fields_guard,_field_class_guard,_field_document_for,_field_shape_guard,_field_type_parity_guard,_merge_field_shape_guard,_merge_field_temporal_guard,_promoted_field_cap_guard,_record_rule_uses,_resolve_choice_words,_rule_shape_guard,_rule_topology_guard,_store_relation_edge_names_its_field,_table_columns_word_guard,_table_shape_guard,_undeclared_key_guard,_value_envelope,_with_display,_work_shape_guard,_workdoors_approval_guard,assert_columns_are_defined,assert_entity_is_organization_scoped,booking_declare,capture_publish,capture_sheet_declare,checklist_declare,checklist_step_complete,doc_sign,doc_signature_write,doc_template_save,entity_field_declare,entity_field_retire,entity_field_update,entity_records_find,entity_table,field_declare,field_retire,field_update,home_add,io_comment_write,io_import_rows,migrate_merge,relation_carry,relation_own,sign_request_create,sign_request_sign,table_declare,validate_value_envelope,validate_values,work_set_state,work_slots_declare,work_take_assignment,work_template_instantiate" },
|
|
1620
|
+
{ code: "23514", raised_by: "_checklist_instantiate,_checklist_step_guard,_containment_guard,_dated_values_guard,_derived_fields,_display_spec_for,_entity_custom_fields_guard,_field_class_guard,_field_document_for,_field_shape_guard,_field_type_parity_guard,_merge_field_shape_guard,_merge_field_temporal_guard,_promoted_field_cap_guard,_record_rule_uses,_resolve_choice_words,_rule_shape_guard,_rule_topology_guard,_store_relation_edge_names_its_field,_table_columns_word_guard,_table_shape_guard,_undeclared_key_guard,_value_envelope,_with_display,_work_shape_guard,_workdoors_approval_guard,assert_columns_are_defined,assert_entity_is_organization_scoped,booking_declare,capture_publish,capture_sheet_declare,checklist_declare,checklist_step_complete,doc_sign,doc_signature_write,doc_template_save,entity_field_declare,entity_field_retire,entity_field_update,entity_records_find,entity_table,field_declare,field_retire,field_update,home_add,io_comment_write,io_import_rows,migrate_merge,portal_archive,portal_restore,relation_carry,relation_own,sign_request_create,sign_request_sign,table_declare,validate_value_envelope,validate_values,work_set_state,work_slots_declare,work_take_assignment,work_template_instantiate" },
|
|
1591
1621
|
{ code: "40001", raised_by: "has_visibility_at" },
|
|
1592
1622
|
{ code: "42501", raised_by: "_doc_render_immutable,_doc_signature_immutable,_field_definition_write,_field_write_door,_rule_definition_write,_store_door,agent_table_claim,anon_capture,anon_inbound_land,anon_publish,anon_token_issue,anon_token_verify,anon_write,assert_client_may_change,assert_client_may_open,assert_client_may_reach,assert_may_know_table,assert_organization_admin,assert_store_door,booking_confirm,booking_declare,booking_hold,capture_submit,checklist_run,comment_write,conversation_scope_bind,conversation_scope_unbind,doc_sign,enrich_declare,enrich_due,enrich_land,enrich_normalize,entity_field_declare,entity_field_retire,entity_field_update,entity_value_write,external_write_through,form_declare,form_submit,inbound_mail_land,io_comment_resolve,io_comment_write,io_import_begin,io_import_finish,io_restore,migrate_purge,migrate_reclass,my_levels,organization_clear,portal_declare,portal_invitation,portal_invite,portal_invite_accept,portal_principal_bind,promote_table,query_visibility_parity,read_record,read_records,read_records_archived,read_records_by_ids,read_records_matching,record_table,share_grant,subscription_mute,subscription_preview,table_share_outside_accept,table_share_outside_invite,table_share_outside_resend,visibility_as_of,work_approval_decide,work_approval_read,work_approval_request,work_person" },
|
|
1593
1623
|
{ code: "42703", raised_by: "entity_table,portal_declare" },
|
|
@@ -2722,6 +2752,19 @@ var DOORS = {
|
|
|
2722
2752
|
fieldOptions: "field_options",
|
|
2723
2753
|
parityValues: "parity_values",
|
|
2724
2754
|
tableDeclare: "table_declare",
|
|
2755
|
+
// GETTING RID OF A TABLE — which is a JOB, NOT A STATEMENT (VERIFIER-11 F3).
|
|
2756
|
+
// `record_delete` above is the store's one soft-delete door and it is right
|
|
2757
|
+
// for a record; aimed at a TABLE it recurses through everything the Table
|
|
2758
|
+
// contains inside one transaction, and that is unbounded by construction. A
|
|
2759
|
+
// person pressing "Delete this table" on 1,430 records the product itself
|
|
2760
|
+
// had just imported waited twelve seconds and was told `57014`, "canceling
|
|
2761
|
+
// statement due to statement timeout … Nothing was changed. Try a smaller
|
|
2762
|
+
// page" — advice that means nothing when what you are doing is getting rid
|
|
2763
|
+
// of a table. `custom.table_archive` does the same work in passes and
|
|
2764
|
+
// answers each one with numbers, so a screen shows a sentence and a count
|
|
2765
|
+
// instead of a spinner and an SQLSTATE. It is STATELESS, so a run cut in
|
|
2766
|
+
// half resumes exactly where it stopped: there is no job row to lose.
|
|
2767
|
+
tableArchive: "table_archive",
|
|
2725
2768
|
// ADDING A COLUMN — the first thing anybody does with a table, and until
|
|
2726
2769
|
// 2026-09-19 there was no door for it. A Field is a record (REC-25), so a
|
|
2727
2770
|
// screen wrote one with `record_write`; that door writes ONE row with
|
|
@@ -2849,6 +2892,7 @@ var DOORS = {
|
|
|
2849
2892
|
// ways to start an import from one client is how they drift.
|
|
2850
2893
|
importPlan: "io_import_plan",
|
|
2851
2894
|
importBegin: "io_import_begin",
|
|
2895
|
+
importDeclareColumns: "io_import_declare_columns",
|
|
2852
2896
|
importRows: "io_import_rows",
|
|
2853
2897
|
importFinish: "io_import_finish",
|
|
2854
2898
|
importReport: "io_import_report",
|
|
@@ -2885,6 +2929,17 @@ var DOORS = {
|
|
|
2885
2929
|
portalInvite: "portal_invite",
|
|
2886
2930
|
portalRevoke: "portal_revoke",
|
|
2887
2931
|
portalPreview: "portal_preview",
|
|
2932
|
+
// ORG-CLEANUP, 2026-09-22 — A PORTAL IS ARCHIVED, NEVER DELETED.
|
|
2933
|
+
// `portals` keeps its signature and HIDES archived portals (the law's default
|
|
2934
|
+
// is to hide); `list_portals(org, 'active'|'archived'|'all')` is the
|
|
2935
|
+
// archive-aware reader, taking the platform archive filter's own three values
|
|
2936
|
+
// so one door serves both lanes and no screen has to invent a second control.
|
|
2937
|
+
// `portal_archive` / `portal_restore` are the way out and the way back; both
|
|
2938
|
+
// take the portal's own title typed back, because ten portals can carry one
|
|
2939
|
+
// title and the title alone is not what picks this one.
|
|
2940
|
+
listPortals: "list_portals",
|
|
2941
|
+
portalArchive: "portal_archive",
|
|
2942
|
+
portalRestore: "portal_restore",
|
|
2888
2943
|
// SCR-16 — the canvas. A dashboard is a record in the presentation kernel
|
|
2889
2944
|
// whose blocks are saved SPECS for the eighth verb; `dashboardRun` walks them
|
|
2890
2945
|
// under the CALLER'S principal, so nothing here is precomputed and nothing is
|
|
@@ -3373,6 +3428,18 @@ function createRecordsClient(config) {
|
|
|
3373
3428
|
"recordRestore"
|
|
3374
3429
|
);
|
|
3375
3430
|
},
|
|
3431
|
+
async tableArchive({ table_id, chunk, includeTable }) {
|
|
3432
|
+
return callDoor(
|
|
3433
|
+
DOORS.tableArchive,
|
|
3434
|
+
{
|
|
3435
|
+
p_organization_id: org,
|
|
3436
|
+
p_table_id: table_id,
|
|
3437
|
+
p_chunk: chunk ?? 50,
|
|
3438
|
+
p_include_table: includeTable ?? true
|
|
3439
|
+
},
|
|
3440
|
+
"tableArchive"
|
|
3441
|
+
);
|
|
3442
|
+
},
|
|
3376
3443
|
async recordRead({ record_id, withComputed = false }) {
|
|
3377
3444
|
const door = await callDoor(
|
|
3378
3445
|
DOORS.readRecord,
|
|
@@ -3926,6 +3993,18 @@ function createRecordsClient(config) {
|
|
|
3926
3993
|
"importBegin"
|
|
3927
3994
|
);
|
|
3928
3995
|
},
|
|
3996
|
+
async importDeclareColumns(args) {
|
|
3997
|
+
return callDoor(
|
|
3998
|
+
DOORS.importDeclareColumns,
|
|
3999
|
+
{
|
|
4000
|
+
p_organization_id: org,
|
|
4001
|
+
p_table_id: args.table_id,
|
|
4002
|
+
p_rows: args.rows,
|
|
4003
|
+
p_mapping: args.mapping ?? {}
|
|
4004
|
+
},
|
|
4005
|
+
"importDeclareColumns"
|
|
4006
|
+
);
|
|
4007
|
+
},
|
|
3929
4008
|
async importRows(args) {
|
|
3930
4009
|
return callDoor(
|
|
3931
4010
|
DOORS.importRows,
|
|
@@ -3996,6 +4075,36 @@ function createRecordsClient(config) {
|
|
|
3996
4075
|
async portals() {
|
|
3997
4076
|
return callDoor(DOORS.portals, { p_organization_id: org }, "portals");
|
|
3998
4077
|
},
|
|
4078
|
+
async listPortals(args) {
|
|
4079
|
+
return callDoor(
|
|
4080
|
+
DOORS.listPortals,
|
|
4081
|
+
{ p_organization_id: org, p_archived: args?.archived ?? "active" },
|
|
4082
|
+
"listPortals"
|
|
4083
|
+
);
|
|
4084
|
+
},
|
|
4085
|
+
async portalArchive(args) {
|
|
4086
|
+
return callDoor(
|
|
4087
|
+
DOORS.portalArchive,
|
|
4088
|
+
{
|
|
4089
|
+
p_organization_id: org,
|
|
4090
|
+
p_portal_id: args.portal_id,
|
|
4091
|
+
p_confirm_title: args.confirm_title,
|
|
4092
|
+
p_reason: args.reason ?? null
|
|
4093
|
+
},
|
|
4094
|
+
"portalArchive"
|
|
4095
|
+
);
|
|
4096
|
+
},
|
|
4097
|
+
async portalRestore(args) {
|
|
4098
|
+
return callDoor(
|
|
4099
|
+
DOORS.portalRestore,
|
|
4100
|
+
{
|
|
4101
|
+
p_organization_id: org,
|
|
4102
|
+
p_portal_id: args.portal_id,
|
|
4103
|
+
p_confirm_title: args.confirm_title
|
|
4104
|
+
},
|
|
4105
|
+
"portalRestore"
|
|
4106
|
+
);
|
|
4107
|
+
},
|
|
3999
4108
|
async portalTables() {
|
|
4000
4109
|
return callDoor(DOORS.portalTables, { p_organization_id: org }, "portalTables");
|
|
4001
4110
|
},
|