@endora-commerce/mod-inventory 0.100.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 (223) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +61 -0
  3. package/dist/admin/api/warehouses-client.d.ts +22 -0
  4. package/dist/admin/api/warehouses-client.d.ts.map +1 -0
  5. package/dist/admin/api/warehouses-client.js +32 -0
  6. package/dist/admin/api/warehouses-client.js.map +1 -0
  7. package/dist/admin/index.d.ts +43 -0
  8. package/dist/admin/index.d.ts.map +1 -0
  9. package/dist/admin/index.js +190 -0
  10. package/dist/admin/index.js.map +1 -0
  11. package/dist/admin/pages/AvailabilityNotificationsPage.d.ts +15 -0
  12. package/dist/admin/pages/AvailabilityNotificationsPage.d.ts.map +1 -0
  13. package/dist/admin/pages/AvailabilityNotificationsPage.js +111 -0
  14. package/dist/admin/pages/AvailabilityNotificationsPage.js.map +1 -0
  15. package/dist/admin/pages/InventoryPage.d.ts +17 -0
  16. package/dist/admin/pages/InventoryPage.d.ts.map +1 -0
  17. package/dist/admin/pages/InventoryPage.js +135 -0
  18. package/dist/admin/pages/InventoryPage.js.map +1 -0
  19. package/dist/admin/pages/LowStockPage.d.ts +16 -0
  20. package/dist/admin/pages/LowStockPage.d.ts.map +1 -0
  21. package/dist/admin/pages/LowStockPage.js +61 -0
  22. package/dist/admin/pages/LowStockPage.js.map +1 -0
  23. package/dist/admin/pages/StockImportWizard.d.ts +17 -0
  24. package/dist/admin/pages/StockImportWizard.d.ts.map +1 -0
  25. package/dist/admin/pages/StockImportWizard.js +111 -0
  26. package/dist/admin/pages/StockImportWizard.js.map +1 -0
  27. package/dist/admin/pages/WarehouseEditor.d.ts +12 -0
  28. package/dist/admin/pages/WarehouseEditor.d.ts.map +1 -0
  29. package/dist/admin/pages/WarehouseEditor.js +194 -0
  30. package/dist/admin/pages/WarehouseEditor.js.map +1 -0
  31. package/dist/admin/pages/WarehousesList.d.ts +12 -0
  32. package/dist/admin/pages/WarehousesList.d.ts.map +1 -0
  33. package/dist/admin/pages/WarehousesList.js +69 -0
  34. package/dist/admin/pages/WarehousesList.js.map +1 -0
  35. package/dist/admin/zones/ChannelWarehouses.d.ts +49 -0
  36. package/dist/admin/zones/ChannelWarehouses.d.ts.map +1 -0
  37. package/dist/admin/zones/ChannelWarehouses.js +109 -0
  38. package/dist/admin/zones/ChannelWarehouses.js.map +1 -0
  39. package/dist/backend/demo/reset.d.ts +18 -0
  40. package/dist/backend/demo/reset.d.ts.map +1 -0
  41. package/dist/backend/demo/reset.js +20 -0
  42. package/dist/backend/demo/reset.js.map +1 -0
  43. package/dist/backend/demo/rows.d.ts +38 -0
  44. package/dist/backend/demo/rows.d.ts.map +1 -0
  45. package/dist/backend/demo/rows.js +38 -0
  46. package/dist/backend/demo/rows.js.map +1 -0
  47. package/dist/backend/demo/seed.d.ts +26 -0
  48. package/dist/backend/demo/seed.d.ts.map +1 -0
  49. package/dist/backend/demo/seed.js +65 -0
  50. package/dist/backend/demo/seed.js.map +1 -0
  51. package/dist/backend/email-templates/transactional-defaults.d.ts +11 -0
  52. package/dist/backend/email-templates/transactional-defaults.d.ts.map +1 -0
  53. package/dist/backend/email-templates/transactional-defaults.js +49 -0
  54. package/dist/backend/email-templates/transactional-defaults.js.map +1 -0
  55. package/dist/backend/entities/availability-notification.entity.d.ts +49 -0
  56. package/dist/backend/entities/availability-notification.entity.d.ts.map +1 -0
  57. package/dist/backend/entities/availability-notification.entity.js +93 -0
  58. package/dist/backend/entities/availability-notification.entity.js.map +1 -0
  59. package/dist/backend/entities/inventory-threshold.entity.d.ts +24 -0
  60. package/dist/backend/entities/inventory-threshold.entity.d.ts.map +1 -0
  61. package/dist/backend/entities/inventory-threshold.entity.js +61 -0
  62. package/dist/backend/entities/inventory-threshold.entity.js.map +1 -0
  63. package/dist/backend/entities/product-warehouse-low-stock-threshold.entity.d.ts +15 -0
  64. package/dist/backend/entities/product-warehouse-low-stock-threshold.entity.d.ts.map +1 -0
  65. package/dist/backend/entities/product-warehouse-low-stock-threshold.entity.js +51 -0
  66. package/dist/backend/entities/product-warehouse-low-stock-threshold.entity.js.map +1 -0
  67. package/dist/backend/entities/stock-allocation.entity.d.ts +22 -0
  68. package/dist/backend/entities/stock-allocation.entity.d.ts.map +1 -0
  69. package/dist/backend/entities/stock-allocation.entity.js +69 -0
  70. package/dist/backend/entities/stock-allocation.entity.js.map +1 -0
  71. package/dist/backend/entities/stock-level.entity.d.ts +24 -0
  72. package/dist/backend/entities/stock-level.entity.d.ts.map +1 -0
  73. package/dist/backend/entities/stock-level.entity.js +74 -0
  74. package/dist/backend/entities/stock-level.entity.js.map +1 -0
  75. package/dist/backend/entities/warehouse-channel-assignment.entity.d.ts +17 -0
  76. package/dist/backend/entities/warehouse-channel-assignment.entity.d.ts.map +1 -0
  77. package/dist/backend/entities/warehouse-channel-assignment.entity.js +60 -0
  78. package/dist/backend/entities/warehouse-channel-assignment.entity.js.map +1 -0
  79. package/dist/backend/entities/warehouse.entity.d.ts +37 -0
  80. package/dist/backend/entities/warehouse.entity.d.ts.map +1 -0
  81. package/dist/backend/entities/warehouse.entity.js +90 -0
  82. package/dist/backend/entities/warehouse.entity.js.map +1 -0
  83. package/dist/backend/index.d.ts +139 -0
  84. package/dist/backend/index.d.ts.map +1 -0
  85. package/dist/backend/index.js +351 -0
  86. package/dist/backend/index.js.map +1 -0
  87. package/dist/backend/plugin.d.ts +113 -0
  88. package/dist/backend/plugin.d.ts.map +1 -0
  89. package/dist/backend/plugin.js +75 -0
  90. package/dist/backend/plugin.js.map +1 -0
  91. package/dist/backend/prompt-tools.d.ts +23 -0
  92. package/dist/backend/prompt-tools.d.ts.map +1 -0
  93. package/dist/backend/prompt-tools.js +77 -0
  94. package/dist/backend/prompt-tools.js.map +1 -0
  95. package/dist/backend/routes.admin.d.ts +62 -0
  96. package/dist/backend/routes.admin.d.ts.map +1 -0
  97. package/dist/backend/routes.admin.js +383 -0
  98. package/dist/backend/routes.admin.js.map +1 -0
  99. package/dist/backend/routes.d.ts +40 -0
  100. package/dist/backend/routes.d.ts.map +1 -0
  101. package/dist/backend/routes.js +263 -0
  102. package/dist/backend/routes.js.map +1 -0
  103. package/dist/backend/services/audit-references.d.ts +15 -0
  104. package/dist/backend/services/audit-references.d.ts.map +1 -0
  105. package/dist/backend/services/audit-references.js +27 -0
  106. package/dist/backend/services/audit-references.js.map +1 -0
  107. package/dist/backend/services/availability-notification-service.d.ts +155 -0
  108. package/dist/backend/services/availability-notification-service.d.ts.map +1 -0
  109. package/dist/backend/services/availability-notification-service.js +363 -0
  110. package/dist/backend/services/availability-notification-service.js.map +1 -0
  111. package/dist/backend/services/availability-worker.d.ts +57 -0
  112. package/dist/backend/services/availability-worker.d.ts.map +1 -0
  113. package/dist/backend/services/availability-worker.js +135 -0
  114. package/dist/backend/services/availability-worker.js.map +1 -0
  115. package/dist/backend/services/csv-stock-importer.d.ts +52 -0
  116. package/dist/backend/services/csv-stock-importer.d.ts.map +1 -0
  117. package/dist/backend/services/csv-stock-importer.js +154 -0
  118. package/dist/backend/services/csv-stock-importer.js.map +1 -0
  119. package/dist/backend/services/display-band-resolver.d.ts +19 -0
  120. package/dist/backend/services/display-band-resolver.d.ts.map +1 -0
  121. package/dist/backend/services/display-band-resolver.js +21 -0
  122. package/dist/backend/services/display-band-resolver.js.map +1 -0
  123. package/dist/backend/services/effective-fulfilment-strategy.d.ts +16 -0
  124. package/dist/backend/services/effective-fulfilment-strategy.d.ts.map +1 -0
  125. package/dist/backend/services/effective-fulfilment-strategy.js +16 -0
  126. package/dist/backend/services/effective-fulfilment-strategy.js.map +1 -0
  127. package/dist/backend/services/fulfilment-strategy-resolver.d.ts +13 -0
  128. package/dist/backend/services/fulfilment-strategy-resolver.d.ts.map +1 -0
  129. package/dist/backend/services/fulfilment-strategy-resolver.js +13 -0
  130. package/dist/backend/services/fulfilment-strategy-resolver.js.map +1 -0
  131. package/dist/backend/services/inventory-read-port.d.ts +65 -0
  132. package/dist/backend/services/inventory-read-port.d.ts.map +1 -0
  133. package/dist/backend/services/inventory-read-port.js +168 -0
  134. package/dist/backend/services/inventory-read-port.js.map +1 -0
  135. package/dist/backend/services/inventory-reservation-apply-port.d.ts +62 -0
  136. package/dist/backend/services/inventory-reservation-apply-port.d.ts.map +1 -0
  137. package/dist/backend/services/inventory-reservation-apply-port.js +134 -0
  138. package/dist/backend/services/inventory-reservation-apply-port.js.map +1 -0
  139. package/dist/backend/services/low-stock-alert-service.d.ts +87 -0
  140. package/dist/backend/services/low-stock-alert-service.d.ts.map +1 -0
  141. package/dist/backend/services/low-stock-alert-service.js +164 -0
  142. package/dist/backend/services/low-stock-alert-service.js.map +1 -0
  143. package/dist/backend/services/product-threshold-write.service.d.ts +38 -0
  144. package/dist/backend/services/product-threshold-write.service.d.ts.map +1 -0
  145. package/dist/backend/services/product-threshold-write.service.js +80 -0
  146. package/dist/backend/services/product-threshold-write.service.js.map +1 -0
  147. package/dist/backend/services/stock-import.service.d.ts +43 -0
  148. package/dist/backend/services/stock-import.service.d.ts.map +1 -0
  149. package/dist/backend/services/stock-import.service.js +124 -0
  150. package/dist/backend/services/stock-import.service.js.map +1 -0
  151. package/dist/backend/services/stock-level-service.d.ts +146 -0
  152. package/dist/backend/services/stock-level-service.d.ts.map +1 -0
  153. package/dist/backend/services/stock-level-service.js +489 -0
  154. package/dist/backend/services/stock-level-service.js.map +1 -0
  155. package/dist/backend/services/threshold-admin-service.d.ts +73 -0
  156. package/dist/backend/services/threshold-admin-service.d.ts.map +1 -0
  157. package/dist/backend/services/threshold-admin-service.js +167 -0
  158. package/dist/backend/services/threshold-admin-service.js.map +1 -0
  159. package/dist/backend/services/threshold-resolver.d.ts +23 -0
  160. package/dist/backend/services/threshold-resolver.d.ts.map +1 -0
  161. package/dist/backend/services/threshold-resolver.js +29 -0
  162. package/dist/backend/services/threshold-resolver.js.map +1 -0
  163. package/dist/backend/services/threshold-settings-mirror.d.ts +55 -0
  164. package/dist/backend/services/threshold-settings-mirror.d.ts.map +1 -0
  165. package/dist/backend/services/threshold-settings-mirror.js +84 -0
  166. package/dist/backend/services/threshold-settings-mirror.js.map +1 -0
  167. package/dist/backend/services/warehouse-channel-reconciler.d.ts +19 -0
  168. package/dist/backend/services/warehouse-channel-reconciler.d.ts.map +1 -0
  169. package/dist/backend/services/warehouse-channel-reconciler.js +65 -0
  170. package/dist/backend/services/warehouse-channel-reconciler.js.map +1 -0
  171. package/dist/backend/services/warehouse-channel-service.d.ts +57 -0
  172. package/dist/backend/services/warehouse-channel-service.d.ts.map +1 -0
  173. package/dist/backend/services/warehouse-channel-service.js +205 -0
  174. package/dist/backend/services/warehouse-channel-service.js.map +1 -0
  175. package/dist/backend/services/warehouse-country-reference.d.ts +14 -0
  176. package/dist/backend/services/warehouse-country-reference.d.ts.map +1 -0
  177. package/dist/backend/services/warehouse-country-reference.js +27 -0
  178. package/dist/backend/services/warehouse-country-reference.js.map +1 -0
  179. package/dist/backend/services/warehouse-service.d.ts +86 -0
  180. package/dist/backend/services/warehouse-service.d.ts.map +1 -0
  181. package/dist/backend/services/warehouse-service.js +267 -0
  182. package/dist/backend/services/warehouse-service.js.map +1 -0
  183. package/dist/manifest.d.ts +219 -0
  184. package/dist/manifest.d.ts.map +1 -0
  185. package/dist/manifest.js +377 -0
  186. package/dist/manifest.js.map +1 -0
  187. package/dist/migrations/20260503T182812_inventory_workflow.d.ts +39 -0
  188. package/dist/migrations/20260503T182812_inventory_workflow.d.ts.map +1 -0
  189. package/dist/migrations/20260503T182812_inventory_workflow.js +205 -0
  190. package/dist/migrations/20260503T182812_inventory_workflow.js.map +1 -0
  191. package/dist/migrations/20260611T140347_inventory_warehouse_default_low_stock_threshold.d.ts +14 -0
  192. package/dist/migrations/20260611T140347_inventory_warehouse_default_low_stock_threshold.d.ts.map +1 -0
  193. package/dist/migrations/20260611T140347_inventory_warehouse_default_low_stock_threshold.js +18 -0
  194. package/dist/migrations/20260611T140347_inventory_warehouse_default_low_stock_threshold.js.map +1 -0
  195. package/dist/migrations/20260611T140348_inventory_per_warehouse_low_stock_thresholds.d.ts +28 -0
  196. package/dist/migrations/20260611T140348_inventory_per_warehouse_low_stock_thresholds.d.ts.map +1 -0
  197. package/dist/migrations/20260611T140348_inventory_per_warehouse_low_stock_thresholds.js +48 -0
  198. package/dist/migrations/20260611T140348_inventory_per_warehouse_low_stock_thresholds.js.map +1 -0
  199. package/dist/migrations/20260818T081243_inventory_stock_allocation_order_item_fk.d.ts +44 -0
  200. package/dist/migrations/20260818T081243_inventory_stock_allocation_order_item_fk.d.ts.map +1 -0
  201. package/dist/migrations/20260818T081243_inventory_stock_allocation_order_item_fk.js +81 -0
  202. package/dist/migrations/20260818T081243_inventory_stock_allocation_order_item_fk.js.map +1 -0
  203. package/dist/migrations/20260830T182139_inventory_organization_attribution.d.ts +109 -0
  204. package/dist/migrations/20260830T182139_inventory_organization_attribution.d.ts.map +1 -0
  205. package/dist/migrations/20260830T182139_inventory_organization_attribution.js +178 -0
  206. package/dist/migrations/20260830T182139_inventory_organization_attribution.js.map +1 -0
  207. package/dist/migrations/20260912T125716_inventory_organization_warehouses.d.ts +34 -0
  208. package/dist/migrations/20260912T125716_inventory_organization_warehouses.d.ts.map +1 -0
  209. package/dist/migrations/20260912T125716_inventory_organization_warehouses.js +50 -0
  210. package/dist/migrations/20260912T125716_inventory_organization_warehouses.js.map +1 -0
  211. package/dist/migrations/index.d.ts +32 -0
  212. package/dist/migrations/index.d.ts.map +1 -0
  213. package/dist/migrations/index.js +39 -0
  214. package/dist/migrations/index.js.map +1 -0
  215. package/dist/ports/index.d.ts +183 -0
  216. package/dist/ports/index.d.ts.map +1 -0
  217. package/dist/ports/index.js +2 -0
  218. package/dist/ports/index.js.map +1 -0
  219. package/docs/inventory.md +177 -0
  220. package/i18n/en.json +32 -0
  221. package/i18n/pl.json +32 -0
  222. package/package.json +105 -0
  223. package/tailwind.css +14 -0
@@ -0,0 +1,194 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useCallback, useEffect, useState, } from 'react';
3
+ import { useNavigate, useParams } from 'react-router-dom';
4
+ import { ArrowLeft, Trash2 } from 'lucide-react';
5
+ import { ApiError, useSurfaceVisibility } from '@endora-commerce/admin-kit/lib';
6
+ import { useTranslation } from '@endora-commerce/admin-kit/i18n';
7
+ import { CountryPicker } from '@endora-commerce/admin-kit/components';
8
+ import { warehousesClient } from '../api/warehouses-client.js';
9
+ const EMPTY = {
10
+ name: '',
11
+ code: '',
12
+ active: true,
13
+ description: '',
14
+ street: '',
15
+ city: '',
16
+ postalCode: '',
17
+ countryCode: '',
18
+ contactName: '',
19
+ contactEmail: '',
20
+ contactPhone: '',
21
+ defaultLowStockThreshold: '',
22
+ };
23
+ function fromWarehouse(w) {
24
+ return {
25
+ name: w.name,
26
+ code: w.code,
27
+ active: w.active,
28
+ description: w.description ?? '',
29
+ street: w.address?.street ?? '',
30
+ city: w.address?.city ?? '',
31
+ postalCode: w.address?.postalCode ?? '',
32
+ countryCode: w.address?.countryCode ?? '',
33
+ contactName: w.contact?.name ?? '',
34
+ contactEmail: w.contact?.email ?? '',
35
+ contactPhone: w.contact?.phone ?? '',
36
+ defaultLowStockThreshold: w.defaultLowStockThreshold == null ? '' : String(w.defaultLowStockThreshold),
37
+ };
38
+ }
39
+ function parseThreshold(value) {
40
+ const trimmed = value.trim();
41
+ if (trimmed === '')
42
+ return null;
43
+ const n = Number.parseInt(trimmed, 10);
44
+ if (Number.isNaN(n) || n < 0)
45
+ return null;
46
+ return n;
47
+ }
48
+ function buildAddress(s) {
49
+ const a = {
50
+ street: s.street.trim() || null,
51
+ city: s.city.trim() || null,
52
+ postalCode: s.postalCode.trim() || null,
53
+ countryCode: s.countryCode.trim() || null,
54
+ };
55
+ if (!a.street && !a.city && !a.postalCode && !a.countryCode)
56
+ return null;
57
+ return a;
58
+ }
59
+ function buildContact(s) {
60
+ const c = {
61
+ name: s.contactName.trim() || null,
62
+ email: s.contactEmail.trim() || null,
63
+ phone: s.contactPhone.trim() || null,
64
+ };
65
+ if (!c.name && !c.email && !c.phone)
66
+ return null;
67
+ return c;
68
+ }
69
+ /**
70
+ * WarehouseEditor — create + edit a single warehouse (feature 010 / US1).
71
+ */
72
+ export function WarehouseEditor() {
73
+ const t = useTranslation('core');
74
+ /**
75
+ * The screen's own gate (2026-08-29) — see `InventoryPage` for the reasoning
76
+ * in full. Both halves are asked here because this one screen is both: the
77
+ * `:id` form loads a warehouse over the read route and saves it over the
78
+ * write one, and `/warehouses/new` is a create with nothing to read. So a
79
+ * read-only operator sees the record and no way to change it, and reaches
80
+ * `/warehouses/new` and sees nothing at all.
81
+ */
82
+ const isVisible = useSurfaceVisibility();
83
+ const canRead = isVisible({ module: 'inventory', requiredPermission: 'inventory:read' });
84
+ const canWrite = isVisible({ module: 'inventory', requiredPermission: 'inventory:write' });
85
+ const navigate = useNavigate();
86
+ const { id } = useParams();
87
+ const isNew = !id || id === 'new';
88
+ const [form, setForm] = useState(EMPTY);
89
+ const [loaded, setLoaded] = useState(null);
90
+ const [loading, setLoading] = useState(!isNew);
91
+ const [submitting, setSubmitting] = useState(false);
92
+ const [error, setError] = useState(null);
93
+ const refresh = useCallback(async () => {
94
+ if (isNew || !canRead) {
95
+ setLoading(false);
96
+ return;
97
+ }
98
+ setLoading(true);
99
+ setError(null);
100
+ try {
101
+ const w = await warehousesClient.get(id);
102
+ setLoaded(w);
103
+ setForm(fromWarehouse(w));
104
+ }
105
+ catch (err) {
106
+ setError(err instanceof ApiError ? err.envelope.error.message : t('warehouses.editor.error.load'));
107
+ }
108
+ finally {
109
+ setLoading(false);
110
+ }
111
+ }, [canRead, id, isNew, t]);
112
+ useEffect(() => {
113
+ void refresh();
114
+ }, [refresh]);
115
+ const update = (patch) => setForm((prev) => ({ ...prev, ...patch }));
116
+ const handleSubmit = async (e) => {
117
+ e.preventDefault();
118
+ setSubmitting(true);
119
+ setError(null);
120
+ try {
121
+ if (isNew) {
122
+ const body = {
123
+ name: form.name.trim(),
124
+ code: form.code.trim(),
125
+ active: form.active,
126
+ description: form.description.trim() || null,
127
+ address: buildAddress(form),
128
+ contact: buildContact(form),
129
+ defaultLowStockThreshold: parseThreshold(form.defaultLowStockThreshold),
130
+ };
131
+ const created = await warehousesClient.create(body);
132
+ navigate(`/warehouses/${created.id}`, { replace: true });
133
+ }
134
+ else {
135
+ const updated = await warehousesClient.update(id, {
136
+ name: form.name.trim(),
137
+ active: form.active,
138
+ description: form.description.trim() || null,
139
+ address: buildAddress(form),
140
+ contact: buildContact(form),
141
+ defaultLowStockThreshold: parseThreshold(form.defaultLowStockThreshold),
142
+ });
143
+ setLoaded(updated);
144
+ }
145
+ }
146
+ catch (err) {
147
+ setError(err instanceof ApiError ? err.envelope.error.message : t('warehouses.editor.error.save'));
148
+ }
149
+ finally {
150
+ setSubmitting(false);
151
+ }
152
+ };
153
+ const handleDelete = async () => {
154
+ if (!loaded)
155
+ return;
156
+ if (!window.confirm(t('warehouses.editor.deleteConfirm', { name: loaded.name })))
157
+ return;
158
+ setSubmitting(true);
159
+ setError(null);
160
+ try {
161
+ await warehousesClient.remove(loaded.id);
162
+ navigate('/warehouses', { replace: true });
163
+ }
164
+ catch (err) {
165
+ setError(err instanceof ApiError ? err.envelope.error.message : t('warehouses.editor.error.delete'));
166
+ }
167
+ finally {
168
+ setSubmitting(false);
169
+ }
170
+ };
171
+ if (loading)
172
+ return _jsx("div", { className: "b2b-page", children: t('warehouses.loading') });
173
+ const isDefault = loaded?.code === 'default';
174
+ const canDelete = canWrite && !isNew && !isDefault;
175
+ if (!canRead || (isNew && !canWrite)) {
176
+ return _jsx("div", { className: "b2b-page", children: t('inventory.noPermission') });
177
+ }
178
+ return (_jsxs("div", { className: "b2b-page", children: [_jsxs("div", { className: "b2b-page-head", children: [_jsxs("div", { className: "b2b-grow", children: [_jsxs("button", { type: "button", className: "b2b-btn b2b-btn--ghost b2b-btn--sm", onClick: () => { void navigate('/warehouses'); }, style: { marginBottom: 8 }, children: [_jsx(ArrowLeft, { size: 13 }), " ", t('warehouses.editor.backToList')] }), _jsx("div", { className: "b2b-page-head__title", children: isNew ? t('warehouses.editor.newTitle') : loaded?.name ?? t('warehouses.editor.fallbackTitle') }), !isNew && loaded ? (_jsxs("div", { className: "b2b-page-head__sub", children: [_jsx("code", { className: "b2b-mono", children: loaded.code }), isDefault ? t('warehouses.editor.systemDefaultSuffix') : '', ' · ', t('warehouses.editor.channelDefaultsSuffix', {
179
+ count: loaded.totals?.isDefaultForChannelCount ?? 0,
180
+ })] })) : null] }), canDelete ? (_jsx("div", { className: "b2b-page-head__actions", children: _jsxs("button", { type: "button", className: "b2b-btn b2b-btn--danger", onClick: () => void handleDelete(), disabled: submitting, children: [_jsx(Trash2, { size: 13 }), " ", t('warehouses.action.delete')] }) })) : null] }), error ? (_jsx("div", { className: "b2b-card", style: {
181
+ background: 'var(--danger-soft)',
182
+ color: 'var(--danger-soft-fg)',
183
+ padding: 12,
184
+ marginBottom: 16,
185
+ border: '1px solid hsl(8 80% 85%)',
186
+ }, children: error })) : null, _jsxs("form", { onSubmit: (e) => { void handleSubmit(e); }, children: [_jsxs("div", { className: "b2b-card", style: { marginBottom: 16 }, children: [_jsx("div", { className: "b2b-card__head", children: _jsx("h2", { children: t('warehouses.editor.identityTitle') }) }), _jsxs("div", { className: "b2b-card__body", children: [_jsxs("div", { className: "b2b-grid b2b-grid--cols-2", children: [_jsxs("div", { children: [_jsx("label", { className: "b2b-label", htmlFor: "wh-name", children: t('warehouses.editor.field.name') }), _jsx("input", { id: "wh-name", className: "b2b-field", value: form.name, onChange: (e) => update({ name: e.target.value }), required: true, maxLength: 160 })] }), _jsxs("div", { children: [_jsx("label", { className: "b2b-label", htmlFor: "wh-code", children: t('warehouses.editor.field.code') }), _jsx("input", { id: "wh-code", className: "b2b-field b2b-field--mono", value: form.code, onChange: (e) => update({ code: e.target.value }), required: true, pattern: "[a-z][a-z0-9_-]*[a-z0-9]", maxLength: 64, disabled: !isNew }), _jsx("div", { className: "b2b-help", children: t('warehouses.editor.field.codeHelp') })] })] }), _jsxs("div", { style: { marginTop: 12 }, children: [_jsx("label", { className: "b2b-label", htmlFor: "wh-desc", children: t('warehouses.editor.field.description') }), _jsx("textarea", { id: "wh-desc", className: "b2b-field", rows: 3, value: form.description, onChange: (e) => update({ description: e.target.value }), maxLength: 2000 })] }), _jsx("div", { style: { marginTop: 12 }, children: _jsxs("label", { className: "b2b-row", style: { gap: 8, alignItems: 'center' }, children: [_jsx("input", { type: "checkbox", checked: form.active, onChange: (e) => update({ active: e.target.checked }) }), t('warehouses.editor.field.active')] }) })] })] }), _jsxs("div", { className: "b2b-card", style: { marginBottom: 16 }, children: [_jsx("div", { className: "b2b-card__head", children: _jsx("h2", { children: t('warehouses.editor.addressTitle') }) }), _jsx("div", { className: "b2b-card__body", children: _jsxs("div", { className: "b2b-grid b2b-grid--cols-2", children: [_jsxs("div", { children: [_jsx("label", { className: "b2b-label", children: t('warehouses.editor.field.street') }), _jsx("input", { className: "b2b-field", value: form.street, onChange: (e) => update({ street: e.target.value }) })] }), _jsxs("div", { children: [_jsx("label", { className: "b2b-label", children: t('warehouses.editor.field.city') }), _jsx("input", { className: "b2b-field", value: form.city, onChange: (e) => update({ city: e.target.value }) })] }), _jsxs("div", { children: [_jsx("label", { className: "b2b-label", children: t('warehouses.editor.field.postalCode') }), _jsx("input", { className: "b2b-field", value: form.postalCode, onChange: (e) => update({ postalCode: e.target.value }) })] }), _jsxs("div", { children: [_jsx("label", { className: "b2b-label", children: t('warehouses.editor.field.countryCode') }), _jsx(CountryPicker, { className: "b2b-field", value: form.countryCode, onChange: (e) => update({ countryCode: e.target.value }), includeBlank: true, blankLabel: t('warehouses.editor.field.countryNone') })] })] }) })] }), _jsxs("div", { className: "b2b-card", style: { marginBottom: 16 }, children: [_jsx("div", { className: "b2b-card__head", children: _jsx("h2", { children: t('warehouses.editor.contactTitle') }) }), _jsx("div", { className: "b2b-card__body", children: _jsxs("div", { className: "b2b-grid b2b-grid--cols-3", children: [_jsxs("div", { children: [_jsx("label", { className: "b2b-label", children: t('warehouses.editor.field.contactName') }), _jsx("input", { className: "b2b-field", value: form.contactName, onChange: (e) => update({ contactName: e.target.value }) })] }), _jsxs("div", { children: [_jsx("label", { className: "b2b-label", children: t('warehouses.editor.field.contactEmail') }), _jsx("input", { className: "b2b-field", type: "email", value: form.contactEmail, onChange: (e) => update({ contactEmail: e.target.value }) })] }), _jsxs("div", { children: [_jsx("label", { className: "b2b-label", children: t('warehouses.editor.field.contactPhone') }), _jsx("input", { className: "b2b-field", value: form.contactPhone, onChange: (e) => update({ contactPhone: e.target.value }) })] })] }) })] }), _jsxs("div", { className: "b2b-card", style: { marginBottom: 16 }, children: [_jsx("div", { className: "b2b-card__head", children: _jsx("h2", { children: t('warehouses.editor.lowStockTitle') }) }), _jsx("div", { className: "b2b-card__body", children: _jsxs("div", { style: { maxWidth: 260 }, children: [_jsx("label", { className: "b2b-label", htmlFor: "wh-low-stock", children: t('warehouses.editor.field.defaultLowStockThreshold') }), _jsx("input", { id: "wh-low-stock", className: "b2b-field", type: "number", min: "0", value: form.defaultLowStockThreshold, placeholder: t('warehouses.editor.field.defaultLowStockThresholdPlaceholder'), onChange: (e) => update({ defaultLowStockThreshold: e.target.value }) }), _jsx("div", { className: "b2b-help", children: t('warehouses.editor.field.defaultLowStockThresholdHelp') })] }) })] }), _jsxs("div", { className: "b2b-row", style: { gap: 8, justifyContent: 'flex-end' }, children: [_jsx("button", { type: "button", className: "b2b-btn b2b-btn--ghost", onClick: () => { void navigate('/warehouses'); }, disabled: submitting, children: t('warehouses.action.cancel') }), canWrite ? (_jsx("button", { type: "submit", className: "b2b-btn b2b-btn--primary", disabled: submitting, children: submitting ? t('warehouses.action.saving') : isNew ? t('warehouses.action.create') : t('warehouses.action.saveChanges') })) : null] })] })] }));
187
+ }
188
+ /**
189
+ * The registry loads a route component through a dynamic-import factory and
190
+ * reads its default export (feature 091, FR-013). The named export stays: it is
191
+ * the spelling this module's own code and its tests use.
192
+ */
193
+ export default WarehouseEditor;
194
+ //# sourceMappingURL=WarehouseEditor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WarehouseEditor.js","sourceRoot":"","sources":["../../../src/admin/pages/WarehouseEditor.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ import { type ReactNode } from 'react';
2
+ /**
3
+ * WarehousesList — admin landing for warehouse identity (feature 010 / US1).
4
+ */
5
+ export declare function WarehousesList(): ReactNode;
6
+ /**
7
+ * The registry loads a route component through a dynamic-import factory and
8
+ * reads its default export (feature 091, FR-013). The named export stays: it is
9
+ * the spelling this module's own code and its tests use.
10
+ */
11
+ export default WarehousesList;
12
+ //# sourceMappingURL=WarehousesList.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WarehousesList.d.ts","sourceRoot":"","sources":["../../../src/admin/pages/WarehousesList.tsx"],"names":[],"mappings":"AAAA,OAAO,EAA6C,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAOlF;;GAEG;AACH,wBAAgB,cAAc,IAAI,SAAS,CAiK1C;AAED;;;;GAIG;AACH,eAAe,cAAc,CAAC"}
@@ -0,0 +1,69 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useCallback, useEffect, useMemo, useState } from 'react';
3
+ import { Link } from 'react-router-dom';
4
+ import { Plus, Search, Warehouse as WarehouseIcon } from 'lucide-react';
5
+ import { ApiError, formatDateTime, cn, useSurfaceVisibility, normalize } from '@endora-commerce/admin-kit/lib';
6
+ import { useTranslation } from '@endora-commerce/admin-kit/i18n';
7
+ import { warehousesClient } from '../api/warehouses-client.js';
8
+ /**
9
+ * WarehousesList — admin landing for warehouse identity (feature 010 / US1).
10
+ */
11
+ export function WarehousesList() {
12
+ const t = useTranslation('core');
13
+ // The screen's own gate (2026-08-29) — see `InventoryPage` for the reasoning
14
+ // in full. Until then this list answered to `orders:read`, so anybody who
15
+ // could look at an order could enumerate every warehouse and its address.
16
+ const isVisible = useSurfaceVisibility();
17
+ const canRead = isVisible({ module: 'inventory', requiredPermission: 'inventory:read' });
18
+ const canWrite = isVisible({ module: 'inventory', requiredPermission: 'inventory:write' });
19
+ const [rows, setRows] = useState([]);
20
+ const [loading, setLoading] = useState(true);
21
+ const [error, setError] = useState(null);
22
+ const [activeOnly, setActiveOnly] = useState(false);
23
+ const [query, setQuery] = useState('');
24
+ const refresh = useCallback(async () => {
25
+ if (!canRead) {
26
+ setLoading(false);
27
+ return;
28
+ }
29
+ setLoading(true);
30
+ setError(null);
31
+ try {
32
+ const res = await warehousesClient.list({ activeOnly, withTotals: true });
33
+ setRows(res.items);
34
+ }
35
+ catch (err) {
36
+ setError(err instanceof ApiError ? err.envelope.error.message : t('warehouses.error.load'));
37
+ }
38
+ finally {
39
+ setLoading(false);
40
+ }
41
+ }, [canRead, activeOnly, t]);
42
+ useEffect(() => {
43
+ void refresh();
44
+ }, [refresh]);
45
+ const filtered = useMemo(() => {
46
+ const q = normalize(query);
47
+ if (!q)
48
+ return rows;
49
+ return rows.filter((r) => normalize(r.code).includes(q) ||
50
+ normalize(r.name).includes(q));
51
+ }, [rows, query]);
52
+ if (!canRead) {
53
+ return _jsx("div", { className: "b2b-page", children: t('inventory.noPermission') });
54
+ }
55
+ return (_jsxs("div", { className: "b2b-page b2b-page--wide", children: [_jsxs("div", { className: "b2b-page-head", children: [_jsxs("div", { className: "b2b-grow", children: [_jsx("div", { className: "b2b-page-head__title", children: t('warehouses.page.title') }), _jsxs("div", { className: "b2b-page-head__sub", children: [t('warehouses.page.sub.prefix'), " ", _jsx("code", { className: "b2b-mono", children: "default" }), " ", t('warehouses.page.sub.suffix')] })] }), _jsx("div", { className: "b2b-page-head__actions", children: canWrite ? (_jsxs(Link, { to: "/warehouses/new", className: "b2b-btn b2b-btn--primary", children: [_jsx(Plus, { size: 14 }), " ", t('warehouses.action.new')] })) : null })] }), error ? (_jsx("div", { className: "b2b-card", style: {
56
+ background: 'var(--danger-soft)',
57
+ color: 'var(--danger-soft-fg)',
58
+ padding: 12,
59
+ marginBottom: 16,
60
+ border: '1px solid hsl(8 80% 85%)',
61
+ }, children: error })) : null, _jsxs("div", { className: "b2b-card", children: [_jsxs("div", { className: "b2b-filterbar", children: [_jsx("div", { className: "b2b-filterbar__search", children: _jsxs("div", { className: "b2b-input-wrap", children: [_jsx(Search, { size: 16, className: "lead" }), _jsx("input", { className: "b2b-field b2b-field--addon", placeholder: t('warehouses.search.placeholder'), value: query, onChange: (e) => setQuery(e.target.value) })] }) }), _jsxs("label", { className: "b2b-row", style: { gap: 6, alignItems: 'center', fontSize: 13 }, children: [_jsx("input", { type: "checkbox", checked: activeOnly, onChange: (e) => setActiveOnly(e.target.checked) }), t('warehouses.filter.activeOnly')] })] }), _jsx("div", { className: "b2b-card__body b2b-card__body--flush", children: loading ? (_jsx("div", { style: { padding: 32, color: 'var(--fg-muted)', fontSize: 13 }, children: t('warehouses.loading') })) : filtered.length === 0 ? (_jsxs("div", { className: "b2b-empty", children: [_jsx("div", { className: "b2b-empty__icon", children: _jsx(WarehouseIcon, { size: 20 }) }), _jsx("div", { className: "b2b-empty__title", children: t('warehouses.empty') })] })) : (_jsxs("table", { className: "b2b-tbl", children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { children: t('warehouses.column.code') }), _jsx("th", { children: t('warehouses.column.name') }), _jsx("th", { className: "num", children: t('warehouses.column.products') }), _jsx("th", { className: "num", children: t('warehouses.column.onHand') }), _jsx("th", { className: "num", children: t('warehouses.column.defaultFor') }), _jsx("th", { children: t('warehouses.column.status') }), _jsx("th", { children: t('warehouses.column.updated') })] }) }), _jsx("tbody", { children: filtered.map((r) => (_jsxs("tr", { children: [_jsx("td", { children: _jsx(Link, { to: `/warehouses/${r.id}`, className: "b2b-mono", style: { fontSize: 12 }, children: r.code }) }), _jsx("td", { children: r.name }), _jsx("td", { className: "num b2b-tabular", children: r.totals?.products?.toLocaleString() ?? '—' }), _jsx("td", { className: "num b2b-tabular", children: r.totals?.onHand?.toLocaleString() ?? '—' }), _jsx("td", { className: "num b2b-tabular", children: r.totals?.isDefaultForChannelCount ?? '—' }), _jsx("td", { children: _jsx("span", { className: cn('b2b-badge', r.active ? 'b2b-badge--success' : 'b2b-badge--muted'), children: r.active ? t('warehouses.status.active') : t('warehouses.status.inactive') }) }), _jsx("td", { children: _jsx("span", { className: "b2b-muted", style: { fontSize: 12 }, children: formatDateTime(r.updatedAt) }) })] }, r.id))) })] })) })] })] }));
62
+ }
63
+ /**
64
+ * The registry loads a route component through a dynamic-import factory and
65
+ * reads its default export (feature 091, FR-013). The named export stays: it is
66
+ * the spelling this module's own code and its tests use.
67
+ */
68
+ export default WarehousesList;
69
+ //# sourceMappingURL=WarehousesList.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"WarehousesList.js","sourceRoot":"","sources":["../../../src/admin/pages/WarehousesList.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,49 @@
1
+ import { type ReactNode } from 'react';
2
+ import type { AdminZoneProps } from '@endora-commerce/contracts';
3
+ /**
4
+ * The warehouses bound to one sales channel (feature 010 / US3, T046).
5
+ *
6
+ * Lists the bindings, lets the operator add one, promote a row to default and
7
+ * unassign a non-default row.
8
+ *
9
+ * ## What moved, and what was rebuilt (feature 091, P7c)
10
+ *
11
+ * The file lived at `admin/src/modules/warehouses/ChannelMembershipPanel.tsx`
12
+ * — `warehouses/`, not `inventory/`; the nav attributes `/warehouses` to
13
+ * `module: 'inventory'`, which is why the boundary ledger keyed it
14
+ * `inventory/ChannelMembershipPanel`. `sales_channels`' edit screen imported it
15
+ * by path, the single key in
16
+ * `backend/scripts/ledgers/cross-module-imports/sales_channels.ts`; that screen
17
+ * renders `sales_channel.editor.after` now and this module declares the
18
+ * contribution.
19
+ *
20
+ * Its warehouse read used `admin/src/modules/warehouses/api/warehouses-client`,
21
+ * which was then still the admin application's file, so moving this one alone
22
+ * would have made a package reach back into `admin/src`. Both of its reads are
23
+ * HTTP paths whose types are already `@endora-commerce/contracts`', so they are
24
+ * rebuilt from the published `apiClient` — P2's exit, and no new reach.
25
+ *
26
+ * That client is this package's own since feature 091's Phase 4 batch 13, which
27
+ * moved both of this module's surface directories into `src/admin/`. The rebuild
28
+ * stays: it is two `GET`s built from the published client and the contract's
29
+ * own types, which is what a zone contribution should be, and importing the
30
+ * screens' client instead would put every warehouse call this module makes into
31
+ * the chunk `sales_channels`' editor downloads.
32
+ *
33
+ * ## The read gate went; the write gate stayed
34
+ *
35
+ * The zone renderer applies both presence axes **and** the contribution's
36
+ * declared `inventory:read` before it touches `React.lazy` (§4), so asking
37
+ * again here would be the same question twice — and the second answer would be
38
+ * the one nobody maintains. `canWrite` stays: a contribution declares one code,
39
+ * and this panel offers a read view and write actions behind two.
40
+ */
41
+ export type ChannelWarehousesProps = AdminZoneProps<'sales_channel.editor.after'>;
42
+ export declare function ChannelWarehouses({ channelId }: ChannelWarehousesProps): ReactNode;
43
+ /**
44
+ * The zone renderer loads a contribution through a dynamic-import factory and
45
+ * reads its default export (feature 091, FR-013). The named export stays: it is
46
+ * the spelling this module's own tests use.
47
+ */
48
+ export default ChannelWarehouses;
49
+ //# sourceMappingURL=ChannelWarehouses.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChannelWarehouses.d.ts","sourceRoot":"","sources":["../../../src/admin/zones/ChannelWarehouses.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAoC,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AACzE,OAAO,KAAK,EACV,cAAc,EAGf,MAAM,4BAA4B,CAAC;AAepC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,MAAM,MAAM,sBAAsB,GAAG,cAAc,CAAC,4BAA4B,CAAC,CAAC;AAElF,wBAAgB,iBAAiB,CAAC,EAAE,SAAS,EAAE,EAAE,sBAAsB,GAAG,SAAS,CAsNlF;AAED;;;;GAIG;AACH,eAAe,iBAAiB,CAAC"}
@@ -0,0 +1,109 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useCallback, useEffect, useState } from 'react';
3
+ import { ApiError, apiClient, useSurfaceVisibility } from '@endora-commerce/admin-kit/lib';
4
+ import { useTranslation } from '@endora-commerce/admin-kit/i18n';
5
+ export function ChannelWarehouses({ channelId }) {
6
+ const t = useTranslation('core');
7
+ const isVisible = useSurfaceVisibility();
8
+ const canWrite = isVisible({ module: 'inventory', requiredPermission: 'inventory:write' });
9
+ const [assignments, setAssignments] = useState([]);
10
+ const [warehouses, setWarehouses] = useState([]);
11
+ const [loading, setLoading] = useState(true);
12
+ const [error, setError] = useState(null);
13
+ const [info, setInfo] = useState(null);
14
+ const [busy, setBusy] = useState(null);
15
+ const [pendingWarehouseId, setPendingWarehouseId] = useState('');
16
+ const refresh = useCallback(async () => {
17
+ setLoading(true);
18
+ setError(null);
19
+ try {
20
+ const [whRes, listRes] = await Promise.all([
21
+ apiClient.get('/api/v1/admin/warehouses?pageSize=200&activeOnly=true&withTotals=false'),
22
+ apiClient.get(`/api/v1/admin/sales-channels/${channelId}/warehouses`),
23
+ ]);
24
+ setWarehouses(whRes.items);
25
+ setAssignments(listRes.items);
26
+ }
27
+ catch (err) {
28
+ setError(err instanceof ApiError ? err.envelope.error.message : t('warehouses.channel.error.load'));
29
+ }
30
+ finally {
31
+ setLoading(false);
32
+ }
33
+ }, [channelId, t]);
34
+ useEffect(() => {
35
+ void refresh();
36
+ }, [refresh]);
37
+ const assignedIds = new Set(assignments.map((a) => a.warehouseId));
38
+ const candidates = warehouses.filter((w) => !assignedIds.has(w.id));
39
+ const handleAssign = async () => {
40
+ if (!pendingWarehouseId)
41
+ return;
42
+ setBusy('assign');
43
+ setError(null);
44
+ try {
45
+ await apiClient.post(`/api/v1/admin/sales-channels/${channelId}/warehouses`, { warehouseId: pendingWarehouseId });
46
+ setInfo(t('warehouses.channel.info.assigned'));
47
+ setPendingWarehouseId('');
48
+ await refresh();
49
+ }
50
+ catch (err) {
51
+ setError(err instanceof ApiError ? err.envelope.error.message : t('warehouses.channel.error.assign'));
52
+ }
53
+ finally {
54
+ setBusy(null);
55
+ }
56
+ };
57
+ const handlePromote = async (id) => {
58
+ setBusy(id);
59
+ setError(null);
60
+ try {
61
+ await apiClient.patch(`/api/v1/admin/sales-channels/${channelId}/warehouses/${id}`, { isDefault: true });
62
+ setInfo(t('warehouses.channel.info.defaultChanged'));
63
+ await refresh();
64
+ }
65
+ catch (err) {
66
+ setError(err instanceof ApiError ? err.envelope.error.message : t('warehouses.channel.error.update'));
67
+ }
68
+ finally {
69
+ setBusy(null);
70
+ }
71
+ };
72
+ const handleUnassign = async (id, isDefault) => {
73
+ if (isDefault) {
74
+ window.alert(t('warehouses.channel.alert.promoteFirst'));
75
+ return;
76
+ }
77
+ if (!window.confirm(t('warehouses.channel.confirm.unassign')))
78
+ return;
79
+ setBusy(id);
80
+ setError(null);
81
+ try {
82
+ await apiClient.delete(`/api/v1/admin/sales-channels/${channelId}/warehouses/${id}`);
83
+ setInfo(t('warehouses.channel.info.removed'));
84
+ await refresh();
85
+ }
86
+ catch (err) {
87
+ setError(err instanceof ApiError ? err.envelope.error.message : t('warehouses.channel.error.unassign'));
88
+ }
89
+ finally {
90
+ setBusy(null);
91
+ }
92
+ };
93
+ // The read gate that used to stand here is the zone renderer's now — absent,
94
+ // not disabled and not a 403 panel, decided before this chunk is fetched.
95
+ if (loading)
96
+ return _jsx("div", { className: "b2b-help", children: t('warehouses.channel.loading') });
97
+ return (_jsxs("div", { className: "b2b-col", style: { gap: 12 }, children: [error ? (_jsx("div", { className: "b2b-card", style: { background: 'var(--danger-soft)', color: 'var(--danger-soft-fg)', padding: 10 }, children: error })) : null, info ? (_jsx("div", { className: "b2b-card", style: { background: 'var(--success-soft)', color: 'var(--success-soft-fg)', padding: 10 }, children: info })) : null, _jsxs("div", { className: "b2b-card", children: [_jsx("div", { className: "b2b-card__head", children: _jsx("h2", { children: t('warehouses.channel.title') }) }), _jsxs("table", { className: "b2b-tbl", children: [_jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { children: t('warehouses.channel.column.warehouse') }), _jsx("th", { children: t('warehouses.channel.column.code') }), _jsx("th", { children: t('warehouses.channel.column.default') }), _jsx("th", { children: t('warehouses.channel.column.sort') }), _jsx("th", {})] }) }), _jsx("tbody", { children: assignments.length === 0 ? (_jsx("tr", { children: _jsx("td", { colSpan: 5, children: _jsx("span", { className: "b2b-muted", children: t('warehouses.channel.empty') }) }) })) : (assignments.map((a) => (_jsxs("tr", { children: [_jsx("td", { children: a.warehouseName }), _jsx("td", { children: _jsx("span", { className: "b2b-mono", style: { fontSize: 12 }, children: a.warehouseCode }) }), _jsx("td", { children: a.isDefault ? (_jsx("span", { className: "b2b-badge b2b-badge--success", children: t('warehouses.channel.defaultBadge') })) : !canWrite ? (
98
+ // Read-only: the row is simply not the default. Rendering
99
+ // the promote button disabled would advertise a
100
+ // capability; rendering the badge would misstate the row.
101
+ _jsx("span", { className: "b2b-muted", children: "\u2014" })) : (_jsx("button", { type: "button", className: "b2b-btn b2b-btn--ghost b2b-btn--sm", onClick: () => { void handlePromote(a.id); }, disabled: busy === a.id, children: t('warehouses.channel.action.makeDefault') })) }), _jsx("td", { children: a.sortOrder }), _jsx("td", { className: "actions", children: canWrite ? (_jsx("button", { type: "button", className: "b2b-btn b2b-btn--ghost b2b-btn--sm", onClick: () => { void handleUnassign(a.id, a.isDefault); }, disabled: busy === a.id, children: t('warehouses.channel.action.unassign') })) : null })] }, a.id)))) })] })] }), canWrite && candidates.length > 0 ? (_jsxs("div", { className: "b2b-card", children: [_jsx("div", { className: "b2b-card__head", children: _jsx("h2", { children: t('warehouses.channel.addTitle') }) }), _jsx("div", { className: "b2b-card__body", children: _jsxs("div", { className: "b2b-row", style: { gap: 8, alignItems: 'flex-end' }, children: [_jsxs("div", { style: { flex: 1 }, children: [_jsx("label", { className: "b2b-label", htmlFor: "ch-add-wh", children: t('warehouses.channel.field.warehouse') }), _jsxs("select", { id: "ch-add-wh", className: "b2b-field", value: pendingWarehouseId, onChange: (e) => setPendingWarehouseId(e.target.value), children: [_jsx("option", { value: "", children: t('warehouses.channel.field.pickOne') }), candidates.map((w) => (_jsxs("option", { value: w.id, children: [w.name, " (", w.code, ")"] }, w.id)))] })] }), _jsx("button", { type: "button", className: "b2b-btn b2b-btn--primary", onClick: () => { void handleAssign(); }, disabled: busy === 'assign' || !pendingWarehouseId, children: busy === 'assign' ? t('warehouses.channel.action.adding') : t('warehouses.channel.action.add') })] }) })] })) : null] }));
102
+ }
103
+ /**
104
+ * The zone renderer loads a contribution through a dynamic-import factory and
105
+ * reads its default export (feature 091, FR-013). The named export stays: it is
106
+ * the spelling this module's own tests use.
107
+ */
108
+ export default ChannelWarehouses;
109
+ //# sourceMappingURL=ChannelWarehouses.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ChannelWarehouses.js","sourceRoot":"","sources":["../../../src/admin/zones/ChannelWarehouses.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Withdraw `inventory`'s demo data (feature 113, T223 — contract §2.5).
3
+ *
4
+ * The demo warehouse by its fixed id, and its channel assignments with it. The
5
+ * assignments the reconciler made for the **system** warehouse are left alone:
6
+ * they are the platform's own invariant — every active channel has a default
7
+ * warehouse — and not something this demo created, even though a demo run is
8
+ * what caused the reconciler to notice a channel it had not seen.
9
+ *
10
+ * The stock the composition spread across this warehouse is the composition's
11
+ * to withdraw, and it does so first: `reset` runs the composition's withdrawal
12
+ * before any module's (§5.5), which is also what leaves no `stock_levels` row
13
+ * pointing at the warehouse deleted below.
14
+ */
15
+ import type { DemoResetResult, ModuleDemoContext } from '@endora-commerce/contracts';
16
+ import type { ModuleContext } from '@endora-commerce/platform/kernel';
17
+ export declare function resetDemo(context: ModuleDemoContext<ModuleContext>): Promise<DemoResetResult>;
18
+ //# sourceMappingURL=reset.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reset.d.ts","sourceRoot":"","sources":["../../../src/backend/demo/reset.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,4BAA4B,CAAC;AACrF,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AAUtE,wBAAsB,SAAS,CAC7B,OAAO,EAAE,iBAAiB,CAAC,aAAa,CAAC,GACxC,OAAO,CAAC,eAAe,CAAC,CAe1B"}
@@ -0,0 +1,20 @@
1
+ import { Warehouse } from '../entities/warehouse.entity.js';
2
+ import { WarehouseChannelAssignment } from '../entities/warehouse-channel-assignment.entity.js';
3
+ import { DEMO_WAREHOUSE } from './rows.js';
4
+ export async function resetDemo(context) {
5
+ // command-coverage-ignore: the withdrawal half of the demo data above. Same
6
+ // entry point, same `mustBeNonProduction()` guard, same absence of an
7
+ // operator to attribute the write to (contract §2.7).
8
+ const em = context.ctx.cradle().emFactory();
9
+ const assignments = await em.nativeDelete(WarehouseChannelAssignment, {
10
+ warehouseId: DEMO_WAREHOUSE.id,
11
+ });
12
+ const warehouses = await em.nativeDelete(Warehouse, { id: DEMO_WAREHOUSE.id });
13
+ return {
14
+ removed: [
15
+ { entity: 'Warehouse', count: warehouses },
16
+ { entity: 'WarehouseChannelAssignment', count: assignments },
17
+ ],
18
+ };
19
+ }
20
+ //# sourceMappingURL=reset.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reset.js","sourceRoot":"","sources":["../../../src/backend/demo/reset.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,SAAS,EAAE,MAAM,iCAAiC,CAAC;AAC5D,OAAO,EAAE,0BAA0B,EAAE,MAAM,oDAAoD,CAAC;AAChG,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAM3C,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,OAAyC;IAEzC,4EAA4E;IAC5E,sEAAsE;IACtE,sDAAsD;IACtD,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,EAAuB,CAAC,SAAS,EAAE,CAAC;IACjE,MAAM,WAAW,GAAG,MAAM,EAAE,CAAC,YAAY,CAAC,0BAA0B,EAAE;QACpE,WAAW,EAAE,cAAc,CAAC,EAAE;KAC/B,CAAC,CAAC;IACH,MAAM,UAAU,GAAG,MAAM,EAAE,CAAC,YAAY,CAAC,SAAS,EAAE,EAAE,EAAE,EAAE,cAAc,CAAC,EAAE,EAAE,CAAC,CAAC;IAC/E,OAAO;QACL,OAAO,EAAE;YACP,EAAE,MAAM,EAAE,WAAW,EAAE,KAAK,EAAE,UAAU,EAAE;YAC1C,EAAE,MAAM,EAAE,4BAA4B,EAAE,KAAK,EAAE,WAAW,EAAE;SAC7D;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * The warehouse this module's demo data creates (feature 113, T223).
3
+ *
4
+ * One place holding the data, imported by both bodies: `seed.ts` creates the
5
+ * warehouse and its channel assignments and `reset.ts` withdraws exactly them,
6
+ * by the fixed id `seed` assigns (contract §2.5).
7
+ *
8
+ * **The id is fixed rather than minted**, and it always has been: the demo's
9
+ * second warehouse is referenced by code from the instance composition's stock
10
+ * spread, and a re-seed that minted a new id would leave the previous one
11
+ * behind with stock on it.
12
+ *
13
+ * ## §2.6, and why this row has no per-language map
14
+ *
15
+ * `Warehouse.name` and `Warehouse.description` are scalar columns — a
16
+ * `varchar(160)` and a `text` — so the per-language shape §2.6 asks for has
17
+ * nowhere to go, and putting it there would be a migration this feature does
18
+ * not take (contract §8). What that leaves is a choice about the value itself,
19
+ * and it is decided the way the rest of the platform decides it: a warehouse
20
+ * name is **operator content**, the sort of string a shop writes for itself, and
21
+ * the default language for anything a developer writes is English (the owner's
22
+ * ruling of 2026-09-01). The demo used to write `Magazyn Kraków`, which is a
23
+ * Polish sentence in a module's own sources with no per-language structure
24
+ * around it — `check:default-language-prose`'s subject exactly, invisible only
25
+ * because `backend/src/seeds/` is in no module walk root. So the label is
26
+ * English and the place name stays a place name.
27
+ */
28
+ /** The demo's second warehouse, in `Warehouse`'s own field names. */
29
+ export declare const DEMO_WAREHOUSE: {
30
+ readonly id: "00000000-0000-4000-8000-00000000d0c0";
31
+ readonly code: "pl-krk";
32
+ readonly name: "Krakow warehouse";
33
+ readonly active: true;
34
+ readonly description: "Demo secondary warehouse — Krakow, PL";
35
+ };
36
+ /** Where the demo's assignments sort, behind the system warehouse's default. */
37
+ export declare const DEMO_ASSIGNMENT_SORT_ORDER = 1;
38
+ //# sourceMappingURL=rows.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rows.d.ts","sourceRoot":"","sources":["../../../src/backend/demo/rows.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,qEAAqE;AACrE,eAAO,MAAM,cAAc;;;;;;CAMjB,CAAC;AAEX,gFAAgF;AAChF,eAAO,MAAM,0BAA0B,IAAI,CAAC"}