@kernhq/module-inventory 0.2.0 → 0.3.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.
Files changed (193) hide show
  1. package/README.md +104 -25
  2. package/dist/contract/capabilities.d.ts +4 -4
  3. package/dist/contract/capabilities.d.ts.map +1 -1
  4. package/dist/contract/capabilities.js +51 -9
  5. package/dist/contract/capabilities.js.map +1 -1
  6. package/dist/contract/events.d.ts +43 -0
  7. package/dist/contract/events.d.ts.map +1 -1
  8. package/dist/contract/events.js +40 -0
  9. package/dist/contract/events.js.map +1 -1
  10. package/dist/contract/index.d.ts +1 -0
  11. package/dist/contract/index.d.ts.map +1 -1
  12. package/dist/contract/index.js +1 -0
  13. package/dist/contract/index.js.map +1 -1
  14. package/dist/contract/models.d.ts +322 -0
  15. package/dist/contract/models.d.ts.map +1 -1
  16. package/dist/contract/models.js +213 -0
  17. package/dist/contract/models.js.map +1 -1
  18. package/dist/contract/notifications.d.ts +24 -0
  19. package/dist/contract/notifications.d.ts.map +1 -0
  20. package/dist/contract/notifications.js +72 -0
  21. package/dist/contract/notifications.js.map +1 -0
  22. package/dist/contract/permissions.d.ts +52 -2
  23. package/dist/contract/permissions.d.ts.map +1 -1
  24. package/dist/contract/permissions.js +55 -2
  25. package/dist/contract/permissions.js.map +1 -1
  26. package/dist/contract/router.d.ts +1052 -0
  27. package/dist/contract/router.d.ts.map +1 -1
  28. package/dist/contract/router.js +225 -1
  29. package/dist/contract/router.js.map +1 -1
  30. package/dist/contract/settings.d.ts +2 -0
  31. package/dist/contract/settings.d.ts.map +1 -1
  32. package/dist/contract/settings.js +24 -4
  33. package/dist/contract/settings.js.map +1 -1
  34. package/dist/server/index.d.ts +8 -4
  35. package/dist/server/index.d.ts.map +1 -1
  36. package/dist/server/index.js +289 -5
  37. package/dist/server/index.js.map +1 -1
  38. package/dist/server/jobs.d.ts +48 -0
  39. package/dist/server/jobs.d.ts.map +1 -0
  40. package/dist/server/jobs.js +358 -0
  41. package/dist/server/jobs.js.map +1 -0
  42. package/dist/server/router.d.ts +1337 -0
  43. package/dist/server/router.d.ts.map +1 -1
  44. package/dist/server/router.js +363 -7
  45. package/dist/server/router.js.map +1 -1
  46. package/dist/server/schema.d.ts +134 -1
  47. package/dist/server/schema.d.ts.map +1 -1
  48. package/dist/server/schema.js +158 -4
  49. package/dist/server/schema.js.map +1 -1
  50. package/dist/server/services/assets.d.ts +69 -3
  51. package/dist/server/services/assets.d.ts.map +1 -1
  52. package/dist/server/services/assets.js +199 -31
  53. package/dist/server/services/assets.js.map +1 -1
  54. package/dist/server/services/attachments.d.ts +80 -0
  55. package/dist/server/services/attachments.d.ts.map +1 -0
  56. package/dist/server/services/attachments.js +182 -0
  57. package/dist/server/services/attachments.js.map +1 -0
  58. package/dist/server/services/audience.d.ts +15 -0
  59. package/dist/server/services/audience.d.ts.map +1 -0
  60. package/dist/server/services/audience.js +64 -0
  61. package/dist/server/services/audience.js.map +1 -0
  62. package/dist/server/services/categories.d.ts +57 -0
  63. package/dist/server/services/categories.d.ts.map +1 -0
  64. package/dist/server/services/categories.js +124 -0
  65. package/dist/server/services/categories.js.map +1 -0
  66. package/dist/server/services/cursor.d.ts +68 -0
  67. package/dist/server/services/cursor.d.ts.map +1 -0
  68. package/dist/server/services/cursor.js +39 -0
  69. package/dist/server/services/cursor.js.map +1 -0
  70. package/dist/server/services/custody.d.ts +175 -0
  71. package/dist/server/services/custody.d.ts.map +1 -0
  72. package/dist/server/services/custody.js +367 -0
  73. package/dist/server/services/custody.js.map +1 -0
  74. package/dist/server/services/db-errors.d.ts +7 -0
  75. package/dist/server/services/db-errors.d.ts.map +1 -0
  76. package/dist/server/services/db-errors.js +32 -0
  77. package/dist/server/services/db-errors.js.map +1 -0
  78. package/dist/server/services/index.d.ts +16 -0
  79. package/dist/server/services/index.d.ts.map +1 -1
  80. package/dist/server/services/index.js +25 -1
  81. package/dist/server/services/index.js.map +1 -1
  82. package/dist/server/services/members.d.ts +27 -0
  83. package/dist/server/services/members.d.ts.map +1 -0
  84. package/dist/server/services/members.js +39 -0
  85. package/dist/server/services/members.js.map +1 -0
  86. package/dist/server/services/notify.d.ts +43 -1
  87. package/dist/server/services/notify.d.ts.map +1 -1
  88. package/dist/server/services/notify.js +47 -5
  89. package/dist/server/services/notify.js.map +1 -1
  90. package/dist/server/services/offboarding.d.ts +70 -0
  91. package/dist/server/services/offboarding.d.ts.map +1 -0
  92. package/dist/server/services/offboarding.js +116 -0
  93. package/dist/server/services/offboarding.js.map +1 -0
  94. package/dist/server/services/repairs.d.ts +204 -0
  95. package/dist/server/services/repairs.d.ts.map +1 -0
  96. package/dist/server/services/repairs.js +476 -0
  97. package/dist/server/services/repairs.js.map +1 -0
  98. package/dist/server/services/search.d.ts +85 -0
  99. package/dist/server/services/search.d.ts.map +1 -0
  100. package/dist/server/services/search.js +142 -0
  101. package/dist/server/services/search.js.map +1 -0
  102. package/dist/server/services/stats.d.ts +42 -0
  103. package/dist/server/services/stats.d.ts.map +1 -0
  104. package/dist/server/services/stats.js +80 -0
  105. package/dist/server/services/stats.js.map +1 -0
  106. package/dist/server/services/status.d.ts +102 -0
  107. package/dist/server/services/status.d.ts.map +1 -0
  108. package/dist/server/services/status.js +71 -0
  109. package/dist/server/services/status.js.map +1 -0
  110. package/migrations/0002_custody_and_categories.sql +23 -0
  111. package/migrations/0003_repairs.sql +23 -0
  112. package/migrations/0004_platform_surfaces.sql +51 -0
  113. package/migrations/0005_repair_dates.sql +35 -0
  114. package/migrations/0006_workspace_registry_read.sql +50 -0
  115. package/migrations/0007_history_sequence.sql +83 -0
  116. package/migrations/meta/0002_snapshot.json +1054 -0
  117. package/migrations/meta/0003_snapshot.json +1070 -0
  118. package/migrations/meta/0004_snapshot.json +1130 -0
  119. package/migrations/meta/0005_snapshot.json +1135 -0
  120. package/migrations/meta/_journal.json +42 -0
  121. package/package.json +1 -1
  122. package/src/client/api-instance.ts +27 -2
  123. package/src/client/bidi.test.ts +148 -0
  124. package/src/client/bidi.ts +85 -0
  125. package/src/client/components/AssetDetailPanel.svelte +614 -0
  126. package/src/client/components/AssetFormDialog.svelte +71 -22
  127. package/src/client/components/AssetPhoto.svelte +178 -0
  128. package/src/client/components/AttachmentsSection.svelte +327 -0
  129. package/src/client/components/CustodyDialog.svelte +201 -0
  130. package/src/client/components/RepairDialog.svelte +271 -0
  131. package/src/client/components/RepairsSection.svelte +318 -0
  132. package/src/client/components/Timeline.svelte +347 -0
  133. package/src/client/components/TimelineText.svelte +124 -0
  134. package/src/client/core-api.ts +71 -0
  135. package/src/client/custody.test.ts +31 -0
  136. package/src/client/custody.ts +34 -0
  137. package/src/client/errors.test.ts +365 -0
  138. package/src/client/errors.ts +201 -0
  139. package/src/client/links.test.ts +74 -0
  140. package/src/client/links.ts +44 -0
  141. package/src/client/members.test.ts +132 -0
  142. package/src/client/members.ts +116 -0
  143. package/src/client/messages.test.ts +127 -0
  144. package/src/client/messages.ts +1043 -18
  145. package/src/client/mock.test.ts +395 -1
  146. package/src/client/mock.ts +1066 -79
  147. package/src/client/module.ts +54 -0
  148. package/src/client/pages/AssetsPage.svelte +317 -45
  149. package/src/client/permissions.ts +7 -0
  150. package/src/client/price.test.ts +151 -3
  151. package/src/client/price.ts +155 -11
  152. package/src/client/query.ts +36 -0
  153. package/src/client/repairs.test.ts +38 -0
  154. package/src/client/repairs.ts +38 -0
  155. package/src/client/settings/CategoriesSettings.svelte +421 -0
  156. package/src/client/settings/GeneralSettings.svelte +0 -0
  157. package/src/client/status.ts +29 -0
  158. package/src/client/timeline.test.ts +175 -0
  159. package/src/client/timeline.ts +206 -0
  160. package/src/client/widgets/OverviewWidget.svelte +127 -26
  161. package/src/client/widgets/RepairsWidget.svelte +124 -0
  162. package/src/contract/capabilities.ts +53 -9
  163. package/src/contract/events.ts +49 -0
  164. package/src/contract/index.ts +1 -0
  165. package/src/contract/models.ts +237 -0
  166. package/src/contract/notifications.ts +73 -0
  167. package/src/contract/permissions.ts +55 -2
  168. package/src/contract/router.ts +255 -1
  169. package/src/contract/settings.ts +24 -4
  170. package/src/module.test.ts +194 -4
  171. package/src/server/index.ts +311 -4
  172. package/src/server/inventory.int.test.ts +3573 -18
  173. package/src/server/jobs.ts +444 -0
  174. package/src/server/migrations.test.ts +113 -0
  175. package/src/server/router.ts +462 -6
  176. package/src/server/schema.ts +160 -3
  177. package/src/server/services/assets.ts +214 -54
  178. package/src/server/services/attachments.ts +215 -0
  179. package/src/server/services/audience.ts +77 -0
  180. package/src/server/services/categories.ts +136 -0
  181. package/src/server/services/cursor.ts +104 -0
  182. package/src/server/services/custody.ts +471 -0
  183. package/src/server/services/db-errors.ts +42 -0
  184. package/src/server/services/index.ts +34 -1
  185. package/src/server/services/members.ts +54 -0
  186. package/src/server/services/notify.ts +52 -7
  187. package/src/server/services/offboarding.ts +150 -0
  188. package/src/server/services/repairs.ts +567 -0
  189. package/src/server/services/search.ts +166 -0
  190. package/src/server/services/stats.ts +88 -0
  191. package/src/server/services/status.test.ts +34 -0
  192. package/src/server/services/status.ts +143 -0
  193. package/src/client/settings/core-api.ts +0 -32
@@ -9,6 +9,71 @@
9
9
  * somebody will eventually write a query that skips it.
10
10
  */
11
11
  export declare const schema: import("drizzle-orm/pg-core").PgSchema<string>;
12
+ /**
13
+ * Workspaces this module is switched on in, so scheduled work can find them.
14
+ *
15
+ * A cron handler starts with no workspace: it is woken by a clock, not by a request, so there is
16
+ * nothing to derive a tenant from and no `withWorkspace` it could already be inside. Core knows the
17
+ * answer and would give it (`core.workspaces.list`), but asking it every tick makes the sweeps fail
18
+ * whenever core is briefly away — for a job whose whole point is to run unattended overnight. So the
19
+ * module keeps the one fact it needs: an id, written when the module is switched on for a workspace
20
+ * and when a workspace is created. `module-tracker` keeps the same table for the same reason.
21
+ *
22
+ * **It carries `workspace_id`, so it is a tenant table and has a policy like every other** — and the
23
+ * one reader that cannot honour that policy is the enumeration itself, because `app.workspace_id` is
24
+ * unset in a job by definition. That was left resting on "the connection is the schema's owner, and
25
+ * an owner bypasses RLS", which is **false here**: every table in this schema carries `force row
26
+ * level security`, and forcing it subjects the owner to the policies too. So `select workspace_id
27
+ * from workspaces` with no workspace bound answered zero rows — not an error, not a warning, simply
28
+ * nothing to sweep, every night, for ever.
29
+ *
30
+ * `0006_workspace_registry_read.sql` is the fix and it is scoped as narrowly as the problem: one
31
+ * extra `for select` policy, on this table only, admitting a session that has **no** workspace bound.
32
+ * A request-bound session still sees exactly its own row, and this table holds nothing but workspace
33
+ * ids anyway — it is the module's own bookkeeping, not tenant data anybody reads. Added in `0004`,
34
+ * because 0.2.0 is published.
35
+ */
36
+ export declare const workspaces: import("drizzle-orm/pg-core").PgTableWithColumns<{
37
+ name: "workspaces";
38
+ schema: string;
39
+ columns: {
40
+ workspaceId: import("drizzle-orm/pg-core").PgColumn<{
41
+ name: "workspace_id";
42
+ tableName: "workspaces";
43
+ dataType: "string";
44
+ columnType: "PgUUID";
45
+ data: string;
46
+ driverParam: string;
47
+ notNull: true;
48
+ hasDefault: false;
49
+ isPrimaryKey: true;
50
+ isAutoincrement: false;
51
+ hasRuntimeDefault: false;
52
+ enumValues: undefined;
53
+ baseColumn: never;
54
+ identity: undefined;
55
+ generated: undefined;
56
+ }, {}, {}>;
57
+ createdAt: import("drizzle-orm/pg-core").PgColumn<{
58
+ name: string;
59
+ tableName: "workspaces";
60
+ dataType: "date";
61
+ columnType: "PgTimestamp";
62
+ data: Date;
63
+ driverParam: string;
64
+ notNull: true;
65
+ hasDefault: true;
66
+ isPrimaryKey: false;
67
+ isAutoincrement: false;
68
+ hasRuntimeDefault: false;
69
+ enumValues: undefined;
70
+ baseColumn: never;
71
+ identity: undefined;
72
+ generated: undefined;
73
+ }, {}, {}>;
74
+ };
75
+ dialect: "pg";
76
+ }>;
12
77
  export declare const counters: import("drizzle-orm/pg-core").PgTableWithColumns<{
13
78
  name: "counters";
14
79
  schema: string;
@@ -139,6 +204,23 @@ export declare const categories: import("drizzle-orm/pg-core").PgTableWithColumn
139
204
  identity: undefined;
140
205
  generated: undefined;
141
206
  }, {}, {}>;
207
+ archivedAt: import("drizzle-orm/pg-core").PgColumn<{
208
+ name: string;
209
+ tableName: "categories";
210
+ dataType: "date";
211
+ columnType: "PgTimestamp";
212
+ data: Date;
213
+ driverParam: string;
214
+ notNull: false;
215
+ hasDefault: false;
216
+ isPrimaryKey: false;
217
+ isAutoincrement: false;
218
+ hasRuntimeDefault: false;
219
+ enumValues: undefined;
220
+ baseColumn: never;
221
+ identity: undefined;
222
+ generated: undefined;
223
+ }, {}, {}>;
142
224
  createdAt: import("drizzle-orm/pg-core").PgColumn<{
143
225
  name: string;
144
226
  tableName: "categories";
@@ -454,6 +536,23 @@ export declare const assets: import("drizzle-orm/pg-core").PgTableWithColumns<{
454
536
  identity: undefined;
455
537
  generated: undefined;
456
538
  }, {}, {}>;
539
+ warrantyNotifiedAt: import("drizzle-orm/pg-core").PgColumn<{
540
+ name: string;
541
+ tableName: "assets";
542
+ dataType: "date";
543
+ columnType: "PgTimestamp";
544
+ data: Date;
545
+ driverParam: string;
546
+ notNull: false;
547
+ hasDefault: false;
548
+ isPrimaryKey: false;
549
+ isAutoincrement: false;
550
+ hasRuntimeDefault: false;
551
+ enumValues: undefined;
552
+ baseColumn: never;
553
+ identity: undefined;
554
+ generated: undefined;
555
+ }, {}, {}>;
457
556
  photoFileId: import("drizzle-orm/pg-core").PgColumn<{
458
557
  name: "photo_file_id";
459
558
  tableName: "assets";
@@ -1150,6 +1249,23 @@ export declare const assetHistory: import("drizzle-orm/pg-core").PgTableWithColu
1150
1249
  identity: undefined;
1151
1250
  generated: undefined;
1152
1251
  }, {}, {}>;
1252
+ seq: import("drizzle-orm/pg-core").PgColumn<{
1253
+ name: "seq";
1254
+ tableName: "asset_history";
1255
+ dataType: "number";
1256
+ columnType: "PgBigInt53";
1257
+ data: number;
1258
+ driverParam: string | number;
1259
+ notNull: true;
1260
+ hasDefault: true;
1261
+ isPrimaryKey: false;
1262
+ isAutoincrement: false;
1263
+ hasRuntimeDefault: false;
1264
+ enumValues: undefined;
1265
+ baseColumn: never;
1266
+ identity: undefined;
1267
+ generated: undefined;
1268
+ }, {}, {}>;
1153
1269
  };
1154
1270
  dialect: "pg";
1155
1271
  }>;
@@ -1329,6 +1445,23 @@ export declare const repairs: import("drizzle-orm/pg-core").PgTableWithColumns<{
1329
1445
  identity: undefined;
1330
1446
  generated: undefined;
1331
1447
  }, {}, {}>;
1448
+ overdueNotifiedAt: import("drizzle-orm/pg-core").PgColumn<{
1449
+ name: string;
1450
+ tableName: "repairs";
1451
+ dataType: "date";
1452
+ columnType: "PgTimestamp";
1453
+ data: Date;
1454
+ driverParam: string;
1455
+ notNull: false;
1456
+ hasDefault: false;
1457
+ isPrimaryKey: false;
1458
+ isAutoincrement: false;
1459
+ hasRuntimeDefault: false;
1460
+ enumValues: undefined;
1461
+ baseColumn: never;
1462
+ identity: undefined;
1463
+ generated: undefined;
1464
+ }, {}, {}>;
1332
1465
  createdBy: import("drizzle-orm/pg-core").PgColumn<{
1333
1466
  name: "created_by";
1334
1467
  tableName: "repairs";
@@ -1562,5 +1695,5 @@ export declare const attachments: import("drizzle-orm/pg-core").PgTableWithColum
1562
1695
  dialect: "pg";
1563
1696
  }>;
1564
1697
  /** Every tenant table, so the RLS migration can be checked against one list rather than memory. */
1565
- export declare const TENANT_TABLES: readonly ["counters", "categories", "assets", "field_defs", "custody_periods", "asset_history", "repairs", "attachments"];
1698
+ export declare const TENANT_TABLES: readonly ["counters", "workspaces", "categories", "assets", "field_defs", "custody_periods", "asset_history", "repairs", "attachments"];
1566
1699
  //# sourceMappingURL=schema.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/server/schema.ts"],"names":[],"mappings":"AAgBA;;;;;;;;;GASG;AACH,eAAO,MAAM,MAAM,gDAA4B,CAAA;AAS/C,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAiBpB,CAAA;AAED,eAAO,MAAM,UAAU;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EActB,CAAA;AAED,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4ClB,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAwBrB,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAc1B,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;uBAQoB,MAAM;sBAAQ,OAAO;oBAAM,OAAO;;;;;;;;;;;;;;uBAAlC,MAAM;sBAAQ,OAAO;oBAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAK9E,CAAA;AAED,eAAO,MAAM,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAmBnB,CAAA;AAED,mGAAmG;AACnG,eAAO,MAAM,WAAW;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAkBvB,CAAA;AAED,mGAAmG;AACnG,eAAO,MAAM,aAAa,2HAahB,CAAA"}
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/server/schema.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { moduleSchema } from '@kernhq/kernel';
2
2
  import { sql } from 'drizzle-orm';
3
- import { boolean, char, date, index, integer, jsonb, primaryKey, text, timestamp, uniqueIndex, uuid, } from 'drizzle-orm/pg-core';
3
+ import { bigint, boolean, char, check, date, index, integer, jsonb, primaryKey, text, timestamp, uniqueIndex, uuid, } from 'drizzle-orm/pg-core';
4
4
  /**
5
5
  * This module's tables, in its own Postgres schema.
6
6
  *
@@ -18,6 +18,34 @@ const ws = () => uuid('workspace_id').notNull();
18
18
  const ts = (name) => timestamp(name, { withTimezone: true, mode: 'date' });
19
19
  const created = () => ts('created_at').notNull().defaultNow();
20
20
  const updated = () => ts('updated_at').notNull().defaultNow();
21
+ /**
22
+ * Workspaces this module is switched on in, so scheduled work can find them.
23
+ *
24
+ * A cron handler starts with no workspace: it is woken by a clock, not by a request, so there is
25
+ * nothing to derive a tenant from and no `withWorkspace` it could already be inside. Core knows the
26
+ * answer and would give it (`core.workspaces.list`), but asking it every tick makes the sweeps fail
27
+ * whenever core is briefly away — for a job whose whole point is to run unattended overnight. So the
28
+ * module keeps the one fact it needs: an id, written when the module is switched on for a workspace
29
+ * and when a workspace is created. `module-tracker` keeps the same table for the same reason.
30
+ *
31
+ * **It carries `workspace_id`, so it is a tenant table and has a policy like every other** — and the
32
+ * one reader that cannot honour that policy is the enumeration itself, because `app.workspace_id` is
33
+ * unset in a job by definition. That was left resting on "the connection is the schema's owner, and
34
+ * an owner bypasses RLS", which is **false here**: every table in this schema carries `force row
35
+ * level security`, and forcing it subjects the owner to the policies too. So `select workspace_id
36
+ * from workspaces` with no workspace bound answered zero rows — not an error, not a warning, simply
37
+ * nothing to sweep, every night, for ever.
38
+ *
39
+ * `0006_workspace_registry_read.sql` is the fix and it is scoped as narrowly as the problem: one
40
+ * extra `for select` policy, on this table only, admitting a session that has **no** workspace bound.
41
+ * A request-bound session still sees exactly its own row, and this table holds nothing but workspace
42
+ * ids anyway — it is the module's own bookkeeping, not tenant data anybody reads. Added in `0004`,
43
+ * because 0.2.0 is published.
44
+ */
45
+ export const workspaces = schema.table('workspaces', {
46
+ workspaceId: uuid('workspace_id').primaryKey(),
47
+ createdAt: created(),
48
+ });
21
49
  export const counters = schema.table('counters',
22
50
  /** Per-workspace sequence sources (`asset_code`). Narrow on purpose: one row per key. */
23
51
  {
@@ -39,9 +67,24 @@ export const categories = schema.table('categories', {
39
67
  workspaceId: ws(),
40
68
  name: text('name').notNull(),
41
69
  order: integer('order').notNull().default(0),
70
+ /**
71
+ * Archived rather than deleted, and the reason is `assets.category_id`.
72
+ *
73
+ * There is no foreign key — a module keeps its joins inside its own schema and its ids plain —
74
+ * so deleting a row here would leave every asset filed under it pointing at nothing. The
75
+ * category column on the row would go blank and the timeline entry that says "category changed
76
+ * to Laptops" would lose the word "Laptops": data destroyed by a settings screen, silently, and
77
+ * with no way back. Archiving takes the category out of every picker and every filter and
78
+ * leaves each asset able to say what it is.
79
+ *
80
+ * Added in `0002`, because 0.2.0 is published.
81
+ */
82
+ archivedAt: ts('archived_at'),
42
83
  createdAt: created(),
43
84
  updatedAt: updated(),
44
85
  }, (t) => [
86
+ // Unique across archived rows too: two categories called "Laptops", one of them archived, is
87
+ // two rows a picker cannot tell apart the moment somebody restores the second.
45
88
  uniqueIndex('inventory_categories_ws_name_uq').on(t.workspaceId, t.name),
46
89
  index('inventory_categories_ws_idx').on(t.workspaceId, t.order),
47
90
  ]);
@@ -66,6 +109,18 @@ export const assets = schema.table('assets', {
66
109
  priceMinor: integer('price_minor'),
67
110
  currency: char('currency', { length: 3 }),
68
111
  warrantyUntil: date('warranty_until'),
112
+ /**
113
+ * When the warranty sweep last told somebody this one is about to run out.
114
+ *
115
+ * The idempotency row `kern-service` asks scheduled work for, as a column. A warranty falls
116
+ * inside the notice window for every one of the thirty days before it expires, so a sweep with
117
+ * no marker sends the same notice thirty times — and `groupKey` collapses that in the
118
+ * notification centre while still sending thirty emails. Cleared by `assets.update` whenever
119
+ * `warranty_until` itself moves, so extending a warranty earns a fresh notice at the new date.
120
+ *
121
+ * Nullable and added in `0004`, so the 0.2.0 image reads the table straight past it.
122
+ */
123
+ warrantyNotifiedAt: ts('warranty_notified_at'),
69
124
  photoFileId: uuid('photo_file_id'),
70
125
  /** Values for this workspace's own `field_defs`, keyed by their `key`. */
71
126
  custom: jsonb('custom').$type().notNull().default({}),
@@ -138,11 +193,51 @@ export const assetHistory = schema.table('asset_history', {
138
193
  workspaceId: ws(),
139
194
  assetId: uuid('asset_id').notNull(),
140
195
  actorId: uuid('actor_id'),
141
- action: text('action').notNull(), // created | updated | transferred | returned | repair_logged | repair_completed | attachment_added | retired | restored
196
+ action: text('action').notNull(), // created | updated | assigned | transferred | returned | repair_logged | repair_completed | attachment_added | retired | restored
142
197
  changes: jsonb('changes').$type(),
143
198
  data: jsonb('data'),
144
199
  occurredAt: created(),
145
- }, (t) => [index('inventory_asset_history_asset_idx').on(t.workspaceId, t.assetId, t.occurredAt)]);
200
+ /**
201
+ * The order these entries actually happened in — a sequence, not a clock and not the id.
202
+ *
203
+ * **A uuidv7 is only ordered to the millisecond.** The kernel's `uuidv7()` puts the clock in
204
+ * bytes 0-5 and fills bytes 6-15 from `randomUUID()` with no intra-millisecond counter, so two
205
+ * entries written in the same millisecond sort by ten random bytes. That is *stable* for a
206
+ * given set of rows, which is why keyset paging never dropped or repeated one and why the
207
+ * defect hid for so long — what it produced instead was a timeline rendering "Bruno removed the
208
+ * file" above "Bruno added the file". A register's whole value is that it says what happened in
209
+ * the order it happened.
210
+ *
211
+ * `occurred_at` cannot stand in for it either: it defaults to `now()`, which is the
212
+ * *transaction* timestamp, so a create and its first history row share it exactly.
213
+ *
214
+ * A sequence is exact rather than probabilistic — `nextval` is strictly increasing whatever the
215
+ * clock does — and it is the one ordering key a module owns outright. Filled by the column
216
+ * default, so nothing in the service has to remember it and the previous image's inserts get
217
+ * one too. Added in `0007`.
218
+ */
219
+ seq: bigint('seq', { mode: 'number' }).notNull().default(sql `nextval('mod_inventory.asset_history_seq')`),
220
+ }, (t) => [
221
+ index('inventory_asset_history_asset_idx').on(t.workspaceId, t.assetId, t.occurredAt),
222
+ /**
223
+ * Superseded by the index below, and left here on purpose.
224
+ *
225
+ * The timeline used to be keyset-paged by **id**, on the reasoning `assets.list` still gives for
226
+ * `sort: 'recent'` — an id is uuidv7, so it carries the clock, and it is unique where
227
+ * `occurred_at` is not. Unique it is; ordered it is only to the millisecond. `seq` replaced it.
228
+ *
229
+ * Dropping this is a schema change and a migration here only adds, so it goes one release from
230
+ * now rather than in the one that stopped reading it. Added in `0002`.
231
+ */
232
+ index('inventory_asset_history_ws_asset_row_idx').on(t.workspaceId, t.assetId, t.id),
233
+ /**
234
+ * What `assets.history` pages on: one asset's entries, newest first, bounded by `seq`.
235
+ *
236
+ * Unique, because the sequence makes it so and saying so lets Postgres stop at the first match
237
+ * for a cursor. Added in `0007`.
238
+ */
239
+ uniqueIndex('inventory_asset_history_ws_asset_seq_uq').on(t.workspaceId, t.assetId, t.seq),
240
+ ]);
146
241
  export const repairs = schema.table('repairs', {
147
242
  id: id(),
148
243
  workspaceId: ws(),
@@ -155,10 +250,65 @@ export const repairs = schema.table('repairs', {
155
250
  sentOn: date('sent_on').notNull(),
156
251
  /** Null while the item is still away — also how `under_repair` is derived. */
157
252
  returnedOn: date('returned_on'),
253
+ /**
254
+ * When the overdue sweep last said this one has been away too long.
255
+ *
256
+ * Same job as `assets.warranty_notified_at` and for the same reason: a repair that passed the
257
+ * threshold yesterday has passed it again today, so a sweep with no marker chases the same
258
+ * vendor every morning until the item comes back. Cleared by `repairs.update` when `sent_on`
259
+ * moves, because that is the date the threshold is measured from.
260
+ *
261
+ * Nullable and added in `0004`, so the 0.2.0 image reads the table straight past it.
262
+ */
263
+ overdueNotifiedAt: ts('overdue_notified_at'),
158
264
  createdBy: uuid('created_by'),
159
265
  createdAt: created(),
160
266
  updatedAt: updated(),
161
- }, (t) => [index('inventory_repairs_ws_asset_idx').on(t.workspaceId, t.assetId, t.sentOn)]);
267
+ }, (t) => [
268
+ index('inventory_repairs_ws_asset_idx').on(t.workspaceId, t.assetId, t.sentOn),
269
+ /**
270
+ * What the overdue sweep reads: one workspace's still-open repairs, oldest first.
271
+ *
272
+ * The index above starts (workspace_id, asset_id, sent_on) and cannot answer "every open repair
273
+ * in this workspace sent before a date" without visiting every asset; `inventory_repairs_one_
274
+ * open_uq` is partial on the right predicate but keyed by `asset_id`, so it cannot be scoped to
275
+ * a workspace either. Added in `0004`.
276
+ */
277
+ index('inventory_repairs_ws_open_idx').on(t.workspaceId, t.sentOn).where(sql `returned_on is null`),
278
+ /**
279
+ * One open repair per asset, decided by the database rather than by the service.
280
+ *
281
+ * Custody leans on a GiST exclusion constraint for the same reason and this is the cheaper
282
+ * version of it: a repair has no range to overlap, only a flag, so a partial unique index says
283
+ * exactly the same thing. Two people pressing *Send for repair* on the same laptop in the same
284
+ * instant both read "it is here", both insert, and Postgres refuses one of them — where a
285
+ * `select … for update` would serialise them into two open repairs, which is a worse answer
286
+ * wearing the clothes of a safer one. `RepairService` turns the 23505 into a sentence.
287
+ *
288
+ * Not scoped by `workspace_id`: an asset id belongs to exactly one workspace, and adding the
289
+ * column would let the same asset be open in two of them if an id ever leaked across.
290
+ *
291
+ * Added in `0003`, because 0.2.0 is published.
292
+ */
293
+ uniqueIndex('inventory_repairs_one_open_uq').on(t.assetId).where(sql `returned_on is null`),
294
+ /**
295
+ * A repair cannot come back before it was sent.
296
+ *
297
+ * Two dates a person types, and nothing but arithmetic decides whether the pair means anything:
298
+ * stored the wrong way round, every "how long was it away" answer is negative and the overdue
299
+ * sweep measures from a date in the future. `repairs.complete` refused it from the start;
300
+ * `repairs.update` did not, and could move `sent_on` past the `returned_on` of a repair that had
301
+ * already come back. The service checks first so a person gets a sentence, and this is what
302
+ * makes the rule true of the table rather than of the code paths somebody remembered.
303
+ *
304
+ * Added in `0005` as `not valid`: the constraint is enforced on every insert and update from
305
+ * that moment, and existing rows are not scanned. That is deliberate — a module's migrations
306
+ * are the first thing the kernel runs, so a validating constraint that met one bad row left
307
+ * over from this defect would not degrade repairs, it would stop the whole host service
308
+ * booting. `RepairService` translates the resulting 23514 into a sentence.
309
+ */
310
+ check('inventory_repairs_returned_after_sent', sql `returned_on is null or returned_on >= sent_on`),
311
+ ]);
162
312
  /** Bytes live in core object storage via `uploadFile`; this only records that an asset has one. */
163
313
  export const attachments = schema.table('attachments', {
164
314
  id: id(),
@@ -182,6 +332,10 @@ export const TENANT_TABLES = [
182
332
  // and therefore out of `0001_rls.sql` — because it holds no asset data, which is not the rule
183
333
  // the file states at the top. Tracker's structurally identical `issue_counters` is covered.
184
334
  'counters',
335
+ // Holds nothing but tenant ids, and is still a tenant table: the rule this list encodes is "has a
336
+ // `workspace_id` column", not "holds asset data". `module-tracker`'s equivalent is deliberately
337
+ // unpolicied and that is the one shape of exception this module does not make.
338
+ 'workspaces',
185
339
  'categories',
186
340
  'assets',
187
341
  'field_defs',
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/server/schema.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/server/schema.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { type Kernel, type Tx } from '@kernhq/kernel';
2
- import type { AssetCreateInput, Asset as AssetModel, AssetPatchInput, AssetSort } from '../../contract/models.js';
3
- import { assets } from '../schema.js';
2
+ import type { AssetCreateInput, AssetHistoryEntry, Asset as AssetModel, AssetPatchInput, AssetSort } from '../../contract/models.js';
3
+ import { assetHistory, assets } from '../schema.js';
4
4
  import type { HistoryInput, NotifyService } from './notify.js';
5
5
  type Row = typeof assets.$inferSelect;
6
6
  /**
@@ -24,6 +24,12 @@ export interface CodeFormat {
24
24
  }
25
25
  /** The wire shape: drizzle gives Date objects for timestamps, the contract promises ISO strings. */
26
26
  export declare function toAsset(row: Row): AssetModel;
27
+ /**
28
+ * The wire shape of one timeline entry. Drizzle's `jsonb` columns are nullable in the row and never
29
+ * null in the contract — `changes: []` and `data: {}` are what "nothing to say" looks like to a
30
+ * screen, where `null` is one more thing every caller has to remember to handle.
31
+ */
32
+ export declare function toHistoryEntry(row: typeof assetHistory.$inferSelect): AssetHistoryEntry;
27
33
  export interface ListInput {
28
34
  workspaceId: string;
29
35
  limit: number;
@@ -62,12 +68,72 @@ export declare class AssetService {
62
68
  items: AssetModel[];
63
69
  nextCursor: string | null;
64
70
  }>;
71
+ /**
72
+ * The asset's own timeline, newest first, paged on the sequence the entries carry.
73
+ *
74
+ * **The ordering is `seq`, not `occurred_at` and not the id**, and the middle one of those three
75
+ * is the interesting correction.
76
+ *
77
+ * `occurred_at` was never a candidate: it defaults to `now()`, which is the *transaction*
78
+ * timestamp, so `create` writes the asset and its `created` entry with the same value and a page
79
+ * boundary between two entries that share a sort key repeats one and drops the other.
80
+ *
81
+ * The id looked like the answer and was only half of one. A uuidv7 is unique, so paging on it is
82
+ * gapless — but the kernel's `uuidv7()` carries the clock only to the millisecond and fills the
83
+ * rest from `randomUUID()` with no counter, so two entries written inside one millisecond sort by
84
+ * ten random bytes. Stable, so nothing was ever dropped or repeated; and arbitrary, so a timeline
85
+ * could show "Bruno removed the file" above "Bruno added the file". `seq` is a sequence: strictly
86
+ * increasing whatever the clock does, at whatever rate. `schema.ts` argues it at the column.
87
+ *
88
+ * The comparison is a single column because the sort key *is* the bookmark, so there is no
89
+ * bookmarked-row subquery here. The bookmark is still checked as a bounded positive integer and
90
+ * still bound to the sort it was issued under, because that is the codec's job and not this
91
+ * query's.
92
+ */
93
+ history(tx: Tx, workspaceId: string, assetId: string, input: {
94
+ limit: number;
95
+ cursor?: string;
96
+ }): Promise<{
97
+ items: AssetHistoryEntry[];
98
+ nextCursor: string | null;
99
+ }>;
100
+ /**
101
+ * A category id in a request is a claim about a row in this workspace, and it is checked before
102
+ * it is stored.
103
+ *
104
+ * The same defect `photoFileId` had, one field over: `assets.create` and `assets.update` took
105
+ * `categoryId` on trust, so any uuid at all went into the column. Two things follow from that,
106
+ * and neither is theoretical. An id belonging to **another workspace** files an asset under a
107
+ * category this one cannot see, name or unfile — the picker resolves names from its own
108
+ * `categories.list`, so the field renders blank and the filter it sits behind matches nothing
109
+ * anybody can select. An id belonging to **nobody** does the same thing with no other workspace
110
+ * involved. Either way the register holds a reference to a row that is not there, which is
111
+ * exactly the state `categories.archive` exists to prevent from the other end.
112
+ *
113
+ * **Checked inside the caller's transaction, unlike `checkPhoto`.** A file lives in core and has
114
+ * to be asked for over the broker, so that check happens before a connection is taken — the rule
115
+ * `codeFormat` documents. A category is this module's own table one join away, so the honest
116
+ * place for it is the transaction that writes the row: it costs one indexed read, and it cannot
117
+ * be raced by somebody deleting the category, because nothing deletes one.
118
+ *
119
+ * An **archived** category is deliberately allowed. Archiving takes it out of every picker and
120
+ * leaves every asset already filed under it still naming it; refusing it here would mean an edit
121
+ * to an asset's location failed because of a category somebody tidied away last year, and it
122
+ * would make re-filing a batch of assets under an old category impossible for no gain.
123
+ */
124
+ private requireCategory;
65
125
  get(tx: Tx, workspaceId: string, assetId: string): Promise<Row>;
66
126
  create(tx: Tx, workspaceId: string, actorId: string | null, input: AssetCreateInput, format: CodeFormat): Promise<Written>;
67
127
  /** Fields a person edits directly, and therefore the fields the timeline reports a diff for. */
68
128
  private static readonly EDITABLE;
69
129
  update(tx: Tx, workspaceId: string, actorId: string | null, assetId: string, input: AssetPatchInput): Promise<Written>;
70
- archive(tx: Tx, workspaceId: string, actorId: string | null, assetId: string, archived: boolean): Promise<Written>;
130
+ /**
131
+ * @param repairsOn whether the workspace records repairs, read before the transaction opened.
132
+ * The "it is away for repair" refusal below tells somebody to go and use `repairs.complete`, and
133
+ * that procedure answers 404 in a workspace with the capability off — so the refusal would be an
134
+ * instruction to open a door that is not there, and the asset could never leave the register.
135
+ */
136
+ archive(tx: Tx, workspaceId: string, actorId: string | null, assetId: string, archived: boolean, repairsOn: boolean): Promise<Written>;
71
137
  }
72
138
  export {};
73
139
  //# sourceMappingURL=assets.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"assets.d.ts","sourceRoot":"","sources":["../../../src/server/services/assets.ts"],"names":[],"mappings":"AAAA,OAAO,EAAa,KAAK,MAAM,EAAE,KAAK,EAAE,EAAU,MAAM,gBAAgB,CAAA;AAGxE,OAAO,KAAK,EACV,gBAAgB,EAChB,KAAK,IAAI,UAAU,EACnB,eAAe,EACf,SAAS,EACV,MAAM,0BAA0B,CAAA;AAEjC,OAAO,EAAE,MAAM,EAAY,MAAM,cAAc,CAAA;AAC/C,OAAO,KAAK,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAE9D,KAAK,GAAG,GAAG,OAAO,MAAM,CAAC,YAAY,CAAA;AAErC;;;;;;;;GAQG;AACH,MAAM,WAAW,OAAO;IACtB,GAAG,EAAE,GAAG,CAAA;IACR,qGAAqG;IACrG,QAAQ,EAAE,YAAY,GAAG,IAAI,CAAA;CAC9B;AAED,oGAAoG;AACpG,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,MAAM,CAAA;IACd,GAAG,EAAE,MAAM,CAAA;CACZ;AAED,oGAAoG;AACpG,wBAAgB,OAAO,CAAC,GAAG,EAAE,GAAG,GAAG,UAAU,CAwB5C;AAgED,MAAM,WAAW,SAAS;IACxB,WAAW,EAAE,MAAM,CAAA;IACnB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,CAAC,CAAC,EAAE,MAAM,CAAA;IACV,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,QAAQ,EAAE,OAAO,CAAA;IACjB,IAAI,EAAE,SAAS,CAAA;CAChB;AAED,qBAAa,YAAY;IAErB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM;gBADN,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,aAAa;IAGxC;;;;;;;;OAQG;IACG,UAAU,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAK1D;;;;;;;OAOG;IACG,QAAQ,CAAC,EAAE,EAAE,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC;IAY1E,IAAI,CAAC,EAAE,EAAE,EAAE,EAAE,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,UAAU,EAAE,CAAC;QAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC;IAoE3F,GAAG,CAAC,EAAE,EAAE,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC;IAS/D,MAAM,CACV,EAAE,EAAE,EAAE,EACN,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,GAAG,IAAI,EACtB,KAAK,EAAE,gBAAgB,EACvB,MAAM,EAAE,UAAU,GACjB,OAAO,CAAC,OAAO,CAAC;IAyBnB,gGAAgG;IAChG,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAYtB;IAEJ,MAAM,CACV,EAAE,EAAE,EAAE,EACN,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,GAAG,IAAI,EACtB,OAAO,EAAE,MAAM,EACf,KAAK,EAAE,eAAe,GACrB,OAAO,CAAC,OAAO,CAAC;IAuCb,OAAO,CACX,EAAE,EAAE,EAAE,EACN,WAAW,EAAE,MAAM,EACnB,OAAO,EAAE,MAAM,GAAG,IAAI,EACtB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,OAAO,GAChB,OAAO,CAAC,OAAO,CAAC;CAgBpB"}
1
+ {"version":3,"file":"assets.d.ts","sourceRoot":"","sources":["../../../src/server/services/assets.ts"],"names":[],"mappings":"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"}