@kernhq/module-inventory 0.1.2 → 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.
- package/README.md +134 -9
- package/dist/contract/capabilities.d.ts +49 -0
- package/dist/contract/capabilities.d.ts.map +1 -0
- package/dist/contract/capabilities.js +94 -0
- package/dist/contract/capabilities.js.map +1 -0
- package/dist/contract/events.d.ts +76 -0
- package/dist/contract/events.d.ts.map +1 -0
- package/dist/contract/events.js +62 -0
- package/dist/contract/events.js.map +1 -0
- package/dist/contract/index.d.ts +16 -0
- package/dist/contract/index.d.ts.map +1 -0
- package/dist/contract/index.js +16 -0
- package/dist/contract/index.js.map +1 -0
- package/dist/contract/models.d.ts +468 -0
- package/dist/contract/models.d.ts.map +1 -0
- package/dist/contract/models.js +320 -0
- package/dist/contract/models.js.map +1 -0
- package/dist/contract/notifications.d.ts +24 -0
- package/dist/contract/notifications.d.ts.map +1 -0
- package/dist/contract/notifications.js +72 -0
- package/dist/contract/notifications.js.map +1 -0
- package/dist/contract/permissions.d.ts +72 -0
- package/dist/contract/permissions.d.ts.map +1 -0
- package/dist/contract/permissions.js +79 -0
- package/dist/contract/permissions.js.map +1 -0
- package/dist/contract/router.d.ts +1378 -0
- package/dist/contract/router.d.ts.map +1 -0
- package/dist/contract/router.js +266 -0
- package/dist/contract/router.js.map +1 -0
- package/dist/contract/settings.d.ts +20 -0
- package/dist/contract/settings.d.ts.map +1 -0
- package/dist/contract/settings.js +49 -0
- package/dist/contract/settings.js.map +1 -0
- package/dist/server/index.d.ts +8 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +288 -8
- package/dist/server/index.js.map +1 -1
- package/dist/server/jobs.d.ts +48 -0
- package/dist/server/jobs.d.ts.map +1 -0
- package/dist/server/jobs.js +358 -0
- package/dist/server/jobs.js.map +1 -0
- package/dist/server/router.d.ts +1789 -0
- package/dist/server/router.d.ts.map +1 -0
- package/dist/server/router.js +439 -0
- package/dist/server/router.js.map +1 -0
- package/dist/server/schema.d.ts +156 -9
- package/dist/server/schema.d.ts.map +1 -1
- package/dist/server/schema.js +183 -11
- package/dist/server/schema.js.map +1 -1
- package/dist/server/services/assets.d.ts +139 -0
- package/dist/server/services/assets.d.ts.map +1 -0
- package/dist/server/services/assets.js +429 -0
- package/dist/server/services/assets.js.map +1 -0
- package/dist/server/services/attachments.d.ts +80 -0
- package/dist/server/services/attachments.d.ts.map +1 -0
- package/dist/server/services/attachments.js +182 -0
- package/dist/server/services/attachments.js.map +1 -0
- package/dist/server/services/audience.d.ts +15 -0
- package/dist/server/services/audience.d.ts.map +1 -0
- package/dist/server/services/audience.js +64 -0
- package/dist/server/services/audience.js.map +1 -0
- package/dist/server/services/categories.d.ts +57 -0
- package/dist/server/services/categories.d.ts.map +1 -0
- package/dist/server/services/categories.js +124 -0
- package/dist/server/services/categories.js.map +1 -0
- package/dist/server/services/cursor.d.ts +68 -0
- package/dist/server/services/cursor.d.ts.map +1 -0
- package/dist/server/services/cursor.js +39 -0
- package/dist/server/services/cursor.js.map +1 -0
- package/dist/server/services/custody.d.ts +175 -0
- package/dist/server/services/custody.d.ts.map +1 -0
- package/dist/server/services/custody.js +367 -0
- package/dist/server/services/custody.js.map +1 -0
- package/dist/server/services/db-errors.d.ts +7 -0
- package/dist/server/services/db-errors.d.ts.map +1 -0
- package/dist/server/services/db-errors.js +32 -0
- package/dist/server/services/db-errors.js.map +1 -0
- package/dist/server/services/index.d.ts +26 -0
- package/dist/server/services/index.d.ts.map +1 -0
- package/dist/server/services/index.js +39 -0
- package/dist/server/services/index.js.map +1 -0
- package/dist/server/services/members.d.ts +27 -0
- package/dist/server/services/members.d.ts.map +1 -0
- package/dist/server/services/members.js +39 -0
- package/dist/server/services/members.js.map +1 -0
- package/dist/server/services/notify.d.ts +105 -0
- package/dist/server/services/notify.d.ts.map +1 -0
- package/dist/server/services/notify.js +147 -0
- package/dist/server/services/notify.js.map +1 -0
- package/dist/server/services/offboarding.d.ts +70 -0
- package/dist/server/services/offboarding.d.ts.map +1 -0
- package/dist/server/services/offboarding.js +116 -0
- package/dist/server/services/offboarding.js.map +1 -0
- package/dist/server/services/repairs.d.ts +204 -0
- package/dist/server/services/repairs.d.ts.map +1 -0
- package/dist/server/services/repairs.js +476 -0
- package/dist/server/services/repairs.js.map +1 -0
- package/dist/server/services/search.d.ts +85 -0
- package/dist/server/services/search.d.ts.map +1 -0
- package/dist/server/services/search.js +142 -0
- package/dist/server/services/search.js.map +1 -0
- package/dist/server/services/stats.d.ts +42 -0
- package/dist/server/services/stats.d.ts.map +1 -0
- package/dist/server/services/stats.js +80 -0
- package/dist/server/services/stats.js.map +1 -0
- package/dist/server/services/status.d.ts +102 -0
- package/dist/server/services/status.d.ts.map +1 -0
- package/dist/server/services/status.js +71 -0
- package/dist/server/services/status.js.map +1 -0
- package/migrations/0000_init.sql +12 -3
- package/migrations/0001_rls.sql +24 -0
- package/migrations/0002_custody_and_categories.sql +23 -0
- package/migrations/0003_repairs.sql +23 -0
- package/migrations/0004_platform_surfaces.sql +51 -0
- package/migrations/0005_repair_dates.sql +35 -0
- package/migrations/0006_workspace_registry_read.sql +50 -0
- package/migrations/0007_history_sequence.sql +83 -0
- package/migrations/meta/0000_snapshot.json +40 -13
- package/migrations/meta/0002_snapshot.json +1054 -0
- package/migrations/meta/0003_snapshot.json +1070 -0
- package/migrations/meta/0004_snapshot.json +1130 -0
- package/migrations/meta/0005_snapshot.json +1135 -0
- package/migrations/meta/_journal.json +44 -2
- package/package.json +5 -4
- package/src/client/api-instance.ts +27 -2
- package/src/client/api.ts +1 -1
- package/src/client/bidi.test.ts +148 -0
- package/src/client/bidi.ts +85 -0
- package/src/client/components/AssetDetailPanel.svelte +614 -0
- package/src/client/components/AssetFormDialog.svelte +191 -59
- package/src/client/components/AssetPhoto.svelte +178 -0
- package/src/client/components/AttachmentsSection.svelte +327 -0
- package/src/client/components/CustodyDialog.svelte +201 -0
- package/src/client/components/RepairDialog.svelte +271 -0
- package/src/client/components/RepairsSection.svelte +318 -0
- package/src/client/components/Timeline.svelte +347 -0
- package/src/client/components/TimelineText.svelte +124 -0
- package/src/client/core-api.ts +71 -0
- package/src/client/custody.test.ts +31 -0
- package/src/client/custody.ts +34 -0
- package/src/client/errors.test.ts +365 -0
- package/src/client/errors.ts +201 -0
- package/src/client/i18n.ts +11 -166
- package/src/client/index.ts +8 -1
- package/src/client/links.test.ts +74 -0
- package/src/client/links.ts +44 -0
- package/src/client/members.test.ts +132 -0
- package/src/client/members.ts +116 -0
- package/src/client/messages.test.ts +296 -0
- package/src/client/messages.ts +1424 -0
- package/src/client/mock.test.ts +555 -0
- package/src/client/mock.ts +1261 -52
- package/src/client/module.ts +76 -2
- package/src/client/pages/AssetsPage.svelte +638 -145
- package/src/client/permissions.ts +8 -1
- package/src/client/price.test.ts +254 -0
- package/src/client/price.ts +279 -0
- package/src/client/query.test.ts +58 -0
- package/src/client/query.ts +51 -2
- package/src/client/repairs.test.ts +38 -0
- package/src/client/repairs.ts +38 -0
- package/src/client/settings/CategoriesSettings.svelte +421 -0
- package/src/client/settings/GeneralSettings.svelte +403 -0
- package/src/client/status.ts +29 -0
- package/src/client/timeline.test.ts +175 -0
- package/src/client/timeline.ts +206 -0
- package/src/client/widgets/OverviewWidget.svelte +140 -26
- package/src/client/widgets/RepairsWidget.svelte +124 -0
- package/src/contract/capabilities.ts +99 -0
- package/src/contract/events.ts +83 -0
- package/src/contract/index.ts +16 -0
- package/src/contract/models.ts +360 -0
- package/src/contract/notifications.ts +73 -0
- package/src/contract/permissions.ts +79 -0
- package/src/contract/router.ts +300 -0
- package/src/contract/settings.ts +50 -0
- package/src/module.test.ts +330 -7
- package/src/server/index.ts +318 -8
- package/src/server/inventory.int.test.ts +4374 -0
- package/src/server/jobs.ts +444 -0
- package/src/server/migrations.test.ts +251 -0
- package/src/server/router.ts +574 -0
- package/src/server/schema.ts +184 -10
- package/src/server/services/assets.ts +528 -0
- package/src/server/services/attachments.ts +215 -0
- package/src/server/services/audience.ts +77 -0
- package/src/server/services/categories.ts +136 -0
- package/src/server/services/cursor.ts +104 -0
- package/src/server/services/custody.ts +471 -0
- package/src/server/services/db-errors.ts +42 -0
- package/src/server/services/index.ts +56 -0
- package/src/server/services/members.ts +54 -0
- package/src/server/services/notify.ts +196 -0
- package/src/server/services/offboarding.ts +150 -0
- package/src/server/services/repairs.ts +567 -0
- package/src/server/services/search.ts +166 -0
- package/src/server/services/stats.ts +88 -0
- package/src/server/services/status.test.ts +34 -0
- package/src/server/services/status.ts +143 -0
- package/tsconfig.base.json +22 -0
- package/tsconfig.client.json +1 -1
- package/tsconfig.json +1 -1
- package/vitest.config.ts +18 -3
- package/dist/contract.d.ts +0 -387
- package/dist/contract.d.ts.map +0 -1
- package/dist/contract.js +0 -119
- package/dist/contract.js.map +0 -1
- package/dist/server/_impl.d.ts +0 -427
- package/dist/server/_impl.d.ts.map +0 -1
- package/dist/server/_impl.js +0 -204
- package/dist/server/_impl.js.map +0 -1
- package/src/contract.ts +0 -143
- package/src/server/_impl.ts +0 -275
package/dist/server/schema.d.ts
CHANGED
|
@@ -10,10 +10,70 @@
|
|
|
10
10
|
*/
|
|
11
11
|
export declare const schema: import("drizzle-orm/pg-core").PgSchema<string>;
|
|
12
12
|
/**
|
|
13
|
-
*
|
|
14
|
-
*
|
|
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.
|
|
15
35
|
*/
|
|
16
|
-
export declare const
|
|
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
|
+
}>;
|
|
17
77
|
export declare const counters: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
18
78
|
name: "counters";
|
|
19
79
|
schema: string;
|
|
@@ -27,7 +87,7 @@ export declare const counters: import("drizzle-orm/pg-core").PgTableWithColumns<
|
|
|
27
87
|
driverParam: string;
|
|
28
88
|
notNull: true;
|
|
29
89
|
hasDefault: false;
|
|
30
|
-
isPrimaryKey:
|
|
90
|
+
isPrimaryKey: false;
|
|
31
91
|
isAutoincrement: false;
|
|
32
92
|
hasRuntimeDefault: false;
|
|
33
93
|
enumValues: undefined;
|
|
@@ -44,7 +104,7 @@ export declare const counters: import("drizzle-orm/pg-core").PgTableWithColumns<
|
|
|
44
104
|
driverParam: string;
|
|
45
105
|
notNull: true;
|
|
46
106
|
hasDefault: false;
|
|
47
|
-
isPrimaryKey:
|
|
107
|
+
isPrimaryKey: false;
|
|
48
108
|
isAutoincrement: false;
|
|
49
109
|
hasRuntimeDefault: false;
|
|
50
110
|
enumValues: [string, ...string[]];
|
|
@@ -144,6 +204,23 @@ export declare const categories: import("drizzle-orm/pg-core").PgTableWithColumn
|
|
|
144
204
|
identity: undefined;
|
|
145
205
|
generated: undefined;
|
|
146
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
|
+
}, {}, {}>;
|
|
147
224
|
createdAt: import("drizzle-orm/pg-core").PgColumn<{
|
|
148
225
|
name: string;
|
|
149
226
|
tableName: "categories";
|
|
@@ -291,15 +368,15 @@ export declare const assets: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
|
291
368
|
name: "status";
|
|
292
369
|
tableName: "assets";
|
|
293
370
|
dataType: "string";
|
|
294
|
-
columnType: "
|
|
295
|
-
data:
|
|
371
|
+
columnType: "PgText";
|
|
372
|
+
data: string;
|
|
296
373
|
driverParam: string;
|
|
297
374
|
notNull: true;
|
|
298
375
|
hasDefault: true;
|
|
299
376
|
isPrimaryKey: false;
|
|
300
377
|
isAutoincrement: false;
|
|
301
378
|
hasRuntimeDefault: false;
|
|
302
|
-
enumValues: [
|
|
379
|
+
enumValues: [string, ...string[]];
|
|
303
380
|
baseColumn: never;
|
|
304
381
|
identity: undefined;
|
|
305
382
|
generated: undefined;
|
|
@@ -459,6 +536,23 @@ export declare const assets: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
|
459
536
|
identity: undefined;
|
|
460
537
|
generated: undefined;
|
|
461
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
|
+
}, {}, {}>;
|
|
462
556
|
photoFileId: import("drizzle-orm/pg-core").PgColumn<{
|
|
463
557
|
name: "photo_file_id";
|
|
464
558
|
tableName: "assets";
|
|
@@ -476,6 +570,25 @@ export declare const assets: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
|
476
570
|
identity: undefined;
|
|
477
571
|
generated: undefined;
|
|
478
572
|
}, {}, {}>;
|
|
573
|
+
custom: import("drizzle-orm/pg-core").PgColumn<{
|
|
574
|
+
name: "custom";
|
|
575
|
+
tableName: "assets";
|
|
576
|
+
dataType: "json";
|
|
577
|
+
columnType: "PgJsonb";
|
|
578
|
+
data: Record<string, unknown>;
|
|
579
|
+
driverParam: unknown;
|
|
580
|
+
notNull: true;
|
|
581
|
+
hasDefault: true;
|
|
582
|
+
isPrimaryKey: false;
|
|
583
|
+
isAutoincrement: false;
|
|
584
|
+
hasRuntimeDefault: false;
|
|
585
|
+
enumValues: undefined;
|
|
586
|
+
baseColumn: never;
|
|
587
|
+
identity: undefined;
|
|
588
|
+
generated: undefined;
|
|
589
|
+
}, {}, {
|
|
590
|
+
$type: Record<string, unknown>;
|
|
591
|
+
}>;
|
|
479
592
|
createdAt: import("drizzle-orm/pg-core").PgColumn<{
|
|
480
593
|
name: string;
|
|
481
594
|
tableName: "assets";
|
|
@@ -1136,6 +1249,23 @@ export declare const assetHistory: import("drizzle-orm/pg-core").PgTableWithColu
|
|
|
1136
1249
|
identity: undefined;
|
|
1137
1250
|
generated: undefined;
|
|
1138
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
|
+
}, {}, {}>;
|
|
1139
1269
|
};
|
|
1140
1270
|
dialect: "pg";
|
|
1141
1271
|
}>;
|
|
@@ -1315,6 +1445,23 @@ export declare const repairs: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
|
1315
1445
|
identity: undefined;
|
|
1316
1446
|
generated: undefined;
|
|
1317
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
|
+
}, {}, {}>;
|
|
1318
1465
|
createdBy: import("drizzle-orm/pg-core").PgColumn<{
|
|
1319
1466
|
name: "created_by";
|
|
1320
1467
|
tableName: "repairs";
|
|
@@ -1548,5 +1695,5 @@ export declare const attachments: import("drizzle-orm/pg-core").PgTableWithColum
|
|
|
1548
1695
|
dialect: "pg";
|
|
1549
1696
|
}>;
|
|
1550
1697
|
/** Every tenant table, so the RLS migration can be checked against one list rather than memory. */
|
|
1551
|
-
export declare const TENANT_TABLES: readonly ["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"];
|
|
1552
1699
|
//# sourceMappingURL=schema.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/server/schema.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/server/schema.ts"],"names":[],"mappings":"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"}
|
package/dist/server/schema.js
CHANGED
|
@@ -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,
|
|
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
|
*
|
|
@@ -19,25 +19,72 @@ 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
21
|
/**
|
|
22
|
-
*
|
|
23
|
-
*
|
|
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.
|
|
24
44
|
*/
|
|
25
|
-
export const
|
|
45
|
+
export const workspaces = schema.table('workspaces', {
|
|
46
|
+
workspaceId: uuid('workspace_id').primaryKey(),
|
|
47
|
+
createdAt: created(),
|
|
48
|
+
});
|
|
26
49
|
export const counters = schema.table('counters',
|
|
27
50
|
/** Per-workspace sequence sources (`asset_code`). Narrow on purpose: one row per key. */
|
|
28
51
|
{
|
|
29
|
-
workspaceId: ws()
|
|
30
|
-
key: text('key').
|
|
52
|
+
workspaceId: ws(),
|
|
53
|
+
key: text('key').notNull(),
|
|
31
54
|
value: integer('value').notNull(),
|
|
32
|
-
}
|
|
55
|
+
},
|
|
56
|
+
/**
|
|
57
|
+
* Composite, declared here rather than as two `.primaryKey()` columns.
|
|
58
|
+
*
|
|
59
|
+
* Column-level `.primaryKey()` twice reads like a compound key and is not one: drizzle emits
|
|
60
|
+
* `PRIMARY KEY` on both columns and Postgres refuses the table outright — "multiple primary keys
|
|
61
|
+
* for table are not allowed", SQLSTATE 42P16. The module's migration is the first thing the
|
|
62
|
+
* kernel runs, so the failure is not a broken table but a service that will not boot.
|
|
63
|
+
*/
|
|
64
|
+
(t) => [primaryKey({ columns: [t.workspaceId, t.key] })]);
|
|
33
65
|
export const categories = schema.table('categories', {
|
|
34
66
|
id: id(),
|
|
35
67
|
workspaceId: ws(),
|
|
36
68
|
name: text('name').notNull(),
|
|
37
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'),
|
|
38
83
|
createdAt: created(),
|
|
39
84
|
updatedAt: updated(),
|
|
40
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.
|
|
41
88
|
uniqueIndex('inventory_categories_ws_name_uq').on(t.workspaceId, t.name),
|
|
42
89
|
index('inventory_categories_ws_idx').on(t.workspaceId, t.order),
|
|
43
90
|
]);
|
|
@@ -48,7 +95,10 @@ export const assets = schema.table('assets', {
|
|
|
48
95
|
name: text('name').notNull(),
|
|
49
96
|
description: text('description').notNull().default(''),
|
|
50
97
|
categoryId: uuid('category_id'),
|
|
51
|
-
|
|
98
|
+
/** `AssetStatus` in the contract. Text, not a pg enum: every other Kern module stores a
|
|
99
|
+
* status this way, and an enum named `asset_status` in `public` is a type this module
|
|
100
|
+
* leaves behind when it is removed. */
|
|
101
|
+
status: text('status').notNull().default('in_stock'),
|
|
52
102
|
/** Denormalized from `custody_periods`, which stays authoritative for history. */
|
|
53
103
|
custodianUserId: uuid('custodian_user_id'),
|
|
54
104
|
custodySince: ts('custody_since'),
|
|
@@ -59,7 +109,21 @@ export const assets = schema.table('assets', {
|
|
|
59
109
|
priceMinor: integer('price_minor'),
|
|
60
110
|
currency: char('currency', { length: 3 }),
|
|
61
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'),
|
|
62
124
|
photoFileId: uuid('photo_file_id'),
|
|
125
|
+
/** Values for this workspace's own `field_defs`, keyed by their `key`. */
|
|
126
|
+
custom: jsonb('custom').$type().notNull().default({}),
|
|
63
127
|
createdAt: created(),
|
|
64
128
|
updatedAt: updated(),
|
|
65
129
|
archivedAt: ts('archived_at'),
|
|
@@ -68,6 +132,10 @@ export const assets = schema.table('assets', {
|
|
|
68
132
|
index('inventory_assets_ws_created_idx').on(t.workspaceId, t.createdAt),
|
|
69
133
|
index('inventory_assets_ws_status_idx').on(t.workspaceId, t.status),
|
|
70
134
|
index('inventory_assets_ws_category_idx').on(t.workspaceId, t.categoryId),
|
|
135
|
+
// "What is Ada holding?" — asked by the person, by the offboarding hook, and by a widget.
|
|
136
|
+
index('inventory_assets_ws_custodian_idx')
|
|
137
|
+
.on(t.workspaceId, t.custodianUserId)
|
|
138
|
+
.where(sql `custodian_user_id is not null`),
|
|
71
139
|
// The "what leaves warranty this month" scan, before a job makes it a widget's cheap query.
|
|
72
140
|
index('inventory_assets_ws_warranty_idx')
|
|
73
141
|
.on(t.workspaceId, t.warrantyUntil)
|
|
@@ -125,11 +193,51 @@ export const assetHistory = schema.table('asset_history', {
|
|
|
125
193
|
workspaceId: ws(),
|
|
126
194
|
assetId: uuid('asset_id').notNull(),
|
|
127
195
|
actorId: uuid('actor_id'),
|
|
128
|
-
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
|
|
129
197
|
changes: jsonb('changes').$type(),
|
|
130
198
|
data: jsonb('data'),
|
|
131
199
|
occurredAt: created(),
|
|
132
|
-
|
|
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
|
+
]);
|
|
133
241
|
export const repairs = schema.table('repairs', {
|
|
134
242
|
id: id(),
|
|
135
243
|
workspaceId: ws(),
|
|
@@ -142,10 +250,65 @@ export const repairs = schema.table('repairs', {
|
|
|
142
250
|
sentOn: date('sent_on').notNull(),
|
|
143
251
|
/** Null while the item is still away — also how `under_repair` is derived. */
|
|
144
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'),
|
|
145
264
|
createdBy: uuid('created_by'),
|
|
146
265
|
createdAt: created(),
|
|
147
266
|
updatedAt: updated(),
|
|
148
|
-
}, (t) => [
|
|
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
|
+
]);
|
|
149
312
|
/** Bytes live in core object storage via `uploadFile`; this only records that an asset has one. */
|
|
150
313
|
export const attachments = schema.table('attachments', {
|
|
151
314
|
id: id(),
|
|
@@ -164,6 +327,15 @@ export const attachments = schema.table('attachments', {
|
|
|
164
327
|
]);
|
|
165
328
|
/** Every tenant table, so the RLS migration can be checked against one list rather than memory. */
|
|
166
329
|
export const TENANT_TABLES = [
|
|
330
|
+
// `counters` is a tenant table like any other: it carries `workspace_id`, so one workspace's
|
|
331
|
+
// asset-code sequence is readable to another without a policy. It was left out of this list —
|
|
332
|
+
// and therefore out of `0001_rls.sql` — because it holds no asset data, which is not the rule
|
|
333
|
+
// the file states at the top. Tracker's structurally identical `issue_counters` is covered.
|
|
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',
|
|
167
339
|
'categories',
|
|
168
340
|
'assets',
|
|
169
341
|
'field_defs',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/server/schema.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAC7C,OAAO,EAAE,GAAG,EAAE,MAAM,aAAa,CAAA;AACjC,OAAO,EACL,OAAO,EACP,IAAI,EACJ,IAAI,EACJ,KAAK,EACL,OAAO,EACP,KAAK,EACL,
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/server/schema.ts"],"names":[],"mappings":"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"}
|