@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.
Files changed (213) hide show
  1. package/README.md +134 -9
  2. package/dist/contract/capabilities.d.ts +49 -0
  3. package/dist/contract/capabilities.d.ts.map +1 -0
  4. package/dist/contract/capabilities.js +94 -0
  5. package/dist/contract/capabilities.js.map +1 -0
  6. package/dist/contract/events.d.ts +76 -0
  7. package/dist/contract/events.d.ts.map +1 -0
  8. package/dist/contract/events.js +62 -0
  9. package/dist/contract/events.js.map +1 -0
  10. package/dist/contract/index.d.ts +16 -0
  11. package/dist/contract/index.d.ts.map +1 -0
  12. package/dist/contract/index.js +16 -0
  13. package/dist/contract/index.js.map +1 -0
  14. package/dist/contract/models.d.ts +468 -0
  15. package/dist/contract/models.d.ts.map +1 -0
  16. package/dist/contract/models.js +320 -0
  17. package/dist/contract/models.js.map +1 -0
  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 +72 -0
  23. package/dist/contract/permissions.d.ts.map +1 -0
  24. package/dist/contract/permissions.js +79 -0
  25. package/dist/contract/permissions.js.map +1 -0
  26. package/dist/contract/router.d.ts +1378 -0
  27. package/dist/contract/router.d.ts.map +1 -0
  28. package/dist/contract/router.js +266 -0
  29. package/dist/contract/router.js.map +1 -0
  30. package/dist/contract/settings.d.ts +20 -0
  31. package/dist/contract/settings.d.ts.map +1 -0
  32. package/dist/contract/settings.js +49 -0
  33. package/dist/contract/settings.js.map +1 -0
  34. package/dist/server/index.d.ts +8 -1
  35. package/dist/server/index.d.ts.map +1 -1
  36. package/dist/server/index.js +288 -8
  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 +1789 -0
  43. package/dist/server/router.d.ts.map +1 -0
  44. package/dist/server/router.js +439 -0
  45. package/dist/server/router.js.map +1 -0
  46. package/dist/server/schema.d.ts +156 -9
  47. package/dist/server/schema.d.ts.map +1 -1
  48. package/dist/server/schema.js +183 -11
  49. package/dist/server/schema.js.map +1 -1
  50. package/dist/server/services/assets.d.ts +139 -0
  51. package/dist/server/services/assets.d.ts.map +1 -0
  52. package/dist/server/services/assets.js +429 -0
  53. package/dist/server/services/assets.js.map +1 -0
  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 +26 -0
  79. package/dist/server/services/index.d.ts.map +1 -0
  80. package/dist/server/services/index.js +39 -0
  81. package/dist/server/services/index.js.map +1 -0
  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 +105 -0
  87. package/dist/server/services/notify.d.ts.map +1 -0
  88. package/dist/server/services/notify.js +147 -0
  89. package/dist/server/services/notify.js.map +1 -0
  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/0000_init.sql +12 -3
  111. package/migrations/0001_rls.sql +24 -0
  112. package/migrations/0002_custody_and_categories.sql +23 -0
  113. package/migrations/0003_repairs.sql +23 -0
  114. package/migrations/0004_platform_surfaces.sql +51 -0
  115. package/migrations/0005_repair_dates.sql +35 -0
  116. package/migrations/0006_workspace_registry_read.sql +50 -0
  117. package/migrations/0007_history_sequence.sql +83 -0
  118. package/migrations/meta/0000_snapshot.json +40 -13
  119. package/migrations/meta/0002_snapshot.json +1054 -0
  120. package/migrations/meta/0003_snapshot.json +1070 -0
  121. package/migrations/meta/0004_snapshot.json +1130 -0
  122. package/migrations/meta/0005_snapshot.json +1135 -0
  123. package/migrations/meta/_journal.json +44 -2
  124. package/package.json +5 -4
  125. package/src/client/api-instance.ts +27 -2
  126. package/src/client/api.ts +1 -1
  127. package/src/client/bidi.test.ts +148 -0
  128. package/src/client/bidi.ts +85 -0
  129. package/src/client/components/AssetDetailPanel.svelte +614 -0
  130. package/src/client/components/AssetFormDialog.svelte +191 -59
  131. package/src/client/components/AssetPhoto.svelte +178 -0
  132. package/src/client/components/AttachmentsSection.svelte +327 -0
  133. package/src/client/components/CustodyDialog.svelte +201 -0
  134. package/src/client/components/RepairDialog.svelte +271 -0
  135. package/src/client/components/RepairsSection.svelte +318 -0
  136. package/src/client/components/Timeline.svelte +347 -0
  137. package/src/client/components/TimelineText.svelte +124 -0
  138. package/src/client/core-api.ts +71 -0
  139. package/src/client/custody.test.ts +31 -0
  140. package/src/client/custody.ts +34 -0
  141. package/src/client/errors.test.ts +365 -0
  142. package/src/client/errors.ts +201 -0
  143. package/src/client/i18n.ts +11 -166
  144. package/src/client/index.ts +8 -1
  145. package/src/client/links.test.ts +74 -0
  146. package/src/client/links.ts +44 -0
  147. package/src/client/members.test.ts +132 -0
  148. package/src/client/members.ts +116 -0
  149. package/src/client/messages.test.ts +296 -0
  150. package/src/client/messages.ts +1424 -0
  151. package/src/client/mock.test.ts +555 -0
  152. package/src/client/mock.ts +1261 -52
  153. package/src/client/module.ts +76 -2
  154. package/src/client/pages/AssetsPage.svelte +638 -145
  155. package/src/client/permissions.ts +8 -1
  156. package/src/client/price.test.ts +254 -0
  157. package/src/client/price.ts +279 -0
  158. package/src/client/query.test.ts +58 -0
  159. package/src/client/query.ts +51 -2
  160. package/src/client/repairs.test.ts +38 -0
  161. package/src/client/repairs.ts +38 -0
  162. package/src/client/settings/CategoriesSettings.svelte +421 -0
  163. package/src/client/settings/GeneralSettings.svelte +403 -0
  164. package/src/client/status.ts +29 -0
  165. package/src/client/timeline.test.ts +175 -0
  166. package/src/client/timeline.ts +206 -0
  167. package/src/client/widgets/OverviewWidget.svelte +140 -26
  168. package/src/client/widgets/RepairsWidget.svelte +124 -0
  169. package/src/contract/capabilities.ts +99 -0
  170. package/src/contract/events.ts +83 -0
  171. package/src/contract/index.ts +16 -0
  172. package/src/contract/models.ts +360 -0
  173. package/src/contract/notifications.ts +73 -0
  174. package/src/contract/permissions.ts +79 -0
  175. package/src/contract/router.ts +300 -0
  176. package/src/contract/settings.ts +50 -0
  177. package/src/module.test.ts +330 -7
  178. package/src/server/index.ts +318 -8
  179. package/src/server/inventory.int.test.ts +4374 -0
  180. package/src/server/jobs.ts +444 -0
  181. package/src/server/migrations.test.ts +251 -0
  182. package/src/server/router.ts +574 -0
  183. package/src/server/schema.ts +184 -10
  184. package/src/server/services/assets.ts +528 -0
  185. package/src/server/services/attachments.ts +215 -0
  186. package/src/server/services/audience.ts +77 -0
  187. package/src/server/services/categories.ts +136 -0
  188. package/src/server/services/cursor.ts +104 -0
  189. package/src/server/services/custody.ts +471 -0
  190. package/src/server/services/db-errors.ts +42 -0
  191. package/src/server/services/index.ts +56 -0
  192. package/src/server/services/members.ts +54 -0
  193. package/src/server/services/notify.ts +196 -0
  194. package/src/server/services/offboarding.ts +150 -0
  195. package/src/server/services/repairs.ts +567 -0
  196. package/src/server/services/search.ts +166 -0
  197. package/src/server/services/stats.ts +88 -0
  198. package/src/server/services/status.test.ts +34 -0
  199. package/src/server/services/status.ts +143 -0
  200. package/tsconfig.base.json +22 -0
  201. package/tsconfig.client.json +1 -1
  202. package/tsconfig.json +1 -1
  203. package/vitest.config.ts +18 -3
  204. package/dist/contract.d.ts +0 -387
  205. package/dist/contract.d.ts.map +0 -1
  206. package/dist/contract.js +0 -119
  207. package/dist/contract.js.map +0 -1
  208. package/dist/server/_impl.d.ts +0 -427
  209. package/dist/server/_impl.d.ts.map +0 -1
  210. package/dist/server/_impl.js +0 -204
  211. package/dist/server/_impl.js.map +0 -1
  212. package/src/contract.ts +0 -143
  213. package/src/server/_impl.ts +0 -275
@@ -0,0 +1,468 @@
1
+ import { z } from 'zod';
2
+ /**
3
+ * The nouns this module owns, and the shapes that cross the wire.
4
+ *
5
+ * Imported by **both** halves — the server implements against them, the client calls against them —
6
+ * so nothing here may touch Node. Types only; the procedures live in `router.ts`.
7
+ */
8
+ /** Lowercase, 2-32 characters. Names the API prefix, the Postgres schema `mod_<id>` and every event. */
9
+ export declare const MODULE_ID = "inventory";
10
+ /**
11
+ * An asset's lifecycle. `in_stock` and `assigned` follow custody (an open row in `custody_periods`
12
+ * means assigned); `under_repair` follows an open repair; `reserved` follows a booking that has not
13
+ * been collected; `lost` and `retired` are set by hand when an item stops being usable.
14
+ *
15
+ * Stored rather than derived, because every list filter asks for it — and kept in step inside the
16
+ * same transaction that writes the row it derives from, never by a job afterwards.
17
+ *
18
+ * **`under_repair` belongs to the `repairs` capability**, so a workspace with that switch off never
19
+ * has an asset in it: the procedure that ends a repair answers 404 there, and a status nothing can
20
+ * move an item out of is a register the workspace cannot correct. The one thing a job does here is
21
+ * bring the rows *nobody touches* back into step after that switch moves, in both directions —
22
+ * `deriveStatus` in `src/server/services/status.ts` argues it, and nothing is destroyed either way.
23
+ */
24
+ export declare const AssetStatus: z.ZodEnum<{
25
+ in_stock: "in_stock";
26
+ assigned: "assigned";
27
+ reserved: "reserved";
28
+ under_repair: "under_repair";
29
+ lost: "lost";
30
+ retired: "retired";
31
+ }>;
32
+ export type AssetStatus = z.infer<typeof AssetStatus>;
33
+ /**
34
+ * A value a workspace defined for itself, stored under its `key` in `assets.custom`.
35
+ *
36
+ * `unknown` rather than a union: the field definition says what the type is, and validating a value
37
+ * against a definition the client may not have loaded yet would fail honest input. The server checks
38
+ * it against `field_defs` before writing.
39
+ */
40
+ export declare const CustomValues: z.ZodRecord<z.ZodString, z.ZodUnknown>;
41
+ export type CustomValues = z.infer<typeof CustomValues>;
42
+ /**
43
+ * A workspace's own grouping of what it owns — Laptops, Furniture, Cameras.
44
+ *
45
+ * Archived rather than deleted, and `archivedAt` is the whole reason: `assets.category_id` is a
46
+ * plain uuid with no foreign key, so a deleted category leaves every asset filed under it pointing
47
+ * at a row that is not there. The list column goes blank and the timeline entry that recorded the
48
+ * move loses the name it recorded. Archiving takes it out of every picker and every filter and
49
+ * leaves each asset able to say what it is.
50
+ */
51
+ export declare const Category: z.ZodObject<{
52
+ id: z.ZodUUID;
53
+ workspaceId: z.core.$ZodBranded<z.ZodUUID, "WorkspaceId", "out">;
54
+ name: z.ZodString;
55
+ order: z.ZodNumber;
56
+ createdAt: z.ZodString;
57
+ updatedAt: z.ZodString;
58
+ archivedAt: z.ZodNullable<z.ZodString>;
59
+ }, z.core.$strip>;
60
+ export type Category = z.infer<typeof Category>;
61
+ export declare const CategoryInput: z.ZodObject<{
62
+ name: z.ZodString;
63
+ order: z.ZodOptional<z.ZodNumber>;
64
+ }, z.core.$strip>;
65
+ export type CategoryInput = z.infer<typeof CategoryInput>;
66
+ /**
67
+ * One stretch of time during which one person held one asset.
68
+ *
69
+ * Effective-dated, exactly as HR keeps employments: nothing is ever updated in place, a change
70
+ * closes the open row and inserts a new one. `effectiveTo === null` means "still holding it", and
71
+ * `inventory_custody_no_overlap` — a GiST exclusion constraint on
72
+ * `(asset_id =, tstzrange(effective_from, effective_to, '[)') &&)` — makes two of those for one
73
+ * asset impossible in the database rather than merely unlikely in the service.
74
+ */
75
+ export declare const CustodyPeriod: z.ZodObject<{
76
+ id: z.ZodUUID;
77
+ workspaceId: z.core.$ZodBranded<z.ZodUUID, "WorkspaceId", "out">;
78
+ assetId: z.ZodUUID;
79
+ userId: z.ZodUUID;
80
+ note: z.ZodNullable<z.ZodString>;
81
+ effectiveFrom: z.ZodString;
82
+ effectiveTo: z.ZodNullable<z.ZodString>;
83
+ createdBy: z.ZodNullable<z.ZodUUID>;
84
+ createdAt: z.ZodString;
85
+ }, z.core.$strip>;
86
+ export type CustodyPeriod = z.infer<typeof CustodyPeriod>;
87
+ /**
88
+ * One entry in an asset's timeline.
89
+ *
90
+ * `action` is a **plain string, deliberately not an enum**. The rows are append-only and outlive
91
+ * the image that wrote them: an instance rolled back to a previous release would fail to parse its
92
+ * own history the moment a newer image had written an action the older enum does not list — a
93
+ * timeline that 500s rather than one that says a little less. The client renders a sentence per
94
+ * action it knows and a neutral one for anything else. What is written today is `created`,
95
+ * `updated`, `assigned`, `transferred`, `returned`, `retired`, `restored`, `repair_logged`,
96
+ * `repair_completed`, `attachment_added` and `attachment_removed`.
97
+ */
98
+ export declare const AssetHistoryEntry: z.ZodObject<{
99
+ id: z.ZodUUID;
100
+ assetId: z.ZodUUID;
101
+ actorId: z.ZodNullable<z.ZodUUID>;
102
+ action: z.ZodString;
103
+ changes: z.ZodArray<z.ZodObject<{
104
+ field: z.ZodString;
105
+ from: z.ZodUnknown;
106
+ to: z.ZodUnknown;
107
+ }, z.core.$strip>>;
108
+ data: z.ZodRecord<z.ZodString, z.ZodUnknown>;
109
+ occurredAt: z.ZodString;
110
+ }, z.core.$strip>;
111
+ export type AssetHistoryEntry = z.infer<typeof AssetHistoryEntry>;
112
+ export declare const Asset: z.ZodObject<{
113
+ id: z.ZodUUID;
114
+ workspaceId: z.core.$ZodBranded<z.ZodUUID, "WorkspaceId", "out">;
115
+ code: z.ZodString;
116
+ name: z.ZodString;
117
+ description: z.ZodString;
118
+ categoryId: z.ZodNullable<z.ZodUUID>;
119
+ status: z.ZodEnum<{
120
+ in_stock: "in_stock";
121
+ assigned: "assigned";
122
+ reserved: "reserved";
123
+ under_repair: "under_repair";
124
+ lost: "lost";
125
+ retired: "retired";
126
+ }>;
127
+ custodianUserId: z.ZodNullable<z.ZodUUID>;
128
+ custodySince: z.ZodNullable<z.ZodString>;
129
+ serialNumber: z.ZodNullable<z.ZodString>;
130
+ location: z.ZodNullable<z.ZodString>;
131
+ purchasedOn: z.ZodNullable<z.ZodString>;
132
+ purchasedFrom: z.ZodNullable<z.ZodString>;
133
+ priceMinor: z.ZodNullable<z.ZodNumber>;
134
+ currency: z.ZodNullable<z.ZodString>;
135
+ warrantyUntil: z.ZodNullable<z.ZodString>;
136
+ photoFileId: z.ZodNullable<z.ZodUUID>;
137
+ custom: z.ZodRecord<z.ZodString, z.ZodUnknown>;
138
+ createdAt: z.ZodString;
139
+ updatedAt: z.ZodString;
140
+ archivedAt: z.ZodNullable<z.ZodString>;
141
+ }, z.core.$strip>;
142
+ export type Asset = z.infer<typeof Asset>;
143
+ /**
144
+ * What a custody procedure answers with: the asset as it now stands, and the period this call
145
+ * opened.
146
+ *
147
+ * Both, because a screen needs both and fetching the asset again afterwards is a second round trip
148
+ * that can read a row somebody else has changed in between — the panel would then show a handover
149
+ * that has already been undone. `period` is null on a return: something closed, nothing opened.
150
+ */
151
+ export declare const CustodyResult: z.ZodObject<{
152
+ asset: z.ZodObject<{
153
+ id: z.ZodUUID;
154
+ workspaceId: z.core.$ZodBranded<z.ZodUUID, "WorkspaceId", "out">;
155
+ code: z.ZodString;
156
+ name: z.ZodString;
157
+ description: z.ZodString;
158
+ categoryId: z.ZodNullable<z.ZodUUID>;
159
+ status: z.ZodEnum<{
160
+ in_stock: "in_stock";
161
+ assigned: "assigned";
162
+ reserved: "reserved";
163
+ under_repair: "under_repair";
164
+ lost: "lost";
165
+ retired: "retired";
166
+ }>;
167
+ custodianUserId: z.ZodNullable<z.ZodUUID>;
168
+ custodySince: z.ZodNullable<z.ZodString>;
169
+ serialNumber: z.ZodNullable<z.ZodString>;
170
+ location: z.ZodNullable<z.ZodString>;
171
+ purchasedOn: z.ZodNullable<z.ZodString>;
172
+ purchasedFrom: z.ZodNullable<z.ZodString>;
173
+ priceMinor: z.ZodNullable<z.ZodNumber>;
174
+ currency: z.ZodNullable<z.ZodString>;
175
+ warrantyUntil: z.ZodNullable<z.ZodString>;
176
+ photoFileId: z.ZodNullable<z.ZodUUID>;
177
+ custom: z.ZodRecord<z.ZodString, z.ZodUnknown>;
178
+ createdAt: z.ZodString;
179
+ updatedAt: z.ZodString;
180
+ archivedAt: z.ZodNullable<z.ZodString>;
181
+ }, z.core.$strip>;
182
+ period: z.ZodNullable<z.ZodObject<{
183
+ id: z.ZodUUID;
184
+ workspaceId: z.core.$ZodBranded<z.ZodUUID, "WorkspaceId", "out">;
185
+ assetId: z.ZodUUID;
186
+ userId: z.ZodUUID;
187
+ note: z.ZodNullable<z.ZodString>;
188
+ effectiveFrom: z.ZodString;
189
+ effectiveTo: z.ZodNullable<z.ZodString>;
190
+ createdBy: z.ZodNullable<z.ZodUUID>;
191
+ createdAt: z.ZodString;
192
+ }, z.core.$strip>>;
193
+ }, z.core.$strip>;
194
+ export type CustodyResult = z.infer<typeof CustodyResult>;
195
+ /**
196
+ * One trip an item made to a repairer.
197
+ *
198
+ * `returnedOn === null` means it is still away, and that single fact is what puts the asset in
199
+ * `under_repair` — see `deriveStatus` in `src/server/services/status.ts`, which is the only place
200
+ * the three columns that drive a status are read together.
201
+ *
202
+ * **A repair is not custody, and neither one cancels the other.** A laptop assigned to Dan that goes
203
+ * to the repairer is still Dan's responsibility: the custody period stays open, `custodianUserId`
204
+ * stays set, and only `status` moves. That is why a repair does not touch custody and custody does
205
+ * not refuse a repaired item — the two answer different questions ("who is answerable for it" and
206
+ * "where is it"), and collapsing them would mean an item could not come back to the person who sent
207
+ * it.
208
+ */
209
+ export declare const Repair: z.ZodObject<{
210
+ id: z.ZodUUID;
211
+ workspaceId: z.core.$ZodBranded<z.ZodUUID, "WorkspaceId", "out">;
212
+ assetId: z.ZodUUID;
213
+ summary: z.ZodString;
214
+ detail: z.ZodNullable<z.ZodString>;
215
+ vendor: z.ZodNullable<z.ZodString>;
216
+ costMinor: z.ZodNullable<z.ZodNumber>;
217
+ currency: z.ZodNullable<z.ZodString>;
218
+ sentOn: z.ZodString;
219
+ returnedOn: z.ZodNullable<z.ZodString>;
220
+ createdBy: z.ZodNullable<z.ZodUUID>;
221
+ createdAt: z.ZodString;
222
+ updatedAt: z.ZodString;
223
+ }, z.core.$strip>;
224
+ export type Repair = z.infer<typeof Repair>;
225
+ /**
226
+ * A repair in a list, with the two things a reader needs to know *which item* it is about.
227
+ *
228
+ * **Joined at read time, never stored here.** `mod_inventory.repairs` holds no asset name, so
229
+ * renaming an asset renames it everywhere at once — a copied label is a label that goes stale, and
230
+ * this module already refuses to copy a person's name for the same reason. The join is inside one
231
+ * schema, which is the kind a module is allowed to make; the kind it is not is a join across the
232
+ * boundary into another module's tables.
233
+ *
234
+ * It extends `Repair` rather than replacing it, so a component that renders a repair renders one of
235
+ * these without knowing the difference. `create`, `update` and `complete` answer with a plain
236
+ * `Repair`: the caller of those already knows which asset it asked about.
237
+ */
238
+ export declare const RepairListItem: z.ZodObject<{
239
+ id: z.ZodUUID;
240
+ workspaceId: z.core.$ZodBranded<z.ZodUUID, "WorkspaceId", "out">;
241
+ assetId: z.ZodUUID;
242
+ summary: z.ZodString;
243
+ detail: z.ZodNullable<z.ZodString>;
244
+ vendor: z.ZodNullable<z.ZodString>;
245
+ costMinor: z.ZodNullable<z.ZodNumber>;
246
+ currency: z.ZodNullable<z.ZodString>;
247
+ sentOn: z.ZodString;
248
+ returnedOn: z.ZodNullable<z.ZodString>;
249
+ createdBy: z.ZodNullable<z.ZodUUID>;
250
+ createdAt: z.ZodString;
251
+ updatedAt: z.ZodString;
252
+ assetCode: z.ZodString;
253
+ assetName: z.ZodString;
254
+ }, z.core.$strip>;
255
+ export type RepairListItem = z.infer<typeof RepairListItem>;
256
+ /**
257
+ * Everything a person can say about a repair.
258
+ *
259
+ * **No field here carries `.default()`, for the reason `AssetInput` spells out**: `update` is built
260
+ * from `.partial()`, and `.partial()` does not strip a default — zod still substitutes it for a key
261
+ * the request never sent, so a patch that renames a repair would silently re-date it. `sentOn` is
262
+ * optional rather than defaulted for the same reason; `repairs.create` fills today's date on the
263
+ * server, which is the only clock this module trusts.
264
+ */
265
+ export declare const RepairInput: z.ZodObject<{
266
+ summary: z.ZodString;
267
+ detail: z.ZodOptional<z.ZodNullable<z.ZodString>>;
268
+ vendor: z.ZodOptional<z.ZodNullable<z.ZodString>>;
269
+ costMinor: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
270
+ currency: z.ZodOptional<z.ZodNullable<z.ZodString>>;
271
+ sentOn: z.ZodOptional<z.ZodISODate>;
272
+ }, z.core.$strip>;
273
+ export type RepairInput = z.infer<typeof RepairInput>;
274
+ export declare const RepairPatchInput: z.ZodObject<{
275
+ summary: z.ZodOptional<z.ZodString>;
276
+ detail: z.ZodOptional<z.ZodOptional<z.ZodNullable<z.ZodString>>>;
277
+ vendor: z.ZodOptional<z.ZodOptional<z.ZodNullable<z.ZodString>>>;
278
+ costMinor: z.ZodOptional<z.ZodOptional<z.ZodNullable<z.ZodNumber>>>;
279
+ currency: z.ZodOptional<z.ZodOptional<z.ZodNullable<z.ZodString>>>;
280
+ sentOn: z.ZodOptional<z.ZodOptional<z.ZodISODate>>;
281
+ }, z.core.$strip>;
282
+ export type RepairPatchInput = z.infer<typeof RepairPatchInput>;
283
+ /**
284
+ * What a repair mutation answers with: the repair, and the asset as it now stands.
285
+ *
286
+ * Both, for the reason `CustodyResult` carries both — sending an item away moves `assets.status`,
287
+ * and a screen that had to fetch the asset again afterwards would be reading a row somebody else
288
+ * may have changed in between.
289
+ */
290
+ export declare const RepairResult: z.ZodObject<{
291
+ repair: z.ZodObject<{
292
+ id: z.ZodUUID;
293
+ workspaceId: z.core.$ZodBranded<z.ZodUUID, "WorkspaceId", "out">;
294
+ assetId: z.ZodUUID;
295
+ summary: z.ZodString;
296
+ detail: z.ZodNullable<z.ZodString>;
297
+ vendor: z.ZodNullable<z.ZodString>;
298
+ costMinor: z.ZodNullable<z.ZodNumber>;
299
+ currency: z.ZodNullable<z.ZodString>;
300
+ sentOn: z.ZodString;
301
+ returnedOn: z.ZodNullable<z.ZodString>;
302
+ createdBy: z.ZodNullable<z.ZodUUID>;
303
+ createdAt: z.ZodString;
304
+ updatedAt: z.ZodString;
305
+ }, z.core.$strip>;
306
+ asset: z.ZodObject<{
307
+ id: z.ZodUUID;
308
+ workspaceId: z.core.$ZodBranded<z.ZodUUID, "WorkspaceId", "out">;
309
+ code: z.ZodString;
310
+ name: z.ZodString;
311
+ description: z.ZodString;
312
+ categoryId: z.ZodNullable<z.ZodUUID>;
313
+ status: z.ZodEnum<{
314
+ in_stock: "in_stock";
315
+ assigned: "assigned";
316
+ reserved: "reserved";
317
+ under_repair: "under_repair";
318
+ lost: "lost";
319
+ retired: "retired";
320
+ }>;
321
+ custodianUserId: z.ZodNullable<z.ZodUUID>;
322
+ custodySince: z.ZodNullable<z.ZodString>;
323
+ serialNumber: z.ZodNullable<z.ZodString>;
324
+ location: z.ZodNullable<z.ZodString>;
325
+ purchasedOn: z.ZodNullable<z.ZodString>;
326
+ purchasedFrom: z.ZodNullable<z.ZodString>;
327
+ priceMinor: z.ZodNullable<z.ZodNumber>;
328
+ currency: z.ZodNullable<z.ZodString>;
329
+ warrantyUntil: z.ZodNullable<z.ZodString>;
330
+ photoFileId: z.ZodNullable<z.ZodUUID>;
331
+ custom: z.ZodRecord<z.ZodString, z.ZodUnknown>;
332
+ createdAt: z.ZodString;
333
+ updatedAt: z.ZodString;
334
+ archivedAt: z.ZodNullable<z.ZodString>;
335
+ }, z.core.$strip>;
336
+ }, z.core.$strip>;
337
+ export type RepairResult = z.infer<typeof RepairResult>;
338
+ /**
339
+ * A file recorded against an asset — a receipt, a warranty card, a manual.
340
+ *
341
+ * **The bytes are core's, not this module's.** A module does not upload: the browser uploads through
342
+ * core's file service and hands this module the id it was given, and reading one back is a download
343
+ * URL core signs. All that lives here is the fact that this asset has that file, plus the name and
344
+ * size copied at attach time so a list can be drawn without asking core once per row.
345
+ *
346
+ * `repairId` is what separates "the invoice for the screen replacement" from "the purchase receipt":
347
+ * null means it belongs to the asset itself.
348
+ */
349
+ export declare const Attachment: z.ZodObject<{
350
+ id: z.ZodUUID;
351
+ workspaceId: z.core.$ZodBranded<z.ZodUUID, "WorkspaceId", "out">;
352
+ assetId: z.ZodUUID;
353
+ repairId: z.ZodNullable<z.ZodUUID>;
354
+ fileId: z.ZodUUID;
355
+ name: z.ZodString;
356
+ mimeType: z.ZodNullable<z.ZodString>;
357
+ size: z.ZodNullable<z.ZodNumber>;
358
+ uploadedBy: z.ZodNullable<z.ZodUUID>;
359
+ createdAt: z.ZodString;
360
+ }, z.core.$strip>;
361
+ export type Attachment = z.infer<typeof Attachment>;
362
+ /**
363
+ * The register in numbers: what a page's count line and a dashboard card need in one request.
364
+ *
365
+ * `total` counts what the list shows by default — live rows — and `archived` is beside it rather
366
+ * than inside it, because a count line that silently included archived rows would disagree with the
367
+ * list under it.
368
+ *
369
+ * **`outForRepair` is null when the workspace does not track repairs.** Zero would be a claim
370
+ * ("nothing is away"), and a workspace with the `repairs` capability off has not made that claim —
371
+ * it has no opinion at all. The screens show the tile only when a number arrives, which is the same
372
+ * rule as hiding the Repairs tab, expressed in the data instead of in a second capability lookup.
373
+ */
374
+ export declare const InventoryStats: z.ZodObject<{
375
+ total: z.ZodNumber;
376
+ archived: z.ZodNumber;
377
+ byStatus: z.ZodRecord<z.ZodEnum<{
378
+ in_stock: "in_stock";
379
+ assigned: "assigned";
380
+ reserved: "reserved";
381
+ under_repair: "under_repair";
382
+ lost: "lost";
383
+ retired: "retired";
384
+ }>, z.ZodNumber>;
385
+ outForRepair: z.ZodNullable<z.ZodNumber>;
386
+ unassigned: z.ZodNumber;
387
+ }, z.core.$strip>;
388
+ export type InventoryStats = z.infer<typeof InventoryStats>;
389
+ /**
390
+ * How a list is ordered, and therefore what a page cursor is a bookmark *into*.
391
+ *
392
+ * Exported rather than written inline in `router.ts` because the server validates a cursor against
393
+ * this same list: a bookmark issued under one sort is meaningless under another, and the only way
394
+ * to say so is for both halves to read one enum.
395
+ */
396
+ export declare const AssetSort: z.ZodEnum<{
397
+ code: "code";
398
+ name: "name";
399
+ recent: "recent";
400
+ }>;
401
+ export type AssetSort = z.infer<typeof AssetSort>;
402
+ /**
403
+ * Everything a person can say about an asset. `create` requires `name`; `update` takes any subset.
404
+ *
405
+ * **No field here carries `.default()`, and that is load-bearing.** `update` is built from
406
+ * `AssetInput.partial()`, and `.partial()` does not strip a default — it only wraps the field in
407
+ * `optional`, so zod still substitutes the default for a key the request never sent. `description`
408
+ * had `.default('')`, so `PATCH {assetId, name}` reached the handler as
409
+ * `{assetId, name, description: ''}`; the service correctly read a present value as "set it" and a
410
+ * rename destroyed the text, writing a bogus `description` diff into `asset_history` as it went.
411
+ * The care the service takes over `undefined` versus `null` is defeated one layer above it, here.
412
+ * A value `create` should fill in belongs on `AssetCreateInput` below, which is never partialled.
413
+ */
414
+ export declare const AssetInput: z.ZodObject<{
415
+ name: z.ZodString;
416
+ description: z.ZodOptional<z.ZodString>;
417
+ categoryId: z.ZodOptional<z.ZodNullable<z.ZodUUID>>;
418
+ serialNumber: z.ZodOptional<z.ZodNullable<z.ZodString>>;
419
+ location: z.ZodOptional<z.ZodNullable<z.ZodString>>;
420
+ purchasedFrom: z.ZodOptional<z.ZodNullable<z.ZodString>>;
421
+ purchasedOn: z.ZodOptional<z.ZodNullable<z.ZodISODate>>;
422
+ warrantyUntil: z.ZodOptional<z.ZodNullable<z.ZodISODate>>;
423
+ priceMinor: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
424
+ currency: z.ZodOptional<z.ZodNullable<z.ZodString>>;
425
+ photoFileId: z.ZodOptional<z.ZodNullable<z.ZodUUID>>;
426
+ }, z.core.$strip>;
427
+ export type AssetInput = z.infer<typeof AssetInput>;
428
+ /**
429
+ * What `create` accepts: the same fields, with the one value a new row may not go without.
430
+ *
431
+ * `description` is `not null` in the database, so a create with no description needs *something*.
432
+ * Defaulting it here rather than in `AssetInput` is what keeps `update` able to tell "leave it
433
+ * alone" from "clear it" — see the note above.
434
+ */
435
+ export declare const AssetCreateInput: z.ZodObject<{
436
+ name: z.ZodString;
437
+ categoryId: z.ZodOptional<z.ZodNullable<z.ZodUUID>>;
438
+ serialNumber: z.ZodOptional<z.ZodNullable<z.ZodString>>;
439
+ location: z.ZodOptional<z.ZodNullable<z.ZodString>>;
440
+ purchasedFrom: z.ZodOptional<z.ZodNullable<z.ZodString>>;
441
+ purchasedOn: z.ZodOptional<z.ZodNullable<z.ZodISODate>>;
442
+ warrantyUntil: z.ZodOptional<z.ZodNullable<z.ZodISODate>>;
443
+ priceMinor: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
444
+ currency: z.ZodOptional<z.ZodNullable<z.ZodString>>;
445
+ photoFileId: z.ZodOptional<z.ZodNullable<z.ZodUUID>>;
446
+ description: z.ZodDefault<z.ZodString>;
447
+ }, z.core.$strip>;
448
+ export type AssetCreateInput = z.infer<typeof AssetCreateInput>;
449
+ /** What `update` accepts: any subset, and nothing filled in for a key that never arrived. */
450
+ export declare const AssetPatchInput: z.ZodObject<{
451
+ name: z.ZodOptional<z.ZodString>;
452
+ description: z.ZodOptional<z.ZodOptional<z.ZodString>>;
453
+ categoryId: z.ZodOptional<z.ZodOptional<z.ZodNullable<z.ZodUUID>>>;
454
+ serialNumber: z.ZodOptional<z.ZodOptional<z.ZodNullable<z.ZodString>>>;
455
+ location: z.ZodOptional<z.ZodOptional<z.ZodNullable<z.ZodString>>>;
456
+ purchasedFrom: z.ZodOptional<z.ZodOptional<z.ZodNullable<z.ZodString>>>;
457
+ purchasedOn: z.ZodOptional<z.ZodOptional<z.ZodNullable<z.ZodISODate>>>;
458
+ warrantyUntil: z.ZodOptional<z.ZodOptional<z.ZodNullable<z.ZodISODate>>>;
459
+ priceMinor: z.ZodOptional<z.ZodOptional<z.ZodNullable<z.ZodNumber>>>;
460
+ currency: z.ZodOptional<z.ZodOptional<z.ZodNullable<z.ZodString>>>;
461
+ photoFileId: z.ZodOptional<z.ZodOptional<z.ZodNullable<z.ZodUUID>>>;
462
+ }, z.core.$strip>;
463
+ export type AssetPatchInput = z.infer<typeof AssetPatchInput>;
464
+ /** Shared by every workspace-scoped procedure, which is all of them. */
465
+ export declare const ws: z.ZodObject<{
466
+ workspaceId: z.core.$ZodBranded<z.ZodUUID, "WorkspaceId", "out">;
467
+ }, z.core.$strip>;
468
+ //# sourceMappingURL=models.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"models.d.ts","sourceRoot":"","sources":["../../src/contract/models.ts"],"names":[],"mappings":"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"}