@ai-matrx/data 0.24.0 → 0.25.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 CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.25.0 — created_by stamped; listAll keeps the database's error
4
+
5
+ - **A signed-in `insert` stamps `created_by`** with the session's person when the table has a
6
+ `created_by` column and the row omits it (row security on `workbench.notes` / `note_folders` and
7
+ similar tables refuses an insert whose `created_by` is not `auth.uid()`). An explicit value is kept;
8
+ the service role never stamps. Descriptors carry `createdBy: boolean` (generated from the columns).
9
+ - **`listAll` throws a `DatabaseError`** carrying the database's own error (message, code, details) —
10
+ it used to surface as a re-worded `readAllRows(...)` `Error` without the code.
11
+
12
+ Consumer action: run `matrx-data generate` again (`pnpm db:generate`) so descriptors carry `createdBy`;
13
+ code that matched `listAll` failures by the `readAllRows(` message should check `instanceof DatabaseError`.
14
+
3
15
  ## 0.24.0 — doors hardened (independent review)
4
16
 
5
17
  - **Every write on a versioned table is guarded.** `remove` (and `archive` / `restore`) take the same
package/bin/generate.mjs CHANGED
@@ -94,6 +94,7 @@ function tableDescriptor(schema, name, t) {
94
94
  readOnlyColumns: reg?.clientReadOnlyColumns ?? [],
95
95
  listScope: reg?.listScope ?? null,
96
96
  realtime: (t.realtime ?? []).includes("supabase_realtime"),
97
+ createdBy: t.columns.some((c) => c.name === "created_by"),
97
98
  };
98
99
  return flags;
99
100
  }
package/dist/db.cjs CHANGED
@@ -1074,7 +1074,10 @@ async function listAll(db, table, where, opts = {}) {
1074
1074
  ({ from: lo, to: hi }) => {
1075
1075
  let q = live(from(db, table).select(selectOf(opts.columns), { count: "exact" }), table, opts.includeDeleted);
1076
1076
  if (where) q = where(q);
1077
- return ordered(q, table, opts.orderBy).range(lo, hi);
1077
+ return Promise.resolve(ordered(q, table, opts.orderBy).range(lo, hi)).then((res) => {
1078
+ if (res.error) throw new DatabaseError(`listAll ${qualified(table)}`, res.error);
1079
+ return res;
1080
+ });
1078
1081
  },
1079
1082
  {
1080
1083
  label: `listAll ${qualified(table)}`,
@@ -1120,7 +1123,12 @@ function withOrganization(db, table, values) {
1120
1123
  async function insert(db, table, values) {
1121
1124
  assertDoor(db, table, "insert");
1122
1125
  const many = Array.isArray(values);
1123
- const rows = (many ? values : [values]).map((v) => withOrganization(db, table, v));
1126
+ let rows = (many ? values : [values]).map((v) => withOrganization(db, table, v));
1127
+ if (table.createdBy && db.role === "user" && rows.some((r) => r.created_by == null) && db.client.auth) {
1128
+ const { data } = await db.client.auth.getSession();
1129
+ const person = data.session?.user?.id;
1130
+ if (person) rows = rows.map((r) => r.created_by == null ? { ...r, created_by: person } : r);
1131
+ }
1124
1132
  const res = await from(db, table).insert(rows).select("*");
1125
1133
  const stored = check(`insert ${qualified(table)}`, res);
1126
1134
  return many ? stored : stored[0];