@happyvertical/smrt-inventory 0.30.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/AGENTS.md +121 -0
- package/CLAUDE.md +1 -0
- package/LICENSE +7 -0
- package/README.md +213 -0
- package/dist/index.d.ts +557 -0
- package/dist/index.js +922 -0
- package/dist/index.js.map +1 -0
- package/dist/manifest.json +1023 -0
- package/dist/smrt-knowledge.json +618 -0
- package/dist/types.d.ts +55 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/package.json +64 -0
|
@@ -0,0 +1,618 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"generatedAt": "2026-06-23T01:11:19.193Z",
|
|
4
|
+
"packageName": "@happyvertical/smrt-inventory",
|
|
5
|
+
"packageVersion": "0.30.0",
|
|
6
|
+
"sourceManifestPath": "dist/manifest.json",
|
|
7
|
+
"agentDocPath": "AGENTS.md",
|
|
8
|
+
"sourceHashes": {
|
|
9
|
+
"manifest": "1034df0ec614f6bc57d31463c7809a28f4b18b28f6b44e71ba97c61ff1ba97e6",
|
|
10
|
+
"packageJson": "a5b4c5801c7d49f7279b2139413aad438a3c8bb9ad1f8aad077b8ab3a859b4c4",
|
|
11
|
+
"agents": "a771bf16d21cabbe43a77d5cb87ca7dedbf2e68d1928cf804cf4fefaad7a765f"
|
|
12
|
+
},
|
|
13
|
+
"exports": [
|
|
14
|
+
".",
|
|
15
|
+
"./manifest",
|
|
16
|
+
"./manifest.json"
|
|
17
|
+
],
|
|
18
|
+
"dependencies": {
|
|
19
|
+
"@happyvertical/logger": "catalog:",
|
|
20
|
+
"@happyvertical/smrt-core": "workspace:*",
|
|
21
|
+
"@happyvertical/smrt-tenancy": "workspace:*",
|
|
22
|
+
"@happyvertical/sql": "catalog:",
|
|
23
|
+
"@happyvertical/smrt-vitest": "workspace:*",
|
|
24
|
+
"@types/node": "25.0.9",
|
|
25
|
+
"typescript": "^5.9.3",
|
|
26
|
+
"vite": "^7.3.1",
|
|
27
|
+
"vitest": "^4.0.17"
|
|
28
|
+
},
|
|
29
|
+
"smrtDependencies": [
|
|
30
|
+
"@happyvertical/smrt-core",
|
|
31
|
+
"@happyvertical/smrt-tenancy",
|
|
32
|
+
"@happyvertical/smrt-vitest"
|
|
33
|
+
],
|
|
34
|
+
"sdkDependencies": [
|
|
35
|
+
"@happyvertical/logger",
|
|
36
|
+
"@happyvertical/sql"
|
|
37
|
+
],
|
|
38
|
+
"tags": [],
|
|
39
|
+
"risks": [],
|
|
40
|
+
"objects": [
|
|
41
|
+
{
|
|
42
|
+
"name": "InventoryLocationCollection",
|
|
43
|
+
"qualifiedName": "@happyvertical/smrt-inventory:InventoryLocationCollection",
|
|
44
|
+
"collection": "inventorylocations",
|
|
45
|
+
"tableName": "inventory_locations",
|
|
46
|
+
"packageName": "@happyvertical/smrt-inventory",
|
|
47
|
+
"extends": "SmrtCollection",
|
|
48
|
+
"fields": [],
|
|
49
|
+
"relationships": [],
|
|
50
|
+
"methods": [
|
|
51
|
+
"findActive",
|
|
52
|
+
"findByCode",
|
|
53
|
+
"findByKind",
|
|
54
|
+
"findByPlace"
|
|
55
|
+
],
|
|
56
|
+
"surfaces": [],
|
|
57
|
+
"relationshipFeatures": [
|
|
58
|
+
"uuidColumns"
|
|
59
|
+
],
|
|
60
|
+
"tags": [],
|
|
61
|
+
"risks": []
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"name": "StockLevelCollection",
|
|
65
|
+
"qualifiedName": "@happyvertical/smrt-inventory:StockLevelCollection",
|
|
66
|
+
"collection": "stocklevels",
|
|
67
|
+
"tableName": "inventory_stock_levels",
|
|
68
|
+
"packageName": "@happyvertical/smrt-inventory",
|
|
69
|
+
"extends": "SmrtCollection",
|
|
70
|
+
"fields": [],
|
|
71
|
+
"relationships": [],
|
|
72
|
+
"methods": [
|
|
73
|
+
"findByLocation",
|
|
74
|
+
"findBySku",
|
|
75
|
+
"getLevel",
|
|
76
|
+
"totalForLocation",
|
|
77
|
+
"totalForSku"
|
|
78
|
+
],
|
|
79
|
+
"surfaces": [],
|
|
80
|
+
"relationshipFeatures": [
|
|
81
|
+
"uuidColumns"
|
|
82
|
+
],
|
|
83
|
+
"tags": [],
|
|
84
|
+
"risks": []
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
"name": "StockMovementCollection",
|
|
88
|
+
"qualifiedName": "@happyvertical/smrt-inventory:StockMovementCollection",
|
|
89
|
+
"collection": "stockmovements",
|
|
90
|
+
"tableName": "inventory_stock_movements",
|
|
91
|
+
"packageName": "@happyvertical/smrt-inventory",
|
|
92
|
+
"extends": "SmrtCollection",
|
|
93
|
+
"fields": [],
|
|
94
|
+
"relationships": [],
|
|
95
|
+
"methods": [
|
|
96
|
+
"findByLocation",
|
|
97
|
+
"findByReason",
|
|
98
|
+
"findBySku",
|
|
99
|
+
"findBySource"
|
|
100
|
+
],
|
|
101
|
+
"surfaces": [],
|
|
102
|
+
"relationshipFeatures": [
|
|
103
|
+
"uuidColumns"
|
|
104
|
+
],
|
|
105
|
+
"tags": [],
|
|
106
|
+
"risks": []
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"name": "InventoryLocation",
|
|
110
|
+
"qualifiedName": "@happyvertical/smrt-inventory:InventoryLocation",
|
|
111
|
+
"collection": "inventorylocations",
|
|
112
|
+
"tableName": "inventory_locations",
|
|
113
|
+
"packageName": "@happyvertical/smrt-inventory",
|
|
114
|
+
"extends": "SmrtObject",
|
|
115
|
+
"fields": [
|
|
116
|
+
{
|
|
117
|
+
"name": "tenantId",
|
|
118
|
+
"type": "text",
|
|
119
|
+
"required": false,
|
|
120
|
+
"columnType": "UUID"
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
"name": "code",
|
|
124
|
+
"type": "text",
|
|
125
|
+
"required": true,
|
|
126
|
+
"columnType": "TEXT"
|
|
127
|
+
},
|
|
128
|
+
{
|
|
129
|
+
"name": "name",
|
|
130
|
+
"type": "text",
|
|
131
|
+
"required": false,
|
|
132
|
+
"columnType": "TEXT"
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
"name": "kind",
|
|
136
|
+
"type": "text",
|
|
137
|
+
"required": false,
|
|
138
|
+
"columnType": "TEXT"
|
|
139
|
+
},
|
|
140
|
+
{
|
|
141
|
+
"name": "placeId",
|
|
142
|
+
"type": "text",
|
|
143
|
+
"required": false,
|
|
144
|
+
"columnType": "TEXT"
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
"name": "active",
|
|
148
|
+
"type": "boolean",
|
|
149
|
+
"required": false,
|
|
150
|
+
"columnType": "BOOLEAN"
|
|
151
|
+
}
|
|
152
|
+
],
|
|
153
|
+
"relationships": [],
|
|
154
|
+
"methods": [],
|
|
155
|
+
"surfaces": [
|
|
156
|
+
{
|
|
157
|
+
"kind": "api",
|
|
158
|
+
"name": "inventorylocations.list",
|
|
159
|
+
"operation": "list",
|
|
160
|
+
"objectName": "@happyvertical/smrt-inventory:InventoryLocation",
|
|
161
|
+
"path": "/inventorylocations",
|
|
162
|
+
"method": "GET"
|
|
163
|
+
},
|
|
164
|
+
{
|
|
165
|
+
"kind": "api",
|
|
166
|
+
"name": "inventorylocations.get",
|
|
167
|
+
"operation": "get",
|
|
168
|
+
"objectName": "@happyvertical/smrt-inventory:InventoryLocation",
|
|
169
|
+
"path": "/inventorylocations/[id]",
|
|
170
|
+
"method": "GET"
|
|
171
|
+
},
|
|
172
|
+
{
|
|
173
|
+
"kind": "api",
|
|
174
|
+
"name": "inventorylocations.create",
|
|
175
|
+
"operation": "create",
|
|
176
|
+
"objectName": "@happyvertical/smrt-inventory:InventoryLocation",
|
|
177
|
+
"path": "/inventorylocations",
|
|
178
|
+
"method": "POST"
|
|
179
|
+
},
|
|
180
|
+
{
|
|
181
|
+
"kind": "api",
|
|
182
|
+
"name": "inventorylocations.update",
|
|
183
|
+
"operation": "update",
|
|
184
|
+
"objectName": "@happyvertical/smrt-inventory:InventoryLocation",
|
|
185
|
+
"path": "/inventorylocations/[id]",
|
|
186
|
+
"method": "PATCH"
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
"kind": "cli",
|
|
190
|
+
"name": "inventorylocation_list",
|
|
191
|
+
"operation": "list",
|
|
192
|
+
"objectName": "@happyvertical/smrt-inventory:InventoryLocation"
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
"kind": "cli",
|
|
196
|
+
"name": "inventorylocation_get",
|
|
197
|
+
"operation": "get",
|
|
198
|
+
"objectName": "@happyvertical/smrt-inventory:InventoryLocation"
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
"kind": "cli",
|
|
202
|
+
"name": "inventorylocation_create",
|
|
203
|
+
"operation": "create",
|
|
204
|
+
"objectName": "@happyvertical/smrt-inventory:InventoryLocation"
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
"kind": "cli",
|
|
208
|
+
"name": "inventorylocation_update",
|
|
209
|
+
"operation": "update",
|
|
210
|
+
"objectName": "@happyvertical/smrt-inventory:InventoryLocation"
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
"kind": "cli",
|
|
214
|
+
"name": "inventorylocation_delete",
|
|
215
|
+
"operation": "delete",
|
|
216
|
+
"objectName": "@happyvertical/smrt-inventory:InventoryLocation"
|
|
217
|
+
},
|
|
218
|
+
{
|
|
219
|
+
"kind": "mcp",
|
|
220
|
+
"name": "inventorylocation_list",
|
|
221
|
+
"operation": "list",
|
|
222
|
+
"objectName": "@happyvertical/smrt-inventory:InventoryLocation"
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
"kind": "mcp",
|
|
226
|
+
"name": "inventorylocation_get",
|
|
227
|
+
"operation": "get",
|
|
228
|
+
"objectName": "@happyvertical/smrt-inventory:InventoryLocation"
|
|
229
|
+
}
|
|
230
|
+
],
|
|
231
|
+
"relationshipFeatures": [
|
|
232
|
+
"uuidColumns"
|
|
233
|
+
],
|
|
234
|
+
"tags": [],
|
|
235
|
+
"risks": []
|
|
236
|
+
},
|
|
237
|
+
{
|
|
238
|
+
"name": "StockLevel",
|
|
239
|
+
"qualifiedName": "@happyvertical/smrt-inventory:StockLevel",
|
|
240
|
+
"collection": "stocklevels",
|
|
241
|
+
"tableName": "inventory_stock_levels",
|
|
242
|
+
"packageName": "@happyvertical/smrt-inventory",
|
|
243
|
+
"extends": "SmrtObject",
|
|
244
|
+
"fields": [
|
|
245
|
+
{
|
|
246
|
+
"name": "tenantId",
|
|
247
|
+
"type": "text",
|
|
248
|
+
"required": false,
|
|
249
|
+
"columnType": "UUID"
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
"name": "skuId",
|
|
253
|
+
"type": "text",
|
|
254
|
+
"required": true,
|
|
255
|
+
"columnType": "TEXT"
|
|
256
|
+
},
|
|
257
|
+
{
|
|
258
|
+
"name": "locationId",
|
|
259
|
+
"type": "text",
|
|
260
|
+
"required": true,
|
|
261
|
+
"columnType": "TEXT"
|
|
262
|
+
},
|
|
263
|
+
{
|
|
264
|
+
"name": "state",
|
|
265
|
+
"type": "text",
|
|
266
|
+
"required": true,
|
|
267
|
+
"columnType": "TEXT"
|
|
268
|
+
},
|
|
269
|
+
{
|
|
270
|
+
"name": "qty",
|
|
271
|
+
"type": "decimal",
|
|
272
|
+
"required": false,
|
|
273
|
+
"columnType": "REAL"
|
|
274
|
+
}
|
|
275
|
+
],
|
|
276
|
+
"relationships": [],
|
|
277
|
+
"methods": [],
|
|
278
|
+
"surfaces": [
|
|
279
|
+
{
|
|
280
|
+
"kind": "api",
|
|
281
|
+
"name": "stocklevels.list",
|
|
282
|
+
"operation": "list",
|
|
283
|
+
"objectName": "@happyvertical/smrt-inventory:StockLevel",
|
|
284
|
+
"path": "/stocklevels",
|
|
285
|
+
"method": "GET"
|
|
286
|
+
},
|
|
287
|
+
{
|
|
288
|
+
"kind": "api",
|
|
289
|
+
"name": "stocklevels.get",
|
|
290
|
+
"operation": "get",
|
|
291
|
+
"objectName": "@happyvertical/smrt-inventory:StockLevel",
|
|
292
|
+
"path": "/stocklevels/[id]",
|
|
293
|
+
"method": "GET"
|
|
294
|
+
},
|
|
295
|
+
{
|
|
296
|
+
"kind": "cli",
|
|
297
|
+
"name": "stocklevel_list",
|
|
298
|
+
"operation": "list",
|
|
299
|
+
"objectName": "@happyvertical/smrt-inventory:StockLevel"
|
|
300
|
+
},
|
|
301
|
+
{
|
|
302
|
+
"kind": "cli",
|
|
303
|
+
"name": "stocklevel_get",
|
|
304
|
+
"operation": "get",
|
|
305
|
+
"objectName": "@happyvertical/smrt-inventory:StockLevel"
|
|
306
|
+
},
|
|
307
|
+
{
|
|
308
|
+
"kind": "mcp",
|
|
309
|
+
"name": "stocklevel_list",
|
|
310
|
+
"operation": "list",
|
|
311
|
+
"objectName": "@happyvertical/smrt-inventory:StockLevel"
|
|
312
|
+
},
|
|
313
|
+
{
|
|
314
|
+
"kind": "mcp",
|
|
315
|
+
"name": "stocklevel_get",
|
|
316
|
+
"operation": "get",
|
|
317
|
+
"objectName": "@happyvertical/smrt-inventory:StockLevel"
|
|
318
|
+
}
|
|
319
|
+
],
|
|
320
|
+
"relationshipFeatures": [
|
|
321
|
+
"uuidColumns"
|
|
322
|
+
],
|
|
323
|
+
"tags": [],
|
|
324
|
+
"risks": []
|
|
325
|
+
},
|
|
326
|
+
{
|
|
327
|
+
"name": "StockMovement",
|
|
328
|
+
"qualifiedName": "@happyvertical/smrt-inventory:StockMovement",
|
|
329
|
+
"collection": "stockmovements",
|
|
330
|
+
"tableName": "inventory_stock_movements",
|
|
331
|
+
"packageName": "@happyvertical/smrt-inventory",
|
|
332
|
+
"extends": "SmrtObject",
|
|
333
|
+
"fields": [
|
|
334
|
+
{
|
|
335
|
+
"name": "tenantId",
|
|
336
|
+
"type": "text",
|
|
337
|
+
"required": false,
|
|
338
|
+
"columnType": "UUID"
|
|
339
|
+
},
|
|
340
|
+
{
|
|
341
|
+
"name": "skuId",
|
|
342
|
+
"type": "text",
|
|
343
|
+
"required": true,
|
|
344
|
+
"columnType": "TEXT"
|
|
345
|
+
},
|
|
346
|
+
{
|
|
347
|
+
"name": "locationId",
|
|
348
|
+
"type": "text",
|
|
349
|
+
"required": true,
|
|
350
|
+
"columnType": "TEXT"
|
|
351
|
+
},
|
|
352
|
+
{
|
|
353
|
+
"name": "fromState",
|
|
354
|
+
"type": "text",
|
|
355
|
+
"required": false,
|
|
356
|
+
"columnType": "TEXT"
|
|
357
|
+
},
|
|
358
|
+
{
|
|
359
|
+
"name": "toState",
|
|
360
|
+
"type": "text",
|
|
361
|
+
"required": false,
|
|
362
|
+
"columnType": "TEXT"
|
|
363
|
+
},
|
|
364
|
+
{
|
|
365
|
+
"name": "qty",
|
|
366
|
+
"type": "decimal",
|
|
367
|
+
"required": false,
|
|
368
|
+
"columnType": "REAL"
|
|
369
|
+
},
|
|
370
|
+
{
|
|
371
|
+
"name": "reasonCode",
|
|
372
|
+
"type": "text",
|
|
373
|
+
"required": true,
|
|
374
|
+
"columnType": "TEXT"
|
|
375
|
+
},
|
|
376
|
+
{
|
|
377
|
+
"name": "sourceType",
|
|
378
|
+
"type": "text",
|
|
379
|
+
"required": false,
|
|
380
|
+
"columnType": "TEXT"
|
|
381
|
+
},
|
|
382
|
+
{
|
|
383
|
+
"name": "sourceId",
|
|
384
|
+
"type": "text",
|
|
385
|
+
"required": false,
|
|
386
|
+
"columnType": "TEXT"
|
|
387
|
+
},
|
|
388
|
+
{
|
|
389
|
+
"name": "note",
|
|
390
|
+
"type": "text",
|
|
391
|
+
"required": false,
|
|
392
|
+
"columnType": "TEXT"
|
|
393
|
+
},
|
|
394
|
+
{
|
|
395
|
+
"name": "occurredAt",
|
|
396
|
+
"type": "datetime",
|
|
397
|
+
"required": false,
|
|
398
|
+
"columnType": "TIMESTAMP"
|
|
399
|
+
}
|
|
400
|
+
],
|
|
401
|
+
"relationships": [],
|
|
402
|
+
"methods": [],
|
|
403
|
+
"surfaces": [
|
|
404
|
+
{
|
|
405
|
+
"kind": "api",
|
|
406
|
+
"name": "stockmovements.list",
|
|
407
|
+
"operation": "list",
|
|
408
|
+
"objectName": "@happyvertical/smrt-inventory:StockMovement",
|
|
409
|
+
"path": "/stockmovements",
|
|
410
|
+
"method": "GET"
|
|
411
|
+
},
|
|
412
|
+
{
|
|
413
|
+
"kind": "api",
|
|
414
|
+
"name": "stockmovements.get",
|
|
415
|
+
"operation": "get",
|
|
416
|
+
"objectName": "@happyvertical/smrt-inventory:StockMovement",
|
|
417
|
+
"path": "/stockmovements/[id]",
|
|
418
|
+
"method": "GET"
|
|
419
|
+
},
|
|
420
|
+
{
|
|
421
|
+
"kind": "cli",
|
|
422
|
+
"name": "stockmovement_list",
|
|
423
|
+
"operation": "list",
|
|
424
|
+
"objectName": "@happyvertical/smrt-inventory:StockMovement"
|
|
425
|
+
},
|
|
426
|
+
{
|
|
427
|
+
"kind": "cli",
|
|
428
|
+
"name": "stockmovement_get",
|
|
429
|
+
"operation": "get",
|
|
430
|
+
"objectName": "@happyvertical/smrt-inventory:StockMovement"
|
|
431
|
+
},
|
|
432
|
+
{
|
|
433
|
+
"kind": "mcp",
|
|
434
|
+
"name": "stockmovement_list",
|
|
435
|
+
"operation": "list",
|
|
436
|
+
"objectName": "@happyvertical/smrt-inventory:StockMovement"
|
|
437
|
+
},
|
|
438
|
+
{
|
|
439
|
+
"kind": "mcp",
|
|
440
|
+
"name": "stockmovement_get",
|
|
441
|
+
"operation": "get",
|
|
442
|
+
"objectName": "@happyvertical/smrt-inventory:StockMovement"
|
|
443
|
+
}
|
|
444
|
+
],
|
|
445
|
+
"relationshipFeatures": [
|
|
446
|
+
"uuidColumns"
|
|
447
|
+
],
|
|
448
|
+
"tags": [],
|
|
449
|
+
"risks": []
|
|
450
|
+
}
|
|
451
|
+
],
|
|
452
|
+
"surfaces": [
|
|
453
|
+
{
|
|
454
|
+
"kind": "api",
|
|
455
|
+
"name": "inventorylocations.list",
|
|
456
|
+
"operation": "list",
|
|
457
|
+
"objectName": "@happyvertical/smrt-inventory:InventoryLocation",
|
|
458
|
+
"path": "/inventorylocations",
|
|
459
|
+
"method": "GET"
|
|
460
|
+
},
|
|
461
|
+
{
|
|
462
|
+
"kind": "api",
|
|
463
|
+
"name": "inventorylocations.get",
|
|
464
|
+
"operation": "get",
|
|
465
|
+
"objectName": "@happyvertical/smrt-inventory:InventoryLocation",
|
|
466
|
+
"path": "/inventorylocations/[id]",
|
|
467
|
+
"method": "GET"
|
|
468
|
+
},
|
|
469
|
+
{
|
|
470
|
+
"kind": "api",
|
|
471
|
+
"name": "inventorylocations.create",
|
|
472
|
+
"operation": "create",
|
|
473
|
+
"objectName": "@happyvertical/smrt-inventory:InventoryLocation",
|
|
474
|
+
"path": "/inventorylocations",
|
|
475
|
+
"method": "POST"
|
|
476
|
+
},
|
|
477
|
+
{
|
|
478
|
+
"kind": "api",
|
|
479
|
+
"name": "inventorylocations.update",
|
|
480
|
+
"operation": "update",
|
|
481
|
+
"objectName": "@happyvertical/smrt-inventory:InventoryLocation",
|
|
482
|
+
"path": "/inventorylocations/[id]",
|
|
483
|
+
"method": "PATCH"
|
|
484
|
+
},
|
|
485
|
+
{
|
|
486
|
+
"kind": "cli",
|
|
487
|
+
"name": "inventorylocation_list",
|
|
488
|
+
"operation": "list",
|
|
489
|
+
"objectName": "@happyvertical/smrt-inventory:InventoryLocation"
|
|
490
|
+
},
|
|
491
|
+
{
|
|
492
|
+
"kind": "cli",
|
|
493
|
+
"name": "inventorylocation_get",
|
|
494
|
+
"operation": "get",
|
|
495
|
+
"objectName": "@happyvertical/smrt-inventory:InventoryLocation"
|
|
496
|
+
},
|
|
497
|
+
{
|
|
498
|
+
"kind": "cli",
|
|
499
|
+
"name": "inventorylocation_create",
|
|
500
|
+
"operation": "create",
|
|
501
|
+
"objectName": "@happyvertical/smrt-inventory:InventoryLocation"
|
|
502
|
+
},
|
|
503
|
+
{
|
|
504
|
+
"kind": "cli",
|
|
505
|
+
"name": "inventorylocation_update",
|
|
506
|
+
"operation": "update",
|
|
507
|
+
"objectName": "@happyvertical/smrt-inventory:InventoryLocation"
|
|
508
|
+
},
|
|
509
|
+
{
|
|
510
|
+
"kind": "cli",
|
|
511
|
+
"name": "inventorylocation_delete",
|
|
512
|
+
"operation": "delete",
|
|
513
|
+
"objectName": "@happyvertical/smrt-inventory:InventoryLocation"
|
|
514
|
+
},
|
|
515
|
+
{
|
|
516
|
+
"kind": "mcp",
|
|
517
|
+
"name": "inventorylocation_list",
|
|
518
|
+
"operation": "list",
|
|
519
|
+
"objectName": "@happyvertical/smrt-inventory:InventoryLocation"
|
|
520
|
+
},
|
|
521
|
+
{
|
|
522
|
+
"kind": "mcp",
|
|
523
|
+
"name": "inventorylocation_get",
|
|
524
|
+
"operation": "get",
|
|
525
|
+
"objectName": "@happyvertical/smrt-inventory:InventoryLocation"
|
|
526
|
+
},
|
|
527
|
+
{
|
|
528
|
+
"kind": "api",
|
|
529
|
+
"name": "stocklevels.list",
|
|
530
|
+
"operation": "list",
|
|
531
|
+
"objectName": "@happyvertical/smrt-inventory:StockLevel",
|
|
532
|
+
"path": "/stocklevels",
|
|
533
|
+
"method": "GET"
|
|
534
|
+
},
|
|
535
|
+
{
|
|
536
|
+
"kind": "api",
|
|
537
|
+
"name": "stocklevels.get",
|
|
538
|
+
"operation": "get",
|
|
539
|
+
"objectName": "@happyvertical/smrt-inventory:StockLevel",
|
|
540
|
+
"path": "/stocklevels/[id]",
|
|
541
|
+
"method": "GET"
|
|
542
|
+
},
|
|
543
|
+
{
|
|
544
|
+
"kind": "cli",
|
|
545
|
+
"name": "stocklevel_list",
|
|
546
|
+
"operation": "list",
|
|
547
|
+
"objectName": "@happyvertical/smrt-inventory:StockLevel"
|
|
548
|
+
},
|
|
549
|
+
{
|
|
550
|
+
"kind": "cli",
|
|
551
|
+
"name": "stocklevel_get",
|
|
552
|
+
"operation": "get",
|
|
553
|
+
"objectName": "@happyvertical/smrt-inventory:StockLevel"
|
|
554
|
+
},
|
|
555
|
+
{
|
|
556
|
+
"kind": "mcp",
|
|
557
|
+
"name": "stocklevel_list",
|
|
558
|
+
"operation": "list",
|
|
559
|
+
"objectName": "@happyvertical/smrt-inventory:StockLevel"
|
|
560
|
+
},
|
|
561
|
+
{
|
|
562
|
+
"kind": "mcp",
|
|
563
|
+
"name": "stocklevel_get",
|
|
564
|
+
"operation": "get",
|
|
565
|
+
"objectName": "@happyvertical/smrt-inventory:StockLevel"
|
|
566
|
+
},
|
|
567
|
+
{
|
|
568
|
+
"kind": "api",
|
|
569
|
+
"name": "stockmovements.list",
|
|
570
|
+
"operation": "list",
|
|
571
|
+
"objectName": "@happyvertical/smrt-inventory:StockMovement",
|
|
572
|
+
"path": "/stockmovements",
|
|
573
|
+
"method": "GET"
|
|
574
|
+
},
|
|
575
|
+
{
|
|
576
|
+
"kind": "api",
|
|
577
|
+
"name": "stockmovements.get",
|
|
578
|
+
"operation": "get",
|
|
579
|
+
"objectName": "@happyvertical/smrt-inventory:StockMovement",
|
|
580
|
+
"path": "/stockmovements/[id]",
|
|
581
|
+
"method": "GET"
|
|
582
|
+
},
|
|
583
|
+
{
|
|
584
|
+
"kind": "cli",
|
|
585
|
+
"name": "stockmovement_list",
|
|
586
|
+
"operation": "list",
|
|
587
|
+
"objectName": "@happyvertical/smrt-inventory:StockMovement"
|
|
588
|
+
},
|
|
589
|
+
{
|
|
590
|
+
"kind": "cli",
|
|
591
|
+
"name": "stockmovement_get",
|
|
592
|
+
"operation": "get",
|
|
593
|
+
"objectName": "@happyvertical/smrt-inventory:StockMovement"
|
|
594
|
+
},
|
|
595
|
+
{
|
|
596
|
+
"kind": "mcp",
|
|
597
|
+
"name": "stockmovement_list",
|
|
598
|
+
"operation": "list",
|
|
599
|
+
"objectName": "@happyvertical/smrt-inventory:StockMovement"
|
|
600
|
+
},
|
|
601
|
+
{
|
|
602
|
+
"kind": "mcp",
|
|
603
|
+
"name": "stockmovement_get",
|
|
604
|
+
"operation": "get",
|
|
605
|
+
"objectName": "@happyvertical/smrt-inventory:StockMovement"
|
|
606
|
+
}
|
|
607
|
+
],
|
|
608
|
+
"prompts": [],
|
|
609
|
+
"relationshipsV2": {
|
|
610
|
+
"foreignKeyFields": 0,
|
|
611
|
+
"crossPackageRefFields": 0,
|
|
612
|
+
"junctionCollections": 0,
|
|
613
|
+
"hierarchicalObjects": 0,
|
|
614
|
+
"polymorphicAssociations": 0,
|
|
615
|
+
"uuidColumns": 9
|
|
616
|
+
},
|
|
617
|
+
"agentDoc": "# @happyvertical/smrt-inventory\n\nMulti-location stock tracking. Strictly industry-neutral — the same primitives serve apparel, furniture, automotive, CPG, electronics, and any other vertical that counts discrete units across locations.\n\n## Models\n\n| Model | Purpose |\n|---|---|\n| _(catalog shapes — `Product`, `Material`, `ProductVariant`, `Sku` — live in `@happyvertical/smrt-products`)_ | Sku is the smallest sellable / countable unit; its `attributes` JSON carries axis-value pins. ProductVariant is the per-product axis declaration. Import either from `@happyvertical/smrt-products` directly. |\n| `InventoryLocation` | Warehouse / factory / retail / in-transit / virtual. Open-ended `kind` string. Optional `placeId` references `@happyvertical/smrt-places`. `conflictColumns: ['code', 'tenant_id']`. |\n| `StockLevel` | Materialized `qty` for a `(skuId, locationId, state)` tuple. Upserted in place. **Mutated only by `StockService`.** States: `available`, `allocated`, `wip`, `qc_hold`, `damaged`. |\n| `StockMovement` | Append-only audit log. Every `StockService` mutation writes one (or two for `transfer`). `sourceType` + `sourceId` carry cross-package attribution. |\n\nAll three inventory models (`InventoryLocation`, `StockLevel`, `StockMovement`) use `@TenantScoped({ mode: 'optional' })` + nullable `tenantId` so they can be used either tenant-scoped or globally. The catalog shapes (`Product`, `Material`, `ProductVariant`, `Sku`) live in `@happyvertical/smrt-products` and carry their own tenant decoration there.\n\n## StockService — the only sanctioned way to mutate stock\n\n```typescript\nimport { createStockService } from '@happyvertical/smrt-inventory';\n\nconst service = await createStockService({ db });\nawait service.receive(skuId, locationId, qty, { sourceType, sourceId });\nawait service.reserve(skuId, locationId, qty, { sourceType, sourceId });\nawait service.release(skuId, locationId, qty, { sourceType, sourceId });\nawait service.fulfill(skuId, locationId, qty, { sourceType, sourceId });\nawait service.transfer(skuId, fromLocId, toLocId, qty, { sourceType, sourceId });\nawait service.adjust(skuId, locationId, delta, { sourceType, sourceId });\n```\n\n| Method | Behavior | Movement reason |\n|---|---|---|\n| `receive` | +qty available — purchase receipt, return, production produce | `receipt` |\n| `reserve` | available → allocated. Throws `InsufficientStockError` on overdraw | `reservation` |\n| `release` | allocated → available (order cancel) | `release` |\n| `fulfill` | -qty allocated. Stock leaves the building | `fulfillment` |\n| `transfer` | move stock between locations (writes two movements) | `transfer_out`, `transfer_in` |\n| `adjust` | signed delta — cycle counts and one-off corrections | `adjustment` |\n\nAll methods reject zero / negative / non-finite quantities except `adjust`, which accepts non-zero signed deltas. Negative deltas that would drive a state below zero throw `InsufficientStockError`.\n\n## Opt-in DispatchBus hooks\n\nOff by default. Wire them up explicitly in the application's `smrt.ts`:\n\n```typescript\nimport { installInventoryDispatchHandlers } from '@happyvertical/smrt-inventory';\n\nconst handlers = await installInventoryDispatchHandlers({\n dispatchBus: bus,\n db, // or stockService: existingService\n});\n```\n\nThis subscribes to:\n- `contract:created` → calls `service.reserve()` for every line inside one `stockService.withTransaction(...)`, attributed to `('Contract', payload.contractId)`\n- `fulfillment:shipped` → calls `service.fulfill()` for every line inside one `stockService.withTransaction(...)`, attributed to `('Fulfillment', payload.fulfillmentId)`\n\nBoth handlers are atomic across lines: a shortfall on line N rolls back lines 1..N-1 so the event is all-or-nothing. Without this guarantee, `DispatchBus` would only log the async handler error and a partially-reserved (or partially-fulfilled) contract would have no compensating event to fix it.\n\nPer-handler toggles: `installContractReserved`, `installFulfillmentShipped`. The `production_order:posted` hook is deliberately not installed here — it depends on the BOM model and ships in `@happyvertical/smrt-manufacturing` (issue #1250).\n\n## Schema migration (Phase 1 release)\n\nThe `Sku` model moved out of this package and into `@happyvertical/smrt-products`. Previously it lived in this package's `inventory_skus` table; it now lives in `product_skus` over there.\n\n**Upgrade procedure** for deployed consumers:\n\n1. **Let the framework create the destination table first.** Boot the new version once with `@happyvertical/smrt-products` registered in your `SmrtClassOptions`; the lazy `syncSchema` path will create `product_skus` with the right primary key, NOT NULL, UNIQUE (`code`, `tenant_id`), and indexes — they're derived from the `Sku` model decorators and would be stripped by a raw `CREATE TABLE AS SELECT`.\n\n2. **Idempotently copy rows across.** SQLite + Postgres:\n\n ```sql\n BEGIN;\n INSERT INTO product_skus (\n id, slug, context, created_at, updated_at,\n tenant_id, product_id, code, barcode, name,\n attributes, weight_grams, parent_sku_id, active\n )\n SELECT\n id, slug, context, created_at, updated_at,\n tenant_id, product_id, code, barcode, name,\n attributes, weight_grams, parent_sku_id, active\n FROM inventory_skus\n WHERE NOT EXISTS (\n SELECT 1 FROM product_skus p WHERE p.id = inventory_skus.id\n );\n COMMIT;\n ```\n\n3. **Drop the legacy table** once you've verified row counts match:\n\n ```sql\n DROP TABLE IF EXISTS inventory_skus;\n ```\n\n`StockLevel.skuId` and `StockMovement.skuId` carry plain string ids that still resolve to the same rows after the rename, so no inventory data has to move.\n\n## Gotchas\n\n- **Movements are append-only.** The materialized `StockLevel` row is derived state; the `StockMovement` ledger is the source of truth. Never let CRUD UIs expose update/delete on the movement table. If you find yourself wanting to \"fix\" a movement row, write a compensating `adjust()` call instead.\n- **Never call `StockLevel.create()` or `save()` directly.** Going around `StockService` silently desyncs the audit log and breaks cycle counts.\n- **Cross-industry constraint.** This package's vocabulary stays generic: `InventoryLocation`, `StockLevel`, `StockMovement`. Apparel-specific concepts (`Style`, `Makeup`, `Colorway`, fashion `Season`, tech-pack metadata) and their analogues in furniture / automotive / CPG live in the relevant template package, never here. PRs that introduce industry vocabulary should be rejected.\n- **Cross-package references are plain strings.** `skuId`, `placeId`, `sourceId` — all plain string ids, never `@foreignKey()`. Inventory's stock-motion logic only ever reads StockLevel/StockMovement; it doesn't follow `skuId` back to the catalog's Sku table, so the layering stays loose.\n- **`conflictColumns` include `tenant_id`** on `InventoryLocation` and `StockLevel`. NULL-matching semantics (`(code, NULL) IS NOT DISTINCT FROM (code, NULL)`) are handled by `@happyvertical/sql >= 0.74.0` natively, so two saves with the same `(code, NULL)` tuple correctly merge in place. Pass `nullsDistinct: true` at the sql layer to opt back into NULL-distinct semantics.\n- **Atomic per-method, transactional across composition.** Each `StockService` mutation (`receive` / `reserve` / `release` / `fulfill` / `transfer` / `adjust`) wraps every write in a single `db.transaction(...)` (via `@happyvertical/sql >= 0.74.0`). Partial failure rolls the whole call back — level writes and the matching `StockMovement` audit row commit together or not at all. `transfer` writes both legs (source decrement, destination increment, and both audit rows) inside one tx, so a failure mid-`transfer` is fully reverted.\n Callers composing multiple `StockService` calls into one logical unit (e.g. consuming materials line-by-line for a production order) should wrap them in `await stockService.withTransaction(async (tx) => { ... })` — `tx` is a tx-bound `StockService` with the same public API; mutation calls inside the callback share one transaction and either all commit or all roll back.\n If the underlying SQL adapter does not expose `transaction()` (extremely rare — all four built-in `@happyvertical/sql >= 0.74.0` adapters implement it), the service degrades to non-atomic serial writes and emits a one-time `console.warn`.\n- **Concurrent reservations: tightened, not bulletproof.** `@happyvertical/sql >= 0.74.0` serialises null-aware *upserts* via a per-key in-process lock (SQLite) or advisory lock (Postgres). That lock fixed the row-creation race (issue #1246) — two concurrent `create()` calls on the same conflict-column tuple no longer race the underlying `INSERT ... ON CONFLICT`. It does NOT serialise the read-modify-write compound that `reserve` / `fulfill` / `transfer` / `adjust` perform on an existing row: each method reads the current level (`SELECT`), computes the new value in JS, then writes it back (`UPDATE` via `save()` on the loaded row). The whole compound is inside one `db.transaction(...)` from round-3, so the level write and audit row commit together — but two concurrent transactions on the same `(skuId, locationId)` can each see the same starting balance, compute the same decrement, and double-spend. Awaited (serial) calls always behave correctly. Use a job queue (e.g. `@happyvertical/smrt-jobs`) or your own mutex when you need hard atomicity across concurrent callers. The full fix is `SELECT ... FOR UPDATE` inside the same transaction (Postgres) or upgrading the journal mode (SQLite); deferred until we see a real high-contention workload that warrants it.\n\n## Source attribution\n\nEvery `StockMovement` carries `sourceType` + `sourceId` so downstream queries can reconstruct \"what caused this movement\". Conventions used by the built-in dispatch handlers:\n\n| sourceType | Emitter | Note |\n|---|---|---|\n| `Contract` | `smrt-commerce` `contract:created` | All reservation/release/fulfilment legs caused by a contract |\n| `Fulfillment` | `smrt-commerce` `fulfillment:shipped` | Outbound shipment |\n| `PurchaseOrder` | (your code) | Inbound receipt |\n| `CycleCount` | (your code) | Adjustments from physical counts |\n| `TransferOrder` | (your code) | Both legs of a transfer |\n| `ProductionOrder` | `smrt-manufacturing` (issue #1250) | Materials consumed + finished goods produced |\n"
|
|
618
|
+
}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared types for @happyvertical/smrt-inventory.
|
|
3
|
+
*
|
|
4
|
+
* These are deliberately industry-neutral: the same vocabulary serves
|
|
5
|
+
* apparel, furniture, automotive, CPG, electronics, and any other domain
|
|
6
|
+
* that tracks countable units across locations.
|
|
7
|
+
*
|
|
8
|
+
* @packageDocumentation
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Open-ended classifier for an InventoryLocation. The framework does not
|
|
13
|
+
* special-case any value — pass whatever taxonomy your application needs.
|
|
14
|
+
*
|
|
15
|
+
* The strings listed here are conventions, not an exhaustive enum:
|
|
16
|
+
* - `warehouse` — fulfillment warehouse
|
|
17
|
+
* - `factory` — manufacturing site
|
|
18
|
+
* - `retail` — storefront / point-of-sale
|
|
19
|
+
* - `in_transit` — virtual location for stock that has left A but not yet
|
|
20
|
+
* arrived at B; balances `transfer()` semantics
|
|
21
|
+
* - `virtual` — any other non-physical bucket (returns staging, scrap,
|
|
22
|
+
* consignment pool)
|
|
23
|
+
*/
|
|
24
|
+
export declare type InventoryLocationKind = string;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Why a StockMovement was written.
|
|
28
|
+
*
|
|
29
|
+
* Each {@link StockService} method writes one movement with a `reasonCode`
|
|
30
|
+
* drawn from this list. Free-form `string` is also accepted so consumers
|
|
31
|
+
* can introduce vocabulary specific to their business (e.g. `'shrink'`,
|
|
32
|
+
* `'sample'`, `'consignment_out'`) without forking the package.
|
|
33
|
+
*/
|
|
34
|
+
export declare type StockMovementReason = 'receipt' | 'reservation' | 'release' | 'fulfillment' | 'transfer_out' | 'transfer_in' | 'adjustment' | 'production_consume' | 'production_produce' | (string & {});
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Logical state of a quantity of stock at a `(skuId, locationId)` pair.
|
|
38
|
+
*
|
|
39
|
+
* StockLevel rows are tuples of `(skuId, locationId, state)`, so a single
|
|
40
|
+
* SKU at a single location can simultaneously have non-zero quantities in
|
|
41
|
+
* several states (e.g. 50 available, 10 allocated, 3 damaged).
|
|
42
|
+
*
|
|
43
|
+
* - `available` — on hand and free to allocate.
|
|
44
|
+
* - `allocated` — reserved against a contract, order, or production plan;
|
|
45
|
+
* physically still on site but no longer free to sell.
|
|
46
|
+
* - `wip` — work-in-progress: consumed materials inside an active
|
|
47
|
+
* production order, not yet emitted as finished goods.
|
|
48
|
+
* - `qc_hold` — held pending quality control; not available to allocate
|
|
49
|
+
* or ship until released.
|
|
50
|
+
* - `damaged` — damaged or otherwise unsellable; kept on the books for
|
|
51
|
+
* shrinkage accounting until written off.
|
|
52
|
+
*/
|
|
53
|
+
export declare type StockState = 'available' | 'allocated' | 'wip' | 'qc_hold' | 'damaged';
|
|
54
|
+
|
|
55
|
+
export { }
|