@endora-commerce/mod-organizations 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 (288) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +62 -0
  3. package/dist/admin/components/OrganizationSalesRepsTab.d.ts +27 -0
  4. package/dist/admin/components/OrganizationSalesRepsTab.d.ts.map +1 -0
  5. package/dist/admin/components/OrganizationSalesRepsTab.js +170 -0
  6. package/dist/admin/components/OrganizationSalesRepsTab.js.map +1 -0
  7. package/dist/admin/index.d.ts +30 -0
  8. package/dist/admin/index.d.ts.map +1 -0
  9. package/dist/admin/index.js +59 -0
  10. package/dist/admin/index.js.map +1 -0
  11. package/dist/admin/pages/OrganizationDetail.d.ts +9 -0
  12. package/dist/admin/pages/OrganizationDetail.d.ts.map +1 -0
  13. package/dist/admin/pages/OrganizationDetail.js +247 -0
  14. package/dist/admin/pages/OrganizationDetail.js.map +1 -0
  15. package/dist/admin/pages/OrganizationsList.d.ts +9 -0
  16. package/dist/admin/pages/OrganizationsList.d.ts.map +1 -0
  17. package/dist/admin/pages/OrganizationsList.js +73 -0
  18. package/dist/admin/pages/OrganizationsList.js.map +1 -0
  19. package/dist/admin/panels/ApplicablePriceListsPanel.d.ts +12 -0
  20. package/dist/admin/panels/ApplicablePriceListsPanel.d.ts.map +1 -0
  21. package/dist/admin/panels/ApplicablePriceListsPanel.js +49 -0
  22. package/dist/admin/panels/ApplicablePriceListsPanel.js.map +1 -0
  23. package/dist/admin/panels/FulfilmentStrategyPanel.d.ts +16 -0
  24. package/dist/admin/panels/FulfilmentStrategyPanel.d.ts.map +1 -0
  25. package/dist/admin/panels/FulfilmentStrategyPanel.js +29 -0
  26. package/dist/admin/panels/FulfilmentStrategyPanel.js.map +1 -0
  27. package/dist/admin/panels/HierarchyPanel.d.ts +15 -0
  28. package/dist/admin/panels/HierarchyPanel.d.ts.map +1 -0
  29. package/dist/admin/panels/HierarchyPanel.js +65 -0
  30. package/dist/admin/panels/HierarchyPanel.js.map +1 -0
  31. package/dist/admin/panels/ModerationActionsPanel.d.ts +28 -0
  32. package/dist/admin/panels/ModerationActionsPanel.d.ts.map +1 -0
  33. package/dist/admin/panels/ModerationActionsPanel.js +111 -0
  34. package/dist/admin/panels/ModerationActionsPanel.js.map +1 -0
  35. package/dist/admin/panels/RestrictionsPanel.d.ts +24 -0
  36. package/dist/admin/panels/RestrictionsPanel.d.ts.map +1 -0
  37. package/dist/admin/panels/RestrictionsPanel.js +121 -0
  38. package/dist/admin/panels/RestrictionsPanel.js.map +1 -0
  39. package/dist/admin/panels/VatValidationPanel.d.ts +28 -0
  40. package/dist/admin/panels/VatValidationPanel.d.ts.map +1 -0
  41. package/dist/admin/panels/VatValidationPanel.js +79 -0
  42. package/dist/admin/panels/VatValidationPanel.js.map +1 -0
  43. package/dist/backend/commands/move.command.d.ts +11 -0
  44. package/dist/backend/commands/move.command.d.ts.map +1 -0
  45. package/dist/backend/commands/move.command.js +11 -0
  46. package/dist/backend/commands/move.command.js.map +1 -0
  47. package/dist/backend/commands/set-cart-approval-policy.command.d.ts +31 -0
  48. package/dist/backend/commands/set-cart-approval-policy.command.d.ts.map +1 -0
  49. package/dist/backend/commands/set-cart-approval-policy.command.js +56 -0
  50. package/dist/backend/commands/set-cart-approval-policy.command.js.map +1 -0
  51. package/dist/backend/commands/set-credit-mode.command.d.ts +16 -0
  52. package/dist/backend/commands/set-credit-mode.command.d.ts.map +1 -0
  53. package/dist/backend/commands/set-credit-mode.command.js +25 -0
  54. package/dist/backend/commands/set-credit-mode.command.js.map +1 -0
  55. package/dist/backend/commands/set-parent.command.d.ts +26 -0
  56. package/dist/backend/commands/set-parent.command.d.ts.map +1 -0
  57. package/dist/backend/commands/set-parent.command.js +51 -0
  58. package/dist/backend/commands/set-parent.command.js.map +1 -0
  59. package/dist/backend/demo/reset.d.ts +20 -0
  60. package/dist/backend/demo/reset.d.ts.map +1 -0
  61. package/dist/backend/demo/reset.js +11 -0
  62. package/dist/backend/demo/reset.js.map +1 -0
  63. package/dist/backend/demo/rows.d.ts +44 -0
  64. package/dist/backend/demo/rows.d.ts.map +1 -0
  65. package/dist/backend/demo/rows.js +44 -0
  66. package/dist/backend/demo/rows.js.map +1 -0
  67. package/dist/backend/demo/seed.d.ts +20 -0
  68. package/dist/backend/demo/seed.d.ts.map +1 -0
  69. package/dist/backend/demo/seed.js +28 -0
  70. package/dist/backend/demo/seed.js.map +1 -0
  71. package/dist/backend/email-templates/invitation.d.ts +23 -0
  72. package/dist/backend/email-templates/invitation.d.ts.map +1 -0
  73. package/dist/backend/email-templates/invitation.js +35 -0
  74. package/dist/backend/email-templates/invitation.js.map +1 -0
  75. package/dist/backend/email-templates/transactional-defaults.d.ts +54 -0
  76. package/dist/backend/email-templates/transactional-defaults.d.ts.map +1 -0
  77. package/dist/backend/email-templates/transactional-defaults.js +242 -0
  78. package/dist/backend/email-templates/transactional-defaults.js.map +1 -0
  79. package/dist/backend/email-templates/verification.d.ts +14 -0
  80. package/dist/backend/email-templates/verification.d.ts.map +1 -0
  81. package/dist/backend/email-templates/verification.js +34 -0
  82. package/dist/backend/email-templates/verification.js.map +1 -0
  83. package/dist/backend/entities/email-verification-token.entity.d.ts +17 -0
  84. package/dist/backend/entities/email-verification-token.entity.d.ts.map +1 -0
  85. package/dist/backend/entities/email-verification-token.entity.js +60 -0
  86. package/dist/backend/entities/email-verification-token.entity.js.map +1 -0
  87. package/dist/backend/entities/organization-delivery-method-link.entity.d.ts +14 -0
  88. package/dist/backend/entities/organization-delivery-method-link.entity.d.ts.map +1 -0
  89. package/dist/backend/entities/organization-delivery-method-link.entity.js +41 -0
  90. package/dist/backend/entities/organization-delivery-method-link.entity.js.map +1 -0
  91. package/dist/backend/entities/organization-invitation.entity.d.ts +21 -0
  92. package/dist/backend/entities/organization-invitation.entity.d.ts.map +1 -0
  93. package/dist/backend/entities/organization-invitation.entity.js +85 -0
  94. package/dist/backend/entities/organization-invitation.entity.js.map +1 -0
  95. package/dist/backend/entities/organization-payment-method-link.entity.d.ts +14 -0
  96. package/dist/backend/entities/organization-payment-method-link.entity.d.ts.map +1 -0
  97. package/dist/backend/entities/organization-payment-method-link.entity.js +41 -0
  98. package/dist/backend/entities/organization-payment-method-link.entity.js.map +1 -0
  99. package/dist/backend/entities/organization-sales-rep-assignment.entity.d.ts +17 -0
  100. package/dist/backend/entities/organization-sales-rep-assignment.entity.d.ts.map +1 -0
  101. package/dist/backend/entities/organization-sales-rep-assignment.entity.js +56 -0
  102. package/dist/backend/entities/organization-sales-rep-assignment.entity.js.map +1 -0
  103. package/dist/backend/entities/organization-tax-id-validation.entity.d.ts +29 -0
  104. package/dist/backend/entities/organization-tax-id-validation.entity.d.ts.map +1 -0
  105. package/dist/backend/entities/organization-tax-id-validation.entity.js +78 -0
  106. package/dist/backend/entities/organization-tax-id-validation.entity.js.map +1 -0
  107. package/dist/backend/entities/organization-warehouse-link.entity.d.ts +15 -0
  108. package/dist/backend/entities/organization-warehouse-link.entity.d.ts.map +1 -0
  109. package/dist/backend/entities/organization-warehouse-link.entity.js +42 -0
  110. package/dist/backend/entities/organization-warehouse-link.entity.js.map +1 -0
  111. package/dist/backend/entities/organization.entity.d.ts +125 -0
  112. package/dist/backend/entities/organization.entity.d.ts.map +1 -0
  113. package/dist/backend/entities/organization.entity.js +282 -0
  114. package/dist/backend/entities/organization.entity.js.map +1 -0
  115. package/dist/backend/index.d.ts +250 -0
  116. package/dist/backend/index.d.ts.map +1 -0
  117. package/dist/backend/index.js +506 -0
  118. package/dist/backend/index.js.map +1 -0
  119. package/dist/backend/integrations/ministerstwo-finansow-client.d.ts +22 -0
  120. package/dist/backend/integrations/ministerstwo-finansow-client.d.ts.map +1 -0
  121. package/dist/backend/integrations/ministerstwo-finansow-client.js +172 -0
  122. package/dist/backend/integrations/ministerstwo-finansow-client.js.map +1 -0
  123. package/dist/backend/integrations/vies-client.d.ts +18 -0
  124. package/dist/backend/integrations/vies-client.d.ts.map +1 -0
  125. package/dist/backend/integrations/vies-client.js +133 -0
  126. package/dist/backend/integrations/vies-client.js.map +1 -0
  127. package/dist/backend/plugin.d.ts +126 -0
  128. package/dist/backend/plugin.d.ts.map +1 -0
  129. package/dist/backend/plugin.js +139 -0
  130. package/dist/backend/plugin.js.map +1 -0
  131. package/dist/backend/routes.admin.d.ts +66 -0
  132. package/dist/backend/routes.admin.d.ts.map +1 -0
  133. package/dist/backend/routes.admin.js +711 -0
  134. package/dist/backend/routes.admin.js.map +1 -0
  135. package/dist/backend/routes.customer.d.ts +33 -0
  136. package/dist/backend/routes.customer.d.ts.map +1 -0
  137. package/dist/backend/routes.customer.js +139 -0
  138. package/dist/backend/routes.customer.js.map +1 -0
  139. package/dist/backend/routes.members.d.ts +31 -0
  140. package/dist/backend/routes.members.d.ts.map +1 -0
  141. package/dist/backend/routes.members.js +109 -0
  142. package/dist/backend/routes.members.js.map +1 -0
  143. package/dist/backend/routes.public.d.ts +49 -0
  144. package/dist/backend/routes.public.d.ts.map +1 -0
  145. package/dist/backend/routes.public.js +220 -0
  146. package/dist/backend/routes.public.js.map +1 -0
  147. package/dist/backend/routes.sales-reps.d.ts +46 -0
  148. package/dist/backend/routes.sales-reps.d.ts.map +1 -0
  149. package/dist/backend/routes.sales-reps.js +114 -0
  150. package/dist/backend/routes.sales-reps.js.map +1 -0
  151. package/dist/backend/routes.storefront.d.ts +25 -0
  152. package/dist/backend/routes.storefront.d.ts.map +1 -0
  153. package/dist/backend/routes.storefront.js +65 -0
  154. package/dist/backend/routes.storefront.js.map +1 -0
  155. package/dist/backend/schemas/organization.d.ts +59 -0
  156. package/dist/backend/schemas/organization.d.ts.map +1 -0
  157. package/dist/backend/schemas/organization.js +55 -0
  158. package/dist/backend/schemas/organization.js.map +1 -0
  159. package/dist/backend/schemas/settings.d.ts +30 -0
  160. package/dist/backend/schemas/settings.d.ts.map +1 -0
  161. package/dist/backend/schemas/settings.js +35 -0
  162. package/dist/backend/schemas/settings.js.map +1 -0
  163. package/dist/backend/services/email-verification-service.d.ts +45 -0
  164. package/dist/backend/services/email-verification-service.d.ts.map +1 -0
  165. package/dist/backend/services/email-verification-service.js +95 -0
  166. package/dist/backend/services/email-verification-service.js.map +1 -0
  167. package/dist/backend/services/invitation-service.d.ts +85 -0
  168. package/dist/backend/services/invitation-service.d.ts.map +1 -0
  169. package/dist/backend/services/invitation-service.js +266 -0
  170. package/dist/backend/services/invitation-service.js.map +1 -0
  171. package/dist/backend/services/normalize-name.d.ts +14 -0
  172. package/dist/backend/services/normalize-name.d.ts.map +1 -0
  173. package/dist/backend/services/normalize-name.js +14 -0
  174. package/dist/backend/services/normalize-name.js.map +1 -0
  175. package/dist/backend/services/org-registration-notifier.d.ts +36 -0
  176. package/dist/backend/services/org-registration-notifier.d.ts.map +1 -0
  177. package/dist/backend/services/org-registration-notifier.js +109 -0
  178. package/dist/backend/services/org-registration-notifier.js.map +1 -0
  179. package/dist/backend/services/org-template-email.d.ts +18 -0
  180. package/dist/backend/services/org-template-email.d.ts.map +1 -0
  181. package/dist/backend/services/org-template-email.js +16 -0
  182. package/dist/backend/services/org-template-email.js.map +1 -0
  183. package/dist/backend/services/organization-context-service.d.ts +52 -0
  184. package/dist/backend/services/organization-context-service.d.ts.map +1 -0
  185. package/dist/backend/services/organization-context-service.js +70 -0
  186. package/dist/backend/services/organization-context-service.js.map +1 -0
  187. package/dist/backend/services/organization-country-reference.d.ts +11 -0
  188. package/dist/backend/services/organization-country-reference.d.ts.map +1 -0
  189. package/dist/backend/services/organization-country-reference.js +24 -0
  190. package/dist/backend/services/organization-country-reference.js.map +1 -0
  191. package/dist/backend/services/organization-details-port.d.ts +33 -0
  192. package/dist/backend/services/organization-details-port.d.ts.map +1 -0
  193. package/dist/backend/services/organization-details-port.js +95 -0
  194. package/dist/backend/services/organization-details-port.js.map +1 -0
  195. package/dist/backend/services/organization-effective-pricelists-service.d.ts +50 -0
  196. package/dist/backend/services/organization-effective-pricelists-service.d.ts.map +1 -0
  197. package/dist/backend/services/organization-effective-pricelists-service.js +68 -0
  198. package/dist/backend/services/organization-effective-pricelists-service.js.map +1 -0
  199. package/dist/backend/services/organization-inheritance-service.d.ts +73 -0
  200. package/dist/backend/services/organization-inheritance-service.d.ts.map +1 -0
  201. package/dist/backend/services/organization-inheritance-service.js +63 -0
  202. package/dist/backend/services/organization-inheritance-service.js.map +1 -0
  203. package/dist/backend/services/organization-moderation-service.d.ts +124 -0
  204. package/dist/backend/services/organization-moderation-service.d.ts.map +1 -0
  205. package/dist/backend/services/organization-moderation-service.js +337 -0
  206. package/dist/backend/services/organization-moderation-service.js.map +1 -0
  207. package/dist/backend/services/organization-restriction-service.d.ts +70 -0
  208. package/dist/backend/services/organization-restriction-service.d.ts.map +1 -0
  209. package/dist/backend/services/organization-restriction-service.js +210 -0
  210. package/dist/backend/services/organization-restriction-service.js.map +1 -0
  211. package/dist/backend/services/organization-tax-id-validation-service.d.ts +59 -0
  212. package/dist/backend/services/organization-tax-id-validation-service.d.ts.map +1 -0
  213. package/dist/backend/services/organization-tax-id-validation-service.js +115 -0
  214. package/dist/backend/services/organization-tax-id-validation-service.js.map +1 -0
  215. package/dist/backend/services/organization-tree-service.d.ts +102 -0
  216. package/dist/backend/services/organization-tree-service.d.ts.map +1 -0
  217. package/dist/backend/services/organization-tree-service.js +184 -0
  218. package/dist/backend/services/organization-tree-service.js.map +1 -0
  219. package/dist/backend/services/personal-organization-service.d.ts +130 -0
  220. package/dist/backend/services/personal-organization-service.d.ts.map +1 -0
  221. package/dist/backend/services/personal-organization-service.js +207 -0
  222. package/dist/backend/services/personal-organization-service.js.map +1 -0
  223. package/dist/backend/services/registration-service.d.ts +80 -0
  224. package/dist/backend/services/registration-service.d.ts.map +1 -0
  225. package/dist/backend/services/registration-service.js +126 -0
  226. package/dist/backend/services/registration-service.js.map +1 -0
  227. package/dist/backend/services/sales-rep-assignment-service.d.ts +89 -0
  228. package/dist/backend/services/sales-rep-assignment-service.d.ts.map +1 -0
  229. package/dist/backend/services/sales-rep-assignment-service.js +176 -0
  230. package/dist/backend/services/sales-rep-assignment-service.js.map +1 -0
  231. package/dist/backend/services/vat-validator-port.d.ts +20 -0
  232. package/dist/backend/services/vat-validator-port.d.ts.map +1 -0
  233. package/dist/backend/services/vat-validator-port.js +2 -0
  234. package/dist/backend/services/vat-validator-port.js.map +1 -0
  235. package/dist/manifest.d.ts +176 -0
  236. package/dist/manifest.d.ts.map +1 -0
  237. package/dist/manifest.js +503 -0
  238. package/dist/manifest.js.map +1 -0
  239. package/dist/migrations/20260424T205317_organizations_init.d.ts +13 -0
  240. package/dist/migrations/20260424T205317_organizations_init.d.ts.map +1 -0
  241. package/dist/migrations/20260424T205317_organizations_init.js +100 -0
  242. package/dist/migrations/20260424T205317_organizations_init.js.map +1 -0
  243. package/dist/migrations/20260425T051700_organizations_invitations_init.d.ts +13 -0
  244. package/dist/migrations/20260425T051700_organizations_invitations_init.d.ts.map +1 -0
  245. package/dist/migrations/20260425T051700_organizations_invitations_init.js +39 -0
  246. package/dist/migrations/20260425T051700_organizations_invitations_init.js.map +1 -0
  247. package/dist/migrations/20260611T140349_organizations_consolidation.d.ts +35 -0
  248. package/dist/migrations/20260611T140349_organizations_consolidation.d.ts.map +1 -0
  249. package/dist/migrations/20260611T140349_organizations_consolidation.js +180 -0
  250. package/dist/migrations/20260611T140349_organizations_consolidation.js.map +1 -0
  251. package/dist/migrations/20260611T140358_organizations_org_order_confirmation_emails.d.ts +10 -0
  252. package/dist/migrations/20260611T140358_organizations_org_order_confirmation_emails.d.ts.map +1 -0
  253. package/dist/migrations/20260611T140358_organizations_org_order_confirmation_emails.js +14 -0
  254. package/dist/migrations/20260611T140358_organizations_org_order_confirmation_emails.js.map +1 -0
  255. package/dist/migrations/20260611T140402_organizations_org_fulfilment_strategy.d.ts +14 -0
  256. package/dist/migrations/20260611T140402_organizations_org_fulfilment_strategy.d.ts.map +1 -0
  257. package/dist/migrations/20260611T140402_organizations_org_fulfilment_strategy.js +20 -0
  258. package/dist/migrations/20260611T140402_organizations_org_fulfilment_strategy.js.map +1 -0
  259. package/dist/migrations/20260717T151403_organizations_personal_organizations.d.ts +24 -0
  260. package/dist/migrations/20260717T151403_organizations_personal_organizations.d.ts.map +1 -0
  261. package/dist/migrations/20260717T151403_organizations_personal_organizations.js +63 -0
  262. package/dist/migrations/20260717T151403_organizations_personal_organizations.js.map +1 -0
  263. package/dist/migrations/20260718T200340_organizations_organization_custom_field_values.d.ts +12 -0
  264. package/dist/migrations/20260718T200340_organizations_organization_custom_field_values.d.ts.map +1 -0
  265. package/dist/migrations/20260718T200340_organizations_organization_custom_field_values.js +16 -0
  266. package/dist/migrations/20260718T200340_organizations_organization_custom_field_values.js.map +1 -0
  267. package/dist/migrations/20260720T044254_organizations_org_hierarchy.d.ts +23 -0
  268. package/dist/migrations/20260720T044254_organizations_org_hierarchy.d.ts.map +1 -0
  269. package/dist/migrations/20260720T044254_organizations_org_hierarchy.js +37 -0
  270. package/dist/migrations/20260720T044254_organizations_org_hierarchy.js.map +1 -0
  271. package/dist/migrations/20260912T094646_organizations_sales_channel_organizations.d.ts +27 -0
  272. package/dist/migrations/20260912T094646_organizations_sales_channel_organizations.d.ts.map +1 -0
  273. package/dist/migrations/20260912T094646_organizations_sales_channel_organizations.js +44 -0
  274. package/dist/migrations/20260912T094646_organizations_sales_channel_organizations.js.map +1 -0
  275. package/dist/migrations/index.d.ts +35 -0
  276. package/dist/migrations/index.d.ts.map +1 -0
  277. package/dist/migrations/index.js +45 -0
  278. package/dist/migrations/index.js.map +1 -0
  279. package/dist/ports/index.d.ts +53 -0
  280. package/dist/ports/index.d.ts.map +1 -0
  281. package/dist/ports/index.js +2 -0
  282. package/dist/ports/index.js.map +1 -0
  283. package/docs/organization-hierarchy.md +117 -0
  284. package/docs/organizations.md +312 -0
  285. package/i18n/en.json +17 -0
  286. package/i18n/pl.json +17 -0
  287. package/package.json +107 -0
  288. package/tailwind.css +14 -0
@@ -0,0 +1,503 @@
1
+ import { defineModuleManifest, defineModuleSettingsManifest, } from '@endora-commerce/contracts';
2
+ /**
3
+ * The demo data this module owns (feature 113, T222 — contract §1.3).
4
+ *
5
+ * A typed `const` rather than an inline object literal: declared inline the
6
+ * parameter infers from the schema and is `never`, so the author loses
7
+ * `context.ctx: ModuleContext`.
8
+ *
9
+ * Both bodies are reached by a **relative `await import()`** (§1.4), in
10
+ * `cliCommands.run`'s shape and for `cliCommands`' reason: a manifest is loaded
11
+ * by every process that composes the platform and by the check scripts that
12
+ * import the generated index, so a demo body imported at the top of this file
13
+ * would be a service graph pulled into all of them. It needs no `exports`
14
+ * subpath and no `files` entry (§1.5).
15
+ *
16
+ * **The buyer who belongs to this organisation and the credit limit granted to
17
+ * it are not here.** Each is another module's row against this one's, so each is
18
+ * a composition step (§5.1) and belongs to whoever owns the instance.
19
+ */
20
+ const demo = {
21
+ summary: 'The buying organisation the demo shop trades with.',
22
+ seed: async (context) => (await import('./backend/demo/seed.js')).seedDemo(context),
23
+ reset: async (context) => (await import('./backend/demo/reset.js')).resetDemo(context),
24
+ };
25
+ /**
26
+ * Organization-owned setting codes (feature 026 consolidation).
27
+ *
28
+ * Both keys are platform-wide policies (no per-channel override).
29
+ */
30
+ export const ORGANIZATIONS_SETTING_CODES = {
31
+ MODERATION_MODE: 'organizations.moderation.mode',
32
+ NEW_REGISTRATION_RECIPIENTS: 'organizations.notifications.new_registration_recipients',
33
+ // Feature 056 — platform-wide factory default for credit inheritance across the
34
+ // organization tree; a per-org `credit_inheritance_mode` column overrides it.
35
+ CREDIT_INHERITANCE_MODE: 'organizations.hierarchy.credit_inheritance_mode',
36
+ };
37
+ const settings = defineModuleSettingsManifest({
38
+ moduleCode: 'organizations',
39
+ groups: [{ code: 'organizations', name: 'Organizations' }],
40
+ settings: [
41
+ {
42
+ code: ORGANIZATIONS_SETTING_CODES.MODERATION_MODE,
43
+ name: 'Moderation mode for new Organizations',
44
+ description: 'Whether newly registered Organizations enter pending_verification (manual moderation) or active (auto-activation). One of: manual | auto.',
45
+ groupCode: 'organizations',
46
+ valueType: 'string',
47
+ defaultValue: 'manual',
48
+ },
49
+ {
50
+ code: ORGANIZATIONS_SETTING_CODES.NEW_REGISTRATION_RECIPIENTS,
51
+ name: 'New Organization registration — email recipients',
52
+ description: 'List of email addresses receiving a notification on every new Organization registration. Validated syntactically; max 50 entries; case-insensitive dedup. Empty list ⇒ no emails sent (in-app admin notification still fires).',
53
+ groupCode: 'organizations',
54
+ valueType: 'json',
55
+ defaultValue: [],
56
+ },
57
+ {
58
+ code: ORGANIZATIONS_SETTING_CODES.CREDIT_INHERITANCE_MODE,
59
+ name: 'Credit inheritance mode (organization hierarchy)',
60
+ description: 'Factory default for how a parent organization\'s credit limit is consumed by sub-organizations that have no own limit. One of: shared_pool (branches draw against one shared pool; concurrent draws never exceed it) | independent_default (each branch draws its own full copy of the inherited amount). A per-organization override may be set by a platform administrator.',
61
+ groupCode: 'organizations',
62
+ valueType: 'string',
63
+ defaultValue: 'shared_pool',
64
+ },
65
+ ],
66
+ });
67
+ /**
68
+ * Organizations module — manifest backfill (Module Lifecycle, feature 018)
69
+ * extended by feature 026 with two settings keys (moderation mode + new
70
+ * registration email recipients).
71
+ */
72
+ export const manifest = defineModuleManifest({
73
+ id: 'organizations',
74
+ name: 'Organizations',
75
+ description: 'B2B organization records, members, addresses, sales-rep assignment, moderation lifecycle, and per-org commercial scoping.',
76
+ version: '1.1.0',
77
+ // Rule 3 (tenancy root) — specs/065-manifest-aware-migrations/research.md §R9.
78
+ // `organizations` is the single unit of tenancy (Principle XI) and must stay
79
+ // installable first, so it declares no tenant-owned domain module. Five
80
+ // cross-module foreign keys are therefore deliberately NOT declared here —
81
+ // each is a late additive column, not an install-time necessity:
82
+ // → customer_accounts (email_verification_tokens.customer_account_id)
83
+ // would cycle: organizations → customer_accounts →
84
+ // organizations
85
+ // → inventory (organization_warehouses.warehouse_id)
86
+ // cycles as soon as the sales_channels bridge edge is
87
+ // also declared: organizations → inventory →
88
+ // sales_channels → organizations
89
+ // → delivery_methods (organization_delivery_methods.delivery_method_id)
90
+ // → payment_methods (organization_payment_methods.payment_method_id)
91
+ // The last two close no cycle on their own; they are dropped because a
92
+ // tenancy root that cannot install before an optional module is
93
+ // not a root. All four are recorded in
94
+ // test/unit/db/acknowledged-fk-edges.ts, which asserts each is still real and
95
+ // still an exception.
96
+ // `dictionaries` since feature 072 (T138): registration validates the
97
+ // Organization's country code against the dictionary. `RegistrationService`
98
+ // has always taken the validator and neither root ever passed one, so the
99
+ // check was dead and the edge undeclared.
100
+ // `email` since feature 072 (T138): the invitation, verification and
101
+ // new-registration mails. The in-app admin notification that accompanies the
102
+ // last of them was declared in the same task and has moved to
103
+ // `nonBindingDependencies` below (D-179.3). `admin_users` comes back with it:
104
+ // the sales-rep endpoints resolve `adminUserReadPort`, and the edge was
105
+ // satisfied transitively through `admin_notifications` until now. It closes no
106
+ // cycle — `admin_users` depends on `admin_roles` and `auth`, neither of which
107
+ // declares this module. `addresses` is deliberately absent for
108
+ // the same reason the five FK edges above are — it declares this module, so
109
+ // the edge is mutual and declaring it back closes the cycle; it is recorded
110
+ // in `acknowledgedDependencies` below instead.
111
+ // `transactional_emails` since T120: verification, invitation and
112
+ // new-registration mail routes through that module's `templateEmailPort`.
113
+ // `admin_roles` since T143a: the sales-rep visibility scope asks
114
+ // `permissionService` whether the rep holds `organizations:rollup` before it
115
+ // expands an assignment to its subtree. Declarable rather than acknowledged —
116
+ // `admin_roles` depends on nothing, so the edge closes no cycle.
117
+ dependencies: [
118
+ 'admin_roles',
119
+ 'admin_users',
120
+ 'custom_fields',
121
+ 'dictionaries',
122
+ 'email',
123
+ 'settings',
124
+ 'transactional_emails',
125
+ ],
126
+ // Feature 073, Amendment A1 — the five port edges this module genuinely has
127
+ // and cannot declare above, moved here from `ACKNOWLEDGED_PORT_EDGES` in
128
+ // `backend/scripts/check-port-dependencies.ts` so that one declaration feeds
129
+ // both the CI check and the flip-time refusal. They are ignored by the
130
+ // install and migration order, which is the only reason they were withheld.
131
+ acknowledgedDependencies: [
132
+ {
133
+ moduleId: 'addresses',
134
+ port: 'addressServicePort',
135
+ reason: 'Mutual by nature. `addresses` declares this module because every stored ' +
136
+ 'address is organization-scoped, and it must install after the tenancy root. ' +
137
+ 'This module resolves the published `AddressServicePort` because its customer ' +
138
+ 'routes expose address CRUD — it named the `addressService` class registration ' +
139
+ 'until issue #195, which is how the entity crossed the boundary behind a ' +
140
+ 'record-shaped type. Declaring the second direction closes the cycle and makes ' +
141
+ 'the tenancy root uninstallable first, which Rule 3 forbids — the same trade the ' +
142
+ "manifest's five acknowledged FK edges record. It goes when the address routes " +
143
+ 'move to the module that owns the table.',
144
+ },
145
+ {
146
+ moduleId: 'customer_accounts',
147
+ port: 'customerAuthPort',
148
+ reason: 'The same mutual pair, five names over. `customer_accounts` declares this ' +
149
+ 'module — every account belongs to one, and feature 051 made that the tenancy ' +
150
+ "direction — while this module's public registration, login and password-reset " +
151
+ 'routes are served by those services. The manifest already ' +
152
+ 'records the mirror of this as an acknowledged FK edge ' +
153
+ '(`email_verification_tokens.customer_account_id`). Feature 075 Phase C ' +
154
+ 'renamed two of the five: `customerAuthService` and `customerRoleService` hand ' +
155
+ "back that module's entity, and this module resolves the record-returning " +
156
+ '`customerAuthPort` / `customerRolePort` beside them instead.',
157
+ },
158
+ {
159
+ moduleId: 'customer_accounts',
160
+ port: 'passwordResetService',
161
+ reason: 'See the `customerAuthPort` edge above — same mutual pair.',
162
+ },
163
+ {
164
+ moduleId: 'customer_accounts',
165
+ port: 'customerRolePort',
166
+ reason: 'See the `customerAuthPort` edge above — same mutual pair.',
167
+ },
168
+ {
169
+ moduleId: 'customer_accounts',
170
+ port: 'customerAccountReadPort',
171
+ reason: 'Feature 075 Phase C. Every route file and three services in this module read ' +
172
+ "that module's `CustomerAccount` entity directly — the member panel, the " +
173
+ 'Org-Admin gate, `GET /me`, registration, invitation and the personal-organization ' +
174
+ 'provisioner. D-87 adds a fourth service: the moderation notifier resolved its ' +
175
+ 'recipient in raw SQL against that table, which named no specifier and so was ' +
176
+ 'invisible to the import predicate. Same mutual pair as `customerAuthPort` above, ' +
177
+ 'so the same trade.',
178
+ },
179
+ {
180
+ moduleId: 'customer_accounts',
181
+ port: 'customerAccountMemberWritePort',
182
+ reason: 'Feature 075 Phase C, the write half of the edge above: this module created and ' +
183
+ "mutated that module's entity in seven places. The writes moved to the owner and " +
184
+ 'the audit rows stayed here. Same mutual pair, same trade.',
185
+ },
186
+ {
187
+ moduleId: 'price_lists',
188
+ port: 'priceListReadPort',
189
+ reason: 'Feature 075 Phase C. The applicable-price-lists panel ran ' +
190
+ "`em.find(PriceList, { status: 'active' })` against that module's table and spelled " +
191
+ "the status filter itself; it asks `price_lists` now. `price_lists` declares this " +
192
+ 'module (every price rule is organization-scoped), so declaring the second direction ' +
193
+ 'closes the cycle and makes the tenancy root uninstallable first, which Rule 3 ' +
194
+ 'forbids — the same trade the four FK edges above record. It goes when the panel ' +
195
+ 'moves to the module that owns the table.',
196
+ },
197
+ ],
198
+ /**
199
+ * D-44 — real to the container, binding on no operator.
200
+ *
201
+ * D-179.1 moves the `credit_limits` edge here. It described its own refusal
202
+ * in prose before the spelling for it existed, and the spelling is what makes
203
+ * the owner's control work.
204
+ *
205
+ * D-179.3 moves `admin_notifications` here for the same reason and with the
206
+ * same kind. `catalog` reaches that owner too and takes `degrades-without`,
207
+ * because its recorder decides absence in front of the gate; the kind belongs
208
+ * to the **edge**, not to the owner, and the two consumers answer differently.
209
+ */
210
+ nonBindingDependencies: [
211
+ {
212
+ moduleId: 'admin_notifications',
213
+ name: 'adminNotificationRecordPort',
214
+ kind: 'refuses-without',
215
+ whenAbsent: 'nobody is told a new organisation has registered: the bell entry refuses, and that ' +
216
+ 'refusal stops the new-registration e-mails too — the registration itself still ' +
217
+ 'completes',
218
+ reason: 'D-179.3. The registration notifier writes one bell entry and then mails the ' +
219
+ 'recipient list, and its `catch` calls `rethrowIfModuleDisabled` first under D-88: a ' +
220
+ 'registration nobody was told about is not a degrade this module may choose on the ' +
221
+ 'owner’s behalf, so the refusal surfaces instead of being absorbed by the ' +
222
+ 'best-effort tolerance around it. That is what `refuses-without` spells, and ' +
223
+ 'declaring `degrades-without` here would reverse D-88 in a manifest field. It was ' +
224
+ '`dependencies`, which bought no schema order — nothing this module owns references ' +
225
+ 'either `admin_notification` table — and only the flip-time refusal that made ' +
226
+ '`admin_notifications.enabled` a control an operator could move with nothing ' +
227
+ 'happening.',
228
+ },
229
+ {
230
+ moduleId: 'credit_limits',
231
+ name: 'creditLimitReadPort',
232
+ kind: 'refuses-without',
233
+ whenAbsent: 'the ancestor-chain lookup for who holds a credit limit refuses — no screen reaches ' +
234
+ "it, because its only caller is that module's own service",
235
+ reason: 'Feature 077, D-87. `creditOwner` walks an ancestor chain and has to know which of ' +
236
+ "those organisations hold a credit limit. It selected from that module's table — a " +
237
+ 'statement naming no import specifier, so the boundary compiled and returned rows ' +
238
+ 'whatever state the owner was in. It asks `creditLimitReadPort` now, through a ' +
239
+ '`lazyPort` call on a `di.providePort` name, with no fallback and no `catch`: an ' +
240
+ 'empty set would read as "nobody here holds a limit", which on a credit check is the ' +
241
+ 'difference between refusing an order and quoting unlimited credit. D-179.1 spells ' +
242
+ 'that `refuses-without`. It was `acknowledgedDependencies`, which described the same ' +
243
+ 'behaviour and carried a bind as well, and the bind is what made the owner\'s ' +
244
+ 'activation control answer 409 forever.',
245
+ },
246
+ ],
247
+ // Feature 072/073 (Constitution XVII). The Organization is the single unit of
248
+ // tenancy (Principle XI): every transacting customer has one, every
249
+ // tenant-scoped entity carries its id, and the global-filter guard in
250
+ // `src/tenancy/` resolves against this module's table. Principle XI states
251
+ // outright that a design with a "no-organization" path is invalid, so there is
252
+ // no coherent deployment with this switched off — it is not a smaller platform
253
+ // but one with no tenant.
254
+ //
255
+ // The declaration is also forced from above: `customer_accounts` is itself
256
+ // non-deactivatable and depends on this module, and dependencies fail closed.
257
+ // Without it, switching `organizations` off would break a module the operator
258
+ // was promised could not be broken.
259
+ demo,
260
+ activation: {
261
+ nonDeactivatable: true,
262
+ reason: 'The single unit of tenancy — every organization-scoped entity, membership and ' +
263
+ 'transacting customer resolves through it; switched off, the platform has no tenant.',
264
+ },
265
+ // D-166 — the code gating the three `/organizations/:id/sales-reps`
266
+ // endpoints, which this module registers from its own `backend.ts`.
267
+ //
268
+ // It is the name this module's own route file proposed in feature 008: those
269
+ // endpoints were gated `rfqs:handle` "for now, because that's the existing
270
+ // admin permission slot for RFQ-adjacent work", with a comment saying a
271
+ // dedicated `organizations:assign-sales-rep` should follow. It has to, and
272
+ // for a reason sharper than tidiness — `rfqs:handle` is declared
273
+ // `module: 'quote_requests'`, so an operator switching quote requests off
274
+ // removes that code from `/admin-roles` while these endpoints, owned by a
275
+ // module that cannot be switched off, keep answering. The screen would sit
276
+ // there behind a permission nobody could be granted.
277
+ //
278
+ // `organizations:rollup` stays in the core `PERMISSION_CATALOGUE`: it is read
279
+ // by `admin_roles`' capability check on behalf of three modules, and moving it
280
+ // is a data migration on every admin role that holds it.
281
+ //
282
+ // D-173 — the two `customers:*` codes are the same finding, one route file
283
+ // over. Every admin organization endpoint here is gated on `customers:manage`
284
+ // (or on `customers:read` OR `customers:manage`), and both codes' core
285
+ // `PERMISSION_CATALOGUE` rows name `customers`, which an operator can switch
286
+ // off while this module cannot be. Declaring them here makes this module a
287
+ // second *owner*, in the shape issue #213 gave `integrations:manage`, so the
288
+ // presence filter keeps them grantable while these screens are on. The
289
+ // labels are why they are shared rather than replaced by codes of this
290
+ // module's own: *"Manage customer organizations"* and *"View customers"*
291
+ // read as sentences about this module's screens, which is what the
292
+ // paragraph above had to invent a new code for and these do not.
293
+ permissions: [
294
+ {
295
+ code: 'organizations:assign-sales-rep',
296
+ label: 'Assign sales representatives to organizations',
297
+ },
298
+ { code: 'customers:read', label: 'View customers' },
299
+ { code: 'customers:manage', label: 'Manage customer organizations' },
300
+ ],
301
+ settings,
302
+ /**
303
+ * The module's landing surface in the command palette (Principle XVI) — its
304
+ * first action, declared by feature 091's Phase 4 batch 14.
305
+ *
306
+ * `AppShell.tsx` carried a hand-written *Navigate* row for `/organizations`
307
+ * until that batch. A hand-written palette row is a copy the server was never
308
+ * asked about, so it went on advertising the screen whatever the effective
309
+ * enabled-set said; a manifest action is the one surface that set filters.
310
+ * The destination and the keywords are the row's, and the label and
311
+ * description are the two strings it rendered
312
+ * (`appShell.nav.organizations`, `appShell.palette.sub.customerAccounts`),
313
+ * moved into this module's own bundle.
314
+ *
315
+ * **`customers:read` and not the row's any-of pair.**
316
+ * `ModuleActionSchema.requiredPermission` is a single string, and either code
317
+ * alone opens `/organizations` — the gate is
318
+ * `requireAdminAny(['customers:read', 'customers:manage'])`, which is the
319
+ * sufficiency `check:action-route-permissions` reads. The narrowing is real
320
+ * for a role holding only `customers:manage` and is recorded where the row
321
+ * used to stand; the sidebar entry keeps the pair, because
322
+ * `AdminNavDeclaration.requiredPermission` takes the whole
323
+ * `PermissionRequirement`.
324
+ */
325
+ actions: [
326
+ {
327
+ id: 'open-organizations',
328
+ labelKey: 'actions.openOrganizations.label',
329
+ descriptionKey: 'actions.openOrganizations.description',
330
+ icon: 'Building2',
331
+ targetRoute: '/organizations',
332
+ requiredPermission: 'customers:read',
333
+ keywords: ['org', 'orgs', 'customer', 'organization', 'organizacja', 'klient'],
334
+ weight: 220,
335
+ },
336
+ ],
337
+ // Feature 047 — admin-editable transactional emails owned by this module.
338
+ transactionalEmails: [
339
+ {
340
+ code: 'email_verification',
341
+ name: 'Email verification',
342
+ group: 'organizations',
343
+ variables: [
344
+ { key: 'organizationName', label: 'Organization name', sampleValue: 'Acme Sp. z o.o.' },
345
+ { key: 'verifyUrl', label: 'Verification link', sampleValue: 'https://shop.example/verify?token=…' },
346
+ ],
347
+ },
348
+ {
349
+ code: 'organization_invitation',
350
+ name: 'Organization invitation',
351
+ group: 'organizations',
352
+ variables: [
353
+ { key: 'organizationName', label: 'Organization name', sampleValue: 'Acme Sp. z o.o.' },
354
+ { key: 'inviterName', label: 'Inviter name', sampleValue: 'Anna Nowak' },
355
+ { key: 'roleLabel', label: 'Role', sampleValue: 'Member' },
356
+ { key: 'acceptUrl', label: 'Accept link', sampleValue: 'https://shop.example/invitations/…/accept' },
357
+ { key: 'expiresOn', label: 'Expiry date', sampleValue: '2026-07-15' },
358
+ ],
359
+ },
360
+ {
361
+ code: 'new_org_registration',
362
+ name: 'New organization registration (admin)',
363
+ group: 'organizations',
364
+ variables: [
365
+ { key: 'organizationName', label: 'Organization name', sampleValue: 'Acme Sp. z o.o.' },
366
+ { key: 'taxId', label: 'Tax ID', sampleValue: 'PL1234567890' },
367
+ { key: 'statusLabel', label: 'Status', sampleValue: 'Oczekuje na weryfikację' },
368
+ { key: 'linkPath', label: 'Admin link', sampleValue: '/organizations/…' },
369
+ ],
370
+ },
371
+ // The two moderation outcomes a buyer is told about. Both reached the
372
+ // transport as hard-coded Polish prose with no code and no language until
373
+ // the seam-B carve-out in `specs/093-backend-delivered-prose/`; declaring
374
+ // them here is what gives them a language at all, and an operator a place
375
+ // to edit them.
376
+ {
377
+ code: 'organization_approved',
378
+ name: 'Organization verified (customer)',
379
+ group: 'organizations',
380
+ variables: [
381
+ { key: 'organizationName', label: 'Organization name', sampleValue: 'Acme Sp. z o.o.' },
382
+ ],
383
+ },
384
+ {
385
+ code: 'organization_rejected',
386
+ name: 'Organization registration rejected (customer)',
387
+ group: 'organizations',
388
+ variables: [
389
+ { key: 'organizationName', label: 'Organization name', sampleValue: 'Acme Sp. z o.o.' },
390
+ { key: 'reason', label: 'Rejection reason', sampleValue: 'Tax ID could not be verified.' },
391
+ ],
392
+ },
393
+ ],
394
+ /**
395
+ * This module's first i18n bundle — D-129's remaining sweep, MR 7.
396
+ *
397
+ * It exists because a **declaring** module that contributes no bundle file is
398
+ * `check:error-translations` exit 2 for the whole tree rather than a finding
399
+ * (`specs/090-module-owned-error-codes/contracts/error-translation-population.md`
400
+ * §2.1, §2.3; `d129-sweep.md` §3.4). The bundle lives at the **package
401
+ * root**, not under `dist`: `manifest-locations.ts` resolves a packaged
402
+ * module's `manifestPath` to its `package.json`, so `dirname` is the package
403
+ * directory. The file is a **flat** `{"a.b.c": "text"}` map, because a nested
404
+ * object fails `TranslationBundleEntriesSchema` and the boot reconciler logs
405
+ * and skips it — silently.
406
+ */
407
+ i18n: { bundlesDir: 'i18n' },
408
+ docs: { dir: 'docs' },
409
+ /**
410
+ * The eight codes whose noun is an organization — D-129's remaining sweep,
411
+ * **Tier C** (`specs/090-module-owned-error-codes/d129-sweep.md` §5.2,
412
+ * Appendix A; MR 7, the largest batch in the sweep).
413
+ *
414
+ * They were declared by `_i18n` until this merge request, not because anybody
415
+ * judged them the platform's but because the deleted prefix chain had no rule
416
+ * for them and its last line was `return 'core'`. **D-121 T1 puts all eight
417
+ * here**: the noun in each is this module's `organizations` row, its
418
+ * invitation, its administrator or its tree.
419
+ *
420
+ * **Two of the eight are raised by a module that does not own them**, which is
421
+ * the shape D-95.2 already ruled for `INVOICE_NOT_READY` and D-186 §1 re-took
422
+ * for `CUSTOMER_*`: the owner of a noun is not required to be the module that
423
+ * throws about it. `ORG_OWNER_DEPLETION` is raised three times in `customers`
424
+ * — deleting, blocking and unassigning the last organization administrator —
425
+ * and the invariant it protects is this module's, not that module's: an
426
+ * organization is the unit of tenancy and may not be left with nobody able to
427
+ * manage it. `ORGANIZATION_SUSPENDED` is raised once in `orders`, at
428
+ * placement, and is a statement about the organization's `status` column,
429
+ * which this module owns and moderates. Homing either with its thrower would
430
+ * split the sentence from the rule it describes and put it in a bundle that
431
+ * says nothing else about organizations.
432
+ *
433
+ * **Two are always tokened, and their token sets were measured rather than
434
+ * read off the bundle** (runbook §5): the arguments of every `HttpError` call
435
+ * naming them were extracted by balancing the call's own parentheses,
436
+ * resolving `ERROR_CODES.<CODE>` and the bare literal alike, and `details`
437
+ * read as the **positional fourth argument** it is — the correction MR 6
438
+ * recorded, because looking for a named `details:` property reports `(none)`
439
+ * for a raise that plainly carries a token. `ORGANIZATION_HAS_CHILDREN` has
440
+ * one raise and it passes `has_children`; `ORGANIZATION_TREE_INVALID` has two
441
+ * and they pass `cycle` and `max_depth_exceeded`. The other six carry no
442
+ * `details` at all, at any raise site, which is why they declare no tokens.
443
+ *
444
+ * **So all four sentences these two codes had were unreachable, and this
445
+ * change is the first time either renders anything.**
446
+ * `localizeErrorEnvelope` composes `` `${target.key}.${token}` `` whenever
447
+ * `details.code` is present and has **no** fall-back to the base key
448
+ * (`packages/platform/src/http/error-envelope.ts`), so `_i18n`'s two prose
449
+ * pairs were read by nobody. The three sub-keys are written here for the
450
+ * first time and are the ones an operator meets.
451
+ *
452
+ * **The base pairs move anyway, and D-190 is why.** They are unreachable for
453
+ * the operator and load-bearing for the instrument at the same time:
454
+ * `findUntranslatedErrorCodes` asks its question at
455
+ * `read(target.moduleId, language)[target.key]` and at **no other key**, so a
456
+ * bundle without them reports both codes as untranslated and exits 1 — MR 6
457
+ * measured exactly that when it tried. `UNTRANSLATED_ERROR_CODES` would be a
458
+ * false entry for a code with five written sentences, and widening P1 to
459
+ * accept "every declared token answered" is a tree-wide instrument changed by
460
+ * the merge request that benefits from it, which D-190 refuses in terms. So
461
+ * the base sentence is carried, and the sub-key beside it is the one to edit
462
+ * when the wording changes.
463
+ *
464
+ * **The other six arrive with prose.** Five carried a placeholder in `_i18n`'s
465
+ * bundle — `"Organization Suspended."` / `"Błąd: organization suspended."`
466
+ * and four like it — which D-186 §2 deletes rather than carries,
467
+ * because in this module's own bundle it would read as this module's answer
468
+ * and every instrument would then count the code as translated.
469
+ * `d129-sweep.md` §5.4 keeps writing the prose available and is not a
470
+ * re-opening of that ruling; every one of the six has a live raise site whose
471
+ * English states the refusal and a reader who meets it — an organization
472
+ * administrator inviting a member, a buyer whose organization was suspended,
473
+ * a company registering with a tax ID somebody already used, an operator on
474
+ * `/customers` removing the last administrator. The sixth,
475
+ * `ORG_OWNER_DEPLETION`, had no sentence at all and sat on
476
+ * `UNTRANSLATED_ERROR_CODES`; writing it is what makes that ledger **shrink**
477
+ * for the first time in the sweep.
478
+ *
479
+ * `ORGANIZATION_TREE_INVALID.max_depth_exceeded` needed one repair before its
480
+ * sentence could be written: the raise interpolates the depth bound into its
481
+ * English message and passed only the token, so a translated sentence with no
482
+ * placeholder would have rendered cleanly and lost the number — the shape
483
+ * !1181 measured at 85 codes tree-wide. The raise now carries
484
+ * `{ code: 'max_depth_exceeded', maxDepth: MAX_TREE_DEPTH_SEGMENTS }` and both
485
+ * sentences name it as `{maxDepth}`. The member is `maxDepth` and not `code`
486
+ * deliberately: `details.code` is the refusal **token**, and a second value
487
+ * written there would re-key the lookup rather than fill the sentence.
488
+ * `test/unit/organizations/error-code-sentences.test.ts` renders a real
489
+ * refusal against these keys, which is the three-way agreement issue #168
490
+ * found nothing was checking and which `check:error-translations` cannot see.
491
+ */
492
+ errorCodes: [
493
+ { code: 'CANNOT_REVOKE_LAST_ADMIN_INVITE' },
494
+ { code: 'EMAIL_ALREADY_IN_ORGANIZATION' },
495
+ { code: 'EMAIL_BELONGS_TO_ANOTHER_ORGANIZATION' },
496
+ { code: 'ORGANIZATION_HAS_CHILDREN', tokens: ['has_children'] },
497
+ { code: 'ORGANIZATION_SUSPENDED' },
498
+ { code: 'ORGANIZATION_TAX_ID_EXISTS' },
499
+ { code: 'ORGANIZATION_TREE_INVALID', tokens: ['cycle', 'max_depth_exceeded'] },
500
+ { code: 'ORG_OWNER_DEPLETION' },
501
+ ],
502
+ });
503
+ //# sourceMappingURL=manifest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manifest.js","sourceRoot":"","sources":["../src/manifest.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { Migration } from '@mikro-orm/migrations';
2
+ /**
3
+ * Organizations module (+ customer_accounts + addresses) — Phase 4b (T116).
4
+ *
5
+ * Also lands email_verification_tokens used by registration + email change flows.
6
+ * The partial unique index on `addresses (organization_id, kind) WHERE is_default`
7
+ * enforces "at most one default per kind" atomically (T097 contract).
8
+ */
9
+ export declare class Migration20260424T205317OrganizationsInit extends Migration {
10
+ up(): Promise<void>;
11
+ down(): Promise<void>;
12
+ }
13
+ //# sourceMappingURL=20260424T205317_organizations_init.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"20260424T205317_organizations_init.d.ts","sourceRoot":"","sources":["../../src/migrations/20260424T205317_organizations_init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAElD;;;;;;GAMG;AACH,qBAAa,yCAA0C,SAAQ,SAAS;IACvD,EAAE,IAAI,OAAO,CAAC,IAAI,CAAC;IAyFnB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;CAMrC"}
@@ -0,0 +1,100 @@
1
+ import { Migration } from '@mikro-orm/migrations';
2
+ /**
3
+ * Organizations module (+ customer_accounts + addresses) — Phase 4b (T116).
4
+ *
5
+ * Also lands email_verification_tokens used by registration + email change flows.
6
+ * The partial unique index on `addresses (organization_id, kind) WHERE is_default`
7
+ * enforces "at most one default per kind" atomically (T097 contract).
8
+ */
9
+ export class Migration20260424T205317OrganizationsInit extends Migration {
10
+ async up() {
11
+ this.addSql(`
12
+ create table "organizations" (
13
+ "id" uuid not null,
14
+ "name" varchar(255) not null,
15
+ "tax_id" varchar(32) not null,
16
+ "status" varchar(32) not null default 'pending_verification',
17
+ "vat_status" varchar(16) not null default 'vat_payer',
18
+ "registered_address" jsonb not null,
19
+ "created_at" timestamptz not null,
20
+ "updated_at" timestamptz not null,
21
+ "deleted_at" timestamptz null,
22
+ constraint "organizations_pkey" primary key ("id"),
23
+ constraint "organizations_tax_id_unique" unique ("tax_id")
24
+ );
25
+ `);
26
+ this.addSql('create index "organizations_name_index" on "organizations" ("name");');
27
+ this.addSql('create index "organizations_status_index" on "organizations" ("status");');
28
+ this.addSql(`
29
+ create table "customer_accounts" (
30
+ "id" uuid not null,
31
+ "organization_id" uuid not null,
32
+ "email" varchar(320) not null,
33
+ "password_hash" varchar(512) not null,
34
+ "first_name" varchar(120) not null,
35
+ "last_name" varchar(120) not null,
36
+ "role" varchar(32) not null default 'regular_user',
37
+ "email_verified_at" timestamptz null,
38
+ "two_factor_secret" varchar(64) null,
39
+ "two_factor_confirmed_at" timestamptz null,
40
+ "last_login_at" timestamptz null,
41
+ "created_at" timestamptz not null,
42
+ "updated_at" timestamptz not null,
43
+ "deleted_at" timestamptz null,
44
+ constraint "customer_accounts_pkey" primary key ("id"),
45
+ constraint "customer_accounts_email_unique" unique ("email"),
46
+ constraint "customer_accounts_organization_fk" foreign key ("organization_id")
47
+ references "organizations" ("id") on delete restrict
48
+ );
49
+ `);
50
+ this.addSql('create index "customer_accounts_organization_id_index" on "customer_accounts" ("organization_id");');
51
+ this.addSql('create index "customer_accounts_role_index" on "customer_accounts" ("role");');
52
+ this.addSql(`
53
+ create table "addresses" (
54
+ "id" uuid not null,
55
+ "organization_id" uuid not null,
56
+ "kind" varchar(16) not null,
57
+ "recipient_name" varchar(160) not null,
58
+ "street" varchar(255) not null,
59
+ "city" varchar(120) not null,
60
+ "postal_code" varchar(20) not null,
61
+ "country" varchar(2) not null,
62
+ "phone" varchar(32) null,
63
+ "is_default" boolean not null default false,
64
+ "created_at" timestamptz not null,
65
+ "updated_at" timestamptz not null,
66
+ "deleted_at" timestamptz null,
67
+ constraint "addresses_pkey" primary key ("id"),
68
+ constraint "addresses_organization_fk" foreign key ("organization_id")
69
+ references "organizations" ("id") on delete restrict
70
+ );
71
+ `);
72
+ this.addSql('create index "addresses_organization_id_index" on "addresses" ("organization_id");');
73
+ this.addSql('create index "addresses_kind_index" on "addresses" ("kind");');
74
+ // At most one default per (organization, kind) — partial unique index.
75
+ this.addSql(`create unique index "addresses_one_default_per_kind" on "addresses" ("organization_id", "kind") where "is_default" = true and "deleted_at" is null;`);
76
+ this.addSql(`
77
+ create table "email_verification_tokens" (
78
+ "id" uuid not null,
79
+ "customer_account_id" uuid not null,
80
+ "token_hash" varchar(128) not null,
81
+ "expires_at" timestamptz not null,
82
+ "consumed_at" timestamptz null,
83
+ "created_at" timestamptz not null,
84
+ constraint "email_verification_tokens_pkey" primary key ("id"),
85
+ constraint "email_verification_tokens_token_hash_unique" unique ("token_hash"),
86
+ constraint "email_verification_tokens_customer_fk" foreign key ("customer_account_id")
87
+ references "customer_accounts" ("id") on delete cascade
88
+ );
89
+ `);
90
+ this.addSql('create index "email_verification_tokens_customer_account_id_index" on "email_verification_tokens" ("customer_account_id");');
91
+ this.addSql('create index "email_verification_tokens_expires_at_index" on "email_verification_tokens" ("expires_at");');
92
+ }
93
+ async down() {
94
+ this.addSql('drop table if exists "email_verification_tokens" cascade;');
95
+ this.addSql('drop table if exists "addresses" cascade;');
96
+ this.addSql('drop table if exists "customer_accounts" cascade;');
97
+ this.addSql('drop table if exists "organizations" cascade;');
98
+ }
99
+ }
100
+ //# sourceMappingURL=20260424T205317_organizations_init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"20260424T205317_organizations_init.js","sourceRoot":"","sources":["../../src/migrations/20260424T205317_organizations_init.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAElD;;;;;;GAMG;AACH,MAAM,OAAO,yCAA0C,SAAQ,SAAS;IAC7D,KAAK,CAAC,EAAE;QACf,IAAI,CAAC,MAAM,CAAC;;;;;;;;;;;;;;KAcX,CAAC,CAAC;QACH,IAAI,CAAC,MAAM,CAAC,sEAAsE,CAAC,CAAC;QACpF,IAAI,CAAC,MAAM,CAAC,0EAA0E,CAAC,CAAC;QAExF,IAAI,CAAC,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;;KAqBX,CAAC,CAAC;QACH,IAAI,CAAC,MAAM,CAAC,oGAAoG,CAAC,CAAC;QAClH,IAAI,CAAC,MAAM,CAAC,8EAA8E,CAAC,CAAC;QAE5F,IAAI,CAAC,MAAM,CAAC;;;;;;;;;;;;;;;;;;;KAmBX,CAAC,CAAC;QACH,IAAI,CAAC,MAAM,CAAC,oFAAoF,CAAC,CAAC;QAClG,IAAI,CAAC,MAAM,CAAC,8DAA8D,CAAC,CAAC;QAC5E,uEAAuE;QACvE,IAAI,CAAC,MAAM,CACT,qJAAqJ,CACtJ,CAAC;QAEF,IAAI,CAAC,MAAM,CAAC;;;;;;;;;;;;;KAaX,CAAC,CAAC;QACH,IAAI,CAAC,MAAM,CAAC,4HAA4H,CAAC,CAAC;QAC1I,IAAI,CAAC,MAAM,CAAC,0GAA0G,CAAC,CAAC;IAC1H,CAAC;IAEQ,KAAK,CAAC,IAAI;QACjB,IAAI,CAAC,MAAM,CAAC,2DAA2D,CAAC,CAAC;QACzE,IAAI,CAAC,MAAM,CAAC,2CAA2C,CAAC,CAAC;QACzD,IAAI,CAAC,MAAM,CAAC,mDAAmD,CAAC,CAAC;QACjE,IAAI,CAAC,MAAM,CAAC,+CAA+C,CAAC,CAAC;IAC/D,CAAC;CACF"}