@fayz-ai/inventory 0.0.0-stage → 0.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 (93) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +41 -2
  3. package/dist/chunk-2FXO63QV.js +1732 -0
  4. package/dist/chunk-2FXO63QV.js.map +1 -0
  5. package/dist/chunk-52AJ7H2W.js +116 -0
  6. package/dist/chunk-52AJ7H2W.js.map +1 -0
  7. package/dist/chunk-AFUR3HLA.js +84 -0
  8. package/dist/chunk-AFUR3HLA.js.map +1 -0
  9. package/dist/chunk-EF5LVTOC.js +65 -0
  10. package/dist/chunk-EF5LVTOC.js.map +1 -0
  11. package/dist/chunk-GBIFZCEN.js +33 -0
  12. package/dist/chunk-GBIFZCEN.js.map +1 -0
  13. package/dist/chunk-GDEIBHAB.js +14 -0
  14. package/dist/chunk-GDEIBHAB.js.map +1 -0
  15. package/dist/chunk-JN5AZ656.js +35 -0
  16. package/dist/chunk-JN5AZ656.js.map +1 -0
  17. package/dist/chunk-JX7NCXJQ.js +15 -0
  18. package/dist/chunk-JX7NCXJQ.js.map +1 -0
  19. package/dist/chunk-MCWG3PMP.js +549 -0
  20. package/dist/chunk-MCWG3PMP.js.map +1 -0
  21. package/dist/chunk-RUOX7OOY.js +30 -0
  22. package/dist/chunk-RUOX7OOY.js.map +1 -0
  23. package/dist/chunk-SZXUGORU.js +13 -0
  24. package/dist/chunk-SZXUGORU.js.map +1 -0
  25. package/dist/chunk-W36J5END.js +48 -0
  26. package/dist/chunk-W36J5END.js.map +1 -0
  27. package/dist/chunk-YZDGJBJD.js +53 -0
  28. package/dist/chunk-YZDGJBJD.js.map +1 -0
  29. package/dist/data/mock.d.ts +3 -0
  30. package/dist/data/mock.d.ts.map +1 -0
  31. package/dist/data/mock.js +10 -0
  32. package/dist/data/mock.js.map +1 -0
  33. package/dist/data/provider.d.ts +120 -0
  34. package/dist/data/provider.d.ts.map +1 -0
  35. package/dist/data/provider.js +3 -0
  36. package/dist/data/provider.js.map +1 -0
  37. package/dist/data/supabase.d.ts +3 -0
  38. package/dist/data/supabase.d.ts.map +1 -0
  39. package/dist/data/supabase.js +13 -0
  40. package/dist/data/supabase.js.map +1 -0
  41. package/dist/data/tables.d.ts +25 -0
  42. package/dist/data/tables.d.ts.map +1 -0
  43. package/dist/data/tables.js +3 -0
  44. package/dist/data/tables.js.map +1 -0
  45. package/dist/domain/consumption.d.ts +33 -0
  46. package/dist/domain/consumption.d.ts.map +1 -0
  47. package/dist/domain/consumption.js +3 -0
  48. package/dist/domain/consumption.js.map +1 -0
  49. package/dist/domain/count.d.ts +85 -0
  50. package/dist/domain/count.d.ts.map +1 -0
  51. package/dist/domain/count.js +3 -0
  52. package/dist/domain/count.js.map +1 -0
  53. package/dist/domain/movement.d.ts +101 -0
  54. package/dist/domain/movement.d.ts.map +1 -0
  55. package/dist/domain/movement.js +3 -0
  56. package/dist/domain/movement.js.map +1 -0
  57. package/dist/domain/product.d.ts +245 -0
  58. package/dist/domain/product.d.ts.map +1 -0
  59. package/dist/domain/product.js +3 -0
  60. package/dist/domain/product.js.map +1 -0
  61. package/dist/domain/query.d.ts +12 -0
  62. package/dist/domain/query.d.ts.map +1 -0
  63. package/dist/domain/query.js +3 -0
  64. package/dist/domain/query.js.map +1 -0
  65. package/dist/domain/recipe-sheet.d.ts +133 -0
  66. package/dist/domain/recipe-sheet.d.ts.map +1 -0
  67. package/dist/domain/recipe-sheet.js +3 -0
  68. package/dist/domain/recipe-sheet.js.map +1 -0
  69. package/dist/domain/recipe.d.ts +138 -0
  70. package/dist/domain/recipe.d.ts.map +1 -0
  71. package/dist/domain/recipe.js +3 -0
  72. package/dist/domain/recipe.js.map +1 -0
  73. package/dist/domain/reference-data.d.ts +37 -0
  74. package/dist/domain/reference-data.d.ts.map +1 -0
  75. package/dist/domain/reference-data.js +3 -0
  76. package/dist/domain/reference-data.js.map +1 -0
  77. package/dist/domain/stock.d.ts +132 -0
  78. package/dist/domain/stock.d.ts.map +1 -0
  79. package/dist/domain/stock.js +5 -0
  80. package/dist/domain/stock.js.map +1 -0
  81. package/dist/domain/usage-audit.d.ts +95 -0
  82. package/dist/domain/usage-audit.d.ts.map +1 -0
  83. package/dist/domain/usage-audit.js +3 -0
  84. package/dist/domain/usage-audit.js.map +1 -0
  85. package/dist/lib/idempotency.d.ts +4 -0
  86. package/dist/lib/idempotency.d.ts.map +1 -0
  87. package/dist/lib/idempotency.js +3 -0
  88. package/dist/lib/idempotency.js.map +1 -0
  89. package/dist/store.d.ts +52 -0
  90. package/dist/store.d.ts.map +1 -0
  91. package/dist/store.js +193 -0
  92. package/dist/store.js.map +1 -0
  93. package/package.json +50 -3
@@ -0,0 +1,138 @@
1
+ export interface Recipe {
2
+ id: string;
3
+ name: string;
4
+ description?: string;
5
+ productId: string;
6
+ productName?: string;
7
+ /** Sale price of the produced product — the denominator of CMV%. */
8
+ productSalePrice?: number;
9
+ yieldQuantity: number;
10
+ yieldUnitId?: string;
11
+ yieldUnitName?: string;
12
+ /** portion = the sheet is one unit sold; batch = the sheet produces the yield. */
13
+ yieldMode?: 'portion' | 'batch';
14
+ preparationTimeMinutes?: number;
15
+ instructions?: string;
16
+ isActive: boolean;
17
+ ingredientCount?: number;
18
+ /** Carries what the assistant could not resolve — see RecipeGaps. */
19
+ metadata?: Record<string, unknown>;
20
+ tenantId: string;
21
+ createdAt: string;
22
+ updatedAt: string;
23
+ }
24
+ /** What an ingredient product contributes to a recipe line's cost. */
25
+ export interface IngredientCostBasis {
26
+ cost: number;
27
+ /** Base units per purchase unit. */
28
+ conversionFactor?: number;
29
+ /** Set only when the product is bought in a unit other than the counted one. */
30
+ purchaseUnitId?: string;
31
+ }
32
+ /** What the assistant proposed but could not match to the catalogue. */
33
+ export interface RecipeGaps {
34
+ unmatchedIngredients?: Array<{
35
+ name?: string;
36
+ quantity?: number;
37
+ notes?: string;
38
+ }>;
39
+ productHint?: string;
40
+ }
41
+ export interface RecipeIngredient {
42
+ id: string;
43
+ recipeId: string;
44
+ productId: string;
45
+ productName?: string;
46
+ quantity: number;
47
+ unitId?: string;
48
+ unitName?: string;
49
+ displayOrder: number;
50
+ notes?: string;
51
+ /** Reading unit of the line; quantity itself stays in the base unit. */
52
+ displayUnitId?: string;
53
+ groupId?: string;
54
+ groupName?: string;
55
+ costBasis?: IngredientCostBasis;
56
+ createdAt: string;
57
+ }
58
+ /** A stage of a recipe — "massa", "recheio", "montagem". */
59
+ export interface RecipeGroup {
60
+ id: string;
61
+ recipeId: string;
62
+ name: string;
63
+ preparationNotes?: string;
64
+ displayOrder: number;
65
+ estimatedMinutes?: number;
66
+ stationId?: string;
67
+ tenantId: string;
68
+ createdAt: string;
69
+ updatedAt: string;
70
+ }
71
+ export interface CreateRecipeIngredientInput {
72
+ productId: string;
73
+ quantity: number;
74
+ unitId?: string;
75
+ displayOrder?: number;
76
+ notes?: string;
77
+ groupId?: string;
78
+ }
79
+ export interface CreateRecipeInput {
80
+ name: string;
81
+ description?: string;
82
+ productId: string;
83
+ yieldQuantity: number;
84
+ yieldUnitId?: string;
85
+ preparationTimeMinutes?: number;
86
+ instructions?: string;
87
+ ingredients: CreateRecipeIngredientInput[];
88
+ }
89
+ /** Above this the dish eats the margin (the legacy app drew it at 35; the owner set 65). */
90
+ export declare const CMV_ALERT_THRESHOLD = 65;
91
+ /** Below this the dish is healthy — food-service practice puts a good CMV at 25–33%. */
92
+ export declare const CMV_GOOD_THRESHOLD = 33;
93
+ export interface CostableLine {
94
+ quantity: number;
95
+ costBasis?: IngredientCostBasis | null;
96
+ }
97
+ export interface CostedLine<T> {
98
+ line: T;
99
+ /** Cost of one unit as the recipe counts it. */
100
+ unitCost: number;
101
+ cost: number;
102
+ }
103
+ /**
104
+ * A recipe line's quantity is assumed to be in the ingredient's own unit. Only a product bought in another
105
+ * unit converts: its cost is per purchase unit, so the per-unit cost is cost ÷ factor.
106
+ */
107
+ export declare function ingredientUnitCost(basis?: IngredientCostBasis | null): number;
108
+ export declare function lineCost(line: CostableLine): number;
109
+ export declare function costLines<T extends CostableLine>(lines: T[]): CostedLine<T>[];
110
+ export declare function recipeCost(lines: CostableLine[]): number;
111
+ /** Cost as a percentage of the sale price. Null when there is no price to divide by. */
112
+ export declare function cmvPercent(cost: number, salePrice?: number | null): number | null;
113
+ export declare function isCmvHigh(cmv: number | null | undefined): boolean;
114
+ export type CmvBand = 'good' | 'attention' | 'high';
115
+ export declare function cmvBand(cmv: number | null | undefined): CmvBand | null;
116
+ /** Text colour for a CMV figure; the middle band stays neutral. */
117
+ export declare const CMV_TONE: Record<CmvBand, string>;
118
+ /** The newest active recipe of a product decides consumption; there should be only one. */
119
+ export declare function activeRecipeFor<T extends Pick<Recipe, 'productId' | 'isActive' | 'updatedAt'>>(recipes: T[], productId: string): T | undefined;
120
+ export interface ExplodableIngredient {
121
+ productId: string;
122
+ quantity: number;
123
+ /** The slot the ingredient leaves from: its default stock location. */
124
+ locationId?: string;
125
+ unitId?: string;
126
+ }
127
+ export interface ConsumptionLine {
128
+ productId: string;
129
+ locationId: string;
130
+ quantity: number;
131
+ unitId?: string;
132
+ }
133
+ /**
134
+ * What selling `soldQuantity` of a recipe's product takes out of stock: each ingredient scaled by
135
+ * sold ÷ yield, rounded to 4 places, and merged per (product, location, unit).
136
+ */
137
+ export declare function explodeRecipe(recipe: Pick<Recipe, 'id' | 'yieldQuantity'>, ingredients: ExplodableIngredient[], soldQuantity: number): ConsumptionLine[];
138
+ //# sourceMappingURL=recipe.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recipe.d.ts","sourceRoot":"","sources":["../../src/domain/recipe.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export { CMV_ALERT_THRESHOLD, CMV_GOOD_THRESHOLD, CMV_TONE, activeRecipeFor, cmvBand, cmvPercent, costLines, explodeRecipe, ingredientUnitCost, isCmvHigh, lineCost, recipeCost } from '../chunk-EF5LVTOC.js';
2
+ //# sourceMappingURL=recipe.js.map
3
+ //# sourceMappingURL=recipe.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"recipe.js"}
@@ -0,0 +1,37 @@
1
+ export declare const DEFAULT_MEASUREMENT_UNITS: readonly [{
2
+ readonly name: "Unit";
3
+ readonly abbreviation: "un";
4
+ }, {
5
+ readonly name: "Box";
6
+ readonly abbreviation: "box";
7
+ }, {
8
+ readonly name: "Kilogram";
9
+ readonly abbreviation: "kg";
10
+ }, {
11
+ readonly name: "Gram";
12
+ readonly abbreviation: "g";
13
+ }, {
14
+ readonly name: "Liter";
15
+ readonly abbreviation: "L";
16
+ }, {
17
+ readonly name: "Milliliter";
18
+ readonly abbreviation: "mL";
19
+ }];
20
+ export declare const DEFAULT_STOCK_LOCATION: {
21
+ readonly name: "Main Storage";
22
+ readonly description: "Primary storage area";
23
+ };
24
+ export declare function getMissingMeasurementUnits(rows: Array<{
25
+ abbreviation?: string | null;
26
+ }>): typeof DEFAULT_MEASUREMENT_UNITS[number][];
27
+ export declare function getDuplicateDefaultUnitIds(rows: Array<{
28
+ id: string;
29
+ abbreviation?: string | null;
30
+ created_at?: string | null;
31
+ }>): string[];
32
+ export declare function getDuplicateAutoCreatedLocationIds(rows: Array<{
33
+ id: string;
34
+ name?: string | null;
35
+ created_at?: string | null;
36
+ }>): string[];
37
+ //# sourceMappingURL=reference-data.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reference-data.d.ts","sourceRoot":"","sources":["../../src/domain/reference-data.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;;;EAO5B,CAAA;AAEV,eAAO,MAAM,sBAAsB;;;CAGzB,CAAA;AAEV,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,KAAK,CAAC;IAAE,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,GAC5C,OAAO,yBAAyB,CAAC,MAAM,CAAC,EAAE,CAO5C;AAED,wBAAgB,0BAA0B,CACxC,IAAI,EAAE,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,GACpF,MAAM,EAAE,CAwBV;AAED,wBAAgB,kCAAkC,CAChD,IAAI,EAAE,KAAK,CAAC;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,GAC5E,MAAM,EAAE,CAaV"}
@@ -0,0 +1,3 @@
1
+ export { DEFAULT_MEASUREMENT_UNITS, DEFAULT_STOCK_LOCATION, getDuplicateAutoCreatedLocationIds, getDuplicateDefaultUnitIds, getMissingMeasurementUnits } from '../chunk-YZDGJBJD.js';
2
+ //# sourceMappingURL=reference-data.js.map
3
+ //# sourceMappingURL=reference-data.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"reference-data.js"}
@@ -0,0 +1,132 @@
1
+ import { type MovementType } from './movement';
2
+ export interface StockLocation {
3
+ id: string;
4
+ name: string;
5
+ description?: string;
6
+ isActive: boolean;
7
+ unitId?: string;
8
+ tenantId: string;
9
+ createdAt: string;
10
+ updatedAt: string;
11
+ }
12
+ /** One slot of stock: product × location × batch × expiry. */
13
+ export interface StockPosition {
14
+ id: string;
15
+ productId: string;
16
+ productName?: string;
17
+ quantity: number;
18
+ unitCost: number;
19
+ stockLocationId?: string;
20
+ stockLocationName?: string;
21
+ batchNumber?: string;
22
+ expirationDate?: string;
23
+ measurementUnitId?: string;
24
+ unitType?: 'base' | 'purchase' | 'content';
25
+ tenantId: string;
26
+ createdAt: string;
27
+ updatedAt?: string;
28
+ }
29
+ /** `negative` exists because the ledger allows an exit posted before the entry that feeds it. */
30
+ export type StockHealth = 'negative' | 'zero' | 'below_min' | 'ok';
31
+ export type ExpiryFilter = 'all' | 'expired' | 'le30' | 'le60' | 'le90' | 'none';
32
+ export interface StockPanelQuery {
33
+ stockLocationId?: string;
34
+ categoryId?: string;
35
+ productSearch?: string;
36
+ batch?: string;
37
+ expiry?: ExpiryFilter;
38
+ /** Empty means every health. */
39
+ status?: StockHealth[];
40
+ limit?: number;
41
+ }
42
+ export interface StockPanelRow {
43
+ id: string;
44
+ productId: string;
45
+ productName: string;
46
+ categoryId?: string;
47
+ categoryName?: string;
48
+ stockLocationId?: string;
49
+ stockLocationName?: string;
50
+ batchNumber?: string;
51
+ expirationDate?: string;
52
+ quantity: number;
53
+ minQuantity: number;
54
+ unitCost: number;
55
+ totalValue: number;
56
+ health: StockHealth;
57
+ }
58
+ export interface InventorySummary {
59
+ totalProducts: number;
60
+ lowStockCount: number;
61
+ outOfStockCount: number;
62
+ totalStockValue: number;
63
+ recentMovementCount: number;
64
+ movementsByType: Record<MovementType, number>;
65
+ /** Active products with no minimum set — why "low stock" can read zero with an empty shelf. */
66
+ noMinimumCount: number;
67
+ }
68
+ export type RestockReason = 'out-of-stock' | 'below-minimum';
69
+ export interface RestockLine {
70
+ productId: string;
71
+ name: string;
72
+ categoryName?: string;
73
+ currentQuantity: number;
74
+ minQuantity: number;
75
+ unit?: string;
76
+ reason: RestockReason;
77
+ }
78
+ export interface CategoryCount {
79
+ categoryId: string | null;
80
+ name: string;
81
+ count: number;
82
+ }
83
+ /** A minimum of zero means "none set", so a product without one never reads as below it. */
84
+ export declare function stockHealth(quantity: number, minQuantity: number): StockHealth;
85
+ export declare function hasMinimum(minQuantity: number | null | undefined): boolean;
86
+ export declare function isOutOfStock(quantity: number): boolean;
87
+ /** The alarm rule the summary, the list and the restock queue share. */
88
+ export declare function isLowStock(quantity: number, minQuantity: number): boolean;
89
+ export declare function restockReason(quantity: number, minQuantity: number): RestockReason | undefined;
90
+ /** What needs buying: below-minimum first (a decided purchase), then zeroed, each by name. */
91
+ export declare function pickRestock<T extends {
92
+ name: string;
93
+ currentQuantity: number;
94
+ minQuantity: number;
95
+ }>(rows: T[], limit: number): Array<T & {
96
+ reason: RestockReason;
97
+ }>;
98
+ /** The day a movement must be on or after to count as recent: seven days back, as a UTC date. */
99
+ export declare function recentMovementCutoff(now: Date): string;
100
+ export interface SummarizableProduct {
101
+ quantity: number;
102
+ minQuantity: number;
103
+ /** The price the adapter values stock at. */
104
+ unitValue: number;
105
+ }
106
+ export declare function summarizeStock(activeProducts: SummarizableProduct[], recentMovementTypes: string[]): InventorySummary;
107
+ /** Nobody filled in a minimum, so the low-stock alarm cannot fire yet. */
108
+ export declare function noProductHasMinimum(summary: Pick<InventorySummary, 'totalProducts' | 'noMinimumCount'> | null | undefined): boolean;
109
+ /** Products per category, biggest first; the uncategorised bucket is named because it is an answer, not a hole. */
110
+ export declare function categoryCounts(categoryIds: Array<string | null | undefined>, nameOf: (id: string) => string | undefined): CategoryCount[];
111
+ /** An expiry filter as a date window relative to `today`; undefined when it filters nothing. */
112
+ export type ExpiryWindow = {
113
+ kind: 'expired';
114
+ before: string;
115
+ } | {
116
+ kind: 'none';
117
+ } | {
118
+ kind: 'within';
119
+ from: string;
120
+ to: string;
121
+ };
122
+ export declare function expiryWindow(expiry: ExpiryFilter | undefined, today: Date): ExpiryWindow | undefined;
123
+ export declare function isInExpiryWindow(window: ExpiryWindow | undefined, expirationDate: string | undefined): boolean;
124
+ /** A panel line for one slot; a slot whose product is not in hand still shows, because hiding it would hide stock. */
125
+ export declare function toPanelRow(position: Pick<StockPosition, 'id' | 'productId' | 'quantity' | 'unitCost' | 'stockLocationId' | 'batchNumber' | 'expirationDate'>, product: {
126
+ name: string;
127
+ minQuantity: number;
128
+ categoryId?: string;
129
+ categoryName?: string;
130
+ } | undefined, stockLocationName: string | undefined): StockPanelRow;
131
+ export declare function hasHealth(row: Pick<StockPanelRow, 'health'>, statuses: StockHealth[] | undefined): boolean;
132
+ //# sourceMappingURL=stock.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stock.d.ts","sourceRoot":"","sources":["../../src/domain/stock.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export { categoryCounts, expiryWindow, hasHealth, hasMinimum, isInExpiryWindow, isLowStock, isOutOfStock, noProductHasMinimum, pickRestock, recentMovementCutoff, restockReason, stockHealth, summarizeStock, toPanelRow } from '../chunk-52AJ7H2W.js';
2
+ import '../chunk-GDEIBHAB.js';
3
+ import '../chunk-AFUR3HLA.js';
4
+ //# sourceMappingURL=stock.js.map
5
+ //# sourceMappingURL=stock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"stock.js"}
@@ -0,0 +1,95 @@
1
+ /**
2
+ * One product used on one sold line, read back from the ledger. The grain is (item × product), not the
3
+ * movement: one consumption splits into several ledger rows when FIFO crosses batches.
4
+ */
5
+ export interface UsageAuditEntry {
6
+ itemId: string;
7
+ productId: string;
8
+ productName?: string;
9
+ productSku?: string;
10
+ usedAt: string;
11
+ movementDate: string;
12
+ /** What the sale posted out of stock. */
13
+ postedQuantity: number;
14
+ /** Posted plus every audit correction — what the balance actually reflects. */
15
+ netQuantity: number;
16
+ /** The recipe's standard for this line. Null when no recipe answers for it. */
17
+ standardQuantity?: number | null;
18
+ /** net − standard. Null follows standardQuantity. */
19
+ variance?: number | null;
20
+ unitAbbreviation?: string;
21
+ totalCost: number;
22
+ stockLocationId?: string;
23
+ stockLocationName?: string;
24
+ /** More than one means the exit crossed batches. */
25
+ locationCount: number;
26
+ recipeId?: string;
27
+ recipeName?: string;
28
+ orderId?: string;
29
+ itemName?: string;
30
+ orderReference?: string;
31
+ performedById?: string;
32
+ performedByName?: string;
33
+ customerId?: string;
34
+ customerName?: string;
35
+ correctedAt?: string;
36
+ correctionReason?: string;
37
+ isCorrected: boolean;
38
+ /** `ledger`: the order posted stock. `clinical`: an appointment used the product and nothing left the ledger. */
39
+ source?: 'ledger' | 'clinical';
40
+ /** False on clinical lines, which is what stops the screen promising a reversal with nothing to reverse. */
41
+ stockPosted?: boolean;
42
+ }
43
+ /** One line of a usage-audit batch: the sold line, the product, and what really left. */
44
+ export interface UsageAuditCorrection {
45
+ itemId: string;
46
+ productId: string;
47
+ quantity: number;
48
+ }
49
+ export interface UsageAuditCorrectionInput extends UsageAuditCorrection {
50
+ reason: string;
51
+ }
52
+ /** `linesUnchanged` already matched and emit no movement. */
53
+ export interface UsageAuditBatchResult {
54
+ operationId?: string;
55
+ linesApplied: number;
56
+ linesUnchanged: number;
57
+ }
58
+ /** A line stock accepts, with or without posting it. */
59
+ export interface UsageAuditApproval {
60
+ itemId: string;
61
+ productId: string;
62
+ }
63
+ export interface UsageAuditApproveInput {
64
+ /** true is "post to stock": accept and deduct. false accepts without touching the balance. */
65
+ post: boolean;
66
+ lines: UsageAuditApproval[];
67
+ reason?: string;
68
+ }
69
+ export interface UsageAuditApproveResult {
70
+ linesApproved: number;
71
+ linesPosted: number;
72
+ linesSkipped: number;
73
+ /** Lines that could not be posted for lack of balance; they stay pending. */
74
+ linesNoStock?: number;
75
+ missing?: Array<{
76
+ product: string;
77
+ needed: number;
78
+ available: number;
79
+ }>;
80
+ }
81
+ export interface UsageAuditQuery {
82
+ search?: string;
83
+ /** Only the lines whose net differs from the recipe standard. */
84
+ divergentOnly?: boolean;
85
+ page?: number;
86
+ pageSize?: number;
87
+ /** ISO instant: only usage from this moment on. The queue has a window. */
88
+ from?: string;
89
+ /** Only what nobody has reviewed yet. */
90
+ pendingOnly?: boolean;
91
+ }
92
+ export declare function usageLineKey(line: UsageAuditApproval): string;
93
+ /** Applies what an approval wrote to the rows already on screen, without a reload. */
94
+ export declare function patchUsageEntries(entries: UsageAuditEntry[], lines: UsageAuditApproval[], patch: Partial<UsageAuditEntry>): UsageAuditEntry[];
95
+ //# sourceMappingURL=usage-audit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage-audit.d.ts","sourceRoot":"","sources":["../../src/domain/usage-audit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export { patchUsageEntries, usageLineKey } from '../chunk-SZXUGORU.js';
2
+ //# sourceMappingURL=usage-audit.js.map
3
+ //# sourceMappingURL=usage-audit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"usage-audit.js"}
@@ -0,0 +1,4 @@
1
+ export declare function randomId(): string;
2
+ /** Created once per operator action and reused on every retry of it. */
3
+ export declare function createIdempotencyKey(scope: string): string;
4
+ //# sourceMappingURL=idempotency.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"idempotency.d.ts","sourceRoot":"","sources":["../../src/lib/idempotency.ts"],"names":[],"mappings":"AAAA,wBAAgB,QAAQ,IAAI,MAAM,CAOjC;AAED,wEAAwE;AACxE,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE1D"}
@@ -0,0 +1,3 @@
1
+ export { createIdempotencyKey, randomId } from '../chunk-JX7NCXJQ.js';
2
+ //# sourceMappingURL=idempotency.js.map
3
+ //# sourceMappingURL=idempotency.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"idempotency.js"}
@@ -0,0 +1,52 @@
1
+ import { type StoreApi } from 'zustand/vanilla';
2
+ import type { InventoryDataProvider } from './data/provider';
3
+ import type { CreateProductInput, Product, ProductQuery } from './domain/product';
4
+ import type { CreateStockMovementInput, MovementQuery, StockMovement } from './domain/movement';
5
+ import type { CategoryCount, InventorySummary, RestockLine, StockLocation } from './domain/stock';
6
+ import type { CreateRecipeInput, Recipe } from './domain/recipe';
7
+ import { type UsageAuditApproval, type UsageAuditApproveInput, type UsageAuditApproveResult, type UsageAuditBatchResult, type UsageAuditCorrection, type UsageAuditCorrectionInput, type UsageAuditEntry, type UsageAuditQuery } from './domain/usage-audit';
8
+ /** Supabase when the app has a client, the in-memory mock otherwise. */
9
+ export declare function createInventoryDataProvider(): InventoryDataProvider;
10
+ export interface InventoryUIState {
11
+ products: Product[];
12
+ productsTotal: number;
13
+ productsLoading: boolean;
14
+ productQuery: ProductQuery;
15
+ movements: StockMovement[];
16
+ movementsTotal: number;
17
+ movementsLoading: boolean;
18
+ usageAudit: UsageAuditEntry[];
19
+ usageAuditTotal: number;
20
+ usageAuditLoading: boolean;
21
+ usageAuditQuery: UsageAuditQuery;
22
+ locations: StockLocation[];
23
+ locationsLoading: boolean;
24
+ recipes: Recipe[];
25
+ recipesLoading: boolean;
26
+ summary: InventorySummary | null;
27
+ summaryLoading: boolean;
28
+ /** Null until read. */
29
+ restock: RestockLine[] | null;
30
+ categoryMix: CategoryCount[] | null;
31
+ fetchSummary(): Promise<void>;
32
+ fetchRestock(): Promise<void>;
33
+ fetchCategoryMix(): Promise<void>;
34
+ fetchProducts(query: ProductQuery): Promise<void>;
35
+ fetchMovements(query: MovementQuery): Promise<void>;
36
+ fetchUsageAudit(query: UsageAuditQuery): Promise<void>;
37
+ correctUsage(input: UsageAuditCorrectionInput): Promise<void>;
38
+ correctUsageBatch(input: {
39
+ reason: string;
40
+ lines: UsageAuditCorrection[];
41
+ }): Promise<UsageAuditBatchResult>;
42
+ approveUsageBatch(input: UsageAuditApproveInput): Promise<UsageAuditApproveResult>;
43
+ /** Applies what an approval wrote to the rows on screen, without a reload. */
44
+ patchUsageAuditEntries(lines: UsageAuditApproval[], patch: Partial<UsageAuditEntry>): void;
45
+ fetchLocations(): Promise<void>;
46
+ fetchRecipes(): Promise<void>;
47
+ createProduct(input: CreateProductInput): Promise<Product>;
48
+ createMovement(input: CreateStockMovementInput): Promise<StockMovement>;
49
+ createRecipe(input: CreateRecipeInput): Promise<Recipe>;
50
+ }
51
+ export declare function createInventoryStore(provider: InventoryDataProvider): StoreApi<InventoryUIState>;
52
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../src/store.ts"],"names":[],"mappings":"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"}