@endora-commerce/contracts 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 (327) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +34 -0
  3. package/dist/actor.d.ts +79 -0
  4. package/dist/actor.d.ts.map +1 -0
  5. package/dist/actor.js +41 -0
  6. package/dist/actor.js.map +1 -0
  7. package/dist/addresses.d.ts +134 -0
  8. package/dist/addresses.d.ts.map +1 -0
  9. package/dist/addresses.js +16 -0
  10. package/dist/addresses.js.map +1 -0
  11. package/dist/admin-actions.d.ts +367 -0
  12. package/dist/admin-actions.d.ts.map +1 -0
  13. package/dist/admin-actions.js +287 -0
  14. package/dist/admin-actions.js.map +1 -0
  15. package/dist/admin-contributions.d.ts +518 -0
  16. package/dist/admin-contributions.d.ts.map +1 -0
  17. package/dist/admin-contributions.js +495 -0
  18. package/dist/admin-contributions.js.map +1 -0
  19. package/dist/admin-i18n.d.ts +135 -0
  20. package/dist/admin-i18n.d.ts.map +1 -0
  21. package/dist/admin-i18n.js +72 -0
  22. package/dist/admin-i18n.js.map +1 -0
  23. package/dist/admin-notifications.d.ts +55 -0
  24. package/dist/admin-notifications.d.ts.map +1 -0
  25. package/dist/admin-notifications.js +16 -0
  26. package/dist/admin-notifications.js.map +1 -0
  27. package/dist/admin-roles.d.ts +125 -0
  28. package/dist/admin-roles.d.ts.map +1 -0
  29. package/dist/admin-roles.js +2 -0
  30. package/dist/admin-roles.js.map +1 -0
  31. package/dist/admin-users.d.ts +178 -0
  32. package/dist/admin-users.d.ts.map +1 -0
  33. package/dist/admin-users.js +14 -0
  34. package/dist/admin-users.js.map +1 -0
  35. package/dist/admin.d.ts +243 -0
  36. package/dist/admin.d.ts.map +1 -0
  37. package/dist/admin.js +246 -0
  38. package/dist/admin.js.map +1 -0
  39. package/dist/analytics.d.ts +123 -0
  40. package/dist/analytics.d.ts.map +1 -0
  41. package/dist/analytics.js +68 -0
  42. package/dist/analytics.js.map +1 -0
  43. package/dist/api-keys.d.ts +97 -0
  44. package/dist/api-keys.d.ts.map +1 -0
  45. package/dist/api-keys.js +64 -0
  46. package/dist/api-keys.js.map +1 -0
  47. package/dist/assets-library.d.ts +684 -0
  48. package/dist/assets-library.d.ts.map +1 -0
  49. package/dist/assets-library.js +181 -0
  50. package/dist/assets-library.js.map +1 -0
  51. package/dist/audit-logs.d.ts +141 -0
  52. package/dist/audit-logs.d.ts.map +1 -0
  53. package/dist/audit-logs.js +31 -0
  54. package/dist/audit-logs.js.map +1 -0
  55. package/dist/auth.d.ts +174 -0
  56. package/dist/auth.d.ts.map +1 -0
  57. package/dist/auth.js +27 -0
  58. package/dist/auth.js.map +1 -0
  59. package/dist/blog.d.ts +669 -0
  60. package/dist/blog.d.ts.map +1 -0
  61. package/dist/blog.js +360 -0
  62. package/dist/blog.js.map +1 -0
  63. package/dist/capabilities.d.ts +40 -0
  64. package/dist/capabilities.d.ts.map +1 -0
  65. package/dist/capabilities.js +38 -0
  66. package/dist/capabilities.js.map +1 -0
  67. package/dist/carts.d.ts +1367 -0
  68. package/dist/carts.d.ts.map +1 -0
  69. package/dist/carts.js +405 -0
  70. package/dist/carts.js.map +1 -0
  71. package/dist/catalog.d.ts +2855 -0
  72. package/dist/catalog.d.ts.map +1 -0
  73. package/dist/catalog.js +1543 -0
  74. package/dist/catalog.js.map +1 -0
  75. package/dist/cms.d.ts +872 -0
  76. package/dist/cms.d.ts.map +1 -0
  77. package/dist/cms.js +468 -0
  78. package/dist/cms.js.map +1 -0
  79. package/dist/common.d.ts +82 -0
  80. package/dist/common.d.ts.map +1 -0
  81. package/dist/common.js +72 -0
  82. package/dist/common.js.map +1 -0
  83. package/dist/comparisons.d.ts +487 -0
  84. package/dist/comparisons.d.ts.map +1 -0
  85. package/dist/comparisons.js +221 -0
  86. package/dist/comparisons.js.map +1 -0
  87. package/dist/credentials.d.ts +292 -0
  88. package/dist/credentials.d.ts.map +1 -0
  89. package/dist/credentials.js +142 -0
  90. package/dist/credentials.js.map +1 -0
  91. package/dist/credit-limits.d.ts +111 -0
  92. package/dist/credit-limits.d.ts.map +1 -0
  93. package/dist/credit-limits.js +35 -0
  94. package/dist/credit-limits.js.map +1 -0
  95. package/dist/currencies.d.ts +127 -0
  96. package/dist/currencies.d.ts.map +1 -0
  97. package/dist/currencies.js +20 -0
  98. package/dist/currencies.js.map +1 -0
  99. package/dist/custom-fields.d.ts +345 -0
  100. package/dist/custom-fields.d.ts.map +1 -0
  101. package/dist/custom-fields.js +185 -0
  102. package/dist/custom-fields.js.map +1 -0
  103. package/dist/customer-accounts.d.ts +690 -0
  104. package/dist/customer-accounts.d.ts.map +1 -0
  105. package/dist/customer-accounts.js +41 -0
  106. package/dist/customer-accounts.js.map +1 -0
  107. package/dist/customers.d.ts +305 -0
  108. package/dist/customers.d.ts.map +1 -0
  109. package/dist/customers.js +158 -0
  110. package/dist/customers.js.map +1 -0
  111. package/dist/dictionary.d.ts +580 -0
  112. package/dist/dictionary.d.ts.map +1 -0
  113. package/dist/dictionary.js +297 -0
  114. package/dist/dictionary.js.map +1 -0
  115. package/dist/email-address.d.ts +62 -0
  116. package/dist/email-address.d.ts.map +1 -0
  117. package/dist/email-address.js +64 -0
  118. package/dist/email-address.js.map +1 -0
  119. package/dist/email.d.ts +175 -0
  120. package/dist/email.d.ts.map +1 -0
  121. package/dist/email.js +45 -0
  122. package/dist/email.js.map +1 -0
  123. package/dist/envelopes.d.ts +15 -0
  124. package/dist/envelopes.d.ts.map +1 -0
  125. package/dist/envelopes.js +16 -0
  126. package/dist/envelopes.js.map +1 -0
  127. package/dist/environment-inputs.d.ts +306 -0
  128. package/dist/environment-inputs.d.ts.map +1 -0
  129. package/dist/environment-inputs.js +277 -0
  130. package/dist/environment-inputs.js.map +1 -0
  131. package/dist/erp-connector.d.ts +52 -0
  132. package/dist/erp-connector.d.ts.map +1 -0
  133. package/dist/erp-connector.js +34 -0
  134. package/dist/erp-connector.js.map +1 -0
  135. package/dist/errors.d.ts +455 -0
  136. package/dist/errors.d.ts.map +1 -0
  137. package/dist/errors.js +532 -0
  138. package/dist/errors.js.map +1 -0
  139. package/dist/google-analytics.d.ts +181 -0
  140. package/dist/google-analytics.d.ts.map +1 -0
  141. package/dist/google-analytics.js +176 -0
  142. package/dist/google-analytics.js.map +1 -0
  143. package/dist/google-tag-manager.d.ts +111 -0
  144. package/dist/google-tag-manager.d.ts.map +1 -0
  145. package/dist/google-tag-manager.js +129 -0
  146. package/dist/google-tag-manager.js.map +1 -0
  147. package/dist/i18n.d.ts +69 -0
  148. package/dist/i18n.d.ts.map +1 -0
  149. package/dist/i18n.js +59 -0
  150. package/dist/i18n.js.map +1 -0
  151. package/dist/import-export.d.ts +63 -0
  152. package/dist/import-export.d.ts.map +1 -0
  153. package/dist/import-export.js +37 -0
  154. package/dist/import-export.js.map +1 -0
  155. package/dist/index.d.ts +82 -0
  156. package/dist/index.d.ts.map +1 -0
  157. package/dist/index.js +126 -0
  158. package/dist/index.js.map +1 -0
  159. package/dist/inventory.d.ts +673 -0
  160. package/dist/inventory.d.ts.map +1 -0
  161. package/dist/inventory.js +412 -0
  162. package/dist/inventory.js.map +1 -0
  163. package/dist/invoice-ledger.d.ts +366 -0
  164. package/dist/invoice-ledger.d.ts.map +1 -0
  165. package/dist/invoice-ledger.js +114 -0
  166. package/dist/invoice-ledger.js.map +1 -0
  167. package/dist/invoices.d.ts +845 -0
  168. package/dist/invoices.d.ts.map +1 -0
  169. package/dist/invoices.js +314 -0
  170. package/dist/invoices.js.map +1 -0
  171. package/dist/kernel.d.ts +49 -0
  172. package/dist/kernel.d.ts.map +1 -0
  173. package/dist/kernel.js +19 -0
  174. package/dist/kernel.js.map +1 -0
  175. package/dist/languages.d.ts +122 -0
  176. package/dist/languages.d.ts.map +1 -0
  177. package/dist/languages.js +24 -0
  178. package/dist/languages.js.map +1 -0
  179. package/dist/linkedin-ads.d.ts +167 -0
  180. package/dist/linkedin-ads.d.ts.map +1 -0
  181. package/dist/linkedin-ads.js +156 -0
  182. package/dist/linkedin-ads.js.map +1 -0
  183. package/dist/megamenu.d.ts +556 -0
  184. package/dist/megamenu.d.ts.map +1 -0
  185. package/dist/megamenu.js +186 -0
  186. package/dist/megamenu.js.map +1 -0
  187. package/dist/meta-ads.d.ts +126 -0
  188. package/dist/meta-ads.d.ts.map +1 -0
  189. package/dist/meta-ads.js +112 -0
  190. package/dist/meta-ads.js.map +1 -0
  191. package/dist/mfa.d.ts +274 -0
  192. package/dist/mfa.d.ts.map +1 -0
  193. package/dist/mfa.js +187 -0
  194. package/dist/mfa.js.map +1 -0
  195. package/dist/modules.d.ts +1706 -0
  196. package/dist/modules.d.ts.map +1 -0
  197. package/dist/modules.js +1390 -0
  198. package/dist/modules.js.map +1 -0
  199. package/dist/newsletter.d.ts +611 -0
  200. package/dist/newsletter.d.ts.map +1 -0
  201. package/dist/newsletter.js +345 -0
  202. package/dist/newsletter.js.map +1 -0
  203. package/dist/orders.d.ts +1175 -0
  204. package/dist/orders.d.ts.map +1 -0
  205. package/dist/orders.js +630 -0
  206. package/dist/orders.js.map +1 -0
  207. package/dist/organizations.d.ts +938 -0
  208. package/dist/organizations.d.ts.map +1 -0
  209. package/dist/organizations.js +418 -0
  210. package/dist/organizations.js.map +1 -0
  211. package/dist/pagination.d.ts +21 -0
  212. package/dist/pagination.d.ts.map +1 -0
  213. package/dist/pagination.js +22 -0
  214. package/dist/pagination.js.map +1 -0
  215. package/dist/payment-methods.d.ts +472 -0
  216. package/dist/payment-methods.d.ts.map +1 -0
  217. package/dist/payment-methods.js +175 -0
  218. package/dist/payment-methods.js.map +1 -0
  219. package/dist/payment-return-url.d.ts +53 -0
  220. package/dist/payment-return-url.d.ts.map +1 -0
  221. package/dist/payment-return-url.js +35 -0
  222. package/dist/payment-return-url.js.map +1 -0
  223. package/dist/payments.d.ts +386 -0
  224. package/dist/payments.d.ts.map +1 -0
  225. package/dist/payments.js +84 -0
  226. package/dist/payments.js.map +1 -0
  227. package/dist/pim-connector.d.ts +60 -0
  228. package/dist/pim-connector.d.ts.map +1 -0
  229. package/dist/pim-connector.js +43 -0
  230. package/dist/pim-connector.js.map +1 -0
  231. package/dist/pim-field-path.d.ts +6 -0
  232. package/dist/pim-field-path.d.ts.map +1 -0
  233. package/dist/pim-field-path.js +101 -0
  234. package/dist/pim-field-path.js.map +1 -0
  235. package/dist/platform-language.d.ts +20 -0
  236. package/dist/platform-language.d.ts.map +1 -0
  237. package/dist/platform-language.js +22 -0
  238. package/dist/platform-language.js.map +1 -0
  239. package/dist/price-lists.d.ts +685 -0
  240. package/dist/price-lists.d.ts.map +1 -0
  241. package/dist/price-lists.js +330 -0
  242. package/dist/price-lists.js.map +1 -0
  243. package/dist/product-feeds.d.ts +2837 -0
  244. package/dist/product-feeds.d.ts.map +1 -0
  245. package/dist/product-feeds.js +1504 -0
  246. package/dist/product-feeds.js.map +1 -0
  247. package/dist/product-scope-overrides.d.ts +134 -0
  248. package/dist/product-scope-overrides.d.ts.map +1 -0
  249. package/dist/product-scope-overrides.js +82 -0
  250. package/dist/product-scope-overrides.js.map +1 -0
  251. package/dist/product-value-resolver.d.ts +88 -0
  252. package/dist/product-value-resolver.d.ts.map +1 -0
  253. package/dist/product-value-resolver.js +128 -0
  254. package/dist/product-value-resolver.js.map +1 -0
  255. package/dist/promotions.d.ts +678 -0
  256. package/dist/promotions.d.ts.map +1 -0
  257. package/dist/promotions.js +479 -0
  258. package/dist/promotions.js.map +1 -0
  259. package/dist/prompt-actions.d.ts +582 -0
  260. package/dist/prompt-actions.d.ts.map +1 -0
  261. package/dist/prompt-actions.js +221 -0
  262. package/dist/prompt-actions.js.map +1 -0
  263. package/dist/pwa.d.ts +293 -0
  264. package/dist/pwa.d.ts.map +1 -0
  265. package/dist/pwa.js +204 -0
  266. package/dist/pwa.js.map +1 -0
  267. package/dist/quick-order.d.ts +340 -0
  268. package/dist/quick-order.d.ts.map +1 -0
  269. package/dist/quick-order.js +177 -0
  270. package/dist/quick-order.js.map +1 -0
  271. package/dist/quote-requests.d.ts +538 -0
  272. package/dist/quote-requests.d.ts.map +1 -0
  273. package/dist/quote-requests.js +308 -0
  274. package/dist/quote-requests.js.map +1 -0
  275. package/dist/returns.d.ts +774 -0
  276. package/dist/returns.d.ts.map +1 -0
  277. package/dist/returns.js +389 -0
  278. package/dist/returns.js.map +1 -0
  279. package/dist/sales-channels.d.ts +392 -0
  280. package/dist/sales-channels.d.ts.map +1 -0
  281. package/dist/sales-channels.js +285 -0
  282. package/dist/sales-channels.js.map +1 -0
  283. package/dist/scope-notice.d.ts +60 -0
  284. package/dist/scope-notice.d.ts.map +1 -0
  285. package/dist/scope-notice.js +56 -0
  286. package/dist/scope-notice.js.map +1 -0
  287. package/dist/search.d.ts +321 -0
  288. package/dist/search.d.ts.map +1 -0
  289. package/dist/search.js +160 -0
  290. package/dist/search.js.map +1 -0
  291. package/dist/seo.d.ts +113 -0
  292. package/dist/seo.d.ts.map +1 -0
  293. package/dist/seo.js +63 -0
  294. package/dist/seo.js.map +1 -0
  295. package/dist/settings.d.ts +453 -0
  296. package/dist/settings.d.ts.map +1 -0
  297. package/dist/settings.js +337 -0
  298. package/dist/settings.js.map +1 -0
  299. package/dist/shipments.d.ts +140 -0
  300. package/dist/shipments.d.ts.map +1 -0
  301. package/dist/shipments.js +14 -0
  302. package/dist/shipments.js.map +1 -0
  303. package/dist/shipping-methods.d.ts +350 -0
  304. package/dist/shipping-methods.d.ts.map +1 -0
  305. package/dist/shipping-methods.js +99 -0
  306. package/dist/shipping-methods.js.map +1 -0
  307. package/dist/shopping-lists.d.ts +122 -0
  308. package/dist/shopping-lists.d.ts.map +1 -0
  309. package/dist/shopping-lists.js +92 -0
  310. package/dist/shopping-lists.js.map +1 -0
  311. package/dist/taxes.d.ts +106 -0
  312. package/dist/taxes.d.ts.map +1 -0
  313. package/dist/taxes.js +80 -0
  314. package/dist/taxes.js.map +1 -0
  315. package/dist/text-normalization.d.ts +199 -0
  316. package/dist/text-normalization.d.ts.map +1 -0
  317. package/dist/text-normalization.js +205 -0
  318. package/dist/text-normalization.js.map +1 -0
  319. package/dist/transactional-emails.d.ts +459 -0
  320. package/dist/transactional-emails.d.ts.map +1 -0
  321. package/dist/transactional-emails.js +212 -0
  322. package/dist/transactional-emails.js.map +1 -0
  323. package/dist/webhooks.d.ts +69 -0
  324. package/dist/webhooks.d.ts.map +1 -0
  325. package/dist/webhooks.js +53 -0
  326. package/dist/webhooks.js.map +1 -0
  327. package/package.json +46 -0
@@ -0,0 +1,938 @@
1
+ import { z } from 'zod';
2
+ import { type FulfilmentStrategy } from './inventory.js';
3
+ /**
4
+ * Organizations, customer accounts, addresses, invitations — Source of truth
5
+ * per Principle V. Drives US2 + US3.
6
+ * See specs/001-b2b-platform-foundation/contracts/organizations.contract.md.
7
+ */
8
+ /**
9
+ * Organization lifecycle status (feature 026 consolidation).
10
+ *
11
+ * - `pending_verification` — newly registered, blocks transactions until
12
+ * moderator approves (manual moderation mode) or auto-activated.
13
+ * - `active` — may transact normally.
14
+ * - `blocked` — operator-blocked (replaces the legacy `suspended`); the
15
+ * Organization cannot place Orders or Quote Requests; reversible.
16
+ * - `rejected` — moderator rejected at registration; terminal.
17
+ */
18
+ export declare const organizationStatusSchema: z.ZodEnum<{
19
+ active: "active";
20
+ rejected: "rejected";
21
+ blocked: "blocked";
22
+ pending_verification: "pending_verification";
23
+ }>;
24
+ export type OrganizationStatus = z.infer<typeof organizationStatusSchema>;
25
+ export declare const vatStatusSchema: z.ZodEnum<{
26
+ vat_payer: "vat_payer";
27
+ vat_exempt: "vat_exempt";
28
+ reverse_charge: "reverse_charge";
29
+ }>;
30
+ export type VatStatus = z.infer<typeof vatStatusSchema>;
31
+ /**
32
+ * Feature 056 — per-organization credit-inheritance mode. Platform-admin only.
33
+ *
34
+ * - `shared_pool` — a descendant with no own credit limit draws against the
35
+ * nearest ancestor's pool; concurrent draws across the subtree are serialized
36
+ * on the owning ancestor's row (zero double-spend).
37
+ * - `independent_default` — the inherited amount is each descendant's own
38
+ * effective limit; draws are independent of siblings.
39
+ *
40
+ * `null` on an Organization ⇒ fall back to the Settings global default
41
+ * (`organizations.hierarchy.credit_inheritance_mode`, factory `shared_pool`).
42
+ */
43
+ export declare const creditInheritanceModeSchema: z.ZodEnum<{
44
+ shared_pool: "shared_pool";
45
+ independent_default: "independent_default";
46
+ }>;
47
+ export type CreditInheritanceMode = z.infer<typeof creditInheritanceModeSchema>;
48
+ export declare const addressKindSchema: z.ZodEnum<{
49
+ delivery: "delivery";
50
+ billing: "billing";
51
+ }>;
52
+ export type AddressKind = z.infer<typeof addressKindSchema>;
53
+ export declare const organizationSchema: z.ZodObject<{
54
+ id: z.ZodString;
55
+ name: z.ZodString;
56
+ taxId: z.ZodString;
57
+ status: z.ZodEnum<{
58
+ active: "active";
59
+ rejected: "rejected";
60
+ blocked: "blocked";
61
+ pending_verification: "pending_verification";
62
+ }>;
63
+ vatStatus: z.ZodEnum<{
64
+ vat_payer: "vat_payer";
65
+ vat_exempt: "vat_exempt";
66
+ reverse_charge: "reverse_charge";
67
+ }>;
68
+ isPersonal: z.ZodOptional<z.ZodBoolean>;
69
+ registeredAddress: z.ZodObject<{
70
+ street: z.ZodString;
71
+ city: z.ZodString;
72
+ postalCode: z.ZodString;
73
+ country: z.ZodString;
74
+ companyName: z.ZodOptional<z.ZodString>;
75
+ taxId: z.ZodOptional<z.ZodString>;
76
+ recipientName: z.ZodOptional<z.ZodString>;
77
+ phone: z.ZodOptional<z.ZodString>;
78
+ }, z.core.$strip>;
79
+ fulfilmentStrategy: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
80
+ any: "any";
81
+ default_first: "default_first";
82
+ lowest_stock_first: "lowest_stock_first";
83
+ highest_stock_first: "highest_stock_first";
84
+ defined_order: "defined_order";
85
+ }>>>;
86
+ fulfilmentStrategyWarehouseOrder: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodString>>>;
87
+ parentId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
88
+ path: z.ZodOptional<z.ZodString>;
89
+ creditInheritanceMode: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
90
+ shared_pool: "shared_pool";
91
+ independent_default: "independent_default";
92
+ }>>>;
93
+ createdAt: z.ZodString;
94
+ updatedAt: z.ZodString;
95
+ }, z.core.$strip>;
96
+ export type Organization = z.infer<typeof organizationSchema>;
97
+ /**
98
+ * A single node in an organization subtree / ancestor chain. `depth` is the
99
+ * node's absolute depth in the tree (root = 0). Returned pre-order (subtree) or
100
+ * nearest-first (ancestors).
101
+ */
102
+ export declare const organizationTreeNodeSchema: z.ZodObject<{
103
+ id: z.ZodString;
104
+ name: z.ZodString;
105
+ parentId: z.ZodNullable<z.ZodString>;
106
+ depth: z.ZodNumber;
107
+ status: z.ZodEnum<{
108
+ active: "active";
109
+ rejected: "rejected";
110
+ blocked: "blocked";
111
+ pending_verification: "pending_verification";
112
+ }>;
113
+ }, z.core.$strip>;
114
+ export type OrganizationTreeNode = z.infer<typeof organizationTreeNodeSchema>;
115
+ /** `GET /admin/organizations/:id/subtree` — descendants (incl. self), pre-order. */
116
+ export declare const organizationSubtreeResponseSchema: z.ZodObject<{
117
+ items: z.ZodArray<z.ZodObject<{
118
+ id: z.ZodString;
119
+ name: z.ZodString;
120
+ parentId: z.ZodNullable<z.ZodString>;
121
+ depth: z.ZodNumber;
122
+ status: z.ZodEnum<{
123
+ active: "active";
124
+ rejected: "rejected";
125
+ blocked: "blocked";
126
+ pending_verification: "pending_verification";
127
+ }>;
128
+ }, z.core.$strip>>;
129
+ }, z.core.$strip>;
130
+ export type OrganizationSubtreeResponse = z.infer<typeof organizationSubtreeResponseSchema>;
131
+ /** `GET /admin/organizations/:id/ancestors` — ancestor chain, nearest-first. */
132
+ export declare const organizationAncestorsResponseSchema: z.ZodObject<{
133
+ items: z.ZodArray<z.ZodObject<{
134
+ id: z.ZodString;
135
+ name: z.ZodString;
136
+ parentId: z.ZodNullable<z.ZodString>;
137
+ depth: z.ZodNumber;
138
+ status: z.ZodEnum<{
139
+ active: "active";
140
+ rejected: "rejected";
141
+ blocked: "blocked";
142
+ pending_verification: "pending_verification";
143
+ }>;
144
+ }, z.core.$strip>>;
145
+ }, z.core.$strip>;
146
+ export type OrganizationAncestorsResponse = z.infer<typeof organizationAncestorsResponseSchema>;
147
+ /**
148
+ * `POST /admin/organizations/:id/parent` — assign / move / detach parent.
149
+ * `parentId = null` makes `:id` a root. Path maintenance + cycle/depth checks
150
+ * are guaranteed server-side (this is the only writable path for `parentId`).
151
+ */
152
+ export declare const assignOrganizationParentRequestSchema: z.ZodObject<{
153
+ parentId: z.ZodNullable<z.ZodString>;
154
+ }, z.core.$strip>;
155
+ export type AssignOrganizationParentRequest = z.infer<typeof assignOrganizationParentRequestSchema>;
156
+ /**
157
+ * `PUT /admin/organizations/:id/credit-inheritance-mode` — platform-admin only.
158
+ * `mode = null` ⇒ fall back to the Settings global default.
159
+ */
160
+ export declare const setCreditInheritanceModeRequestSchema: z.ZodObject<{
161
+ mode: z.ZodNullable<z.ZodEnum<{
162
+ shared_pool: "shared_pool";
163
+ independent_default: "independent_default";
164
+ }>>;
165
+ }, z.core.$strip>;
166
+ export type SetCreditInheritanceModeRequest = z.infer<typeof setCreditInheritanceModeRequestSchema>;
167
+ export declare const customerAccountSchema: z.ZodObject<{
168
+ id: z.ZodString;
169
+ organizationId: z.ZodString;
170
+ email: z.ZodString;
171
+ firstName: z.ZodString;
172
+ lastName: z.ZodString;
173
+ role: z.ZodEnum<{
174
+ organization_admin: "organization_admin";
175
+ regular_user: "regular_user";
176
+ }>;
177
+ emailVerifiedAt: z.ZodNullable<z.ZodString>;
178
+ twoFactorEnabled: z.ZodBoolean;
179
+ createdAt: z.ZodString;
180
+ updatedAt: z.ZodString;
181
+ }, z.core.$strip>;
182
+ export type CustomerAccount = z.infer<typeof customerAccountSchema>;
183
+ export declare const addressSchema: z.ZodObject<{
184
+ id: z.ZodString;
185
+ organizationId: z.ZodString;
186
+ kind: z.ZodEnum<{
187
+ delivery: "delivery";
188
+ billing: "billing";
189
+ }>;
190
+ recipientName: z.ZodString;
191
+ street: z.ZodString;
192
+ city: z.ZodString;
193
+ postalCode: z.ZodString;
194
+ country: z.ZodString;
195
+ phone: z.ZodOptional<z.ZodNullable<z.ZodString>>;
196
+ isDefault: z.ZodBoolean;
197
+ }, z.core.$strip>;
198
+ export type Address = z.infer<typeof addressSchema>;
199
+ export declare const registerOrganizationRequestSchema: z.ZodObject<{
200
+ organization: z.ZodObject<{
201
+ name: z.ZodString;
202
+ taxId: z.ZodString;
203
+ registeredAddress: z.ZodObject<{
204
+ street: z.ZodString;
205
+ city: z.ZodString;
206
+ postalCode: z.ZodString;
207
+ country: z.ZodString;
208
+ }, z.core.$strip>;
209
+ vatStatus: z.ZodOptional<z.ZodEnum<{
210
+ vat_payer: "vat_payer";
211
+ vat_exempt: "vat_exempt";
212
+ reverse_charge: "reverse_charge";
213
+ }>>;
214
+ }, z.core.$strip>;
215
+ firstUser: z.ZodObject<{
216
+ email: z.ZodString;
217
+ password: z.ZodString;
218
+ firstName: z.ZodString;
219
+ lastName: z.ZodString;
220
+ }, z.core.$strip>;
221
+ acceptedTermsVersion: z.ZodString;
222
+ }, z.core.$strip>;
223
+ export type RegisterOrganizationRequest = z.infer<typeof registerOrganizationRequestSchema>;
224
+ export declare const emailVerificationRequestSchema: z.ZodObject<{
225
+ token: z.ZodString;
226
+ }, z.core.$strip>;
227
+ export declare const passwordResetRequestSchema: z.ZodObject<{
228
+ email: z.ZodString;
229
+ }, z.core.$strip>;
230
+ export declare const passwordResetConfirmSchema: z.ZodObject<{
231
+ token: z.ZodString;
232
+ newPassword: z.ZodString;
233
+ }, z.core.$strip>;
234
+ export declare const customerLoginRequestSchema: z.ZodObject<{
235
+ email: z.ZodString;
236
+ password: z.ZodString;
237
+ }, z.core.$strip>;
238
+ /**
239
+ * Outcome of the anonymous-cart → customer-cart merge that runs inside the
240
+ * customer-login flow (feature 037-cart-merge-on-login).
241
+ *
242
+ * Internal shape — split between two `noop_*` variants so the audit /
243
+ * observability paths can distinguish "anon cart was empty" from "no anon
244
+ * cart was supplied". The HTTP-facing shape collapses both into a single
245
+ * `'noop'`; see `cartMergeOutcomePublicSchema` below.
246
+ */
247
+ export declare const cartMergeOutcomeSchema: z.ZodObject<{
248
+ outcome: z.ZodEnum<{
249
+ adopted: "adopted";
250
+ merged: "merged";
251
+ noop_empty: "noop_empty";
252
+ noop_no_anon: "noop_no_anon";
253
+ }>;
254
+ movedLineCount: z.ZodNumber;
255
+ summedLineCount: z.ZodNumber;
256
+ destinationCartId: z.ZodString;
257
+ }, z.core.$strip>;
258
+ export type CartMergeOutcome = z.infer<typeof cartMergeOutcomeSchema>;
259
+ /**
260
+ * Public (HTTP) narrowing of `cartMergeOutcomeSchema`. The storefront only
261
+ * needs three buckets to decide whether to surface the merge-confirmation
262
+ * toast (`adopted | merged → toast`, `noop → silent`) and the destination
263
+ * cart id for the next cart read.
264
+ */
265
+ export declare const cartMergeOutcomePublicSchema: z.ZodObject<{
266
+ outcome: z.ZodEnum<{
267
+ adopted: "adopted";
268
+ merged: "merged";
269
+ noop: "noop";
270
+ }>;
271
+ destinationCartId: z.ZodString;
272
+ }, z.core.$strip>;
273
+ export type CartMergeOutcomePublic = z.infer<typeof cartMergeOutcomePublicSchema>;
274
+ /**
275
+ * Customer login response. The `cartMerge` field is populated when the
276
+ * login carries an anonymous-cart cookie; `null` when no anon cookie was
277
+ * supplied; `outcome: 'noop'` when the cookie was supplied but had no
278
+ * observable effect (no anon cart, or the anon cart was empty).
279
+ */
280
+ export declare const customerLoginResponseSchema: z.ZodObject<{
281
+ data: z.ZodObject<{
282
+ customerAccount: z.ZodObject<{
283
+ id: z.ZodString;
284
+ email: z.ZodString;
285
+ organizationId: z.ZodNullable<z.ZodString>;
286
+ role: z.ZodEnum<{
287
+ organization_admin: "organization_admin";
288
+ regular_user: "regular_user";
289
+ }>;
290
+ twoFactorEnabled: z.ZodBoolean;
291
+ }, z.core.$strip>;
292
+ cartMerge: z.ZodOptional<z.ZodNullable<z.ZodObject<{
293
+ outcome: z.ZodEnum<{
294
+ adopted: "adopted";
295
+ merged: "merged";
296
+ noop: "noop";
297
+ }>;
298
+ destinationCartId: z.ZodString;
299
+ }, z.core.$strip>>>;
300
+ }, z.core.$strip>;
301
+ }, z.core.$strip>;
302
+ export type CustomerLoginResponse = z.infer<typeof customerLoginResponseSchema>;
303
+ export declare const changePasswordRequestSchema: z.ZodObject<{
304
+ currentPassword: z.ZodString;
305
+ newPassword: z.ZodString;
306
+ }, z.core.$strip>;
307
+ export declare const createAddressRequestSchema: z.ZodObject<{
308
+ kind: z.ZodEnum<{
309
+ delivery: "delivery";
310
+ billing: "billing";
311
+ }>;
312
+ recipientName: z.ZodString;
313
+ street: z.ZodString;
314
+ city: z.ZodString;
315
+ postalCode: z.ZodString;
316
+ country: z.ZodString;
317
+ phone: z.ZodOptional<z.ZodString>;
318
+ isDefault: z.ZodOptional<z.ZodBoolean>;
319
+ }, z.core.$strip>;
320
+ export type CreateAddressRequest = z.infer<typeof createAddressRequestSchema>;
321
+ export declare const updateAddressRequestSchema: z.ZodObject<{
322
+ kind: z.ZodOptional<z.ZodEnum<{
323
+ delivery: "delivery";
324
+ billing: "billing";
325
+ }>>;
326
+ recipientName: z.ZodOptional<z.ZodString>;
327
+ street: z.ZodOptional<z.ZodString>;
328
+ city: z.ZodOptional<z.ZodString>;
329
+ postalCode: z.ZodOptional<z.ZodString>;
330
+ country: z.ZodOptional<z.ZodString>;
331
+ phone: z.ZodOptional<z.ZodOptional<z.ZodString>>;
332
+ isDefault: z.ZodOptional<z.ZodOptional<z.ZodBoolean>>;
333
+ }, z.core.$strip>;
334
+ export type UpdateAddressRequest = z.infer<typeof updateAddressRequestSchema>;
335
+ export declare const inviteMemberRequestSchema: z.ZodObject<{
336
+ email: z.ZodString;
337
+ role: z.ZodOptional<z.ZodEnum<{
338
+ organization_admin: "organization_admin";
339
+ regular_user: "regular_user";
340
+ }>>;
341
+ }, z.core.$strip>;
342
+ export declare const acceptInvitationRequestSchema: z.ZodObject<{
343
+ password: z.ZodString;
344
+ firstName: z.ZodString;
345
+ lastName: z.ZodString;
346
+ }, z.core.$strip>;
347
+ export declare const changeMemberRoleRequestSchema: z.ZodObject<{
348
+ role: z.ZodEnum<{
349
+ organization_admin: "organization_admin";
350
+ regular_user: "regular_user";
351
+ }>;
352
+ }, z.core.$strip>;
353
+ /** Platform admin — PATCH `/admin/organizations/:id` */
354
+ export declare const adminPatchOrganizationRequestSchema: z.ZodObject<{
355
+ name: z.ZodOptional<z.ZodString>;
356
+ vatStatus: z.ZodOptional<z.ZodEnum<{
357
+ vat_payer: "vat_payer";
358
+ vat_exempt: "vat_exempt";
359
+ reverse_charge: "reverse_charge";
360
+ }>>;
361
+ status: z.ZodOptional<z.ZodEnum<{
362
+ active: "active";
363
+ rejected: "rejected";
364
+ blocked: "blocked";
365
+ pending_verification: "pending_verification";
366
+ }>>;
367
+ orderConfirmationEmails: z.ZodOptional<z.ZodArray<z.ZodString>>;
368
+ fulfilmentStrategy: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
369
+ any: "any";
370
+ default_first: "default_first";
371
+ lowest_stock_first: "lowest_stock_first";
372
+ highest_stock_first: "highest_stock_first";
373
+ defined_order: "defined_order";
374
+ }>>>;
375
+ fulfilmentStrategyWarehouseOrder: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodString>>>;
376
+ customFieldValues: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnknown>>;
377
+ expectedUpdatedAt: z.ZodOptional<z.ZodString>;
378
+ }, z.core.$strip>;
379
+ /** Platform admin — POST `/admin/organizations/:id/recover-admin-access` */
380
+ export declare const adminRecoverOrgAccessRequestSchema: z.ZodObject<{
381
+ promoteCustomerAccountId: z.ZodString;
382
+ }, z.core.$strip>;
383
+ /** Platform admin — POST `/admin/organizations/:id/members` (direct create) */
384
+ export declare const adminDirectMemberRequestSchema: z.ZodObject<{
385
+ email: z.ZodString;
386
+ firstName: z.ZodString;
387
+ lastName: z.ZodString;
388
+ password: z.ZodString;
389
+ role: z.ZodOptional<z.ZodEnum<{
390
+ organization_admin: "organization_admin";
391
+ regular_user: "regular_user";
392
+ }>>;
393
+ }, z.core.$strip>;
394
+ /** Platform admin — PATCH member role */
395
+ export declare const adminPatchMemberRoleRequestSchema: z.ZodObject<{
396
+ role: z.ZodEnum<{
397
+ organization_admin: "organization_admin";
398
+ regular_user: "regular_user";
399
+ }>;
400
+ expectedUpdatedAt: z.ZodOptional<z.ZodString>;
401
+ }, z.core.$strip>;
402
+ /**
403
+ * Feature 056 (T032) — Platform admin — PATCH member roll-up capability.
404
+ * When enabled, this customer login sees/acts across its organization's subtree.
405
+ */
406
+ export declare const adminSetMemberRollupRequestSchema: z.ZodObject<{
407
+ subtreeRollupEnabled: z.ZodBoolean;
408
+ expectedUpdatedAt: z.ZodOptional<z.ZodString>;
409
+ }, z.core.$strip>;
410
+ export type AdminSetMemberRollupRequest = z.infer<typeof adminSetMemberRollupRequestSchema>;
411
+ /** Platform admin — PATCH `/admin/organizations/:id/members/:customerAccountId` (profile) */
412
+ export declare const adminPatchMemberProfileRequestSchema: z.ZodObject<{
413
+ firstName: z.ZodOptional<z.ZodString>;
414
+ lastName: z.ZodOptional<z.ZodString>;
415
+ email: z.ZodOptional<z.ZodString>;
416
+ expectedUpdatedAt: z.ZodOptional<z.ZodString>;
417
+ }, z.core.$strip>;
418
+ export declare const registerOrganizationResponseSchema: z.ZodObject<{
419
+ organization: z.ZodObject<{
420
+ id: z.ZodString;
421
+ name: z.ZodString;
422
+ taxId: z.ZodString;
423
+ status: z.ZodEnum<{
424
+ active: "active";
425
+ rejected: "rejected";
426
+ blocked: "blocked";
427
+ pending_verification: "pending_verification";
428
+ }>;
429
+ vatStatus: z.ZodEnum<{
430
+ vat_payer: "vat_payer";
431
+ vat_exempt: "vat_exempt";
432
+ reverse_charge: "reverse_charge";
433
+ }>;
434
+ isPersonal: z.ZodOptional<z.ZodBoolean>;
435
+ registeredAddress: z.ZodObject<{
436
+ street: z.ZodString;
437
+ city: z.ZodString;
438
+ postalCode: z.ZodString;
439
+ country: z.ZodString;
440
+ companyName: z.ZodOptional<z.ZodString>;
441
+ taxId: z.ZodOptional<z.ZodString>;
442
+ recipientName: z.ZodOptional<z.ZodString>;
443
+ phone: z.ZodOptional<z.ZodString>;
444
+ }, z.core.$strip>;
445
+ fulfilmentStrategy: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
446
+ any: "any";
447
+ default_first: "default_first";
448
+ lowest_stock_first: "lowest_stock_first";
449
+ highest_stock_first: "highest_stock_first";
450
+ defined_order: "defined_order";
451
+ }>>>;
452
+ fulfilmentStrategyWarehouseOrder: z.ZodOptional<z.ZodNullable<z.ZodArray<z.ZodString>>>;
453
+ parentId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
454
+ path: z.ZodOptional<z.ZodString>;
455
+ creditInheritanceMode: z.ZodOptional<z.ZodNullable<z.ZodEnum<{
456
+ shared_pool: "shared_pool";
457
+ independent_default: "independent_default";
458
+ }>>>;
459
+ createdAt: z.ZodString;
460
+ updatedAt: z.ZodString;
461
+ }, z.core.$strip>;
462
+ customerAccount: z.ZodObject<{
463
+ id: z.ZodString;
464
+ organizationId: z.ZodString;
465
+ email: z.ZodString;
466
+ firstName: z.ZodString;
467
+ lastName: z.ZodString;
468
+ role: z.ZodEnum<{
469
+ organization_admin: "organization_admin";
470
+ regular_user: "regular_user";
471
+ }>;
472
+ emailVerifiedAt: z.ZodNullable<z.ZodString>;
473
+ twoFactorEnabled: z.ZodBoolean;
474
+ createdAt: z.ZodString;
475
+ updatedAt: z.ZodString;
476
+ }, z.core.$strip>;
477
+ emailVerificationSent: z.ZodBoolean;
478
+ }, z.core.$strip>;
479
+ export type RegisterOrganizationResponse = z.infer<typeof registerOrganizationResponseSchema>;
480
+ /**
481
+ * One row of the admin Organization picker.
482
+ *
483
+ * A **projection**, not the `GET /api/v1/admin/organizations` envelope: the
484
+ * picker renders a label, a status pill and nothing else, and it commits the
485
+ * `id`. `version` rides along because a caller that picks an Organization in
486
+ * order to write to it needs the optimistic-concurrency token it already had.
487
+ *
488
+ * Published because `@endora-commerce/admin-kit` builds this request itself
489
+ * (feature 091's P2 — the picker moved into the kit and rebuilt its call from
490
+ * the published `apiClient`), so the shape crosses a package boundary and
491
+ * Principle II puts it here. Before P2 it was declared in
492
+ * `admin/src/modules/organizations/api/organizations-picker-client.ts`, where a
493
+ * kit component could only reach it by importing a module's admin code.
494
+ *
495
+ * The status is `organizationStatusSchema` and not a picker-local enum: the four
496
+ * members the picker filters on are exactly that schema's, so a second name
497
+ * would be two spellings of one set with nothing keeping them equal.
498
+ */
499
+ export declare const organizationPickerListItemSchema: z.ZodObject<{
500
+ id: z.ZodString;
501
+ name: z.ZodString;
502
+ legalName: z.ZodNullable<z.ZodString>;
503
+ status: z.ZodEnum<{
504
+ active: "active";
505
+ rejected: "rejected";
506
+ blocked: "blocked";
507
+ pending_verification: "pending_verification";
508
+ }>;
509
+ countryCode: z.ZodOptional<z.ZodNullable<z.ZodString>>;
510
+ salesRepAdminUserIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
511
+ memberCount: z.ZodOptional<z.ZodNumber>;
512
+ version: z.ZodNumber;
513
+ }, z.core.$strip>;
514
+ export type OrganizationPickerListItem = z.infer<typeof organizationPickerListItemSchema>;
515
+ /** One page of picker rows. `nextCursor` is `null` on the last page. */
516
+ export declare const organizationPickerPageSchema: z.ZodObject<{
517
+ items: z.ZodArray<z.ZodObject<{
518
+ id: z.ZodString;
519
+ name: z.ZodString;
520
+ legalName: z.ZodNullable<z.ZodString>;
521
+ status: z.ZodEnum<{
522
+ active: "active";
523
+ rejected: "rejected";
524
+ blocked: "blocked";
525
+ pending_verification: "pending_verification";
526
+ }>;
527
+ countryCode: z.ZodOptional<z.ZodNullable<z.ZodString>>;
528
+ salesRepAdminUserIds: z.ZodOptional<z.ZodArray<z.ZodString>>;
529
+ memberCount: z.ZodOptional<z.ZodNumber>;
530
+ version: z.ZodNumber;
531
+ }, z.core.$strip>>;
532
+ nextCursor: z.ZodNullable<z.ZodString>;
533
+ }, z.core.$strip>;
534
+ export type OrganizationPickerPage = z.infer<typeof organizationPickerPageSchema>;
535
+ export declare const salesRepAssignmentSchema: z.ZodObject<{
536
+ id: z.ZodString;
537
+ organizationId: z.ZodString;
538
+ adminUserId: z.ZodString;
539
+ displayName: z.ZodString;
540
+ email: z.ZodString;
541
+ assignedAt: z.ZodString;
542
+ assignedByAdminUserId: z.ZodNullable<z.ZodString>;
543
+ }, z.core.$strip>;
544
+ export type SalesRepAssignment = z.infer<typeof salesRepAssignmentSchema>;
545
+ export declare const assignSalesRepRequestSchema: z.ZodObject<{
546
+ adminUserId: z.ZodString;
547
+ }, z.core.$strip>;
548
+ export type AssignSalesRepRequest = z.infer<typeof assignSalesRepRequestSchema>;
549
+ export declare const salesRepOrganizationSchema: z.ZodObject<{
550
+ organizationId: z.ZodString;
551
+ name: z.ZodString;
552
+ openRfqCount: z.ZodNumber;
553
+ assignedAt: z.ZodString;
554
+ }, z.core.$strip>;
555
+ export type SalesRepOrganization = z.infer<typeof salesRepOrganizationSchema>;
556
+ export type VatValidationProvider = 'vies' | 'mf_pl' | 'format_only';
557
+ export type VatValidationOutcome = 'validated' | 'failed' | 'deferred' | 'unverified';
558
+ /** The JSONB snapshot the organisation's registered address is stored as. */
559
+ export interface OrganizationRegisteredAddress {
560
+ street: string;
561
+ city: string;
562
+ postalCode: string;
563
+ country: string;
564
+ }
565
+ /**
566
+ * An organisation as it crosses a module boundary — a plain shape, never the
567
+ * ORM entity (FR-011). `nameSearch` is absent: it is a derived column the
568
+ * entity hooks maintain, "never read or written by callers directly", and
569
+ * publishing it would invite exactly that.
570
+ */
571
+ export interface OrganizationRecord {
572
+ id: string;
573
+ name: string;
574
+ legalName: string | null;
575
+ taxId: string;
576
+ status: OrganizationStatus;
577
+ vatStatus: VatStatus;
578
+ isPersonal: boolean;
579
+ customerGroupId: string | null;
580
+ registeredAddress: OrganizationRegisteredAddress;
581
+ orderConfirmationEmails: string[];
582
+ vatValidatedAt: Date | null;
583
+ vatValidationProvider: VatValidationProvider | null;
584
+ vatValidationOutcome: VatValidationOutcome | null;
585
+ blockedReason: string | null;
586
+ blockedAt: Date | null;
587
+ rejectedReason: string | null;
588
+ rejectedAt: Date | null;
589
+ approvedAt: Date | null;
590
+ approvedByAdminUserId: string | null;
591
+ requiresCartApproval: boolean;
592
+ fulfilmentStrategy: FulfilmentStrategy | null;
593
+ fulfilmentStrategyWarehouseOrder: string[] | null;
594
+ parentId: string | null;
595
+ /** Materialised ancestor chain `'/<rootId>/…/<thisId>/'`. */
596
+ path: string;
597
+ creditInheritanceMode: CreditInheritanceMode | null;
598
+ customFieldValues: Record<string, unknown>;
599
+ /** Optimistic-lock token. Pass it back on a versioned write. */
600
+ version: number;
601
+ createdAt: Date;
602
+ updatedAt: Date;
603
+ deletedAt: Date | null;
604
+ }
605
+ /**
606
+ * Container name: `organizationDetailsPort`. Owner: `organizations`.
607
+ *
608
+ * The union of what eleven modules measurably ask for when they read the
609
+ * organisation row itself: 24 of the 47 inbound sites are `em.findOne` /
610
+ * `em.find` on the entity, and between them they touch nearly every column.
611
+ *
612
+ * **Why this is a second port and not a wider `OrganizationSnapshot`.** The
613
+ * kernel's `OrganizationReadPort` (`src/kernel/ports/organizations.ts`) is the
614
+ * *tenancy projection* — `{ id, status }` plus the two questions Principle XI
615
+ * asks — and D-55 settled it at what its callers use. `organizationTaxProfilePort`
616
+ * already declined to widen it, in those words, for the same reason: a tax
617
+ * profile is one consumer's question. So is a name picker, and so is a
618
+ * fulfilment override. Widening the snapshot to carry them would make the
619
+ * kernel declare a domain record.
620
+ *
621
+ * The name search is here rather than in each caller because it is not a
622
+ * `LIKE` on `name`: the column that answers it is the diacritic-folded
623
+ * `nameSearch`, and two of the three existing callers query `name` instead —
624
+ * so "a search for lodz finds Łódź" holds in one of them and not in the others.
625
+ *
626
+ * When `organizations` is off every method fails closed. The module is the
627
+ * platform's one tenant concept, so in practice the gate cannot close; it is
628
+ * registered anyway, because an exception carved into the port machinery costs
629
+ * more than the predicate does.
630
+ */
631
+ export interface OrganizationDetailsPort {
632
+ findById(id: string): Promise<OrganizationRecord | null>;
633
+ findByIds(ids: readonly string[]): Promise<OrganizationRecord[]>;
634
+ /** How many of these ids exist — the `count === ids.length` existence check. */
635
+ countByIds(ids: readonly string[]): Promise<number>;
636
+ /**
637
+ * Diacritic-insensitive name search over `nameSearch`, ordered by name.
638
+ * An empty `query` returns the first `limit` organisations.
639
+ */
640
+ searchByName(query: string, limit: number): Promise<OrganizationRecord[]>;
641
+ /** The same search, ids only — for the order list's organisation filter. */
642
+ searchIdsByName(query: string): Promise<string[]>;
643
+ }
644
+ /**
645
+ * Diacritic-insensitive normalisation for the organisation's `name_search`
646
+ * column and for any query string matched against it.
647
+ *
648
+ * The character fold itself is `foldDiacritics` in `text-normalization.ts`,
649
+ * shared with `admin/` and reachable from `storefront/` (issue #240): it strips
650
+ * every Unicode combining mark through NFD decomposition and then maps the
651
+ * handful of precomposed Latin letters NFD does not decompose (notably Polish
652
+ * `ł`/`Ł`, Scandinavian `ø`/`Ø`, Croatian `đ`/`Đ`, Icelandic `ð`/`Ð`,
653
+ * `þ`/`Þ`, German `ß`, ligatures `æ` and `œ`). What is specific to an
654
+ * organisation name is the whitespace policy below, and only that: a name typed
655
+ * with a double space must match one stored with a single one.
656
+ *
657
+ * Published as a **function, not a port** (FR-013): it is pure over its
658
+ * argument, so switching `organizations` off does not change the answer, and a
659
+ * gated port answering 503 to "fold these diacritics" would be a bug. The
660
+ * entity's `@BeforeCreate` / `@BeforeUpdate` hooks and `orders`' list filter
661
+ * both call it, and they must agree or the filter silently stops matching.
662
+ *
663
+ * That agreement is why the fold is characterised rather than merely tested:
664
+ * `backend/test/unit/organizations/name-search-fold-characterisation.test.ts`
665
+ * pins the output for every input this function can meet, because a change here
666
+ * re-folds nothing already written to `name_search` and reports no error when
667
+ * the two stop agreeing.
668
+ *
669
+ * Node natives only (Principle IV).
670
+ */
671
+ export declare function normalizeOrganizationName(input: string): string;
672
+ /**
673
+ * Thrown when the organisation a read names does not exist. The kernel's
674
+ * `OrganizationReadPort` has documented it as `assertCanTransact`'s failure
675
+ * mode since D-32 while the class itself lived in a module, which is the gap
676
+ * this publication closes.
677
+ */
678
+ export declare class OrganizationNotFoundError extends Error {
679
+ readonly organizationId: string;
680
+ constructor(organizationId: string);
681
+ }
682
+ /**
683
+ * Thrown when a write is attempted for an organisation whose status forbids
684
+ * transacting. Four modules — `carts`, `orders`, `quote_requests` and the
685
+ * external order intake — catch it by class to turn it into a 409 envelope,
686
+ * which is why it is published here rather than being a port: an error is a
687
+ * shape, and `DictionaryReferenceError` in `dictionary.ts` set the precedent.
688
+ */
689
+ export declare class OrganizationCannotTransactError extends Error {
690
+ readonly organizationId: string;
691
+ readonly status: Exclude<OrganizationStatus, 'active'>;
692
+ constructor(organizationId: string, status: Exclude<OrganizationStatus, 'active'>);
693
+ }
694
+ /** Where a subtree's credit limit is held, and under which mode. */
695
+ export interface OrganizationCreditOwner {
696
+ /** Nearest ancestor-or-self holding a `CreditLimit` row, or null when none exists. */
697
+ readonly ownerOrgId: string | null;
698
+ /** Effective mode: the owner's per-org column, else the Settings global default. */
699
+ readonly mode: CreditInheritanceMode;
700
+ }
701
+ /**
702
+ * Container name: `organizationInheritancePort`. Owner: `organizations`.
703
+ *
704
+ * `credit_limits` is the only consumer: it asks which organisation in the
705
+ * hierarchy actually holds the limit that applies here.
706
+ *
707
+ * **Owner off:** the seam fails closed — resolving this port throws
708
+ * `ModuleDisabledError` and the call answers 503 `MODULE_DISABLED`, so nothing
709
+ * half-executes. Whether `organizations` has an off state at all is its manifest's
710
+ * `activation` to say, not this line's: a module declaring
711
+ * `nonDeactivatable` never enters one.
712
+ */
713
+ export interface OrganizationInheritancePort {
714
+ creditOwner(organizationId: string): Promise<OrganizationCreditOwner>;
715
+ }
716
+ /** What a cart-approval-policy write answers with. */
717
+ export interface CartApprovalPolicyWriteResult {
718
+ readonly organization: OrganizationRecord;
719
+ /**
720
+ * `false` when the row already carried the requested value, so nothing was
721
+ * written and nothing was audited. It is part of the return type rather than
722
+ * something the caller re-derives from a read, because the caller's cascade
723
+ * hangs off it: `carts` resets its pending and approved carts when — and only
724
+ * when — the policy actually moved to `false`.
725
+ */
726
+ readonly changed: boolean;
727
+ }
728
+ /**
729
+ * Container name: `organizationCartApprovalWritePort`. Owner: `organizations`.
730
+ *
731
+ * The per-organisation "an Org Admin must approve a cart before checkout"
732
+ * policy (feature 027 US4). `carts` drives both surfaces that flip it — the
733
+ * platform-admin route and the Org-Admin self-service one — but the column is
734
+ * this module's, so the operation is (issue #175, D-78 step 1).
735
+ *
736
+ * The write runs through `CommandBus.run`, so it carries the audit row it had
737
+ * never had while `carts` was writing the column directly, with the actor
738
+ * derived from the caller's ambient context (Constitution XIII). The cart
739
+ * cascade that follows a switch-off stays with `carts`: those are its rows, and
740
+ * they are audited in its own per-cart trail.
741
+ *
742
+ * This module is non-deactivatable, so the gate the port registration applies
743
+ * cannot be reached; the registration is a `providePort` anyway, for the reason
744
+ * its siblings give.
745
+ */
746
+ export interface OrganizationCartApprovalWritePort {
747
+ setCartApprovalPolicy(organizationId: string, requiresCartApproval: boolean): Promise<CartApprovalPolicyWriteResult>;
748
+ }
749
+ /** The three allow-list kinds an organisation can restrict. */
750
+ export type OrganizationAllowListKind = 'paymentMethodIds' | 'deliveryMethodIds' | 'warehouseIds';
751
+ /**
752
+ * Container name: `organizationRestrictionPort`. Owner: `organizations`.
753
+ *
754
+ * `null` means "no restriction configured — everything is allowed", and it is
755
+ * deliberately part of the return type rather than something a caller infers
756
+ * from a thrown error. That is the worked example the composition checklist
757
+ * cites for putting a degrade inside the owner's implementation: a consumer
758
+ * that caught an exception here would turn a fail-closed edge into a
759
+ * fail-open one.
760
+ *
761
+ * **Owner off:** the seam fails closed — resolving this port throws
762
+ * `ModuleDisabledError` and the call answers 503 `MODULE_DISABLED`, so nothing
763
+ * half-executes. Whether `organizations` has an off state at all is its manifest's
764
+ * `activation` to say, not this line's: a module declaring
765
+ * `nonDeactivatable` never enters one.
766
+ */
767
+ export interface OrganizationRestrictionPort {
768
+ allowedIdsFor(organizationId: string, kind: OrganizationAllowListKind): Promise<string[] | null>;
769
+ }
770
+ /**
771
+ * Container name: `personalOrganizationPort`. Owner: `organizations`.
772
+ *
773
+ * Feature 051 — a B2C customer is backed by a single-member personal
774
+ * organisation, so ordering, RFQ, credit and invoicing work and the tenant
775
+ * guard isolates each individual as their own tenant. There is no
776
+ * "no-organization" path (Principle XI), which is why this is idempotent
777
+ * rather than a create.
778
+ *
779
+ * Takes the account **id**, not the account: the entity that used to cross
780
+ * here is the shape feature 075 removes, and the second `EntityManager`
781
+ * argument went with it — the one caller already flushes the account before
782
+ * calling.
783
+ *
784
+ * **Owner off:** the seam fails closed — resolving this port throws
785
+ * `ModuleDisabledError` and the call answers 503 `MODULE_DISABLED`, so nothing
786
+ * half-executes. Whether `organizations` has an off state at all is its manifest's
787
+ * `activation` to say, not this line's: a module declaring
788
+ * `nonDeactivatable` never enters one.
789
+ */
790
+ export interface PersonalOrganizationPort {
791
+ ensureForCustomerAccount(customerAccountId: string): Promise<OrganizationRecord>;
792
+ /**
793
+ * D-178 — the organisation an account is moved **to** when an operator
794
+ * detaches it from a company, and the one it would already be in had it never
795
+ * joined one.
796
+ *
797
+ * It differs from {@link ensureForCustomerAccount} in exactly one way, and
798
+ * the difference is the whole reason it exists: that method answers with the
799
+ * account's *current* organisation when it has one, so an account inside a
800
+ * company gets that company back. This one always answers with the account's
801
+ * **own** personal organisation, provisioning it if it has never existed.
802
+ *
803
+ * It writes no membership. Binding the account is the caller's write on
804
+ * `customer_accounts`' side of the boundary
805
+ * (`CustomerAccountLifecycleWritePort.detachToPersonalOrganization`), because
806
+ * the authority check and the "an organisation keeps an administrator" guard
807
+ * that must precede it are `customers`' policy.
808
+ *
809
+ * Idempotent: the personal organisation's `taxId` is derived from the account
810
+ * id, so a second call re-finds the row rather than creating a second one.
811
+ */
812
+ provisionPersonalOrganization(customerAccountId: string): Promise<OrganizationRecord>;
813
+ /**
814
+ * Feature 051, the other end of the same rule — the retention sweep's
815
+ * cascade. Once the single member of a personal organisation has been
816
+ * anonymised, the organisation is left with nobody in it and its name is
817
+ * derived from that person's name, so it is scrubbed and soft-deleted too.
818
+ *
819
+ * Answers `null`, and writes nothing, in every case where the cascade does
820
+ * not apply: an org-less account, an organisation that is not personal, one
821
+ * already soft-deleted, and one that still has a live member. That is why it
822
+ * takes the **account** id rather than the organisation's — the caller
823
+ * (`customers`' anonymisation sweep) knows which customer it just scrubbed
824
+ * and must not be the one deciding whether the organisation qualifies.
825
+ *
826
+ * Idempotent: a second call over the same account finds the organisation
827
+ * already soft-deleted and answers `null`.
828
+ */
829
+ anonymizeIfOrphaned(customerAccountId: string): Promise<OrganizationRecord | null>;
830
+ }
831
+ /** One sales-rep ↔ organisation assignment row. */
832
+ export interface SalesRepAssignmentRow {
833
+ readonly id: string;
834
+ readonly organizationId: string;
835
+ readonly adminUserId: string;
836
+ readonly assignedByAdminUserId?: string | null;
837
+ readonly createdAt: Date;
838
+ }
839
+ /**
840
+ * Container name: `organizationSalesRepScopePort`. Owner: `organizations`.
841
+ *
842
+ * The sales-rep assignment relation as other modules see it. `quote_requests`
843
+ * scopes an admin's RFQ list with it; the admin surfaces read it to decide
844
+ * whether a rep may see an organisation at all.
845
+ *
846
+ * **Owner off:** the seam fails closed — resolving this port throws
847
+ * `ModuleDisabledError` and the call answers 503 `MODULE_DISABLED`, so nothing
848
+ * half-executes. Whether `organizations` has an off state at all is its manifest's
849
+ * `activation` to say, not this line's: a module declaring
850
+ * `nonDeactivatable` never enters one.
851
+ */
852
+ export interface SalesRepAssignmentPort {
853
+ canSeeOrganization(adminUserId: string, organizationId: string): Promise<boolean>;
854
+ listAssignedOrganizationIds(adminUserId: string): Promise<string[]>;
855
+ listForOrganization(organizationId: string): Promise<SalesRepAssignmentRow[]>;
856
+ assign(input: {
857
+ organizationId: string;
858
+ adminUserId: string;
859
+ assignedByAdminUserId?: string | null;
860
+ }): Promise<SalesRepAssignmentRow>;
861
+ unassign(input: {
862
+ organizationId: string;
863
+ adminUserId: string;
864
+ }): Promise<boolean>;
865
+ }
866
+ /** The address a VAT registry hands back when it recognises the tax id. */
867
+ export interface VatReturnedAddress {
868
+ line1?: string | null;
869
+ line2?: string | null;
870
+ postalCode?: string | null;
871
+ city?: string | null;
872
+ countryCode?: string | null;
873
+ }
874
+ export interface VatValidationResult {
875
+ outcome: VatValidationOutcome;
876
+ legalName: string | null;
877
+ address: VatReturnedAddress | null;
878
+ errorKind: string | null;
879
+ }
880
+ /**
881
+ * Container name: `vatValidatorPort`. Owner: `organizations`.
882
+ *
883
+ * Pluggable VAT-ID validator (feature 026 US7), published so `customers` can
884
+ * name the shape without naming a file in `organizations`.
885
+ *
886
+ * **Owner off:** the seam fails closed — resolving the port throws
887
+ * `ModuleDisabledError` and the call answers 503 `MODULE_DISABLED`. That is
888
+ * not the same thing as the `deferred` outcome below: `deferred` is the
889
+ * *registry* being unreachable, which the caller may retry, while a refused
890
+ * resolution says the platform is not offering the check at all.
891
+ *
892
+ * Every adapter MUST degrade safely: a transient network failure or a
893
+ * provider-side 5xx returns `{ outcome: 'deferred', errorKind: … }` rather
894
+ * than throwing. A clean "not registered" response returns
895
+ * `{ outcome: 'failed', errorKind: 'not_found' }`. Only `validated` carries
896
+ * the optional `legalName` + `address` payloads the auto-fill flow consumes.
897
+ */
898
+ export interface VatValidator {
899
+ readonly provider: VatValidationProvider;
900
+ validate(input: {
901
+ taxId: string;
902
+ /** Optional country hint extracted upstream (VIES needs the country split). */
903
+ countryCode?: string | undefined;
904
+ }): Promise<VatValidationResult>;
905
+ }
906
+ /**
907
+ * Container name: `organizationTaxProfilePort`. Owner: `organizations`.
908
+ *
909
+ * The Organization facts a VAT rate depends on (T143c).
910
+ *
911
+ * `country` is nullable because the caller's fallback is a business rule
912
+ * (`'PL'`, in the Quote Requests resolver) and belongs where that rule is
913
+ * written, not here — a port that invented a country would make an
914
+ * unregistered address indistinguishable from a Polish one.
915
+ *
916
+ * Deliberately not a widening of the kernel's `OrganizationSnapshot`. That
917
+ * shape is the tenancy projection every module reads; a tax profile is one
918
+ * consumer's question, and D-55 settled the snapshot at what its callers
919
+ * actually use.
920
+ *
921
+ * **Owner off:** the seam fails closed — resolving the port throws
922
+ * `ModuleDisabledError` and the call answers 503 `MODULE_DISABLED`. The Quote
923
+ * Requests tax closure deliberately carries no `catch` (issue #84): quoting
924
+ * 0 % on an operator's behalf is worse than failing.
925
+ *
926
+ * It is declared here rather than in `organizations`' own `./backend` because
927
+ * a port's type argument is a contract type and never the provider's file
928
+ * (composition checklist item 3). The production composition root resolves this
929
+ * name, and `specs/110-instance-repository/` T118 moves that read into
930
+ * `@endora-commerce/platform`, where naming a module is D-52/D-53's refusal.
931
+ */
932
+ export interface OrganizationTaxProfilePort {
933
+ taxProfileOf(organizationId: string): Promise<{
934
+ vatStatus: 'vat_payer' | 'vat_exempt' | 'reverse_charge';
935
+ country: string | null;
936
+ } | null>;
937
+ }
938
+ //# sourceMappingURL=organizations.d.ts.map