@ai-matrx/records 0.8.0 → 0.11.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.
@@ -64,6 +64,11 @@ __export(react_exports, {
64
64
  measureKey: () => measureKey,
65
65
  ok: () => ok,
66
66
  publicFormPath: () => publicFormPath,
67
+ useEntityFieldMutation: () => useEntityFieldMutation,
68
+ useEntityFieldRights: () => useEntityFieldRights,
69
+ useEntityFields: () => useEntityFields,
70
+ useEntityRecord: () => useEntityRecord,
71
+ useEntityTable: () => useEntityTable,
67
72
  useFieldMutation: () => useFieldMutation,
68
73
  useFields: () => useFields,
69
74
  useMergeField: () => useMergeField,
@@ -1672,6 +1677,24 @@ var DOORS = {
1672
1677
  fieldDeclare: "field_declare",
1673
1678
  fieldUpdate: "field_update",
1674
1679
  fieldRetire: "field_retire",
1680
+ // CUSTOM FIELDS ON A STANDARD BUSINESS TABLE. Every door above is keyed by a
1681
+ // custom Table's uuid, and a standard table has no Table record - so until
1682
+ // 2026-09-20 `custom.applicable_fields(org, 'party', null)` answered `22P02
1683
+ // invalid input syntax for uuid` and there was no other way in. These are
1684
+ // keyed by the REGISTRY TOKEN instead, and they are one set for all 643
1685
+ // tables the registry types Entity or Detail. The three value doors are
1686
+ // SECURITY INVOKER in the database on purpose: the standard table's own
1687
+ // row-level security is what decides who may read and write its rows, and a
1688
+ // definer wrapper would replace it with a second access system.
1689
+ entityTable: "entity_table",
1690
+ entityFields: "entity_fields",
1691
+ entityFieldDeclare: "entity_field_declare",
1692
+ entityFieldUpdate: "entity_field_update",
1693
+ entityFieldRetire: "entity_field_retire",
1694
+ entityFieldRights: "entity_field_rights",
1695
+ entityRecordRead: "entity_record_read",
1696
+ entityValueWrite: "entity_value_write",
1697
+ entityRecordsFind: "entity_records_find",
1675
1698
  tableCapacity: "table_capacity",
1676
1699
  tableStorage: "table_storage",
1677
1700
  promoteTable: "promote_table",
@@ -1778,6 +1801,23 @@ var DOORS = {
1778
1801
  workSlotRelease: "work_slot_release",
1779
1802
  workSlotHolds: "work_slot_holds",
1780
1803
  workSlotExpire: "work_slot_expire",
1804
+ // THE WORK LAYER'S OWN DOORS (lane WORK-DOORS, 2026-09-20). Until this lane
1805
+ // all nineteen `custom.work_*` functions were SECURITY INVOKER with no client
1806
+ // grant: REC-69, REC-70 and REC-71 were live in the store and unreachable
1807
+ // from a browser. These are the verbs a person actually uses.
1808
+ workPerson: "work_person",
1809
+ workAssign: "work_assign",
1810
+ workRecordStates: "work_record_states",
1811
+ workSetState: "work_set_state",
1812
+ workList: "work_list",
1813
+ workTemplates: "work_templates",
1814
+ /** THE ONE QUEUE: assignments, approvals and the agent's proposals together. */
1815
+ workInbox: "work_inbox",
1816
+ workApprovalApprovers: "work_approval_approvers",
1817
+ workApprovalRequest: "work_approval_request",
1818
+ workApprovalMayDecide: "work_approval_may_decide",
1819
+ workApprovalDecide: "work_approval_decide",
1820
+ workApprovalRead: "work_approval_read",
1781
1821
  // Declared here BECAUSE they do not exist yet: naming them is what makes the
1782
1822
  // absence visible to `pnpm check:store-registry` and to the suite.
1783
1823
  metadataSearch: "metadata_search",
@@ -2203,6 +2243,88 @@ function createRecordsClient(config) {
2203
2243
  "fieldDeclare"
2204
2244
  );
2205
2245
  },
2246
+ async entityTable({ token }) {
2247
+ const answer = await callDoor(
2248
+ DOORS.entityTable,
2249
+ { p_token: token },
2250
+ "entityTable"
2251
+ );
2252
+ if (!answer.ok) return err(answer.error);
2253
+ const row = Array.isArray(answer.data) ? answer.data[0] : answer.data;
2254
+ if (!row) {
2255
+ return err({
2256
+ code: "not_found",
2257
+ message: `The registry answered nothing for the table "${token}".`,
2258
+ hint: "REC-33: a standard table is named by its registry token. Nothing was read."
2259
+ });
2260
+ }
2261
+ return ok(row);
2262
+ },
2263
+ async entityFields({ token }) {
2264
+ const rows = await callDoor(
2265
+ DOORS.entityFields,
2266
+ { p_organization_id: org, p_token: token },
2267
+ "entityFields"
2268
+ );
2269
+ if (!rows.ok) return err(rows.error);
2270
+ return ok((rows.data ?? []).map((row) => ({ id: row.id, ...row.data })));
2271
+ },
2272
+ async entityFieldDeclare({ token, spec }) {
2273
+ return callDoor(
2274
+ DOORS.entityFieldDeclare,
2275
+ { p_organization_id: org, p_token: token, p_spec: spec },
2276
+ "entityFieldDeclare"
2277
+ );
2278
+ },
2279
+ async entityFieldUpdate({ field_id, patch }) {
2280
+ return callDoor(
2281
+ DOORS.entityFieldUpdate,
2282
+ { p_organization_id: org, p_field_id: field_id, p_patch: patch },
2283
+ "entityFieldUpdate"
2284
+ );
2285
+ },
2286
+ async entityFieldRetire({ field_id }) {
2287
+ return callDoor(
2288
+ DOORS.entityFieldRetire,
2289
+ { p_organization_id: org, p_field_id: field_id },
2290
+ "entityFieldRetire"
2291
+ );
2292
+ },
2293
+ async entityFieldRights({ token }) {
2294
+ return callDoor(
2295
+ DOORS.entityFieldRights,
2296
+ { p_organization_id: org, p_token: token },
2297
+ "entityFieldRights"
2298
+ );
2299
+ },
2300
+ async entityRecordRead({ token, record_id }) {
2301
+ return callDoor(
2302
+ DOORS.entityRecordRead,
2303
+ { p_organization_id: org, p_token: token, p_record_id: record_id },
2304
+ "entityRecordRead"
2305
+ );
2306
+ },
2307
+ async entityValueWrite({ token, record_id, patch }) {
2308
+ return callDoor(
2309
+ DOORS.entityValueWrite,
2310
+ { p_organization_id: org, p_token: token, p_record_id: record_id, p_patch: patch },
2311
+ "entityValueWrite"
2312
+ );
2313
+ },
2314
+ async entityRecordsFind({ token, key, value, limit, offset }) {
2315
+ return callDoor(
2316
+ DOORS.entityRecordsFind,
2317
+ {
2318
+ p_organization_id: org,
2319
+ p_token: token,
2320
+ p_key: key,
2321
+ p_value: value === void 0 ? null : value,
2322
+ ...limit === void 0 ? {} : { p_limit: limit },
2323
+ ...offset === void 0 ? {} : { p_offset: offset }
2324
+ },
2325
+ "entityRecordsFind"
2326
+ );
2327
+ },
2206
2328
  async fieldUpdate({ field_id, patch }) {
2207
2329
  return callDoor(
2208
2330
  DOORS.fieldUpdate,
@@ -2620,6 +2742,128 @@ function createRecordsClient(config) {
2620
2742
  "workSlotExpire"
2621
2743
  );
2622
2744
  },
2745
+ // ── the work layer a person actually uses ────────────────────────────
2746
+ async workInbox(args) {
2747
+ return callDoor(
2748
+ DOORS.workInbox,
2749
+ {
2750
+ p_organization_id: org,
2751
+ p_limit: args?.limit ?? 50,
2752
+ p_offset: args?.offset ?? 0,
2753
+ p_include_decided: args?.includeDecided ?? false
2754
+ },
2755
+ "workInbox"
2756
+ );
2757
+ },
2758
+ async workList(args) {
2759
+ return callDoor(
2760
+ DOORS.workList,
2761
+ {
2762
+ p_organization_id: org,
2763
+ p_flavour: args?.flavour ?? "mine",
2764
+ p_include_finished: args?.includeFinished ?? false,
2765
+ p_limit: args?.limit ?? 100,
2766
+ p_offset: args?.offset ?? 0
2767
+ },
2768
+ "workList"
2769
+ );
2770
+ },
2771
+ async workAssign({ record_id, user_id = null, dueDate = null, clearDue = false }) {
2772
+ return callDoor(
2773
+ DOORS.workAssign,
2774
+ {
2775
+ p_organization_id: org,
2776
+ p_record_id: record_id,
2777
+ p_assignee_user_id: user_id,
2778
+ p_due_date: dueDate,
2779
+ p_clear_due: clearDue
2780
+ },
2781
+ "workAssign"
2782
+ );
2783
+ },
2784
+ async workRecordStates({ record_id }) {
2785
+ return callDoor(
2786
+ DOORS.workRecordStates,
2787
+ { p_organization_id: org, p_record_id: record_id },
2788
+ "workRecordStates"
2789
+ );
2790
+ },
2791
+ async workSetState({ record_id, state_id }) {
2792
+ return callDoor(
2793
+ DOORS.workSetState,
2794
+ { p_organization_id: org, p_record_id: record_id, p_state_id: state_id },
2795
+ "workSetState"
2796
+ );
2797
+ },
2798
+ async workPerson({ user_id, create = true }) {
2799
+ return callDoor(
2800
+ DOORS.workPerson,
2801
+ { p_organization_id: org, p_user_id: user_id, p_create: create },
2802
+ "workPerson"
2803
+ );
2804
+ },
2805
+ async workTemplates(args) {
2806
+ return callDoor(
2807
+ DOORS.workTemplates,
2808
+ { p_organization_id: org, p_limit: args?.limit ?? 100 },
2809
+ "workTemplates"
2810
+ );
2811
+ },
2812
+ async workApprovalApprovers({ subject_id, approver_id = null }) {
2813
+ return callDoor(
2814
+ DOORS.workApprovalApprovers,
2815
+ { p_organization_id: org, p_subject_id: subject_id, p_approver_id: approver_id },
2816
+ "workApprovalApprovers"
2817
+ );
2818
+ },
2819
+ async workApprovalRequest({
2820
+ subject_id,
2821
+ change,
2822
+ note = null,
2823
+ approver_id = null,
2824
+ origin = "person",
2825
+ conversation_id = null
2826
+ }) {
2827
+ return callDoor(
2828
+ DOORS.workApprovalRequest,
2829
+ {
2830
+ p_organization_id: org,
2831
+ p_subject_id: subject_id,
2832
+ p_change: change,
2833
+ p_note: note,
2834
+ p_approver_id: approver_id,
2835
+ p_origin: origin,
2836
+ p_conversation_id: conversation_id
2837
+ },
2838
+ "workApprovalRequest"
2839
+ );
2840
+ },
2841
+ async workApprovalMayDecide({ approval_id }) {
2842
+ return callDoor(
2843
+ DOORS.workApprovalMayDecide,
2844
+ { p_organization_id: org, p_approval_id: approval_id },
2845
+ "workApprovalMayDecide"
2846
+ );
2847
+ },
2848
+ async workApprovalDecide({ approval_id, approve, note = null }) {
2849
+ return callDoor(
2850
+ DOORS.workApprovalDecide,
2851
+ {
2852
+ p_organization_id: org,
2853
+ p_approval_id: approval_id,
2854
+ p_approve: approve,
2855
+ p_note: note
2856
+ },
2857
+ "workApprovalDecide"
2858
+ );
2859
+ },
2860
+ async workApprovalRead({ approval_id }) {
2861
+ return callDoor(
2862
+ DOORS.workApprovalRead,
2863
+ { p_organization_id: org, p_approval_id: approval_id },
2864
+ "workApprovalRead"
2865
+ );
2866
+ },
2623
2867
  // ── the trust doors ──────────────────────────────────────────────────
2624
2868
  async isExternalPrincipal(args) {
2625
2869
  return trustDoor(
@@ -2946,6 +3190,72 @@ function useRecordMutation() {
2946
3190
  [client, run, saving, error, conflict]
2947
3191
  );
2948
3192
  }
3193
+ function useEntityFields(token) {
3194
+ return useAsync(
3195
+ (client) => token ? client.entityFields({ token }) : Promise.resolve({ ok: true, data: [] }),
3196
+ [token]
3197
+ );
3198
+ }
3199
+ function useEntityRecord(token, recordId) {
3200
+ return useAsync(
3201
+ (client) => token && recordId ? client.entityRecordRead({ token, record_id: recordId }) : Promise.resolve({ ok: true, data: null }),
3202
+ [token, recordId]
3203
+ );
3204
+ }
3205
+ function useEntityTable(token) {
3206
+ return useAsync(
3207
+ (client) => token ? client.entityTable({ token }) : Promise.resolve({ ok: true, data: null }),
3208
+ [token]
3209
+ );
3210
+ }
3211
+ function useEntityFieldRights(token) {
3212
+ return useAsync(
3213
+ (client) => token ? client.entityFieldRights({ token }) : Promise.resolve({ ok: true, data: null }),
3214
+ [token]
3215
+ );
3216
+ }
3217
+ function useEntityFieldMutation() {
3218
+ const client = useRecordsClient();
3219
+ const [saving, setSaving] = (0, import_react2.useState)(false);
3220
+ const [error, setError] = (0, import_react2.useState)(null);
3221
+ const run = (0, import_react2.useCallback)(
3222
+ async (call, whenRefused) => {
3223
+ setSaving(true);
3224
+ setError(null);
3225
+ try {
3226
+ const result = await call();
3227
+ if (result.ok) return result.data;
3228
+ setError(result.error);
3229
+ return whenRefused;
3230
+ } finally {
3231
+ setSaving(false);
3232
+ }
3233
+ },
3234
+ []
3235
+ );
3236
+ return (0, import_react2.useMemo)(
3237
+ () => ({
3238
+ declare: (args) => run(() => client.entityFieldDeclare({ token: args.token, spec: args.spec }), null),
3239
+ update: (args) => run(
3240
+ () => client.entityFieldUpdate({ field_id: args.field_id, patch: args.patch }),
3241
+ null
3242
+ ),
3243
+ retire: (args) => run(() => client.entityFieldRetire({ field_id: args.field_id }), null),
3244
+ write: (args) => run(
3245
+ () => client.entityValueWrite({
3246
+ token: args.token,
3247
+ record_id: args.record_id,
3248
+ patch: args.patch
3249
+ }),
3250
+ null
3251
+ ),
3252
+ saving,
3253
+ error,
3254
+ clearError: () => setError(null)
3255
+ }),
3256
+ [client, run, saving, error]
3257
+ );
3258
+ }
2949
3259
  function useFieldMutation() {
2950
3260
  const client = useRecordsClient();
2951
3261
  const [saving, setSaving] = (0, import_react2.useState)(false);