@adminiumjs/meta 0.1.0-rc.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.
Files changed (194) hide show
  1. package/LICENSE +661 -0
  2. package/dist/bootstrap.d.ts +103 -0
  3. package/dist/bootstrap.d.ts.map +1 -0
  4. package/dist/bootstrap.js +225 -0
  5. package/dist/bootstrap.js.map +1 -0
  6. package/dist/columns.d.ts +44 -0
  7. package/dist/columns.d.ts.map +1 -0
  8. package/dist/columns.js +57 -0
  9. package/dist/columns.js.map +1 -0
  10. package/dist/connect.d.ts +38 -0
  11. package/dist/connect.d.ts.map +1 -0
  12. package/dist/connect.js +57 -0
  13. package/dist/connect.js.map +1 -0
  14. package/dist/ids.d.ts +79 -0
  15. package/dist/ids.d.ts.map +1 -0
  16. package/dist/ids.js +165 -0
  17. package/dist/ids.js.map +1 -0
  18. package/dist/index.d.ts +21 -0
  19. package/dist/index.d.ts.map +1 -0
  20. package/dist/index.js +21 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/migrations/0001_core_auth.d.ts +9 -0
  23. package/dist/migrations/0001_core_auth.d.ts.map +1 -0
  24. package/dist/migrations/0001_core_auth.js +102 -0
  25. package/dist/migrations/0001_core_auth.js.map +1 -0
  26. package/dist/migrations/0002_rbac.d.ts +8 -0
  27. package/dist/migrations/0002_rbac.d.ts.map +1 -0
  28. package/dist/migrations/0002_rbac.js +75 -0
  29. package/dist/migrations/0002_rbac.js.map +1 -0
  30. package/dist/migrations/0003_connections_schema.d.ts +9 -0
  31. package/dist/migrations/0003_connections_schema.d.ts.map +1 -0
  32. package/dist/migrations/0003_connections_schema.js +100 -0
  33. package/dist/migrations/0003_connections_schema.js.map +1 -0
  34. package/dist/migrations/0004_pages_views.d.ts +8 -0
  35. package/dist/migrations/0004_pages_views.d.ts.map +1 -0
  36. package/dist/migrations/0004_pages_views.js +59 -0
  37. package/dist/migrations/0004_pages_views.js.map +1 -0
  38. package/dist/migrations/0005_ops.d.ts +9 -0
  39. package/dist/migrations/0005_ops.d.ts.map +1 -0
  40. package/dist/migrations/0005_ops.js +104 -0
  41. package/dist/migrations/0005_ops.js.map +1 -0
  42. package/dist/migrations/0006_platform.d.ts +11 -0
  43. package/dist/migrations/0006_platform.d.ts.map +1 -0
  44. package/dist/migrations/0006_platform.js +259 -0
  45. package/dist/migrations/0006_platform.js.map +1 -0
  46. package/dist/migrations/0007_llm_runs.d.ts +33 -0
  47. package/dist/migrations/0007_llm_runs.d.ts.map +1 -0
  48. package/dist/migrations/0007_llm_runs.js +62 -0
  49. package/dist/migrations/0007_llm_runs.js.map +1 -0
  50. package/dist/migrations/0008_llm_overrides.d.ts +18 -0
  51. package/dist/migrations/0008_llm_overrides.d.ts.map +1 -0
  52. package/dist/migrations/0008_llm_overrides.js +24 -0
  53. package/dist/migrations/0008_llm_overrides.js.map +1 -0
  54. package/dist/migrations/0009_views_kind.d.ts +20 -0
  55. package/dist/migrations/0009_views_kind.d.ts.map +1 -0
  56. package/dist/migrations/0009_views_kind.js +24 -0
  57. package/dist/migrations/0009_views_kind.js.map +1 -0
  58. package/dist/migrations/0010_llm_prompt_version_width.d.ts +19 -0
  59. package/dist/migrations/0010_llm_prompt_version_width.d.ts.map +1 -0
  60. package/dist/migrations/0010_llm_prompt_version_width.js +28 -0
  61. package/dist/migrations/0010_llm_prompt_version_width.js.map +1 -0
  62. package/dist/migrations/index.d.ts +29 -0
  63. package/dist/migrations/index.d.ts.map +1 -0
  64. package/dist/migrations/index.js +43 -0
  65. package/dist/migrations/index.js.map +1 -0
  66. package/dist/migrator.d.ts +83 -0
  67. package/dist/migrator.d.ts.map +1 -0
  68. package/dist/migrator.js +173 -0
  69. package/dist/migrator.js.map +1 -0
  70. package/dist/prefix.d.ts +19 -0
  71. package/dist/prefix.d.ts.map +1 -0
  72. package/dist/prefix.js +33 -0
  73. package/dist/prefix.js.map +1 -0
  74. package/dist/repos/api-keys.d.ts +31 -0
  75. package/dist/repos/api-keys.d.ts.map +1 -0
  76. package/dist/repos/api-keys.js +62 -0
  77. package/dist/repos/api-keys.js.map +1 -0
  78. package/dist/repos/audit.d.ts +51 -0
  79. package/dist/repos/audit.d.ts.map +1 -0
  80. package/dist/repos/audit.js +78 -0
  81. package/dist/repos/audit.js.map +1 -0
  82. package/dist/repos/connections.d.ts +90 -0
  83. package/dist/repos/connections.d.ts.map +1 -0
  84. package/dist/repos/connections.js +191 -0
  85. package/dist/repos/connections.js.map +1 -0
  86. package/dist/repos/email-templates.d.ts +47 -0
  87. package/dist/repos/email-templates.d.ts.map +1 -0
  88. package/dist/repos/email-templates.js +93 -0
  89. package/dist/repos/email-templates.js.map +1 -0
  90. package/dist/repos/exports.d.ts +67 -0
  91. package/dist/repos/exports.d.ts.map +1 -0
  92. package/dist/repos/exports.js +132 -0
  93. package/dist/repos/exports.js.map +1 -0
  94. package/dist/repos/files.d.ts +52 -0
  95. package/dist/repos/files.d.ts.map +1 -0
  96. package/dist/repos/files.js +86 -0
  97. package/dist/repos/files.js.map +1 -0
  98. package/dist/repos/imports.d.ts +71 -0
  99. package/dist/repos/imports.d.ts.map +1 -0
  100. package/dist/repos/imports.js +111 -0
  101. package/dist/repos/imports.js.map +1 -0
  102. package/dist/repos/index.d.ts +26 -0
  103. package/dist/repos/index.d.ts.map +1 -0
  104. package/dist/repos/index.js +26 -0
  105. package/dist/repos/index.js.map +1 -0
  106. package/dist/repos/jobs.d.ts +71 -0
  107. package/dist/repos/jobs.d.ts.map +1 -0
  108. package/dist/repos/jobs.js +187 -0
  109. package/dist/repos/jobs.js.map +1 -0
  110. package/dist/repos/llm-overrides.d.ts +89 -0
  111. package/dist/repos/llm-overrides.d.ts.map +1 -0
  112. package/dist/repos/llm-overrides.js +205 -0
  113. package/dist/repos/llm-overrides.js.map +1 -0
  114. package/dist/repos/llm-runs.d.ts +114 -0
  115. package/dist/repos/llm-runs.d.ts.map +1 -0
  116. package/dist/repos/llm-runs.js +214 -0
  117. package/dist/repos/llm-runs.js.map +1 -0
  118. package/dist/repos/notification-prefs.d.ts +34 -0
  119. package/dist/repos/notification-prefs.d.ts.map +1 -0
  120. package/dist/repos/notification-prefs.js +80 -0
  121. package/dist/repos/notification-prefs.js.map +1 -0
  122. package/dist/repos/notifications.d.ts +60 -0
  123. package/dist/repos/notifications.d.ts.map +1 -0
  124. package/dist/repos/notifications.js +107 -0
  125. package/dist/repos/notifications.js.map +1 -0
  126. package/dist/repos/overrides.d.ts +59 -0
  127. package/dist/repos/overrides.d.ts.map +1 -0
  128. package/dist/repos/overrides.js +143 -0
  129. package/dist/repos/overrides.js.map +1 -0
  130. package/dist/repos/pages.d.ts +192 -0
  131. package/dist/repos/pages.d.ts.map +1 -0
  132. package/dist/repos/pages.js +374 -0
  133. package/dist/repos/pages.js.map +1 -0
  134. package/dist/repos/password-resets.d.ts +32 -0
  135. package/dist/repos/password-resets.d.ts.map +1 -0
  136. package/dist/repos/password-resets.js +56 -0
  137. package/dist/repos/password-resets.js.map +1 -0
  138. package/dist/repos/permissions.d.ts +28 -0
  139. package/dist/repos/permissions.d.ts.map +1 -0
  140. package/dist/repos/permissions.js +100 -0
  141. package/dist/repos/permissions.js.map +1 -0
  142. package/dist/repos/roles.d.ts +33 -0
  143. package/dist/repos/roles.d.ts.map +1 -0
  144. package/dist/repos/roles.js +89 -0
  145. package/dist/repos/roles.js.map +1 -0
  146. package/dist/repos/scheduled-reports.d.ts +73 -0
  147. package/dist/repos/scheduled-reports.d.ts.map +1 -0
  148. package/dist/repos/scheduled-reports.js +132 -0
  149. package/dist/repos/scheduled-reports.js.map +1 -0
  150. package/dist/repos/sessions.d.ts +33 -0
  151. package/dist/repos/sessions.d.ts.map +1 -0
  152. package/dist/repos/sessions.js +79 -0
  153. package/dist/repos/sessions.js.map +1 -0
  154. package/dist/repos/settings.d.ts +25 -0
  155. package/dist/repos/settings.d.ts.map +1 -0
  156. package/dist/repos/settings.js +73 -0
  157. package/dist/repos/settings.js.map +1 -0
  158. package/dist/repos/snapshots.d.ts +79 -0
  159. package/dist/repos/snapshots.d.ts.map +1 -0
  160. package/dist/repos/snapshots.js +191 -0
  161. package/dist/repos/snapshots.js.map +1 -0
  162. package/dist/repos/user-prefs.d.ts +56 -0
  163. package/dist/repos/user-prefs.d.ts.map +1 -0
  164. package/dist/repos/user-prefs.js +147 -0
  165. package/dist/repos/user-prefs.js.map +1 -0
  166. package/dist/repos/users.d.ts +38 -0
  167. package/dist/repos/users.d.ts.map +1 -0
  168. package/dist/repos/users.js +103 -0
  169. package/dist/repos/users.js.map +1 -0
  170. package/dist/repos/util.d.ts +45 -0
  171. package/dist/repos/util.d.ts.map +1 -0
  172. package/dist/repos/util.js +81 -0
  173. package/dist/repos/util.js.map +1 -0
  174. package/dist/repos/views.d.ts +75 -0
  175. package/dist/repos/views.d.ts.map +1 -0
  176. package/dist/repos/views.js +180 -0
  177. package/dist/repos/views.js.map +1 -0
  178. package/dist/schema/index.d.ts +4 -0
  179. package/dist/schema/index.d.ts.map +1 -0
  180. package/dist/schema/index.js +4 -0
  181. package/dist/schema/index.js.map +1 -0
  182. package/dist/schema/json-payloads.d.ts +479 -0
  183. package/dist/schema/json-payloads.d.ts.map +1 -0
  184. package/dist/schema/json-payloads.js +340 -0
  185. package/dist/schema/json-payloads.js.map +1 -0
  186. package/dist/schema/settings-registry.d.ts +187 -0
  187. package/dist/schema/settings-registry.d.ts.map +1 -0
  188. package/dist/schema/settings-registry.js +183 -0
  189. package/dist/schema/settings-registry.js.map +1 -0
  190. package/dist/schema/tables.d.ts +568 -0
  191. package/dist/schema/tables.d.ts.map +1 -0
  192. package/dist/schema/tables.js +51 -0
  193. package/dist/schema/tables.js.map +1 -0
  194. package/package.json +33 -0
@@ -0,0 +1,107 @@
1
+ /**
2
+ * notificationsRepo — adminium_notifications (07-meta-store.md §3.20): one row
3
+ * per in-app notification. Write-once rows read later, so `kind` is the
4
+ * stable, translatable key and `title`/`body` are the en-US fallback for a
5
+ * client that does not know the kind (the backup/notify.ts convention — the
6
+ * first producer — now shared by every producer through this repo).
7
+ *
8
+ * Keyset pagination: `(created_at DESC, id DESC)` — ids are monotonic ULIDs,
9
+ * so the pair is a stable total order (08-server-api.md §1.5).
10
+ */
11
+ import { newId } from '../ids.js';
12
+ import { affected, packJson, readJsonOrNull } from './util.js';
13
+ /** System-actor events render actor "Adminium" (09-generated-app.md §5.4). */
14
+ export const SYSTEM_ACTOR_LABEL = 'Adminium';
15
+ function decode(row) {
16
+ return {
17
+ id: row.id,
18
+ userId: row.userId,
19
+ kind: row.kind,
20
+ actorLabel: row.actorLabel,
21
+ title: row.title,
22
+ body: row.body,
23
+ entity: readJsonOrNull(row.entity),
24
+ actionUrl: row.actionUrl,
25
+ readAt: row.readAt,
26
+ createdAt: row.createdAt,
27
+ };
28
+ }
29
+ export function notificationsRepo(meta) {
30
+ const { db } = meta;
31
+ return {
32
+ async create(input, at = Date.now()) {
33
+ const row = {
34
+ id: newId('ntf'),
35
+ userId: input.userId,
36
+ kind: input.kind,
37
+ actorLabel: input.actorLabel ?? SYSTEM_ACTOR_LABEL,
38
+ title: input.title,
39
+ body: input.body ?? null,
40
+ entity: input.entity === null || input.entity === undefined ? null : packJson(input.entity),
41
+ actionUrl: input.actionUrl ?? null,
42
+ readAt: null,
43
+ createdAt: at,
44
+ };
45
+ await db.insertInto('adminium_notifications').values(row).execute();
46
+ return decode(row);
47
+ },
48
+ async findById(id) {
49
+ const row = await db
50
+ .selectFrom('adminium_notifications')
51
+ .selectAll()
52
+ .where('id', '=', id)
53
+ .executeTakeFirst();
54
+ return row ? decode(row) : null;
55
+ },
56
+ /** Newest first; keyset `before` = the previous page's last row. */
57
+ async listForUser(userId, opts = {}) {
58
+ let query = db.selectFrom('adminium_notifications').selectAll().where('userId', '=', userId);
59
+ if (opts.unreadOnly === true)
60
+ query = query.where('readAt', 'is', null);
61
+ const before = opts.before;
62
+ if (before !== undefined) {
63
+ query = query.where((eb) => eb.or([
64
+ eb('createdAt', '<', before.createdAt),
65
+ eb.and([eb('createdAt', '=', before.createdAt), eb('id', '<', before.id)]),
66
+ ]));
67
+ }
68
+ const rows = await query
69
+ .orderBy('createdAt', 'desc')
70
+ .orderBy('id', 'desc')
71
+ .limit(opts.limit ?? 20)
72
+ .execute();
73
+ return rows.map(decode);
74
+ },
75
+ /** The nav-badge / bell number (09 §5.4 `unread-count`). */
76
+ async unreadCount(userId) {
77
+ const row = await db
78
+ .selectFrom('adminium_notifications')
79
+ .select((eb) => eb.fn.countAll().as('count'))
80
+ .where('userId', '=', userId)
81
+ .where('readAt', 'is', null)
82
+ .executeTakeFirst();
83
+ return Number(row?.count ?? 0);
84
+ },
85
+ /** Scoped to the owner — a foreign id is a silent no-op, never a leak. */
86
+ async markRead(id, userId, at = Date.now()) {
87
+ const res = await db
88
+ .updateTable('adminium_notifications')
89
+ .set({ readAt: at })
90
+ .where('id', '=', id)
91
+ .where('userId', '=', userId)
92
+ .where('readAt', 'is', null)
93
+ .executeTakeFirst();
94
+ return affected(res.numUpdatedRows) === 1;
95
+ },
96
+ async markAllRead(userId, at = Date.now()) {
97
+ const res = await db
98
+ .updateTable('adminium_notifications')
99
+ .set({ readAt: at })
100
+ .where('userId', '=', userId)
101
+ .where('readAt', 'is', null)
102
+ .executeTakeFirst();
103
+ return affected(res.numUpdatedRows);
104
+ },
105
+ };
106
+ }
107
+ //# sourceMappingURL=notifications.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"notifications.js","sourceRoot":"","sources":["../../src/repos/notifications.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * overridesRepo — adminium_schema_overrides (07-meta-store.md §3.15).
3
+ *
4
+ * One row = one correction op layered over the active snapshot (labels, type
5
+ * overrides, relation add/suppress, enum semantics, PII masks, …). Payloads
6
+ * are validated against the §3.15 op vocabulary (`overridePatchSchema`) —
7
+ * an invalid payload never reaches the database. The effective schema =
8
+ * active snapshot + active ops applied in created_at order (later ops win
9
+ * per (op, table, column) target — applied by the server, not here).
10
+ */
11
+ import type { MetaDb } from '../connect.js';
12
+ import { type OverrideOp, type OverridePatch } from '../schema/json-payloads.js';
13
+ export interface SchemaOverride {
14
+ id: string;
15
+ connectionId: string;
16
+ op: OverrideOp;
17
+ tableName: string;
18
+ columnName: string | null;
19
+ value: Record<string, unknown>;
20
+ origin: 'user' | 'llm';
21
+ llmRunId: string | null;
22
+ status: 'active' | 'disabled';
23
+ createdBy: string | null;
24
+ createdAt: number;
25
+ updatedAt: number;
26
+ }
27
+ export interface CreateOverrideInput {
28
+ connectionId: string;
29
+ op: string;
30
+ /** Qualified source name, e.g. `public.customers`. */
31
+ tableName: string;
32
+ columnName?: string | null | undefined;
33
+ value: unknown;
34
+ origin?: 'user' | 'llm' | undefined;
35
+ llmRunId?: string | null | undefined;
36
+ status?: 'active' | 'disabled' | undefined;
37
+ createdBy?: string | null | undefined;
38
+ }
39
+ /** Validate one op + payload against the §3.15 vocabulary; throws on failure. */
40
+ export declare function validateOverrideInput(input: CreateOverrideInput): OverridePatch;
41
+ export declare function overridesRepo(meta: MetaDb): {
42
+ create(input: CreateOverrideInput, at?: number): Promise<SchemaOverride>;
43
+ findById(id: string): Promise<SchemaOverride | null>;
44
+ /** Ordered by created_at (application order); optionally filtered by status. */
45
+ listForConnection(connectionId: string, opts?: {
46
+ status?: "active" | "disabled";
47
+ }): Promise<SchemaOverride[]>;
48
+ /**
49
+ * PUT semantics for the remap editor (08 §2.5): replace the connection's
50
+ * override set in one transaction. Every row is validated before any
51
+ * write happens, so a bad payload leaves the set untouched.
52
+ */
53
+ replaceForConnection(connectionId: string, inputs: Omit<CreateOverrideInput, "connectionId">[], at?: number): Promise<SchemaOverride[]>;
54
+ /** Toggle a correction off without deleting it (§3.15). */
55
+ setStatus(id: string, status: "active" | "disabled", at?: number): Promise<boolean>;
56
+ delete(id: string): Promise<boolean>;
57
+ };
58
+ export type OverridesRepo = ReturnType<typeof overridesRepo>;
59
+ //# sourceMappingURL=overrides.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overrides.d.ts","sourceRoot":"","sources":["../../src/repos/overrides.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAIH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,eAAe,CAAC;AAE5C,OAAO,EAIL,KAAK,UAAU,EACf,KAAK,aAAa,EACnB,MAAM,4BAA4B,CAAC;AAapC,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,YAAY,EAAE,MAAM,CAAC;IACrB,EAAE,EAAE,UAAU,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,MAAM,EAAE,MAAM,GAAG,KAAK,CAAC;IACvB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,EAAE,QAAQ,GAAG,UAAU,CAAC;IAC9B,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,mBAAmB;IAClC,YAAY,EAAE,MAAM,CAAC;IACrB,EAAE,EAAE,MAAM,CAAC;IACX,sDAAsD;IACtD,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACvC,KAAK,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;IACrC,MAAM,CAAC,EAAE,QAAQ,GAAG,UAAU,GAAG,SAAS,CAAC;IAC3C,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC;CACvC;AAmBD,iFAAiF;AACjF,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,mBAAmB,GAAG,aAAa,CAoB/E;AAED,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM;kBA4ClB,mBAAmB,OAAM,MAAM,GAAgB,OAAO,CAAC,cAAc,CAAC;iBAMvE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,IAAI,CAAC;IAS1D,gFAAgF;oCAEhE,MAAM,SACd;QAAE,MAAM,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAA;KAAE,GACvC,OAAO,CAAC,cAAc,EAAE,CAAC;IAY5B;;;;OAIG;uCAEa,MAAM,UACZ,IAAI,CAAC,mBAAmB,EAAE,cAAc,CAAC,EAAE,OAC/C,MAAM,GACT,OAAO,CAAC,cAAc,EAAE,CAAC;IAW5B,2DAA2D;kBACvC,MAAM,UAAU,QAAQ,GAAG,UAAU,OAAM,MAAM,GAAgB,OAAO,CAAC,OAAO,CAAC;eAWpF,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;EAK7C;AAED,MAAM,MAAM,aAAa,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC"}
@@ -0,0 +1,143 @@
1
+ /**
2
+ * overridesRepo — adminium_schema_overrides (07-meta-store.md §3.15).
3
+ *
4
+ * One row = one correction op layered over the active snapshot (labels, type
5
+ * overrides, relation add/suppress, enum semantics, PII masks, …). Payloads
6
+ * are validated against the §3.15 op vocabulary (`overridePatchSchema`) —
7
+ * an invalid payload never reaches the database. The effective schema =
8
+ * active snapshot + active ops applied in created_at order (later ops win
9
+ * per (op, table, column) target — applied by the server, not here).
10
+ */
11
+ import { newId } from '../ids.js';
12
+ import { overrideOriginSchema, overridePatchSchema, overrideStatusSchema, } from '../schema/json-payloads.js';
13
+ import { MetaValidationError, packJson, readJson } from './util.js';
14
+ /** Ops that target a column and therefore require `columnName`. */
15
+ const COLUMN_OPS = new Set([
16
+ 'column.label',
17
+ 'column.semanticType',
18
+ 'column.enumLabels',
19
+ 'column.pii',
20
+ 'column.hidden',
21
+ ]);
22
+ function decode(row) {
23
+ return {
24
+ id: row.id,
25
+ connectionId: row.connectionId,
26
+ op: row.op,
27
+ tableName: row.tableName,
28
+ columnName: row.columnName,
29
+ value: readJson(row.value),
30
+ origin: row.origin,
31
+ llmRunId: row.llmRunId,
32
+ status: row.status,
33
+ createdBy: row.createdBy,
34
+ createdAt: row.createdAt,
35
+ updatedAt: row.updatedAt,
36
+ };
37
+ }
38
+ /** Validate one op + payload against the §3.15 vocabulary; throws on failure. */
39
+ export function validateOverrideInput(input) {
40
+ const parsed = overridePatchSchema.safeParse({ op: input.op, value: input.value });
41
+ if (!parsed.success) {
42
+ throw new MetaValidationError(`invalid override payload for op ${JSON.stringify(input.op)}`, parsed.error.issues);
43
+ }
44
+ const needsColumn = COLUMN_OPS.has(parsed.data.op);
45
+ const hasColumn = typeof input.columnName === 'string' && input.columnName.length > 0;
46
+ if (needsColumn && !hasColumn) {
47
+ throw new MetaValidationError(`op ${parsed.data.op} requires columnName`);
48
+ }
49
+ if (!needsColumn && hasColumn) {
50
+ throw new MetaValidationError(`op ${parsed.data.op} is table-level — columnName must be null`);
51
+ }
52
+ if (input.tableName.length === 0) {
53
+ throw new MetaValidationError('tableName must not be empty');
54
+ }
55
+ return parsed.data;
56
+ }
57
+ export function overridesRepo(meta) {
58
+ const { db } = meta;
59
+ function buildRow(input, at) {
60
+ const patch = validateOverrideInput(input);
61
+ const origin = overrideOriginSchema.safeParse(input.origin ?? 'user');
62
+ if (!origin.success)
63
+ throw new MetaValidationError('invalid override origin', origin.error.issues);
64
+ const status = overrideStatusSchema.safeParse(input.status ?? 'active');
65
+ if (!status.success)
66
+ throw new MetaValidationError('invalid override status', status.error.issues);
67
+ return {
68
+ id: newId('ovr'),
69
+ connectionId: input.connectionId,
70
+ op: patch.op,
71
+ tableName: input.tableName,
72
+ columnName: COLUMN_OPS.has(patch.op) ? input.columnName : null,
73
+ value: packJson(patch.value),
74
+ origin: origin.data,
75
+ llmRunId: input.llmRunId ?? null,
76
+ status: status.data,
77
+ confidence: null,
78
+ createdBy: input.createdBy ?? null,
79
+ createdAt: at,
80
+ updatedAt: at,
81
+ };
82
+ }
83
+ return {
84
+ async create(input, at = Date.now()) {
85
+ const row = buildRow(input, at);
86
+ await db.insertInto('adminium_schema_overrides').values(row).execute();
87
+ return decode(row);
88
+ },
89
+ async findById(id) {
90
+ const row = await db
91
+ .selectFrom('adminium_schema_overrides')
92
+ .selectAll()
93
+ .where('id', '=', id)
94
+ .executeTakeFirst();
95
+ return row === undefined ? null : decode(row);
96
+ },
97
+ /** Ordered by created_at (application order); optionally filtered by status. */
98
+ async listForConnection(connectionId, opts = {}) {
99
+ let query = db
100
+ .selectFrom('adminium_schema_overrides')
101
+ .selectAll()
102
+ .where('connectionId', '=', connectionId)
103
+ .orderBy('createdAt', 'asc')
104
+ .orderBy('id', 'asc');
105
+ if (opts.status !== undefined)
106
+ query = query.where('status', '=', opts.status);
107
+ const rows = await query.execute();
108
+ return rows.map(decode);
109
+ },
110
+ /**
111
+ * PUT semantics for the remap editor (08 §2.5): replace the connection's
112
+ * override set in one transaction. Every row is validated before any
113
+ * write happens, so a bad payload leaves the set untouched.
114
+ */
115
+ async replaceForConnection(connectionId, inputs, at = Date.now()) {
116
+ const rows = inputs.map((input) => buildRow({ ...input, connectionId }, at));
117
+ return db.transaction().execute(async (trx) => {
118
+ await trx.deleteFrom('adminium_schema_overrides').where('connectionId', '=', connectionId).execute();
119
+ for (const row of rows) {
120
+ await trx.insertInto('adminium_schema_overrides').values(row).execute();
121
+ }
122
+ return rows.map(decode);
123
+ });
124
+ },
125
+ /** Toggle a correction off without deleting it (§3.15). */
126
+ async setStatus(id, status, at = Date.now()) {
127
+ const valid = overrideStatusSchema.safeParse(status);
128
+ if (!valid.success)
129
+ throw new MetaValidationError('invalid override status', valid.error.issues);
130
+ const res = await db
131
+ .updateTable('adminium_schema_overrides')
132
+ .set({ status: valid.data, updatedAt: at })
133
+ .where('id', '=', id)
134
+ .executeTakeFirst();
135
+ return Number(res.numUpdatedRows) === 1;
136
+ },
137
+ async delete(id) {
138
+ const res = await db.deleteFrom('adminium_schema_overrides').where('id', '=', id).executeTakeFirst();
139
+ return Number(res.numDeletedRows ?? 0n) === 1;
140
+ },
141
+ };
142
+ }
143
+ //# sourceMappingURL=overrides.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"overrides.js","sourceRoot":"","sources":["../../src/repos/overrides.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,192 @@
1
+ /**
2
+ * pagesRepo — adminium_pages (07-meta-store.md §3.16).
3
+ *
4
+ * Every navigable page of the Generated App, dashboards included. The
5
+ * `config` column is the opaque, already-validated envelope JSON
6
+ * (01-architecture.md §6.1) — `@adminium/meta` never imports the engine
7
+ * schemas; the server is the single write-time validator.
8
+ *
9
+ * Generator contract (M4-T08): `upsertGenerated` is idempotent — stable
10
+ * `page_<slug>` ids, unchanged documents are not rewritten, changed ones
11
+ * bump `revision`, rows the generator no longer emits are pruned (unless
12
+ * human-edited — see below), and rows whose `origin` is not `generated`
13
+ * (user/manifest/system pages) are never touched or pruned. The M5
14
+ * regeneration safety net keys on the `config.generatedHash` the engine
15
+ * embeds in each generated envelope (04-widget-registry.md §6.3 note: user
16
+ * delta wins): when the caller supplies the hash function, a stored document
17
+ * whose embedded hash no longer matches (a human edited it — `setLayout`
18
+ * deliberately leaves the hash stale) is skipped, not overwritten, and
19
+ * reported in `skippedEdited` — the full diff proposal UI is 04-T15. The
20
+ * same guard extends to deletion: an edited row missing from the new set is
21
+ * kept, not pruned, and reported in `keptEdited`; only unedited orphans
22
+ * (byte-identically regenerable) are deleted. Without `hashEnvelope` the
23
+ * legacy full prune applies.
24
+ */
25
+ import type { MetaDb } from '../connect.js';
26
+ export declare const PAGE_ORIGINS: readonly ["generated", "user", "manifest", "system", "llm"];
27
+ export type PageOrigin = (typeof PAGE_ORIGINS)[number];
28
+ export interface Page {
29
+ id: string;
30
+ connectionId: string | null;
31
+ slug: string;
32
+ /** Page-template id, e.g. `page-crud`, `page-dashboard`. */
33
+ type: string;
34
+ title: string;
35
+ icon: string | null;
36
+ navGroup: string | null;
37
+ navOrder: number;
38
+ /** Opaque validated envelope (§3.17). */
39
+ config: unknown;
40
+ origin: string;
41
+ manifestId: string | null;
42
+ generatedFromSnapshotId: string | null;
43
+ revision: number;
44
+ isEnabled: boolean;
45
+ createdBy: string | null;
46
+ createdAt: number;
47
+ updatedAt: number;
48
+ }
49
+ /** The projection the bootstrap nav tree builds from (09 §2.2). */
50
+ export interface PageNavRow {
51
+ id: string;
52
+ /** Owning connection — lets the nav disambiguate multi-connection setups. */
53
+ connectionId: string | null;
54
+ slug: string;
55
+ title: string;
56
+ icon: string | null;
57
+ navGroup: string | null;
58
+ navOrder: number;
59
+ isEnabled: boolean | 0 | 1;
60
+ updatedAt: number;
61
+ }
62
+ /** One generated page as the server glue hands it over (engine-validated). */
63
+ export interface GeneratedPageInput {
64
+ /** Stable `page_<slug>` id from the generator. */
65
+ id: string;
66
+ slug: string;
67
+ /** Template id → the `type` column. */
68
+ type: string;
69
+ title: string;
70
+ icon?: string | null;
71
+ navGroup?: string | null;
72
+ navOrder?: number;
73
+ /** The full validated envelope document. */
74
+ config: unknown;
75
+ }
76
+ export interface UpsertGeneratedOptions {
77
+ snapshotId?: string | null;
78
+ createdBy?: string | null;
79
+ /** Delete generated rows the new set no longer contains. Default true. */
80
+ prune?: boolean;
81
+ at?: number;
82
+ /**
83
+ * The engine's `hashEnvelope` (canonical-JSON sha256, embedded-hash
84
+ * excluded), injected because `@adminium/meta` never imports the engine.
85
+ * When present, a changed generated-origin row is re-hashed first: a
86
+ * mismatch with its embedded `config.generatedHash` means a human edited the
87
+ * stored document, so the overwrite is skipped (user delta wins, 04 §6.3)
88
+ * and the id lands in `skippedEdited`. The prune pass applies the same
89
+ * test: an edited orphan is kept (`keptEdited`) instead of deleted.
90
+ * Omitted ⇒ the pre-M5 overwrite-and-full-prune behavior (unit tests,
91
+ * seeds).
92
+ */
93
+ hashEnvelope?: (envelope: Record<string, unknown>) => string;
94
+ }
95
+ export interface UpsertGeneratedResult {
96
+ created: number;
97
+ updated: number;
98
+ unchanged: number;
99
+ pruned: number;
100
+ /** Ids that exist with a non-generated origin — left untouched (user wins). */
101
+ preserved: string[];
102
+ /** Generated-origin ids whose stored document was human-edited — not overwritten. */
103
+ skippedEdited: string[];
104
+ /**
105
+ * Human-edited generated-origin ids the new set no longer contains — kept,
106
+ * not pruned (user delta wins extends to deletion, 04 §6.3). The row is
107
+ * untouched: it keeps `origin: 'generated'`, stays enabled, and keeps its
108
+ * snapshot lineage. Unedited orphans are byte-identically regenerable and
109
+ * still delete; without `hashEnvelope` this is always empty (legacy full
110
+ * prune).
111
+ */
112
+ keptEdited: string[];
113
+ }
114
+ export declare function pagesRepo(meta: MetaDb): {
115
+ /**
116
+ * Idempotent bulk upsert of one generation run for a connection.
117
+ * Insert new rows, update changed ones (revision + 1), skip unchanged,
118
+ * prune generated rows missing from the new set. Non-generated rows are
119
+ * reported in `preserved` and never modified.
120
+ */
121
+ upsertGenerated(connectionId: string, pages: readonly GeneratedPageInput[], opts?: UpsertGeneratedOptions): Promise<UpsertGeneratedResult>;
122
+ /** Create a non-generated page (user/manifest/system flows, seeds). */
123
+ create(input: {
124
+ connectionId?: string | null;
125
+ slug: string;
126
+ type: string;
127
+ title: string;
128
+ icon?: string | null;
129
+ navGroup?: string | null;
130
+ navOrder?: number;
131
+ config: unknown;
132
+ origin?: PageOrigin;
133
+ createdBy?: string | null;
134
+ }, at?: number): Promise<Page>;
135
+ findById(id: string): Promise<Page | null>;
136
+ /**
137
+ * Write the shared default dashboard layout into the envelope's
138
+ * `config.layout` slot (04-widget-registry.md §6.3; the renderer and engine
139
+ * envelope validator both read `envelope.config.layout`). Merges over the
140
+ * stored envelope so the rest of the document (title/source/nav and the
141
+ * other template config keys) is untouched, and bumps `updatedAt` so the
142
+ * bootstrap `configVersion` advances and clients re-fetch. `revision`
143
+ * bumps too — the counter tracks every changed document, human or machine
144
+ * (override-staleness and future H5 diff/telemetry read it) — while the
145
+ * embedded `config.generatedHash` deliberately stays stale: that mismatch
146
+ * IS the edited-page signal `upsertGenerated` keys on. The `layout` value
147
+ * is validated by the server route before it reaches here. Returns the
148
+ * reloaded page, or null if the id does not exist.
149
+ */
150
+ setLayout(pageId: string, layout: unknown, at?: number): Promise<Page | null>;
151
+ /**
152
+ * Replace a page's whole config document — the 06-llm-assist.md §8.3
153
+ * materialization write: the apply executor seeds `origin: 'llm'` rows with
154
+ * a minimal `{source, llmRunId}` config and the regeneration hook expands
155
+ * it into the full validated envelope from the active snapshot. Bumps
156
+ * `revision` + `updatedAt` (configVersion advances → clients re-fetch);
157
+ * `icon` is back-filled only when the row has none. `title`/`navGroup`,
158
+ * when provided, sync the row's nav projection from the envelope — the
159
+ * bootstrap tree reads the ROW columns, so without this an expanded llm
160
+ * page would stay outside the nav (and `/p/$slug` resolves from the nav
161
+ * tree, leaving the page unreachable). Returns the reloaded page, or null
162
+ * if the id does not exist.
163
+ */
164
+ replaceConfig(pageId: string, config: unknown, opts?: {
165
+ icon?: string | null;
166
+ title?: string;
167
+ navGroup?: string | null;
168
+ at?: number;
169
+ }): Promise<Page | null>;
170
+ /**
171
+ * Toggle a page's visibility (nav + GET both key on `isEnabled`). Bumps
172
+ * `updatedAt` only — the document itself is unchanged, so `revision`
173
+ * stays. Used by the §8.3 materialization pass to park an llm seed whose
174
+ * template cannot compose yet, instead of serving an invalid-config card.
175
+ */
176
+ setEnabled(pageId: string, isEnabled: boolean, at?: number): Promise<void>;
177
+ /** Slugs are unique per connection (uq_adminium_pages_conn_slug). */
178
+ findBySlug(connectionId: string | null, slug: string): Promise<Page | null>;
179
+ listForConnection(connectionId: string): Promise<Page[]>;
180
+ /**
181
+ * The bootstrap nav projection — every page row, nav fields only
182
+ * (09-generated-app.md §2.2; the route buckets these into the five fixed
183
+ * groups and derives `configVersion` from max updatedAt).
184
+ */
185
+ navRows(): Promise<PageNavRow[]>;
186
+ /** Generated-page counts per connection (connections-hub cards, 09 §8.1). */
187
+ countGeneratedByConnection(): Promise<Record<string, number>>;
188
+ /** Max updatedAt over all pages — the bootstrap `configVersion` stamp. */
189
+ configVersion(): Promise<number>;
190
+ };
191
+ export type PagesRepo = ReturnType<typeof pagesRepo>;
192
+ //# sourceMappingURL=pages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pages.d.ts","sourceRoot":"","sources":["../../src/repos/pages.ts"],"names":[],"mappings":"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"}