@fuzdev/fuz_app 0.41.1 → 0.43.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/dist/db/status.js CHANGED
@@ -6,13 +6,29 @@
6
6
  *
7
7
  * @module
8
8
  */
9
+ const has_table_column = async (db, table_name, column_name) => {
10
+ const row = await db.query_one(`SELECT EXISTS (
11
+ SELECT 1 FROM information_schema.columns
12
+ WHERE table_schema = 'public'
13
+ AND table_name = $1
14
+ AND column_name = $2
15
+ ) as exists`, [table_name, column_name]);
16
+ return row?.exists ?? false;
17
+ };
18
+ const has_table = async (db, table_name) => {
19
+ const row = await db.query_one(`SELECT EXISTS (
20
+ SELECT 1 FROM information_schema.tables
21
+ WHERE table_schema = 'public' AND table_name = $1
22
+ ) as exists`, [table_name]);
23
+ return row?.exists ?? false;
24
+ };
9
25
  /**
10
- * Query database status including connectivity, tables, and migration versions.
26
+ * Query database status including connectivity, tables, and migration state.
11
27
  *
12
28
  * Designed for CLI `db:status` commands. Does not modify the database.
13
29
  *
14
30
  * @param db - the database instance
15
- * @param namespaces - migration namespaces to check versions for
31
+ * @param namespaces - migration namespaces to check status for
16
32
  * @returns a snapshot of database status
17
33
  */
18
34
  export const query_db_status = async (db, namespaces) => {
@@ -42,34 +58,42 @@ export const query_db_status = async (db, namespaces) => {
42
58
  row_count: result ? parseInt(result.count, 10) : 0,
43
59
  });
44
60
  }
45
- // check migration versions
61
+ // check migration state
46
62
  const migrations = [];
63
+ let old_tracker_shape;
47
64
  if (namespaces?.length) {
48
- // check if schema_version table exists
49
- const sv_exists = await db.query_one(`SELECT EXISTS (
50
- SELECT 1 FROM information_schema.tables
51
- WHERE table_schema = 'public' AND table_name = 'schema_version'
52
- ) as exists`);
53
- if (sv_exists?.exists) {
65
+ const sv_exists = await has_table(db, 'schema_version');
66
+ // pre-0.42 shape carries a `version` column; new shape carries `name`
67
+ const old_shape = sv_exists ? await has_table_column(db, 'schema_version', 'version') : false;
68
+ if (old_shape)
69
+ old_tracker_shape = true;
70
+ if (sv_exists && !old_shape) {
54
71
  for (const { namespace, migrations: ns_migrations } of namespaces) {
55
- const row = await db.query_one('SELECT version FROM schema_version WHERE namespace = $1', [namespace]);
56
- const current_version = row?.version ?? 0;
72
+ const rows = await db.query(`SELECT name FROM schema_version
73
+ WHERE namespace = $1
74
+ ORDER BY sequence ASC`, [namespace]);
75
+ const applied_names = rows.map((r) => r.name);
76
+ const code_names = ns_migrations.map((m) => m.name);
77
+ // pending = the suffix of code names beyond applied.length (callers
78
+ // see the boot algorithm's tail without paying for verify here)
79
+ const pending_names = code_names.slice(applied_names.length);
57
80
  migrations.push({
58
81
  namespace,
59
- current_version,
60
- available_version: ns_migrations.length,
61
- up_to_date: current_version === ns_migrations.length,
82
+ applied_names,
83
+ pending_names,
84
+ up_to_date: applied_names.length === code_names.length && pending_names.length === 0,
62
85
  });
63
86
  }
64
87
  }
65
88
  else {
66
- // no schema_version tableall namespaces are at version 0
89
+ // no tracker, or pre-0.42 shape every namespace shows as "nothing applied yet"
67
90
  for (const { namespace, migrations: ns_migrations } of namespaces) {
91
+ const code_names = ns_migrations.map((m) => m.name);
68
92
  migrations.push({
69
93
  namespace,
70
- current_version: 0,
71
- available_version: ns_migrations.length,
72
- up_to_date: ns_migrations.length === 0,
94
+ applied_names: [],
95
+ pending_names: code_names,
96
+ up_to_date: code_names.length === 0,
73
97
  });
74
98
  }
75
99
  }
@@ -79,6 +103,7 @@ export const query_db_status = async (db, namespaces) => {
79
103
  table_count: tables.length,
80
104
  tables,
81
105
  migrations,
106
+ ...(old_tracker_shape ? { old_tracker_shape: true } : {}),
82
107
  };
83
108
  };
84
109
  /**
@@ -102,12 +127,23 @@ export const format_db_status = (status) => {
102
127
  lines.push(` ${t.name.padEnd(max_name)} ${t.row_count} rows`);
103
128
  }
104
129
  }
130
+ if (status.old_tracker_shape) {
131
+ lines.push('');
132
+ lines.push(' Migrations: pre-0.42 schema_version shape detected.');
133
+ lines.push(' Drop the table and re-run, or call `baseline()` first if preserving the schema.');
134
+ }
105
135
  if (status.migrations.length > 0) {
106
136
  lines.push('');
107
137
  lines.push(' Migrations:');
108
138
  for (const m of status.migrations) {
109
- const marker = m.up_to_date ? 'up to date' : `${m.current_version}/${m.available_version}`;
110
- lines.push(` ${m.namespace}: v${m.current_version} (${marker})`);
139
+ const total = m.applied_names.length + m.pending_names.length;
140
+ if (m.up_to_date) {
141
+ lines.push(` ${m.namespace}: up to date (${m.applied_names.length}/${total})`);
142
+ }
143
+ else {
144
+ const pending_list = m.pending_names.join(', ');
145
+ lines.push(` ${m.namespace}: applied ${m.applied_names.length}/${total} (pending: ${pending_list})`);
146
+ }
111
147
  }
112
148
  }
113
149
  return lines.join('\n');
@@ -18,6 +18,15 @@ import { type RateLimitKey, type RouteErrorSchemas } from './error_schemas.js';
18
18
  * but also accept other values.
19
19
  */
20
20
  export declare const is_null_schema: (schema: z.ZodType) => boolean;
21
+ /**
22
+ * Check if a schema is exactly `z.void()`.
23
+ *
24
+ * RPC action specs use `z.void()` to declare a parameterless method —
25
+ * JSON-RPC 2.0 forbids `params: null` (params must be omitted or be a
26
+ * Structured value), so `z.void()` is the correct schema for "no params"
27
+ * and the dispatcher maps absent params to `undefined` for these specs.
28
+ */
29
+ export declare const is_void_schema: (schema: z.ZodType) => boolean;
21
30
  /**
22
31
  * Check if a schema is a strict object (`z.strictObject()`).
23
32
  *
@@ -1 +1 @@
1
- {"version":3,"file":"schema_helpers.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/http/schema_helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAEtB,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAuB,KAAK,YAAY,EAAE,KAAK,iBAAiB,EAAC,MAAM,oBAAoB,CAAC;AAEnG;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,OAAsC,CAAC;AAE1F;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,OACe,CAAC;AAE5E;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,OAQrD,CAAC;AAoBF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,kBAAkB,GAAI,SAAS,MAAM,EAAE,YAAY,MAAM,KAAG,OAQxE,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB,GAC/B,MAAM;IACL,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC;IACrB,KAAK,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC;IACpB,UAAU,CAAC,EAAE,YAAY,CAAC;IAC1B,MAAM,CAAC,EAAE,iBAAiB,CAAC;CAC3B,EACD,oBAAoB,iBAAiB,GAAG,IAAI,KAC1C,iBAAiB,GAAG,IAUtB,CAAC"}
1
+ {"version":3,"file":"schema_helpers.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/http/schema_helpers.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAC,CAAC,EAAC,MAAM,KAAK,CAAC;AAEtB,OAAO,KAAK,EAAC,SAAS,EAAC,MAAM,iBAAiB,CAAC;AAC/C,OAAO,EAAuB,KAAK,YAAY,EAAE,KAAK,iBAAiB,EAAC,MAAM,oBAAoB,CAAC;AAEnG;;;;;;GAMG;AACH,eAAO,MAAM,cAAc,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,OAAsC,CAAC;AAE1F;;;;;;;GAOG;AACH,eAAO,MAAM,cAAc,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,OAAsC,CAAC;AAE1F;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,OACe,CAAC;AAE5E;;;;GAIG;AACH,eAAO,MAAM,iBAAiB,GAAI,QAAQ,CAAC,CAAC,OAAO,KAAG,OAQrD,CAAC;AAoBF;;;;;;;;;;GAUG;AACH,eAAO,MAAM,kBAAkB,GAAI,SAAS,MAAM,EAAE,YAAY,MAAM,KAAG,OAQxE,CAAC;AAEF;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB,GAC/B,MAAM;IACL,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,CAAC,CAAC,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC;IACrB,KAAK,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC;IACpB,UAAU,CAAC,EAAE,YAAY,CAAC;IAC1B,MAAM,CAAC,EAAE,iBAAiB,CAAC;CAC3B,EACD,oBAAoB,iBAAiB,GAAG,IAAI,KAC1C,iBAAiB,GAAG,IAUtB,CAAC"}
@@ -17,6 +17,15 @@ import { derive_error_schemas } from './error_schemas.js';
17
17
  * but also accept other values.
18
18
  */
19
19
  export const is_null_schema = (schema) => schema instanceof z.ZodNull;
20
+ /**
21
+ * Check if a schema is exactly `z.void()`.
22
+ *
23
+ * RPC action specs use `z.void()` to declare a parameterless method —
24
+ * JSON-RPC 2.0 forbids `params: null` (params must be omitted or be a
25
+ * Structured value), so `z.void()` is the correct schema for "no params"
26
+ * and the dispatcher maps absent params to `undefined` for these specs.
27
+ */
28
+ export const is_void_schema = (schema) => schema instanceof z.ZodVoid;
20
29
  /**
21
30
  * Check if a schema is a strict object (`z.strictObject()`).
22
31
  *
@@ -70,8 +70,9 @@ export interface CreateAppBackendOptions {
70
70
  audit_log_config?: AuditLogConfig;
71
71
  /**
72
72
  * Additional migration namespaces to run after the builtin auth namespace.
73
- * Each namespace's own `schema_version` row tracks progress; order is
74
- * append-only so forward-only guarantees hold per-namespace.
73
+ * The shared `schema_version` table records one row per applied migration
74
+ * (`namespace`, `name`, `sequence`); order is append-only so forward-only
75
+ * guarantees hold per-namespace.
75
76
  *
76
77
  * The reserved `'fuz_auth'` namespace is rejected at startup. Omit for no
77
78
  * extra namespaces. This is the only place to splice consumer migrations
@@ -1 +1 @@
1
- {"version":3,"file":"app_backend.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/server/app_backend.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAC,MAAM,EAAC,MAAM,yBAAyB,CAAC;AAE/C,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,iBAAiB,CAAC;AAC7C,OAAO,KAAK,EAAC,cAAc,EAAE,aAAa,EAAC,MAAM,6BAA6B,CAAC;AAC/E,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,aAAa,CAAC;AACxC,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,oBAAoB,CAAC;AAChD,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAiB,KAAK,kBAAkB,EAAE,KAAK,eAAe,EAAC,MAAM,kBAAkB,CAAC;AAI/F;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IAC1B,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,oIAAoI;IACpI,QAAQ,CAAC,iBAAiB,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;IAC3D,iEAAiE;IACjE,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAED;;;;;GAKG;AACH,MAAM,WAAW,uBAAuB;IACvC,+DAA+D;IAC/D,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IACnD,2BAA2B;IAC3B,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAClD,qBAAqB;IACrB,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,0EAA0E;IAC1E,YAAY,EAAE,MAAM,CAAC;IACrB,wCAAwC;IACxC,OAAO,EAAE,OAAO,CAAC;IACjB,iFAAiF;IACjF,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,6EAA6E;IAC7E,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAChD;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,cAAc,CAAC;IAClC;;;;;;;;OAQG;IACH,oBAAoB,CAAC,EAAE,aAAa,CAAC,kBAAkB,CAAC,CAAC;CACzD;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,GAAU,SAAS,uBAAuB,KAAG,OAAO,CAAC,UAAU,CAoC7F,CAAC"}
1
+ {"version":3,"file":"app_backend.d.ts","sourceRoot":"../src/lib/","sources":["../../src/lib/server/app_backend.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAC,MAAM,EAAC,MAAM,yBAAyB,CAAC;AAE/C,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,iBAAiB,CAAC;AAC7C,OAAO,KAAK,EAAC,cAAc,EAAE,aAAa,EAAC,MAAM,6BAA6B,CAAC;AAC/E,OAAO,KAAK,EAAC,MAAM,EAAC,MAAM,aAAa,CAAC;AACxC,OAAO,KAAK,EAAC,OAAO,EAAC,MAAM,oBAAoB,CAAC;AAChD,OAAO,KAAK,EAAC,gBAAgB,EAAC,MAAM,qBAAqB,CAAC;AAC1D,OAAO,KAAK,EAAC,UAAU,EAAC,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAiB,KAAK,kBAAkB,EAAE,KAAK,eAAe,EAAC,MAAM,kBAAkB,CAAC;AAI/F;;;;;GAKG;AACH,MAAM,WAAW,UAAU;IAC1B,IAAI,EAAE,OAAO,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,oIAAoI;IACpI,QAAQ,CAAC,iBAAiB,EAAE,aAAa,CAAC,eAAe,CAAC,CAAC;IAC3D,iEAAiE;IACjE,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3B;AAED;;;;;GAKG;AACH,MAAM,WAAW,uBAAuB;IACvC,+DAA+D;IAC/D,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IACnD,2BAA2B;IAC3B,cAAc,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IAClD,qBAAqB;IACrB,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7C,0EAA0E;IAC1E,YAAY,EAAE,MAAM,CAAC;IACrB,wCAAwC;IACxC,OAAO,EAAE,OAAO,CAAC;IACjB,iFAAiF;IACjF,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,6EAA6E;IAC7E,GAAG,CAAC,EAAE,MAAM,CAAC;IACb;;;;OAIG;IACH,cAAc,CAAC,EAAE,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,CAAC;IAChD;;;;;;OAMG;IACH,gBAAgB,CAAC,EAAE,cAAc,CAAC;IAClC;;;;;;;;;OASG;IACH,oBAAoB,CAAC,EAAE,aAAa,CAAC,kBAAkB,CAAC,CAAC;CACzD;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,kBAAkB,GAAU,SAAS,uBAAuB,KAAG,OAAO,CAAC,UAAU,CAoC7F,CAAC"}
@@ -81,19 +81,19 @@ Factory builders for parameterized DB tests. Consumer projects pass their
81
81
  `init_schema` callback (which calls `run_migrations(db, [AUTH_MIGRATION_NS, ...app_migrations])`);
82
82
  factories accept any migration namespace set.
83
83
 
84
- | Helper | Role |
85
- | ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
86
- | `IS_CI` | `process.env.CI === 'true'` — CI detection. |
87
- | `DbFactory` interface | `{name, create, close, skip, skip_reason?}`. |
88
- | `reset_pglite(db)` | `DROP SCHEMA public CASCADE` + recreate. Reuses a live PGlite instance. |
89
- | `create_pglite_factory(init_schema)` | In-memory; no external deps; `skip: false`. See WASM caching below. |
90
- | `create_pg_factory(init_schema, test_url?)` | PostgreSQL; `skip: true` when `test_url` is missing; drops `schema_version` before `init_schema` so migrations re-evaluate against actual tables; pool is reused + cleaned up across `create()` calls. |
91
- | `AUTH_TRUNCATE_TABLES` | `['invite', 'api_token', 'auth_session', 'permit', 'permit_offer', 'actor', 'account']` in FK-safe order. Excludes `audit_log` — unit DB tests don't need to truncate it. |
92
- | `AUTH_INTEGRATION_TRUNCATE_TABLES` | `AUTH_TRUNCATE_TABLES + ['audit_log']` — for integration suites that exercise the audit path. |
93
- | `AUTH_DROP_TABLES` | Full set from `AUTH_MIGRATIONS` in drop order; call `drop_auth_schema(db)` at the top of `init_schema` on persistent pg databases that may hold stale DDL from previous fuz_app versions. |
94
- | `drop_auth_schema(db)` | `DROP TABLE IF EXISTS <table> CASCADE` for every entry in `AUTH_DROP_TABLES` plus `schema_version`. Safe on fresh DBs. |
95
- | `create_describe_db(factories, truncate_tables)` | Returns `describe_db(name, fn)` that runs `fn(get_db)` once per factory, inside a `describe` block with shared `beforeAll(create)` + `beforeEach(TRUNCATE)` + `afterAll(close)`. Skipped factories use `describe.skip`. |
96
- | `log_db_factory_status(factories)` | Console summary of enabled / skipped factories. |
84
+ | Helper | Role |
85
+ | ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
86
+ | `IS_CI` | `process.env.CI === 'true'` — CI detection. |
87
+ | `DbFactory` interface | `{name, create, close, skip, skip_reason?}`. |
88
+ | `reset_pglite(db)` | `DROP SCHEMA public CASCADE` + recreate. Reuses a live PGlite instance. |
89
+ | `create_pglite_factory(init_schema)` | In-memory; no external deps; `skip: false`. See WASM caching below. |
90
+ | `create_pg_factory(init_schema, test_url?)` | PostgreSQL; `skip: true` when `test_url` is missing; drops `schema_version` before `init_schema` so migrations re-evaluate against actual tables (prevents stale tracker rows from skipping migrations when DDL changes between test sessions); pool is reused + cleaned up across `create()` calls. |
91
+ | `AUTH_TRUNCATE_TABLES` | `['invite', 'api_token', 'auth_session', 'permit', 'permit_offer', 'actor', 'account']` in FK-safe order. Excludes `audit_log` — unit DB tests don't need to truncate it. |
92
+ | `AUTH_INTEGRATION_TRUNCATE_TABLES` | `AUTH_TRUNCATE_TABLES + ['audit_log']` — for integration suites that exercise the audit path. |
93
+ | `AUTH_DROP_TABLES` | Full set from `AUTH_MIGRATIONS` in drop order; call `drop_auth_schema(db)` at the top of `init_schema` on persistent pg databases that may hold stale DDL from previous fuz_app versions. |
94
+ | `drop_auth_schema(db)` | `DROP TABLE IF EXISTS <table> CASCADE` for every entry in `AUTH_DROP_TABLES` plus `schema_version`. Safe on fresh DBs. |
95
+ | `create_describe_db(factories, truncate_tables)` | Returns `describe_db(name, fn)` that runs `fn(get_db)` once per factory, inside a `describe` block with shared `beforeAll(create)` + `beforeEach(TRUNCATE)` + `afterAll(close)`. Skipped factories use `describe.skip`. |
96
+ | `log_db_factory_status(factories)` | Console summary of enabled / skipped factories. |
97
97
 
98
98
  **PGlite WASM caching.** `create_pglite_factory` shares a single PGlite
99
99
  instance in a module-level ref (`module_db`) across all factories in the
@@ -163,7 +163,7 @@ export const describe_standard_admin_integration_tests = (options) => {
163
163
  app: test_app.app,
164
164
  path: rpc_path,
165
165
  spec: admin_account_list_action_spec,
166
- params: null,
166
+ params: undefined,
167
167
  headers: test_app.create_session_headers(),
168
168
  });
169
169
  assert.ok(res.ok, `admin_account_list failed: ${res.ok ? '' : JSON.stringify(res.error)}`);
@@ -181,7 +181,7 @@ export const describe_standard_admin_integration_tests = (options) => {
181
181
  app: test_app.app,
182
182
  path: rpc_path,
183
183
  spec: admin_account_list_action_spec,
184
- params: null,
184
+ params: undefined,
185
185
  headers: test_app.create_session_headers(),
186
186
  });
187
187
  assert.ok(!res.ok, 'Expected admin_account_list to fail for non-admin');
@@ -205,7 +205,7 @@ export const describe_standard_admin_integration_tests = (options) => {
205
205
  app: test_app.app,
206
206
  path: rpc_path,
207
207
  spec: admin_session_list_action_spec,
208
- params: null,
208
+ params: undefined,
209
209
  headers: test_app.create_session_headers(),
210
210
  });
211
211
  assert.ok(res.ok, `admin_session_list failed: ${res.ok ? '' : JSON.stringify(res.error)}`);
@@ -220,7 +220,7 @@ export const describe_standard_admin_integration_tests = (options) => {
220
220
  app: test_app.app,
221
221
  path: rpc_path,
222
222
  spec: account_verify_action_spec,
223
- params: null,
223
+ params: undefined,
224
224
  headers: create_headers(user_two.session_cookie),
225
225
  });
226
226
  assert.strictEqual(before.status, 200);
@@ -240,7 +240,7 @@ export const describe_standard_admin_integration_tests = (options) => {
240
240
  app: test_app.app,
241
241
  path: rpc_path,
242
242
  spec: account_verify_action_spec,
243
- params: null,
243
+ params: undefined,
244
244
  headers: create_headers(user_two.session_cookie),
245
245
  });
246
246
  assert.strictEqual(after.status, 401);
@@ -263,7 +263,7 @@ export const describe_standard_admin_integration_tests = (options) => {
263
263
  app: test_app.app,
264
264
  path: rpc_path,
265
265
  spec: account_verify_action_spec,
266
- params: null,
266
+ params: undefined,
267
267
  headers: test_app.create_session_headers(),
268
268
  });
269
269
  assert.strictEqual(after.status, 401);
@@ -279,7 +279,7 @@ export const describe_standard_admin_integration_tests = (options) => {
279
279
  app: test_app.app,
280
280
  path: rpc_path,
281
281
  spec: account_verify_action_spec,
282
- params: null,
282
+ params: undefined,
283
283
  headers: { authorization: `Bearer ${user_two.api_token}` },
284
284
  suppress_default_origin: true,
285
285
  });
@@ -300,7 +300,7 @@ export const describe_standard_admin_integration_tests = (options) => {
300
300
  app: test_app.app,
301
301
  path: rpc_path,
302
302
  spec: account_verify_action_spec,
303
- params: null,
303
+ params: undefined,
304
304
  headers: { authorization: `Bearer ${user_two.api_token}` },
305
305
  suppress_default_origin: true,
306
306
  });
@@ -725,7 +725,7 @@ export const describe_standard_admin_integration_tests = (options) => {
725
725
  app: test_app.app,
726
726
  path: rpc_path,
727
727
  spec: admin_account_list_action_spec,
728
- params: null,
728
+ params: undefined,
729
729
  headers: create_headers(regular_user.session_cookie),
730
730
  });
731
731
  assert.ok(!res.ok, 'Expected admin_account_list to fail for non-admin');
@@ -144,7 +144,7 @@ export const describe_audit_completeness_tests = (options) => {
144
144
  app: test_app.app,
145
145
  path: rpc_path,
146
146
  spec: account_token_list_action_spec,
147
- params: null,
147
+ params: undefined,
148
148
  headers: test_app.create_session_headers(),
149
149
  });
150
150
  assert.ok(list_res.ok, 'account_token_list should succeed');
@@ -179,7 +179,7 @@ export const describe_audit_completeness_tests = (options) => {
179
179
  app: test_app.app,
180
180
  path: rpc_path,
181
181
  spec: account_session_list_action_spec,
182
- params: null,
182
+ params: undefined,
183
183
  headers: test_app.create_session_headers(),
184
184
  });
185
185
  assert.ok(list_res.ok, 'account_session_list should succeed');
@@ -203,7 +203,7 @@ export const describe_audit_completeness_tests = (options) => {
203
203
  app: test_app.app,
204
204
  path: rpc_path,
205
205
  spec: account_session_revoke_all_action_spec,
206
- params: null,
206
+ params: undefined,
207
207
  headers: test_app.create_session_headers(),
208
208
  });
209
209
  assert.ok(res.ok, `account_session_revoke_all failed: ${res.ok ? '' : JSON.stringify(res.error)}`);
@@ -41,7 +41,7 @@ export declare const create_pglite_factory: (init_schema: (db: Db) => Promise<vo
41
41
  *
42
42
  * Skipped when `test_url` is not provided.
43
43
  * Drops `schema_version` before running `init_schema`, forcing migrations
44
- * to re-evaluate against the actual tables. Prevents stale version entries
44
+ * to re-evaluate against the actual tables. Prevents stale tracker rows
45
45
  * from skipping migrations when DDL changes between test sessions.
46
46
  *
47
47
  * For full clean-slate behavior (recommended), call `drop_auth_schema(db)`
@@ -82,7 +82,7 @@ export const create_pglite_factory = (init_schema) => ({
82
82
  *
83
83
  * Skipped when `test_url` is not provided.
84
84
  * Drops `schema_version` before running `init_schema`, forcing migrations
85
- * to re-evaluate against the actual tables. Prevents stale version entries
85
+ * to re-evaluate against the actual tables. Prevents stale tracker rows
86
86
  * from skipping migrations when DDL changes between test sessions.
87
87
  *
88
88
  * For full clean-slate behavior (recommended), call `drop_auth_schema(db)`
@@ -122,7 +122,7 @@ export const create_pg_factory = (init_schema, test_url) => {
122
122
  const { db } = create_pg_db(pool);
123
123
  try {
124
124
  // Drop schema_version so migrations re-evaluate against the actual
125
- // tables. Prevents stale version entries from skipping migrations
125
+ // tables. Prevents stale tracker rows from skipping migrations
126
126
  // when DDL changes between test sessions. Migrations use
127
127
  // IF NOT EXISTS guards, so re-running is safe.
128
128
  await db.query('DROP TABLE IF EXISTS schema_version');