@axova/shared 1.0.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 (112) hide show
  1. package/CONFIGURATION_GUIDE.md +1 -0
  2. package/README.md +384 -0
  3. package/SCHEMA_ORGANIZATION.md +209 -0
  4. package/dist/configs/index.d.ts +85 -0
  5. package/dist/configs/index.js +555 -0
  6. package/dist/events/kafka.d.ts +40 -0
  7. package/dist/events/kafka.js +311 -0
  8. package/dist/index.d.ts +13 -0
  9. package/dist/index.js +41 -0
  10. package/dist/interfaces/customer-events.d.ts +85 -0
  11. package/dist/interfaces/customer-events.js +2 -0
  12. package/dist/interfaces/inventory-events.d.ts +453 -0
  13. package/dist/interfaces/inventory-events.js +3 -0
  14. package/dist/interfaces/inventory-types.d.ts +894 -0
  15. package/dist/interfaces/inventory-types.js +3 -0
  16. package/dist/interfaces/order-events.d.ts +320 -0
  17. package/dist/interfaces/order-events.js +3 -0
  18. package/dist/lib/auditLogger.d.ts +162 -0
  19. package/dist/lib/auditLogger.js +626 -0
  20. package/dist/lib/authOrganization.d.ts +24 -0
  21. package/dist/lib/authOrganization.js +110 -0
  22. package/dist/lib/db.d.ts +6 -0
  23. package/dist/lib/db.js +88 -0
  24. package/dist/middleware/serviceAuth.d.ts +60 -0
  25. package/dist/middleware/serviceAuth.js +272 -0
  26. package/dist/middleware/storeOwnership.d.ts +15 -0
  27. package/dist/middleware/storeOwnership.js +156 -0
  28. package/dist/middleware/storeValidationMiddleware.d.ts +44 -0
  29. package/dist/middleware/storeValidationMiddleware.js +180 -0
  30. package/dist/middleware/userAuth.d.ts +27 -0
  31. package/dist/middleware/userAuth.js +218 -0
  32. package/dist/schemas/admin/admin-schema.d.ts +741 -0
  33. package/dist/schemas/admin/admin-schema.js +111 -0
  34. package/dist/schemas/ai-moderation/ai-moderation-schema.d.ts +648 -0
  35. package/dist/schemas/ai-moderation/ai-moderation-schema.js +88 -0
  36. package/dist/schemas/common/common-schemas.d.ts +436 -0
  37. package/dist/schemas/common/common-schemas.js +94 -0
  38. package/dist/schemas/compliance/compliance-schema.d.ts +3388 -0
  39. package/dist/schemas/compliance/compliance-schema.js +472 -0
  40. package/dist/schemas/compliance/kyc-schema.d.ts +2642 -0
  41. package/dist/schemas/compliance/kyc-schema.js +361 -0
  42. package/dist/schemas/customer/customer-schema.d.ts +2727 -0
  43. package/dist/schemas/customer/customer-schema.js +399 -0
  44. package/dist/schemas/index.d.ts +27 -0
  45. package/dist/schemas/index.js +138 -0
  46. package/dist/schemas/inventory/inventory-tables.d.ts +9476 -0
  47. package/dist/schemas/inventory/inventory-tables.js +1470 -0
  48. package/dist/schemas/inventory/lot-tables.d.ts +3281 -0
  49. package/dist/schemas/inventory/lot-tables.js +608 -0
  50. package/dist/schemas/order/order-schema.d.ts +5825 -0
  51. package/dist/schemas/order/order-schema.js +954 -0
  52. package/dist/schemas/product/discount-relations.d.ts +15 -0
  53. package/dist/schemas/product/discount-relations.js +34 -0
  54. package/dist/schemas/product/discount-schema.d.ts +1975 -0
  55. package/dist/schemas/product/discount-schema.js +297 -0
  56. package/dist/schemas/product/product-relations.d.ts +41 -0
  57. package/dist/schemas/product/product-relations.js +133 -0
  58. package/dist/schemas/product/product-schema.d.ts +4544 -0
  59. package/dist/schemas/product/product-schema.js +671 -0
  60. package/dist/schemas/store/store-audit-schema.d.ts +4135 -0
  61. package/dist/schemas/store/store-audit-schema.js +556 -0
  62. package/dist/schemas/store/store-schema.d.ts +3100 -0
  63. package/dist/schemas/store/store-schema.js +381 -0
  64. package/dist/schemas/store/store-settings-schema.d.ts +665 -0
  65. package/dist/schemas/store/store-settings-schema.js +141 -0
  66. package/dist/schemas/types.d.ts +50 -0
  67. package/dist/schemas/types.js +3 -0
  68. package/dist/types/events.d.ts +2396 -0
  69. package/dist/types/events.js +505 -0
  70. package/dist/utils/errorHandler.d.ts +12 -0
  71. package/dist/utils/errorHandler.js +36 -0
  72. package/dist/utils/subdomain.d.ts +6 -0
  73. package/dist/utils/subdomain.js +20 -0
  74. package/nul +8 -0
  75. package/package.json +43 -0
  76. package/src/configs/index.ts +654 -0
  77. package/src/events/kafka.ts +429 -0
  78. package/src/index.ts +26 -0
  79. package/src/interfaces/customer-events.ts +106 -0
  80. package/src/interfaces/inventory-events.ts +545 -0
  81. package/src/interfaces/inventory-types.ts +1004 -0
  82. package/src/interfaces/order-events.ts +381 -0
  83. package/src/lib/auditLogger.ts +1117 -0
  84. package/src/lib/authOrganization.ts +153 -0
  85. package/src/lib/db.ts +64 -0
  86. package/src/middleware/serviceAuth.ts +328 -0
  87. package/src/middleware/storeOwnership.ts +199 -0
  88. package/src/middleware/storeValidationMiddleware.ts +247 -0
  89. package/src/middleware/userAuth.ts +248 -0
  90. package/src/schemas/admin/admin-schema.ts +208 -0
  91. package/src/schemas/ai-moderation/ai-moderation-schema.ts +180 -0
  92. package/src/schemas/common/common-schemas.ts +108 -0
  93. package/src/schemas/compliance/compliance-schema.ts +927 -0
  94. package/src/schemas/compliance/kyc-schema.ts +649 -0
  95. package/src/schemas/customer/customer-schema.ts +576 -0
  96. package/src/schemas/index.ts +189 -0
  97. package/src/schemas/inventory/inventory-tables.ts +1927 -0
  98. package/src/schemas/inventory/lot-tables.ts +799 -0
  99. package/src/schemas/order/order-schema.ts +1400 -0
  100. package/src/schemas/product/discount-relations.ts +44 -0
  101. package/src/schemas/product/discount-schema.ts +464 -0
  102. package/src/schemas/product/product-relations.ts +187 -0
  103. package/src/schemas/product/product-schema.ts +955 -0
  104. package/src/schemas/store/ethiopian_business_api.md.resolved +212 -0
  105. package/src/schemas/store/store-audit-schema.ts +1257 -0
  106. package/src/schemas/store/store-schema.ts +661 -0
  107. package/src/schemas/store/store-settings-schema.ts +231 -0
  108. package/src/schemas/types.ts +67 -0
  109. package/src/types/events.ts +646 -0
  110. package/src/utils/errorHandler.ts +44 -0
  111. package/src/utils/subdomain.ts +19 -0
  112. package/tsconfig.json +21 -0
@@ -0,0 +1,1004 @@
1
+ // Comprehensive inventory management types and interfaces
2
+
3
+ import type {
4
+ BaseFilter,
5
+ DateRangeFilter,
6
+ LocationFilter,
7
+ StatusFilter,
8
+ } from "../schemas/types";
9
+
10
+ // =====================================================
11
+ // CORE INVENTORY TYPES
12
+ // =====================================================
13
+
14
+ export interface InventoryItem {
15
+ id: string;
16
+ tenantId: string;
17
+ storeId: string;
18
+ productId: string;
19
+ variantId: string;
20
+ sku: string;
21
+ locationId: string;
22
+ locationType: "warehouse" | "pos";
23
+ zoneId?: string;
24
+ binLocation?: string;
25
+ quantityAvailable: number;
26
+ quantityCommitted: number;
27
+ quantityReserved: number;
28
+ quantityIncoming: number;
29
+ quantityInTransit: number;
30
+ safetyStock: number;
31
+ cycleStock: number;
32
+ reorderPoint: number;
33
+ maxStock: number;
34
+ unitCost?: number;
35
+ averageCost?: number;
36
+ lastCost?: number;
37
+ trackingType: "simple" | "batch" | "serial";
38
+ expiryTracking: boolean;
39
+ serialNumberTracking: boolean;
40
+ createdAt: Date;
41
+ updatedAt: Date;
42
+ lastCountDate?: Date;
43
+ lastMovementDate?: Date;
44
+ notes?: string;
45
+ customAttributes?: Record<string, unknown>;
46
+ }
47
+
48
+ export interface CreateInventoryItemRequest {
49
+ productId: string;
50
+ variantId: string;
51
+ sku: string;
52
+ locationId: string;
53
+ locationType: "warehouse" | "pos";
54
+ zoneId?: string;
55
+ binLocation?: string;
56
+ initialQuantity: number;
57
+ safetyStock?: number;
58
+ reorderPoint?: number;
59
+ maxStock?: number;
60
+ unitCost?: number;
61
+ trackingType?: "simple" | "batch" | "serial";
62
+ expiryTracking?: boolean;
63
+ serialNumberTracking?: boolean;
64
+ notes?: string;
65
+ customAttributes?: Record<string, unknown>;
66
+ }
67
+
68
+ export interface UpdateInventoryItemRequest {
69
+ quantityAvailable?: number;
70
+ safetyStock?: number;
71
+ reorderPoint?: number;
72
+ maxStock?: number;
73
+ unitCost?: number;
74
+ notes?: string;
75
+ customAttributes?: Record<string, unknown>;
76
+ }
77
+
78
+ export interface InventoryFilter
79
+ extends BaseFilter,
80
+ DateRangeFilter,
81
+ StatusFilter,
82
+ LocationFilter {
83
+ productId?: string;
84
+ variantId?: string;
85
+ sku?: string;
86
+ skus?: string[];
87
+ trackingType?: "simple" | "batch" | "serial";
88
+ lowStock?: boolean;
89
+ outOfStock?: boolean;
90
+ hasAlerts?: boolean;
91
+ categoryId?: string;
92
+ }
93
+
94
+ export interface QuantityUpdate {
95
+ inventoryItemId: string;
96
+ quantityChange: number;
97
+ changeType: "adjustment" | "sale" | "return" | "transfer" | "cycle_count";
98
+ reason: string;
99
+ sourceTransactionId?: string;
100
+ batchNumber?: string;
101
+ serialNumbers?: string[];
102
+ }
103
+
104
+ // =====================================================
105
+ // WAREHOUSE TYPES
106
+ // =====================================================
107
+
108
+ export interface Warehouse {
109
+ id: string;
110
+ tenantId: string;
111
+ storeId: string;
112
+ name: string;
113
+ code: string;
114
+ description?: string;
115
+ address?: {
116
+ street: string;
117
+ city: string;
118
+ state: string;
119
+ country: string;
120
+ postalCode: string;
121
+ latitude?: number;
122
+ longitude?: number;
123
+ };
124
+ latitude?: number;
125
+ longitude?: number;
126
+ timeZone?: string;
127
+ totalCapacity?: number;
128
+ usedCapacity: number;
129
+ capacityUnit: "units" | "cubic_meters" | "pallets";
130
+ temperatureControlled: boolean;
131
+ minTemperature?: number;
132
+ maxTemperature?: number;
133
+ humidityControlled: boolean;
134
+ status: "active" | "inactive" | "maintenance" | "closed";
135
+ operationalHours?: Record<string, { open: string; close: string }>;
136
+ priority: number;
137
+ warehouseGroupId?: string;
138
+ managerId?: string;
139
+ contactEmail?: string;
140
+ contactPhone?: string;
141
+ allowNegativeStock: boolean;
142
+ autoReceiveTransfers: boolean;
143
+ requirePickConfirmation: boolean;
144
+ createdAt: Date;
145
+ updatedAt: Date;
146
+ customAttributes?: Record<string, unknown>;
147
+ }
148
+
149
+ export interface CreateWarehouseRequest {
150
+ name: string;
151
+ code: string;
152
+ description?: string;
153
+ address?: Warehouse["address"];
154
+ latitude?: number;
155
+ longitude?: number;
156
+ timeZone?: string;
157
+ totalCapacity?: number;
158
+ capacityUnit?: "units" | "cubic_meters" | "pallets";
159
+ temperatureControlled?: boolean;
160
+ minTemperature?: number;
161
+ maxTemperature?: number;
162
+ humidityControlled?: boolean;
163
+ operationalHours?: Record<string, { open: string; close: string }>;
164
+ priority?: number;
165
+ warehouseGroupId?: string;
166
+ managerId?: string;
167
+ contactEmail?: string;
168
+ contactPhone?: string;
169
+ allowNegativeStock?: boolean;
170
+ autoReceiveTransfers?: boolean;
171
+ requirePickConfirmation?: boolean;
172
+ customAttributes?: Record<string, unknown>;
173
+ }
174
+
175
+ export interface POSLocation {
176
+ id: string;
177
+ tenantId: string;
178
+ storeId: string;
179
+ name: string;
180
+ code: string;
181
+ description?: string;
182
+ address?: Warehouse["address"];
183
+ latitude?: number;
184
+ longitude?: number;
185
+ timeZone?: string;
186
+ status: "active" | "inactive" | "maintenance";
187
+ locationType: "retail_store" | "kiosk" | "popup" | "mobile";
188
+ businessHours?: Record<string, { open: string; close: string }>;
189
+ managerId?: string;
190
+ contactEmail?: string;
191
+ contactPhone?: string;
192
+ allowNegativeStock: boolean;
193
+ autoSyncInventory: boolean;
194
+ syncInterval: number;
195
+ offlineThreshold: number;
196
+ allowLocalPricing: boolean;
197
+ localPricingMarkup?: number;
198
+ lastSyncAt?: Date;
199
+ syncStatus: "synced" | "pending" | "error" | "offline";
200
+ pendingChanges: number;
201
+ createdAt: Date;
202
+ updatedAt: Date;
203
+ customAttributes?: Record<string, unknown>;
204
+ }
205
+
206
+ export interface CreatePOSLocationRequest {
207
+ name: string;
208
+ code: string;
209
+ description?: string;
210
+ address?: POSLocation["address"];
211
+ latitude?: number;
212
+ longitude?: number;
213
+ timeZone?: string;
214
+ locationType: "retail_store" | "kiosk" | "popup" | "mobile";
215
+ businessHours?: Record<string, { open: string; close: string }>;
216
+ managerId?: string;
217
+ contactEmail?: string;
218
+ contactPhone?: string;
219
+ allowNegativeStock?: boolean;
220
+ autoSyncInventory?: boolean;
221
+ syncInterval?: number;
222
+ offlineThreshold?: number;
223
+ allowLocalPricing?: boolean;
224
+ localPricingMarkup?: number;
225
+ customAttributes?: Record<string, unknown>;
226
+ }
227
+
228
+ // =====================================================
229
+ // BATCH TRACKING TYPES
230
+ // =====================================================
231
+
232
+ export interface BatchInfo {
233
+ id: string;
234
+ tenantId: string;
235
+ storeId: string;
236
+ batchNumber: string;
237
+ lotNumber?: string;
238
+ internalBatchId?: string;
239
+ productId: string;
240
+ variantId: string;
241
+ sku: string;
242
+ status: "active" | "quarantine" | "expired" | "recalled" | "depleted";
243
+ batchType: "production" | "purchase" | "transfer" | "adjustment";
244
+ manufactureDate?: Date;
245
+ receivedDate: Date;
246
+ expiryDate?: Date;
247
+ bestByDate?: Date;
248
+ sellByDate?: Date;
249
+ useByDate?: Date;
250
+ initialQuantity: number;
251
+ currentQuantity: number;
252
+ reservedQuantity: number;
253
+ committedQuantity: number;
254
+ unitCost?: number;
255
+ totalCost?: number;
256
+ averageCost?: number;
257
+ vendorId?: string;
258
+ vendorName?: string;
259
+ vendorBatchNumber?: string;
260
+ purchaseOrderNumber?: string;
261
+ qualityGrade?: string;
262
+ qualityNotes?: string;
263
+ certifications?: Array<{
264
+ type: string;
265
+ number: string;
266
+ issuedBy: string;
267
+ issuedDate: string;
268
+ expiryDate?: string;
269
+ }>;
270
+ originalLocationId: string;
271
+ currentLocationIds?: string[];
272
+ hasAlerts: boolean;
273
+ alertReasons?: string[];
274
+ quarantineReason?: string;
275
+ createdBy: string;
276
+ lastModifiedBy?: string;
277
+ createdAt: Date;
278
+ updatedAt: Date;
279
+ lastMovementAt?: Date;
280
+ notes?: string;
281
+ customAttributes?: Record<string, unknown>;
282
+ }
283
+
284
+ export interface CreateBatchRequest {
285
+ batchNumber: string;
286
+ lotNumber?: string;
287
+ productId: string;
288
+ variantId: string;
289
+ sku: string;
290
+ batchType: "production" | "purchase" | "transfer" | "adjustment";
291
+ manufactureDate?: Date;
292
+ receivedDate: Date;
293
+ expiryDate?: Date;
294
+ bestByDate?: Date;
295
+ sellByDate?: Date;
296
+ useByDate?: Date;
297
+ initialQuantity: number;
298
+ unitCost?: number;
299
+ vendorId?: string;
300
+ vendorName?: string;
301
+ vendorBatchNumber?: string;
302
+ purchaseOrderNumber?: string;
303
+ qualityGrade?: string;
304
+ qualityNotes?: string;
305
+ originalLocationId: string;
306
+ notes?: string;
307
+ customAttributes?: Record<string, unknown>;
308
+ }
309
+
310
+ export interface BatchFilter extends BaseFilter, DateRangeFilter, StatusFilter {
311
+ batchNumber?: string;
312
+ productId?: string;
313
+ sku?: string;
314
+ vendorId?: string;
315
+ expiringBefore?: Date;
316
+ hasAlerts?: boolean;
317
+ qualityGrade?: string;
318
+ }
319
+
320
+ // =====================================================
321
+ // CYCLE COUNT TYPES
322
+ // =====================================================
323
+
324
+ export interface CycleCount {
325
+ id: string;
326
+ tenantId: string;
327
+ storeId: string;
328
+ countNumber: string;
329
+ countName: string;
330
+ description?: string;
331
+ countType:
332
+ | "full_physical"
333
+ | "spot_check"
334
+ | "abc_analysis"
335
+ | "high_velocity"
336
+ | "low_velocity"
337
+ | "location_specific"
338
+ | "category_specific";
339
+ countMethod: "manual" | "barcode_assisted" | "rfid" | "automated";
340
+ locationId?: string;
341
+ locationType?: "warehouse" | "pos";
342
+ zoneIds?: string[];
343
+ binIds?: string[];
344
+ itemSelectionType:
345
+ | "all_items"
346
+ | "specific_skus"
347
+ | "category"
348
+ | "velocity_based"
349
+ | "value_based"
350
+ | "accuracy_based";
351
+ selectionCriteria?: {
352
+ categories?: string[];
353
+ skus?: string[];
354
+ productIds?: string[];
355
+ minValue?: number;
356
+ maxValue?: number;
357
+ velocityThreshold?: number;
358
+ accuracyThreshold?: number;
359
+ lastCountedBefore?: string;
360
+ };
361
+ scheduledDate: Date;
362
+ scheduledBy: string;
363
+ frequency?: "weekly" | "monthly" | "quarterly" | "annual" | "ad_hoc";
364
+ isRecurring: boolean;
365
+ status:
366
+ | "scheduled"
367
+ | "in_progress"
368
+ | "completed"
369
+ | "reconciled"
370
+ | "cancelled"
371
+ | "on_hold";
372
+ startedAt?: Date;
373
+ completedAt?: Date;
374
+ reconciledAt?: Date;
375
+ assignedTo?: string[];
376
+ supervisorId?: string;
377
+ totalItemsToCount?: number;
378
+ totalItemsCounted: number;
379
+ itemsWithDiscrepancies: number;
380
+ accuracyPercentage?: number;
381
+ totalVarianceValue?: number;
382
+ tolerancePercentage: number;
383
+ requiresApproval: boolean;
384
+ approvedBy?: string;
385
+ approvedAt?: Date;
386
+ reviewedBy?: string;
387
+ reviewedAt?: Date;
388
+ reviewNotes?: string;
389
+ allowBlindCounts: boolean;
390
+ requirePhotos: boolean;
391
+ allowPartialCounts: boolean;
392
+ autoReconcileWithinTolerance: boolean;
393
+ createdAt: Date;
394
+ updatedAt: Date;
395
+ notes?: string;
396
+ customAttributes?: Record<string, unknown>;
397
+ }
398
+
399
+ export interface CycleCountItem {
400
+ id: string;
401
+ tenantId: string;
402
+ storeId: string;
403
+ cycleCountId: string;
404
+ countNumber: string;
405
+ inventoryItemId: string;
406
+ productId: string;
407
+ variantId: string;
408
+ sku: string;
409
+ productName?: string;
410
+ locationId: string;
411
+ locationType: "warehouse" | "pos";
412
+ zoneId?: string;
413
+ binLocation?: string;
414
+ systemQuantity: number;
415
+ systemValue?: number;
416
+ unitCost?: number;
417
+ countedQuantity?: number;
418
+ countedValue?: number;
419
+ quantityVariance?: number;
420
+ valueVariance?: number;
421
+ variancePercentage?: number;
422
+ batchNumber?: string;
423
+ serialNumbers?: string[];
424
+ expiryDate?: Date;
425
+ countStatus:
426
+ | "pending"
427
+ | "counted"
428
+ | "recount_required"
429
+ | "discrepancy"
430
+ | "reconciled"
431
+ | "skipped";
432
+ countedBy?: string;
433
+ countedAt?: Date;
434
+ recountedBy?: string;
435
+ recountedAt?: Date;
436
+ recountQuantity?: number;
437
+ countMethod?: "manual" | "barcode" | "scale" | "estimated";
438
+ confidenceLevel?: "high" | "medium" | "low";
439
+ requiresRecount: boolean;
440
+ recountReason?: string;
441
+ conditionNotes?: string;
442
+ qualityIssues?: string[];
443
+ damageObserved: boolean;
444
+ isReconciled: boolean;
445
+ reconciledBy?: string;
446
+ reconciledAt?: Date;
447
+ reconciliationMethod?:
448
+ | "adjust_system"
449
+ | "accept_variance"
450
+ | "investigate"
451
+ | "recount";
452
+ createdAt: Date;
453
+ updatedAt: Date;
454
+ notes?: string;
455
+ }
456
+
457
+ export interface CreateCycleCountRequest {
458
+ countName: string;
459
+ description?: string;
460
+ countType: CycleCount["countType"];
461
+ countMethod: CycleCount["countMethod"];
462
+ locationId?: string;
463
+ locationType?: "warehouse" | "pos";
464
+ zoneIds?: string[];
465
+ binIds?: string[];
466
+ itemSelectionType: CycleCount["itemSelectionType"];
467
+ selectionCriteria?: CycleCount["selectionCriteria"];
468
+ scheduledDate: Date;
469
+ frequency?: CycleCount["frequency"];
470
+ isRecurring?: boolean;
471
+ assignedTo?: string[];
472
+ supervisorId?: string;
473
+ tolerancePercentage?: number;
474
+ requiresApproval?: boolean;
475
+ allowBlindCounts?: boolean;
476
+ requirePhotos?: boolean;
477
+ allowPartialCounts?: boolean;
478
+ autoReconcileWithinTolerance?: boolean;
479
+ notes?: string;
480
+ customAttributes?: Record<string, unknown>;
481
+ }
482
+
483
+ export interface CountItemRequest {
484
+ cycleCountItemId: string;
485
+ countedQuantity: number;
486
+ countMethod?: "manual" | "barcode" | "scale" | "estimated";
487
+ confidenceLevel?: "high" | "medium" | "low";
488
+ conditionNotes?: string;
489
+ qualityIssues?: string[];
490
+ damageObserved?: boolean;
491
+ notes?: string;
492
+ }
493
+
494
+ export interface CycleCountFilter
495
+ extends BaseFilter,
496
+ DateRangeFilter,
497
+ StatusFilter {
498
+ countType?: string;
499
+ locationId?: string;
500
+ scheduledBy?: string;
501
+ hasDiscrepancies?: boolean;
502
+ frequency?: string;
503
+ }
504
+
505
+ // =====================================================
506
+ // TRANSFER TYPES
507
+ // =====================================================
508
+
509
+ export interface TransferRequest {
510
+ sourceLocationId: string;
511
+ sourceLocationType: "warehouse" | "pos";
512
+ destinationLocationId: string;
513
+ destinationLocationType: "warehouse" | "pos";
514
+ transferType: "standard" | "urgent" | "emergency" | "rebalancing" | "return";
515
+ priority: "low" | "normal" | "high" | "urgent";
516
+ expectedShipDate?: Date;
517
+ expectedReceiveDate?: Date;
518
+ shippingMethod?: string;
519
+ notes?: string;
520
+ specialInstructions?: string;
521
+ requiresApproval?: boolean;
522
+ allowPartialTransfer?: boolean;
523
+ requiresInspection?: boolean;
524
+ items: Array<{
525
+ inventoryItemId: string;
526
+ requestedQuantity: number;
527
+ batchNumber?: string;
528
+ serialNumbers?: string[];
529
+ sourceZoneId?: string;
530
+ sourceBinLocation?: string;
531
+ destinationZoneId?: string;
532
+ destinationBinLocation?: string;
533
+ notes?: string;
534
+ }>;
535
+ customAttributes?: Record<string, unknown>;
536
+ }
537
+
538
+ export interface TransferItem {
539
+ id: string;
540
+ tenantId: string;
541
+ storeId: string;
542
+ transferId: string;
543
+ transferNumber: string;
544
+ inventoryItemId: string;
545
+ productId: string;
546
+ variantId: string;
547
+ sku: string;
548
+ productName?: string;
549
+ requestedQuantity: number;
550
+ approvedQuantity?: number;
551
+ pickedQuantity?: number;
552
+ shippedQuantity?: number;
553
+ receivedQuantity?: number;
554
+ acceptedQuantity?: number;
555
+ rejectedQuantity: number;
556
+ unitCost?: number;
557
+ totalCost?: number;
558
+ batchNumber?: string;
559
+ serialNumbers?: string[];
560
+ expiryDate?: Date;
561
+ sourceZoneId?: string;
562
+ sourceBinLocation?: string;
563
+ destinationZoneId?: string;
564
+ destinationBinLocation?: string;
565
+ conditionAtPick?: string;
566
+ conditionAtReceive?: string;
567
+ qualityNotes?: string;
568
+ hasDiscrepancy: boolean;
569
+ discrepancyType?: "quantity" | "damage" | "missing" | "extra" | "condition";
570
+ discrepancyReason?: string;
571
+ discrepancyResolution?: "accept" | "reject" | "adjust" | "investigate";
572
+ status:
573
+ | "pending"
574
+ | "picked"
575
+ | "shipped"
576
+ | "received"
577
+ | "accepted"
578
+ | "rejected";
579
+ createdAt: Date;
580
+ updatedAt: Date;
581
+ pickedAt?: Date;
582
+ shippedAt?: Date;
583
+ receivedAt?: Date;
584
+ notes?: string;
585
+ }
586
+
587
+ export interface TransferFilter
588
+ extends BaseFilter,
589
+ DateRangeFilter,
590
+ StatusFilter {
591
+ transferType?: string;
592
+ priority?: string;
593
+ sourceLocationId?: string;
594
+ destinationLocationId?: string;
595
+ requestedBy?: string;
596
+ hasDiscrepancies?: boolean;
597
+ }
598
+
599
+ // =====================================================
600
+ // AUTOMATION TYPES
601
+ // =====================================================
602
+
603
+ export interface AutomationRule {
604
+ id: string;
605
+ tenantId: string;
606
+ storeId: string;
607
+ ruleName: string;
608
+ description?: string;
609
+ ruleType:
610
+ | "reorder"
611
+ | "transfer"
612
+ | "adjustment"
613
+ | "alert"
614
+ | "threshold"
615
+ | "expiry"
616
+ | "velocity"
617
+ | "optimization";
618
+ scope: "global" | "location" | "category" | "product" | "sku";
619
+ locationIds?: string[];
620
+ locationTypes?: string[];
621
+ productCategories?: string[];
622
+ productIds?: string[];
623
+ skus?: string[];
624
+ triggerConditions?: Record<string, unknown>;
625
+ actions?: Array<{
626
+ actionType: string;
627
+ priority: "low" | "medium" | "high" | "urgent";
628
+ parameters: Record<string, unknown>;
629
+ requiresApproval?: boolean;
630
+ approvalRoles?: string[];
631
+ }>;
632
+ aiEnabled: boolean;
633
+ mlModelId?: string;
634
+ confidenceThreshold?: number;
635
+ learningEnabled: boolean;
636
+ executionMode: "automatic" | "manual_approval" | "suggestion_only";
637
+ maxExecutionsPerDay?: number;
638
+ cooldownPeriod?: number;
639
+ priority: number;
640
+ executionOrder: number;
641
+ isScheduled: boolean;
642
+ schedulePattern?: string;
643
+ nextScheduledRun?: Date;
644
+ isActive: boolean;
645
+ canOverride: boolean;
646
+ temporaryDisableUntil?: Date;
647
+ executionCount: number;
648
+ successCount: number;
649
+ failureCount: number;
650
+ lastExecutedAt?: Date;
651
+ lastSuccessAt?: Date;
652
+ lastFailureAt?: Date;
653
+ averageExecutionTime?: number;
654
+ successRate?: number;
655
+ costSavings?: number;
656
+ createdBy: string;
657
+ updatedBy?: string;
658
+ createdAt: Date;
659
+ updatedAt: Date;
660
+ tags?: string[];
661
+ customAttributes?: Record<string, unknown>;
662
+ }
663
+
664
+ export interface CreateAutomationRuleRequest {
665
+ ruleName: string;
666
+ description?: string;
667
+ ruleType: AutomationRule["ruleType"];
668
+ scope: AutomationRule["scope"];
669
+ locationIds?: string[];
670
+ locationTypes?: string[];
671
+ productCategories?: string[];
672
+ productIds?: string[];
673
+ skus?: string[];
674
+ triggerConditions?: Record<string, unknown>;
675
+ actions?: AutomationRule["actions"];
676
+ aiEnabled?: boolean;
677
+ mlModelId?: string;
678
+ confidenceThreshold?: number;
679
+ learningEnabled?: boolean;
680
+ executionMode?: AutomationRule["executionMode"];
681
+ maxExecutionsPerDay?: number;
682
+ cooldownPeriod?: number;
683
+ priority?: number;
684
+ executionOrder?: number;
685
+ isScheduled?: boolean;
686
+ schedulePattern?: string;
687
+ nextScheduledRun?: Date;
688
+ canOverride?: boolean;
689
+ tags?: string[];
690
+ customAttributes?: Record<string, unknown>;
691
+ }
692
+
693
+ export interface AutomationRuleFilter extends BaseFilter, StatusFilter {
694
+ ruleType?: string;
695
+ scope?: string;
696
+ aiEnabled?: boolean;
697
+ executionMode?: string;
698
+ isScheduled?: boolean;
699
+ tags?: string[];
700
+ }
701
+
702
+ export interface AIRecommendation {
703
+ id: string;
704
+ type: "reorder" | "transfer" | "pricing" | "optimization";
705
+ confidence: number;
706
+ priority: "low" | "medium" | "high" | "urgent";
707
+ title: string;
708
+ description: string;
709
+ impact: {
710
+ financial?: number;
711
+ operational?: string;
712
+ risk?: string;
713
+ };
714
+ actions: Array<{
715
+ actionType: string;
716
+ parameters: Record<string, unknown>;
717
+ estimatedOutcome: string;
718
+ }>;
719
+ dataPoints: Record<string, unknown>;
720
+ expiresAt?: Date;
721
+ createdAt: Date;
722
+ }
723
+
724
+ // =====================================================
725
+ // ANALYTICS AND REPORTING TYPES
726
+ // =====================================================
727
+
728
+ export interface InventorySnapshot {
729
+ date: Date;
730
+ totalItems: number;
731
+ totalValue: number;
732
+ lowStockItems: number;
733
+ outOfStockItems: number;
734
+ averageTurnover: number;
735
+ topMovingItems: Array<{
736
+ sku: string;
737
+ productName: string;
738
+ quantity: number;
739
+ value: number;
740
+ }>;
741
+ }
742
+
743
+ export interface LowStockAlert {
744
+ id: string;
745
+ inventoryItemId: string;
746
+ sku: string;
747
+ productName: string;
748
+ locationId: string;
749
+ locationName: string;
750
+ currentQuantity: number;
751
+ reorderPoint: number;
752
+ safetyStock: number;
753
+ daysOfSupply: number;
754
+ severity: "low" | "medium" | "high" | "critical";
755
+ createdAt: Date;
756
+ }
757
+
758
+ export interface InventoryInsight {
759
+ type: "trend" | "anomaly" | "opportunity" | "risk";
760
+ title: string;
761
+ description: string;
762
+ metric: string;
763
+ value: number;
764
+ change: number;
765
+ changeDirection: "up" | "down" | "stable";
766
+ timeframe: string;
767
+ actionable: boolean;
768
+ recommendations?: string[];
769
+ }
770
+
771
+ export interface DashboardMetrics {
772
+ totalItems: number;
773
+ totalValue: number;
774
+ lowStockCount: number;
775
+ outOfStockCount: number;
776
+ expiringSoonCount: number;
777
+ pendingTransfersCount: number;
778
+ averageTurnoverRate: number;
779
+ inventoryAccuracy: number;
780
+ recentActivity: Array<{
781
+ type: string;
782
+ description: string;
783
+ timestamp: Date;
784
+ }>;
785
+ alerts: LowStockAlert[];
786
+ insights: InventoryInsight[];
787
+ }
788
+
789
+ export interface InventoryOverview {
790
+ totalItems: number;
791
+ totalValue: number;
792
+ totalLocations: number;
793
+ lowStockPercentage: number;
794
+ outOfStockPercentage: number;
795
+ turnoverRate: number;
796
+ accuracy: number;
797
+ categoryBreakdown: Array<{
798
+ category: string;
799
+ itemCount: number;
800
+ value: number;
801
+ percentage: number;
802
+ }>;
803
+ locationBreakdown: Array<{
804
+ locationId: string;
805
+ locationName: string;
806
+ itemCount: number;
807
+ value: number;
808
+ utilization: number;
809
+ }>;
810
+ }
811
+
812
+ export interface StockMovementReport {
813
+ period: {
814
+ startDate: Date;
815
+ endDate: Date;
816
+ };
817
+ totalMovements: number;
818
+ inboundMovements: number;
819
+ outboundMovements: number;
820
+ adjustments: number;
821
+ transfers: number;
822
+ valueChange: number;
823
+ topMovingItems: Array<{
824
+ sku: string;
825
+ productName: string;
826
+ totalMovement: number;
827
+ inbound: number;
828
+ outbound: number;
829
+ netChange: number;
830
+ }>;
831
+ movementsByDay: Array<{
832
+ date: Date;
833
+ inbound: number;
834
+ outbound: number;
835
+ net: number;
836
+ }>;
837
+ }
838
+
839
+ export interface VelocityAnalysis {
840
+ period: {
841
+ startDate: Date;
842
+ endDate: Date;
843
+ };
844
+ items: Array<{
845
+ sku: string;
846
+ productName: string;
847
+ currentQuantity: number;
848
+ totalSold: number;
849
+ averageDailySales: number;
850
+ turnoverRate: number;
851
+ daysOfSupply: number;
852
+ velocityCategory: "fast" | "medium" | "slow" | "dead";
853
+ reorderRecommendation: string;
854
+ }>;
855
+ summary: {
856
+ fastMoving: number;
857
+ mediumMoving: number;
858
+ slowMoving: number;
859
+ deadStock: number;
860
+ averageTurnover: number;
861
+ };
862
+ }
863
+
864
+ export interface ABCClassification {
865
+ items: Array<{
866
+ sku: string;
867
+ productName: string;
868
+ annualValue: number;
869
+ annualQuantity: number;
870
+ cumulativeValue: number;
871
+ cumulativePercentage: number;
872
+ classification: "A" | "B" | "C";
873
+ recommendedManagement: string;
874
+ }>;
875
+ summary: {
876
+ classA: { count: number; valuePercentage: number };
877
+ classB: { count: number; valuePercentage: number };
878
+ classC: { count: number; valuePercentage: number };
879
+ };
880
+ }
881
+
882
+ export interface StockValuation {
883
+ totalValue: number;
884
+ valuationMethod: "FIFO" | "LIFO" | "weighted_average";
885
+ byCategory: Array<{
886
+ category: string;
887
+ value: number;
888
+ percentage: number;
889
+ itemCount: number;
890
+ }>;
891
+ byLocation: Array<{
892
+ locationId: string;
893
+ locationName: string;
894
+ value: number;
895
+ percentage: number;
896
+ itemCount: number;
897
+ }>;
898
+ ageAnalysis: Array<{
899
+ ageRange: string;
900
+ value: number;
901
+ percentage: number;
902
+ itemCount: number;
903
+ }>;
904
+ }
905
+
906
+ export interface ExpiryReport {
907
+ expiredItems: Array<{
908
+ sku: string;
909
+ productName: string;
910
+ batchNumber: string;
911
+ expiryDate: Date;
912
+ quantity: number;
913
+ value: number;
914
+ daysExpired: number;
915
+ locationName: string;
916
+ }>;
917
+ expiringSoon: Array<{
918
+ sku: string;
919
+ productName: string;
920
+ batchNumber: string;
921
+ expiryDate: Date;
922
+ quantity: number;
923
+ value: number;
924
+ daysUntilExpiry: number;
925
+ locationName: string;
926
+ }>;
927
+ summary: {
928
+ totalExpiredValue: number;
929
+ totalExpiredQuantity: number;
930
+ expiringInNext30Days: number;
931
+ expiringInNext7Days: number;
932
+ averageDaysToExpiry: number;
933
+ };
934
+ }
935
+
936
+ export interface ForecastData {
937
+ sku: string;
938
+ productName: string;
939
+ forecastPeriod: {
940
+ startDate: Date;
941
+ endDate: Date;
942
+ };
943
+ historicalDemand: Array<{
944
+ date: Date;
945
+ demand: number;
946
+ actual?: number;
947
+ }>;
948
+ forecastedDemand: Array<{
949
+ date: Date;
950
+ predicted: number;
951
+ confidence: number;
952
+ upperBound: number;
953
+ lowerBound: number;
954
+ }>;
955
+ accuracy: {
956
+ mape: number; // Mean Absolute Percentage Error
957
+ rmse: number; // Root Mean Square Error
958
+ bias: number;
959
+ };
960
+ seasonality: {
961
+ detected: boolean;
962
+ pattern: string;
963
+ strength: number;
964
+ };
965
+ trend: {
966
+ direction: "up" | "down" | "stable";
967
+ strength: number;
968
+ };
969
+ }
970
+
971
+ export interface ReorderRecommendation {
972
+ sku: string;
973
+ productName: string;
974
+ locationId: string;
975
+ locationName: string;
976
+ currentQuantity: number;
977
+ reorderPoint: number;
978
+ safetyStock: number;
979
+ recommendedOrderQuantity: number;
980
+ leadTime: number;
981
+ daysOfSupply: number;
982
+ priority: "low" | "medium" | "high" | "urgent";
983
+ reasoning: string[];
984
+ estimatedCost: number;
985
+ estimatedStockoutRisk: number;
986
+ supplierRecommendations: Array<{
987
+ supplierId: string;
988
+ supplierName: string;
989
+ unitPrice: number;
990
+ leadTime: number;
991
+ minimumOrder: number;
992
+ reliability: number;
993
+ }>;
994
+ aiConfidence: number;
995
+ lastUpdated: Date;
996
+ }
997
+
998
+ // Re-export common types
999
+ export type {
1000
+ OperationResult,
1001
+ PaginatedResult,
1002
+ TenantContext,
1003
+ UserContext,
1004
+ } from "../schemas/types";