@axova/shared 1.0.2 → 1.1.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 (68) hide show
  1. package/dist/index.d.ts +1 -0
  2. package/dist/index.js +2 -0
  3. package/dist/lib/db.d.ts +34406 -1
  4. package/dist/lib/db.js +21 -1
  5. package/dist/middleware/storeOwnership.js +22 -3
  6. package/dist/middleware/storeValidationMiddleware.js +16 -39
  7. package/dist/schemas/admin/admin-schema.d.ts +2 -2
  8. package/dist/schemas/ai-moderation/ai-moderation-schema.d.ts +6 -6
  9. package/dist/schemas/common/common-schemas.d.ts +71 -71
  10. package/dist/schemas/compliance/compliance-schema.d.ts +20 -20
  11. package/dist/schemas/compliance/kyc-schema.d.ts +8 -8
  12. package/dist/schemas/customer/customer-schema.d.ts +18 -18
  13. package/dist/schemas/index.d.ts +28 -0
  14. package/dist/schemas/index.js +134 -3
  15. package/dist/schemas/inventory/inventory-tables.d.ts +188 -188
  16. package/dist/schemas/inventory/lot-tables.d.ts +102 -102
  17. package/dist/schemas/order/cart-schema.d.ts +2865 -0
  18. package/dist/schemas/order/cart-schema.js +396 -0
  19. package/dist/schemas/order/order-schema.d.ts +19 -19
  20. package/dist/schemas/order/order-schema.js +8 -2
  21. package/dist/schemas/product/discount-schema.d.ts +3 -3
  22. package/dist/schemas/product/product-schema.d.ts +3 -3
  23. package/dist/schemas/store/store-audit-schema.d.ts +20 -20
  24. package/dist/schemas/store/store-schema.d.ts +182 -2
  25. package/dist/schemas/store/store-schema.js +19 -0
  26. package/dist/schemas/store/storefront-config-schema.d.ts +434 -823
  27. package/dist/schemas/store/storefront-config-schema.js +35 -62
  28. package/dist/utils/subdomain.d.ts +1 -1
  29. package/dist/utils/subdomain.js +10 -15
  30. package/package.json +1 -1
  31. package/src/configs/index.ts +654 -654
  32. package/src/index.ts +26 -23
  33. package/src/interfaces/customer-events.ts +106 -106
  34. package/src/interfaces/inventory-events.ts +545 -545
  35. package/src/interfaces/inventory-types.ts +1004 -1004
  36. package/src/interfaces/order-events.ts +381 -381
  37. package/src/lib/auditLogger.ts +1117 -1117
  38. package/src/lib/authOrganization.ts +153 -153
  39. package/src/lib/db.ts +84 -64
  40. package/src/middleware/serviceAuth.ts +328 -328
  41. package/src/middleware/storeOwnership.ts +199 -181
  42. package/src/middleware/storeValidationMiddleware.ts +17 -50
  43. package/src/middleware/userAuth.ts +248 -248
  44. package/src/schemas/admin/admin-schema.ts +208 -208
  45. package/src/schemas/ai-moderation/ai-moderation-schema.ts +180 -180
  46. package/src/schemas/common/common-schemas.ts +108 -108
  47. package/src/schemas/compliance/compliance-schema.ts +927 -0
  48. package/src/schemas/compliance/kyc-schema.ts +649 -0
  49. package/src/schemas/customer/customer-schema.ts +576 -0
  50. package/src/schemas/index.ts +202 -3
  51. package/src/schemas/inventory/inventory-tables.ts +1927 -0
  52. package/src/schemas/inventory/lot-tables.ts +799 -0
  53. package/src/schemas/order/cart-schema.ts +652 -0
  54. package/src/schemas/order/order-schema.ts +1406 -0
  55. package/src/schemas/product/discount-relations.ts +44 -0
  56. package/src/schemas/product/discount-schema.ts +464 -0
  57. package/src/schemas/product/product-relations.ts +187 -0
  58. package/src/schemas/product/product-schema.ts +955 -0
  59. package/src/schemas/store/ethiopian_business_api.md.resolved +212 -0
  60. package/src/schemas/store/store-audit-schema.ts +1257 -0
  61. package/src/schemas/store/store-schema.ts +682 -0
  62. package/src/schemas/store/store-settings-schema.ts +231 -0
  63. package/src/schemas/store/storefront-config-schema.ts +382 -0
  64. package/src/schemas/types.ts +67 -67
  65. package/src/types/events.ts +646 -646
  66. package/src/utils/errorHandler.ts +44 -44
  67. package/src/utils/subdomain.ts +19 -23
  68. package/tsconfig.json +21 -21
@@ -1,1004 +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";
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";