@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.
- package/LICENSE +21 -0
- package/README.md +62 -0
- package/dist/admin/components/OrganizationSalesRepsTab.d.ts +27 -0
- package/dist/admin/components/OrganizationSalesRepsTab.d.ts.map +1 -0
- package/dist/admin/components/OrganizationSalesRepsTab.js +170 -0
- package/dist/admin/components/OrganizationSalesRepsTab.js.map +1 -0
- package/dist/admin/index.d.ts +30 -0
- package/dist/admin/index.d.ts.map +1 -0
- package/dist/admin/index.js +59 -0
- package/dist/admin/index.js.map +1 -0
- package/dist/admin/pages/OrganizationDetail.d.ts +9 -0
- package/dist/admin/pages/OrganizationDetail.d.ts.map +1 -0
- package/dist/admin/pages/OrganizationDetail.js +247 -0
- package/dist/admin/pages/OrganizationDetail.js.map +1 -0
- package/dist/admin/pages/OrganizationsList.d.ts +9 -0
- package/dist/admin/pages/OrganizationsList.d.ts.map +1 -0
- package/dist/admin/pages/OrganizationsList.js +73 -0
- package/dist/admin/pages/OrganizationsList.js.map +1 -0
- package/dist/admin/panels/ApplicablePriceListsPanel.d.ts +12 -0
- package/dist/admin/panels/ApplicablePriceListsPanel.d.ts.map +1 -0
- package/dist/admin/panels/ApplicablePriceListsPanel.js +49 -0
- package/dist/admin/panels/ApplicablePriceListsPanel.js.map +1 -0
- package/dist/admin/panels/FulfilmentStrategyPanel.d.ts +16 -0
- package/dist/admin/panels/FulfilmentStrategyPanel.d.ts.map +1 -0
- package/dist/admin/panels/FulfilmentStrategyPanel.js +29 -0
- package/dist/admin/panels/FulfilmentStrategyPanel.js.map +1 -0
- package/dist/admin/panels/HierarchyPanel.d.ts +15 -0
- package/dist/admin/panels/HierarchyPanel.d.ts.map +1 -0
- package/dist/admin/panels/HierarchyPanel.js +65 -0
- package/dist/admin/panels/HierarchyPanel.js.map +1 -0
- package/dist/admin/panels/ModerationActionsPanel.d.ts +28 -0
- package/dist/admin/panels/ModerationActionsPanel.d.ts.map +1 -0
- package/dist/admin/panels/ModerationActionsPanel.js +111 -0
- package/dist/admin/panels/ModerationActionsPanel.js.map +1 -0
- package/dist/admin/panels/RestrictionsPanel.d.ts +24 -0
- package/dist/admin/panels/RestrictionsPanel.d.ts.map +1 -0
- package/dist/admin/panels/RestrictionsPanel.js +121 -0
- package/dist/admin/panels/RestrictionsPanel.js.map +1 -0
- package/dist/admin/panels/VatValidationPanel.d.ts +28 -0
- package/dist/admin/panels/VatValidationPanel.d.ts.map +1 -0
- package/dist/admin/panels/VatValidationPanel.js +79 -0
- package/dist/admin/panels/VatValidationPanel.js.map +1 -0
- package/dist/backend/commands/move.command.d.ts +11 -0
- package/dist/backend/commands/move.command.d.ts.map +1 -0
- package/dist/backend/commands/move.command.js +11 -0
- package/dist/backend/commands/move.command.js.map +1 -0
- package/dist/backend/commands/set-cart-approval-policy.command.d.ts +31 -0
- package/dist/backend/commands/set-cart-approval-policy.command.d.ts.map +1 -0
- package/dist/backend/commands/set-cart-approval-policy.command.js +56 -0
- package/dist/backend/commands/set-cart-approval-policy.command.js.map +1 -0
- package/dist/backend/commands/set-credit-mode.command.d.ts +16 -0
- package/dist/backend/commands/set-credit-mode.command.d.ts.map +1 -0
- package/dist/backend/commands/set-credit-mode.command.js +25 -0
- package/dist/backend/commands/set-credit-mode.command.js.map +1 -0
- package/dist/backend/commands/set-parent.command.d.ts +26 -0
- package/dist/backend/commands/set-parent.command.d.ts.map +1 -0
- package/dist/backend/commands/set-parent.command.js +51 -0
- package/dist/backend/commands/set-parent.command.js.map +1 -0
- package/dist/backend/demo/reset.d.ts +20 -0
- package/dist/backend/demo/reset.d.ts.map +1 -0
- package/dist/backend/demo/reset.js +11 -0
- package/dist/backend/demo/reset.js.map +1 -0
- package/dist/backend/demo/rows.d.ts +44 -0
- package/dist/backend/demo/rows.d.ts.map +1 -0
- package/dist/backend/demo/rows.js +44 -0
- package/dist/backend/demo/rows.js.map +1 -0
- package/dist/backend/demo/seed.d.ts +20 -0
- package/dist/backend/demo/seed.d.ts.map +1 -0
- package/dist/backend/demo/seed.js +28 -0
- package/dist/backend/demo/seed.js.map +1 -0
- package/dist/backend/email-templates/invitation.d.ts +23 -0
- package/dist/backend/email-templates/invitation.d.ts.map +1 -0
- package/dist/backend/email-templates/invitation.js +35 -0
- package/dist/backend/email-templates/invitation.js.map +1 -0
- package/dist/backend/email-templates/transactional-defaults.d.ts +54 -0
- package/dist/backend/email-templates/transactional-defaults.d.ts.map +1 -0
- package/dist/backend/email-templates/transactional-defaults.js +242 -0
- package/dist/backend/email-templates/transactional-defaults.js.map +1 -0
- package/dist/backend/email-templates/verification.d.ts +14 -0
- package/dist/backend/email-templates/verification.d.ts.map +1 -0
- package/dist/backend/email-templates/verification.js +34 -0
- package/dist/backend/email-templates/verification.js.map +1 -0
- package/dist/backend/entities/email-verification-token.entity.d.ts +17 -0
- package/dist/backend/entities/email-verification-token.entity.d.ts.map +1 -0
- package/dist/backend/entities/email-verification-token.entity.js +60 -0
- package/dist/backend/entities/email-verification-token.entity.js.map +1 -0
- package/dist/backend/entities/organization-delivery-method-link.entity.d.ts +14 -0
- package/dist/backend/entities/organization-delivery-method-link.entity.d.ts.map +1 -0
- package/dist/backend/entities/organization-delivery-method-link.entity.js +41 -0
- package/dist/backend/entities/organization-delivery-method-link.entity.js.map +1 -0
- package/dist/backend/entities/organization-invitation.entity.d.ts +21 -0
- package/dist/backend/entities/organization-invitation.entity.d.ts.map +1 -0
- package/dist/backend/entities/organization-invitation.entity.js +85 -0
- package/dist/backend/entities/organization-invitation.entity.js.map +1 -0
- package/dist/backend/entities/organization-payment-method-link.entity.d.ts +14 -0
- package/dist/backend/entities/organization-payment-method-link.entity.d.ts.map +1 -0
- package/dist/backend/entities/organization-payment-method-link.entity.js +41 -0
- package/dist/backend/entities/organization-payment-method-link.entity.js.map +1 -0
- package/dist/backend/entities/organization-sales-rep-assignment.entity.d.ts +17 -0
- package/dist/backend/entities/organization-sales-rep-assignment.entity.d.ts.map +1 -0
- package/dist/backend/entities/organization-sales-rep-assignment.entity.js +56 -0
- package/dist/backend/entities/organization-sales-rep-assignment.entity.js.map +1 -0
- package/dist/backend/entities/organization-tax-id-validation.entity.d.ts +29 -0
- package/dist/backend/entities/organization-tax-id-validation.entity.d.ts.map +1 -0
- package/dist/backend/entities/organization-tax-id-validation.entity.js +78 -0
- package/dist/backend/entities/organization-tax-id-validation.entity.js.map +1 -0
- package/dist/backend/entities/organization-warehouse-link.entity.d.ts +15 -0
- package/dist/backend/entities/organization-warehouse-link.entity.d.ts.map +1 -0
- package/dist/backend/entities/organization-warehouse-link.entity.js +42 -0
- package/dist/backend/entities/organization-warehouse-link.entity.js.map +1 -0
- package/dist/backend/entities/organization.entity.d.ts +125 -0
- package/dist/backend/entities/organization.entity.d.ts.map +1 -0
- package/dist/backend/entities/organization.entity.js +282 -0
- package/dist/backend/entities/organization.entity.js.map +1 -0
- package/dist/backend/index.d.ts +250 -0
- package/dist/backend/index.d.ts.map +1 -0
- package/dist/backend/index.js +506 -0
- package/dist/backend/index.js.map +1 -0
- package/dist/backend/integrations/ministerstwo-finansow-client.d.ts +22 -0
- package/dist/backend/integrations/ministerstwo-finansow-client.d.ts.map +1 -0
- package/dist/backend/integrations/ministerstwo-finansow-client.js +172 -0
- package/dist/backend/integrations/ministerstwo-finansow-client.js.map +1 -0
- package/dist/backend/integrations/vies-client.d.ts +18 -0
- package/dist/backend/integrations/vies-client.d.ts.map +1 -0
- package/dist/backend/integrations/vies-client.js +133 -0
- package/dist/backend/integrations/vies-client.js.map +1 -0
- package/dist/backend/plugin.d.ts +126 -0
- package/dist/backend/plugin.d.ts.map +1 -0
- package/dist/backend/plugin.js +139 -0
- package/dist/backend/plugin.js.map +1 -0
- package/dist/backend/routes.admin.d.ts +66 -0
- package/dist/backend/routes.admin.d.ts.map +1 -0
- package/dist/backend/routes.admin.js +711 -0
- package/dist/backend/routes.admin.js.map +1 -0
- package/dist/backend/routes.customer.d.ts +33 -0
- package/dist/backend/routes.customer.d.ts.map +1 -0
- package/dist/backend/routes.customer.js +139 -0
- package/dist/backend/routes.customer.js.map +1 -0
- package/dist/backend/routes.members.d.ts +31 -0
- package/dist/backend/routes.members.d.ts.map +1 -0
- package/dist/backend/routes.members.js +109 -0
- package/dist/backend/routes.members.js.map +1 -0
- package/dist/backend/routes.public.d.ts +49 -0
- package/dist/backend/routes.public.d.ts.map +1 -0
- package/dist/backend/routes.public.js +220 -0
- package/dist/backend/routes.public.js.map +1 -0
- package/dist/backend/routes.sales-reps.d.ts +46 -0
- package/dist/backend/routes.sales-reps.d.ts.map +1 -0
- package/dist/backend/routes.sales-reps.js +114 -0
- package/dist/backend/routes.sales-reps.js.map +1 -0
- package/dist/backend/routes.storefront.d.ts +25 -0
- package/dist/backend/routes.storefront.d.ts.map +1 -0
- package/dist/backend/routes.storefront.js +65 -0
- package/dist/backend/routes.storefront.js.map +1 -0
- package/dist/backend/schemas/organization.d.ts +59 -0
- package/dist/backend/schemas/organization.d.ts.map +1 -0
- package/dist/backend/schemas/organization.js +55 -0
- package/dist/backend/schemas/organization.js.map +1 -0
- package/dist/backend/schemas/settings.d.ts +30 -0
- package/dist/backend/schemas/settings.d.ts.map +1 -0
- package/dist/backend/schemas/settings.js +35 -0
- package/dist/backend/schemas/settings.js.map +1 -0
- package/dist/backend/services/email-verification-service.d.ts +45 -0
- package/dist/backend/services/email-verification-service.d.ts.map +1 -0
- package/dist/backend/services/email-verification-service.js +95 -0
- package/dist/backend/services/email-verification-service.js.map +1 -0
- package/dist/backend/services/invitation-service.d.ts +85 -0
- package/dist/backend/services/invitation-service.d.ts.map +1 -0
- package/dist/backend/services/invitation-service.js +266 -0
- package/dist/backend/services/invitation-service.js.map +1 -0
- package/dist/backend/services/normalize-name.d.ts +14 -0
- package/dist/backend/services/normalize-name.d.ts.map +1 -0
- package/dist/backend/services/normalize-name.js +14 -0
- package/dist/backend/services/normalize-name.js.map +1 -0
- package/dist/backend/services/org-registration-notifier.d.ts +36 -0
- package/dist/backend/services/org-registration-notifier.d.ts.map +1 -0
- package/dist/backend/services/org-registration-notifier.js +109 -0
- package/dist/backend/services/org-registration-notifier.js.map +1 -0
- package/dist/backend/services/org-template-email.d.ts +18 -0
- package/dist/backend/services/org-template-email.d.ts.map +1 -0
- package/dist/backend/services/org-template-email.js +16 -0
- package/dist/backend/services/org-template-email.js.map +1 -0
- package/dist/backend/services/organization-context-service.d.ts +52 -0
- package/dist/backend/services/organization-context-service.d.ts.map +1 -0
- package/dist/backend/services/organization-context-service.js +70 -0
- package/dist/backend/services/organization-context-service.js.map +1 -0
- package/dist/backend/services/organization-country-reference.d.ts +11 -0
- package/dist/backend/services/organization-country-reference.d.ts.map +1 -0
- package/dist/backend/services/organization-country-reference.js +24 -0
- package/dist/backend/services/organization-country-reference.js.map +1 -0
- package/dist/backend/services/organization-details-port.d.ts +33 -0
- package/dist/backend/services/organization-details-port.d.ts.map +1 -0
- package/dist/backend/services/organization-details-port.js +95 -0
- package/dist/backend/services/organization-details-port.js.map +1 -0
- package/dist/backend/services/organization-effective-pricelists-service.d.ts +50 -0
- package/dist/backend/services/organization-effective-pricelists-service.d.ts.map +1 -0
- package/dist/backend/services/organization-effective-pricelists-service.js +68 -0
- package/dist/backend/services/organization-effective-pricelists-service.js.map +1 -0
- package/dist/backend/services/organization-inheritance-service.d.ts +73 -0
- package/dist/backend/services/organization-inheritance-service.d.ts.map +1 -0
- package/dist/backend/services/organization-inheritance-service.js +63 -0
- package/dist/backend/services/organization-inheritance-service.js.map +1 -0
- package/dist/backend/services/organization-moderation-service.d.ts +124 -0
- package/dist/backend/services/organization-moderation-service.d.ts.map +1 -0
- package/dist/backend/services/organization-moderation-service.js +337 -0
- package/dist/backend/services/organization-moderation-service.js.map +1 -0
- package/dist/backend/services/organization-restriction-service.d.ts +70 -0
- package/dist/backend/services/organization-restriction-service.d.ts.map +1 -0
- package/dist/backend/services/organization-restriction-service.js +210 -0
- package/dist/backend/services/organization-restriction-service.js.map +1 -0
- package/dist/backend/services/organization-tax-id-validation-service.d.ts +59 -0
- package/dist/backend/services/organization-tax-id-validation-service.d.ts.map +1 -0
- package/dist/backend/services/organization-tax-id-validation-service.js +115 -0
- package/dist/backend/services/organization-tax-id-validation-service.js.map +1 -0
- package/dist/backend/services/organization-tree-service.d.ts +102 -0
- package/dist/backend/services/organization-tree-service.d.ts.map +1 -0
- package/dist/backend/services/organization-tree-service.js +184 -0
- package/dist/backend/services/organization-tree-service.js.map +1 -0
- package/dist/backend/services/personal-organization-service.d.ts +130 -0
- package/dist/backend/services/personal-organization-service.d.ts.map +1 -0
- package/dist/backend/services/personal-organization-service.js +207 -0
- package/dist/backend/services/personal-organization-service.js.map +1 -0
- package/dist/backend/services/registration-service.d.ts +80 -0
- package/dist/backend/services/registration-service.d.ts.map +1 -0
- package/dist/backend/services/registration-service.js +126 -0
- package/dist/backend/services/registration-service.js.map +1 -0
- package/dist/backend/services/sales-rep-assignment-service.d.ts +89 -0
- package/dist/backend/services/sales-rep-assignment-service.d.ts.map +1 -0
- package/dist/backend/services/sales-rep-assignment-service.js +176 -0
- package/dist/backend/services/sales-rep-assignment-service.js.map +1 -0
- package/dist/backend/services/vat-validator-port.d.ts +20 -0
- package/dist/backend/services/vat-validator-port.d.ts.map +1 -0
- package/dist/backend/services/vat-validator-port.js +2 -0
- package/dist/backend/services/vat-validator-port.js.map +1 -0
- package/dist/manifest.d.ts +176 -0
- package/dist/manifest.d.ts.map +1 -0
- package/dist/manifest.js +503 -0
- package/dist/manifest.js.map +1 -0
- package/dist/migrations/20260424T205317_organizations_init.d.ts +13 -0
- package/dist/migrations/20260424T205317_organizations_init.d.ts.map +1 -0
- package/dist/migrations/20260424T205317_organizations_init.js +100 -0
- package/dist/migrations/20260424T205317_organizations_init.js.map +1 -0
- package/dist/migrations/20260425T051700_organizations_invitations_init.d.ts +13 -0
- package/dist/migrations/20260425T051700_organizations_invitations_init.d.ts.map +1 -0
- package/dist/migrations/20260425T051700_organizations_invitations_init.js +39 -0
- package/dist/migrations/20260425T051700_organizations_invitations_init.js.map +1 -0
- package/dist/migrations/20260611T140349_organizations_consolidation.d.ts +35 -0
- package/dist/migrations/20260611T140349_organizations_consolidation.d.ts.map +1 -0
- package/dist/migrations/20260611T140349_organizations_consolidation.js +180 -0
- package/dist/migrations/20260611T140349_organizations_consolidation.js.map +1 -0
- package/dist/migrations/20260611T140358_organizations_org_order_confirmation_emails.d.ts +10 -0
- package/dist/migrations/20260611T140358_organizations_org_order_confirmation_emails.d.ts.map +1 -0
- package/dist/migrations/20260611T140358_organizations_org_order_confirmation_emails.js +14 -0
- package/dist/migrations/20260611T140358_organizations_org_order_confirmation_emails.js.map +1 -0
- package/dist/migrations/20260611T140402_organizations_org_fulfilment_strategy.d.ts +14 -0
- package/dist/migrations/20260611T140402_organizations_org_fulfilment_strategy.d.ts.map +1 -0
- package/dist/migrations/20260611T140402_organizations_org_fulfilment_strategy.js +20 -0
- package/dist/migrations/20260611T140402_organizations_org_fulfilment_strategy.js.map +1 -0
- package/dist/migrations/20260717T151403_organizations_personal_organizations.d.ts +24 -0
- package/dist/migrations/20260717T151403_organizations_personal_organizations.d.ts.map +1 -0
- package/dist/migrations/20260717T151403_organizations_personal_organizations.js +63 -0
- package/dist/migrations/20260717T151403_organizations_personal_organizations.js.map +1 -0
- package/dist/migrations/20260718T200340_organizations_organization_custom_field_values.d.ts +12 -0
- package/dist/migrations/20260718T200340_organizations_organization_custom_field_values.d.ts.map +1 -0
- package/dist/migrations/20260718T200340_organizations_organization_custom_field_values.js +16 -0
- package/dist/migrations/20260718T200340_organizations_organization_custom_field_values.js.map +1 -0
- package/dist/migrations/20260720T044254_organizations_org_hierarchy.d.ts +23 -0
- package/dist/migrations/20260720T044254_organizations_org_hierarchy.d.ts.map +1 -0
- package/dist/migrations/20260720T044254_organizations_org_hierarchy.js +37 -0
- package/dist/migrations/20260720T044254_organizations_org_hierarchy.js.map +1 -0
- package/dist/migrations/20260912T094646_organizations_sales_channel_organizations.d.ts +27 -0
- package/dist/migrations/20260912T094646_organizations_sales_channel_organizations.d.ts.map +1 -0
- package/dist/migrations/20260912T094646_organizations_sales_channel_organizations.js +44 -0
- package/dist/migrations/20260912T094646_organizations_sales_channel_organizations.js.map +1 -0
- package/dist/migrations/index.d.ts +35 -0
- package/dist/migrations/index.d.ts.map +1 -0
- package/dist/migrations/index.js +45 -0
- package/dist/migrations/index.js.map +1 -0
- package/dist/ports/index.d.ts +53 -0
- package/dist/ports/index.d.ts.map +1 -0
- package/dist/ports/index.js +2 -0
- package/dist/ports/index.js.map +1 -0
- package/docs/organization-hierarchy.md +117 -0
- package/docs/organizations.md +312 -0
- package/i18n/en.json +17 -0
- package/i18n/pl.json +17 -0
- package/package.json +107 -0
- package/tailwind.css +14 -0
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* Ministerstwo Finansów ("Biała lista podatników VAT") REST client.
|
|
4
|
+
* Feature 026 US7.
|
|
5
|
+
*
|
|
6
|
+
* Hits `GET https://wl-api.mf.gov.pl/api/search/nip/{nip}?date=YYYY-MM-DD`.
|
|
7
|
+
* Times out at 5 s; degrades to `deferred` on network errors or 5xx
|
|
8
|
+
* responses. A clean "not registered" becomes `failed` / `not_found`.
|
|
9
|
+
*
|
|
10
|
+
* MF rate-limits to ~10 req/sec per source IP. The simple in-process
|
|
11
|
+
* token bucket here enforces a conservative 1 req/sec; production
|
|
12
|
+
* traffic for this feature is < 100/day so the bucket will rarely
|
|
13
|
+
* throttle.
|
|
14
|
+
*/
|
|
15
|
+
const MF_RESPONSE_SCHEMA = z.object({
|
|
16
|
+
result: z
|
|
17
|
+
.object({
|
|
18
|
+
subject: z
|
|
19
|
+
.object({
|
|
20
|
+
name: z.string().nullable().optional(),
|
|
21
|
+
nip: z.string().nullable().optional(),
|
|
22
|
+
statusVat: z.string().nullable().optional(),
|
|
23
|
+
regon: z.string().nullable().optional(),
|
|
24
|
+
workingAddress: z.string().nullable().optional(),
|
|
25
|
+
residenceAddress: z.string().nullable().optional(),
|
|
26
|
+
})
|
|
27
|
+
.nullable()
|
|
28
|
+
.optional(),
|
|
29
|
+
})
|
|
30
|
+
.nullable()
|
|
31
|
+
.optional(),
|
|
32
|
+
code: z.string().nullable().optional(),
|
|
33
|
+
message: z.string().nullable().optional(),
|
|
34
|
+
});
|
|
35
|
+
export class MinisterstwoFinansowClient {
|
|
36
|
+
provider = 'mf_pl';
|
|
37
|
+
baseUrl;
|
|
38
|
+
timeoutMs;
|
|
39
|
+
fetchImpl;
|
|
40
|
+
minIntervalMs;
|
|
41
|
+
lastRequestAt = 0;
|
|
42
|
+
constructor(options = {}) {
|
|
43
|
+
this.baseUrl = options.baseUrl ?? 'https://wl-api.mf.gov.pl';
|
|
44
|
+
this.timeoutMs = options.timeoutMs ?? 5000;
|
|
45
|
+
this.fetchImpl = options.fetchImpl ?? globalThis.fetch.bind(globalThis);
|
|
46
|
+
this.minIntervalMs = options.minIntervalMs ?? 100;
|
|
47
|
+
}
|
|
48
|
+
async validate(input) {
|
|
49
|
+
const nip = input.taxId.replace(/^PL/i, '').replace(/[\s-]+/g, '');
|
|
50
|
+
if (!/^[0-9]{10}$/.test(nip)) {
|
|
51
|
+
return {
|
|
52
|
+
outcome: 'unverified',
|
|
53
|
+
legalName: null,
|
|
54
|
+
address: null,
|
|
55
|
+
errorKind: 'invalid_format',
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
await this.throttle();
|
|
59
|
+
const date = todayIsoDate();
|
|
60
|
+
const url = `${this.baseUrl}/api/search/nip/${nip}?date=${date}`;
|
|
61
|
+
const controller = new AbortController();
|
|
62
|
+
const timer = setTimeout(() => controller.abort(), this.timeoutMs);
|
|
63
|
+
try {
|
|
64
|
+
const res = await this.fetchImpl(url, {
|
|
65
|
+
method: 'GET',
|
|
66
|
+
headers: { accept: 'application/json' },
|
|
67
|
+
signal: controller.signal,
|
|
68
|
+
});
|
|
69
|
+
if (res.status === 429) {
|
|
70
|
+
return {
|
|
71
|
+
outcome: 'deferred',
|
|
72
|
+
legalName: null,
|
|
73
|
+
address: null,
|
|
74
|
+
errorKind: 'rate_limited',
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
if (res.status >= 500) {
|
|
78
|
+
return {
|
|
79
|
+
outcome: 'deferred',
|
|
80
|
+
legalName: null,
|
|
81
|
+
address: null,
|
|
82
|
+
errorKind: `provider_${res.status}`,
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
if (res.status === 404) {
|
|
86
|
+
return {
|
|
87
|
+
outcome: 'failed',
|
|
88
|
+
legalName: null,
|
|
89
|
+
address: null,
|
|
90
|
+
errorKind: 'not_found',
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
if (!res.ok) {
|
|
94
|
+
return {
|
|
95
|
+
outcome: 'failed',
|
|
96
|
+
legalName: null,
|
|
97
|
+
address: null,
|
|
98
|
+
errorKind: `http_${res.status}`,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
const json = await res.json().catch(() => null);
|
|
102
|
+
const parsed = MF_RESPONSE_SCHEMA.safeParse(json);
|
|
103
|
+
if (!parsed.success) {
|
|
104
|
+
return {
|
|
105
|
+
outcome: 'deferred',
|
|
106
|
+
legalName: null,
|
|
107
|
+
address: null,
|
|
108
|
+
errorKind: 'invalid_response_shape',
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
const subject = parsed.data.result?.subject ?? null;
|
|
112
|
+
if (!subject) {
|
|
113
|
+
return {
|
|
114
|
+
outcome: 'failed',
|
|
115
|
+
legalName: null,
|
|
116
|
+
address: null,
|
|
117
|
+
errorKind: 'not_found',
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
// Active VAT-payer statuses on MF: 'Czynny' (active) is the green
|
|
121
|
+
// light; everything else means the taxpayer is registered but
|
|
122
|
+
// suspended / cancelled. We surface those as `failed` rather than
|
|
123
|
+
// `validated` because they generally shouldn't trade.
|
|
124
|
+
const statusOk = (subject.statusVat ?? '').toLowerCase().includes('czynn');
|
|
125
|
+
return {
|
|
126
|
+
outcome: statusOk ? 'validated' : 'failed',
|
|
127
|
+
legalName: subject.name ?? null,
|
|
128
|
+
address: subject.workingAddress
|
|
129
|
+
? { line1: subject.workingAddress, countryCode: 'PL' }
|
|
130
|
+
: subject.residenceAddress
|
|
131
|
+
? { line1: subject.residenceAddress, countryCode: 'PL' }
|
|
132
|
+
: { countryCode: 'PL' },
|
|
133
|
+
errorKind: statusOk ? null : 'not_active_vat_payer',
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
catch (err) {
|
|
137
|
+
if (err.name === 'AbortError') {
|
|
138
|
+
return {
|
|
139
|
+
outcome: 'deferred',
|
|
140
|
+
legalName: null,
|
|
141
|
+
address: null,
|
|
142
|
+
errorKind: 'network_timeout',
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
return {
|
|
146
|
+
outcome: 'deferred',
|
|
147
|
+
legalName: null,
|
|
148
|
+
address: null,
|
|
149
|
+
errorKind: 'network_error',
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
finally {
|
|
153
|
+
clearTimeout(timer);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
async throttle() {
|
|
157
|
+
const now = Date.now();
|
|
158
|
+
const elapsed = now - this.lastRequestAt;
|
|
159
|
+
if (elapsed < this.minIntervalMs) {
|
|
160
|
+
await new Promise((resolve) => setTimeout(resolve, this.minIntervalMs - elapsed));
|
|
161
|
+
}
|
|
162
|
+
this.lastRequestAt = Date.now();
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
function todayIsoDate() {
|
|
166
|
+
const d = new Date();
|
|
167
|
+
const yyyy = d.getUTCFullYear();
|
|
168
|
+
const mm = String(d.getUTCMonth() + 1).padStart(2, '0');
|
|
169
|
+
const dd = String(d.getUTCDate()).padStart(2, '0');
|
|
170
|
+
return `${yyyy}-${mm}-${dd}`;
|
|
171
|
+
}
|
|
172
|
+
//# sourceMappingURL=ministerstwo-finansow-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ministerstwo-finansow-client.js","sourceRoot":"","sources":["../../../src/backend/integrations/ministerstwo-finansow-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { VatValidationResult, VatValidator } from '../services/vat-validator-port.js';
|
|
2
|
+
export interface ViesClientOptions {
|
|
3
|
+
baseUrl?: string;
|
|
4
|
+
timeoutMs?: number;
|
|
5
|
+
fetchImpl?: typeof globalThis.fetch;
|
|
6
|
+
}
|
|
7
|
+
export declare class ViesClient implements VatValidator {
|
|
8
|
+
readonly provider: "vies";
|
|
9
|
+
private readonly baseUrl;
|
|
10
|
+
private readonly timeoutMs;
|
|
11
|
+
private readonly fetchImpl;
|
|
12
|
+
constructor(options?: ViesClientOptions);
|
|
13
|
+
validate(input: {
|
|
14
|
+
taxId: string;
|
|
15
|
+
countryCode?: string | undefined;
|
|
16
|
+
}): Promise<VatValidationResult>;
|
|
17
|
+
}
|
|
18
|
+
//# sourceMappingURL=vies-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vies-client.d.ts","sourceRoot":"","sources":["../../../src/backend/integrations/vies-client.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,mBAAmB,EACnB,YAAY,EACb,MAAM,mCAAmC,CAAC;AAqB3C,MAAM,WAAW,iBAAiB;IAChC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,OAAO,UAAU,CAAC,KAAK,CAAC;CACrC;AAED,qBAAa,UAAW,YAAW,YAAY;IAC7C,QAAQ,CAAC,QAAQ,EAAG,MAAM,CAAU;IACpC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAA0B;gBAExC,OAAO,GAAE,iBAAsB;IAOrC,QAAQ,CAAC,KAAK,EAAE;QACpB,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;KAClC,GAAG,OAAO,CAAC,mBAAmB,CAAC;CAkFjC"}
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
/**
|
|
3
|
+
* VIES REST client (feature 026 US7).
|
|
4
|
+
*
|
|
5
|
+
* Hits `POST https://ec.europa.eu/taxation_customs/vies/rest-api/check-vat-number`.
|
|
6
|
+
* Times out at 5 s; degrades to `deferred` on network errors or 5xx
|
|
7
|
+
* responses. A clean `valid=false` becomes `failed` / `not_found`.
|
|
8
|
+
*
|
|
9
|
+
* The response shape is validated by Zod — if VIES ever surfaces a
|
|
10
|
+
* different schema we degrade to `deferred` rather than crashing.
|
|
11
|
+
*/
|
|
12
|
+
const VIES_RESPONSE_SCHEMA = z.object({
|
|
13
|
+
valid: z.boolean().optional(),
|
|
14
|
+
isValid: z.boolean().optional(),
|
|
15
|
+
countryCode: z.string().optional(),
|
|
16
|
+
vatNumber: z.string().optional(),
|
|
17
|
+
name: z.string().nullable().optional(),
|
|
18
|
+
address: z.string().nullable().optional(),
|
|
19
|
+
});
|
|
20
|
+
export class ViesClient {
|
|
21
|
+
provider = 'vies';
|
|
22
|
+
baseUrl;
|
|
23
|
+
timeoutMs;
|
|
24
|
+
fetchImpl;
|
|
25
|
+
constructor(options = {}) {
|
|
26
|
+
this.baseUrl =
|
|
27
|
+
options.baseUrl ?? 'https://ec.europa.eu/taxation_customs/vies/rest-api/check-vat-number';
|
|
28
|
+
this.timeoutMs = options.timeoutMs ?? 5000;
|
|
29
|
+
this.fetchImpl = options.fetchImpl ?? globalThis.fetch.bind(globalThis);
|
|
30
|
+
}
|
|
31
|
+
async validate(input) {
|
|
32
|
+
const { countryCode, number } = splitEuVatId(input.taxId, input.countryCode);
|
|
33
|
+
if (!countryCode || !number) {
|
|
34
|
+
return {
|
|
35
|
+
outcome: 'unverified',
|
|
36
|
+
legalName: null,
|
|
37
|
+
address: null,
|
|
38
|
+
errorKind: 'invalid_format',
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
const controller = new AbortController();
|
|
42
|
+
const timer = setTimeout(() => controller.abort(), this.timeoutMs);
|
|
43
|
+
try {
|
|
44
|
+
const res = await this.fetchImpl(this.baseUrl, {
|
|
45
|
+
method: 'POST',
|
|
46
|
+
headers: { 'content-type': 'application/json' },
|
|
47
|
+
body: JSON.stringify({ countryCode, vatNumber: number }),
|
|
48
|
+
signal: controller.signal,
|
|
49
|
+
});
|
|
50
|
+
if (res.status >= 500) {
|
|
51
|
+
return {
|
|
52
|
+
outcome: 'deferred',
|
|
53
|
+
legalName: null,
|
|
54
|
+
address: null,
|
|
55
|
+
errorKind: `provider_${res.status}`,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
if (!res.ok) {
|
|
59
|
+
return {
|
|
60
|
+
outcome: 'failed',
|
|
61
|
+
legalName: null,
|
|
62
|
+
address: null,
|
|
63
|
+
errorKind: `http_${res.status}`,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
const json = await res.json().catch(() => null);
|
|
67
|
+
const parsed = VIES_RESPONSE_SCHEMA.safeParse(json);
|
|
68
|
+
if (!parsed.success) {
|
|
69
|
+
return {
|
|
70
|
+
outcome: 'deferred',
|
|
71
|
+
legalName: null,
|
|
72
|
+
address: null,
|
|
73
|
+
errorKind: 'invalid_response_shape',
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
const valid = parsed.data.valid ?? parsed.data.isValid ?? false;
|
|
77
|
+
if (!valid) {
|
|
78
|
+
return {
|
|
79
|
+
outcome: 'failed',
|
|
80
|
+
legalName: null,
|
|
81
|
+
address: null,
|
|
82
|
+
errorKind: 'not_found',
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
return {
|
|
86
|
+
outcome: 'validated',
|
|
87
|
+
legalName: parsed.data.name ?? null,
|
|
88
|
+
address: parsed.data.address
|
|
89
|
+
? { line1: parsed.data.address, countryCode }
|
|
90
|
+
: { countryCode },
|
|
91
|
+
errorKind: null,
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
catch (err) {
|
|
95
|
+
if (err.name === 'AbortError') {
|
|
96
|
+
return {
|
|
97
|
+
outcome: 'deferred',
|
|
98
|
+
legalName: null,
|
|
99
|
+
address: null,
|
|
100
|
+
errorKind: 'network_timeout',
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
return {
|
|
104
|
+
outcome: 'deferred',
|
|
105
|
+
legalName: null,
|
|
106
|
+
address: null,
|
|
107
|
+
errorKind: 'network_error',
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
finally {
|
|
111
|
+
clearTimeout(timer);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* VIES expects the country code split from the digits. Accept either
|
|
117
|
+
* `'PL1234567890'`, `'PL 123-456-78-90'`, or a separate country hint +
|
|
118
|
+
* a digit-only tax id. The function strips whitespace and dashes
|
|
119
|
+
* defensively (the Zod boundary already does this for new orgs but the
|
|
120
|
+
* service-side path also accepts historical inputs).
|
|
121
|
+
*/
|
|
122
|
+
function splitEuVatId(taxId, hint) {
|
|
123
|
+
const cleaned = taxId.replace(/[\s-]+/g, '').toUpperCase();
|
|
124
|
+
const m = cleaned.match(/^([A-Z]{2})(.+)$/);
|
|
125
|
+
if (m) {
|
|
126
|
+
return { countryCode: m[1], number: m[2] };
|
|
127
|
+
}
|
|
128
|
+
if (hint && /^[A-Z]{2}$/.test(hint)) {
|
|
129
|
+
return { countryCode: hint.toUpperCase(), number: cleaned };
|
|
130
|
+
}
|
|
131
|
+
return { countryCode: null, number: null };
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=vies-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vies-client.js","sourceRoot":"","sources":["../../../src/backend/integrations/vies-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import type { FastifyInstance, FastifyRequest } from 'fastify';
|
|
2
|
+
import type { EntityManager } from '@mikro-orm/postgresql';
|
|
3
|
+
import type { AddressServicePort, CartMergeOutcome, CustomFieldValuePort, CustomerAccountMemberWritePort, CustomerAccountReadPort, CustomerAuthPort, CustomerPasswordResetPort, CustomerRolePort, EmailMailerPort } from '@endora-commerce/contracts';
|
|
4
|
+
import type { EventBus } from '@endora-commerce/platform/events';
|
|
5
|
+
import type { OrganizationModerationService } from './services/organization-moderation-service.js';
|
|
6
|
+
import type { OrganizationRestrictionService } from './services/organization-restriction-service.js';
|
|
7
|
+
import type { OrganizationEffectivePriceListsService } from './services/organization-effective-pricelists-service.js';
|
|
8
|
+
import type { OrganizationTaxIdValidationService } from './services/organization-tax-id-validation-service.js';
|
|
9
|
+
import { type OrgTemplateEmail } from './services/org-template-email.js';
|
|
10
|
+
import type { AuditPort } from '@endora-commerce/platform/kernel';
|
|
11
|
+
import type { CommandBus } from '@endora-commerce/platform/commands';
|
|
12
|
+
import type { RequireAdminAnyFactory } from '@endora-commerce/platform/kernel';
|
|
13
|
+
import type { DictionaryValidator } from '@endora-commerce/contracts';
|
|
14
|
+
import type { RequireAdminFactory } from '@endora-commerce/platform/kernel';
|
|
15
|
+
/**
|
|
16
|
+
* Composition root for the organizations + customer_accounts + addresses
|
|
17
|
+
* module family. One plugin registers all three because their routes share
|
|
18
|
+
* the same auth flow and serializers.
|
|
19
|
+
*/
|
|
20
|
+
export interface OrganizationsModuleOptions {
|
|
21
|
+
/**
|
|
22
|
+
* Feature 072 (T094) — `customer_accounts` owns these now. Injected rather
|
|
23
|
+
* than built here, because this host and `customers` each built their own and the
|
|
24
|
+
* MFA argument differed between them.
|
|
25
|
+
*/
|
|
26
|
+
customerAuthService: CustomerAuthPort;
|
|
27
|
+
passwordResetService: CustomerPasswordResetPort;
|
|
28
|
+
customerRoleService: CustomerRolePort;
|
|
29
|
+
/**
|
|
30
|
+
* `customer_accounts`' published read and member write (feature 075, Phase
|
|
31
|
+
* C). Registration, invitation accept, the member panel, `GET /me` and the
|
|
32
|
+
* Org-Admin gate all reached this module's entity directly before the cut.
|
|
33
|
+
*/
|
|
34
|
+
customerAccountRead: CustomerAccountReadPort;
|
|
35
|
+
customerAccountWrite: CustomerAccountMemberWritePort;
|
|
36
|
+
emFactory: () => EntityManager;
|
|
37
|
+
eventBus: EventBus;
|
|
38
|
+
requireCustomer: (req: FastifyRequest, reply: unknown) => Promise<void>;
|
|
39
|
+
resolveCustomerContext: (req: FastifyRequest) => {
|
|
40
|
+
customerAccountId: string;
|
|
41
|
+
organizationId: string;
|
|
42
|
+
impersonatorAdminUserId?: string | null;
|
|
43
|
+
};
|
|
44
|
+
/** Expose the /api/v1/_test/latest-verification-token probe (test-only). */
|
|
45
|
+
exposeTestProbe?: boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Optional post-login hook — the commerce module uses this to merge
|
|
48
|
+
* carts; the comparisons module uses it to adopt the customer's
|
|
49
|
+
* anonymous Comparison (R-2). Each token is extracted from the request
|
|
50
|
+
* cookies if present and forwarded to the hook. The optional
|
|
51
|
+
* `cartMerge` return field carries the outcome of the cart-merge step
|
|
52
|
+
* back to the login route so it can serialise the result for the
|
|
53
|
+
* storefront (feature 037-cart-merge-on-login).
|
|
54
|
+
*/
|
|
55
|
+
onLogin?: (ctx: {
|
|
56
|
+
customerAccountId: string;
|
|
57
|
+
/** Null for no-org Customer accounts (feature 026 US2). */
|
|
58
|
+
organizationId: string | null;
|
|
59
|
+
anonymousCartToken?: string;
|
|
60
|
+
/** `compare_token` cookie value, if the caller was building an anonymous comparison. */
|
|
61
|
+
anonymousCompareToken?: string;
|
|
62
|
+
}) => Promise<{
|
|
63
|
+
cartMerge?: CartMergeOutcome;
|
|
64
|
+
}>;
|
|
65
|
+
/** Admin gate for /admin/organizations routes. */
|
|
66
|
+
requireAdmin?: RequireAdminFactory;
|
|
67
|
+
/** Read-only org routes accept `customers:read` OR `customers:manage`. */
|
|
68
|
+
requireAdminAny?: RequireAdminAnyFactory;
|
|
69
|
+
/**
|
|
70
|
+
* Transport for the invitation and verification e-mails.
|
|
71
|
+
*
|
|
72
|
+
* Required since feature 075's Phase C. It defaulted to `new ConsoleMailer()`
|
|
73
|
+
* — a value import of `email`'s driver — and the default has had no reachable
|
|
74
|
+
* caller since the container started resolving `emailMailer` for every
|
|
75
|
+
* composition: an omitted mailer would mean an e-mail nobody receives and a
|
|
76
|
+
* registration that reports it as sent.
|
|
77
|
+
*/
|
|
78
|
+
mailer: EmailMailerPort;
|
|
79
|
+
/**
|
|
80
|
+
* Feature 047 / 072 (T120) — the template-routed sender, supplied by
|
|
81
|
+
* `transactional_emails` through `templateEmailPort`. Absent, every
|
|
82
|
+
* template-routed send falls back to the legacy in-code builder.
|
|
83
|
+
*/
|
|
84
|
+
templateEmail?: OrgTemplateEmail;
|
|
85
|
+
/** Storefront base URL for the invitation accept link. */
|
|
86
|
+
storefrontBaseUrl?: string;
|
|
87
|
+
/** Required when `requireAdmin` is set — audit trail for admin org mutations. */
|
|
88
|
+
auditLogService?: AuditPort;
|
|
89
|
+
dictionaryValidator?: DictionaryValidator;
|
|
90
|
+
/** Resolved from the container since feature 072 (T090) — one instance, always armed. */
|
|
91
|
+
addressService: AddressServicePort;
|
|
92
|
+
/**
|
|
93
|
+
* Feature 026 — moderation service that owns approve / reject / block /
|
|
94
|
+
* unblock. When provided alongside `requireAdmin`, the matching admin
|
|
95
|
+
* endpoints are mounted; otherwise only the legacy PATCH endpoint runs.
|
|
96
|
+
*/
|
|
97
|
+
moderationService?: OrganizationModerationService;
|
|
98
|
+
/**
|
|
99
|
+
* Feature 026 US4 — restriction service that owns the per-Organization
|
|
100
|
+
* payment / delivery / warehouse allow-lists. When provided alongside
|
|
101
|
+
* `requireAdmin`, the matching admin endpoints are mounted.
|
|
102
|
+
*/
|
|
103
|
+
restrictionService?: OrganizationRestrictionService;
|
|
104
|
+
/**
|
|
105
|
+
* Feature 026 US5 — service returning the Price Lists currently
|
|
106
|
+
* applicable to an Organization. Mounts the
|
|
107
|
+
* `/applicable-price-lists` admin endpoint when provided.
|
|
108
|
+
*/
|
|
109
|
+
effectivePriceListsService?: OrganizationEffectivePriceListsService;
|
|
110
|
+
/**
|
|
111
|
+
* Feature 026 US7 — service that runs VAT-ID validation via VIES /
|
|
112
|
+
* Ministerstwo Finansów. Mounts the `/vat-validations` admin endpoints
|
|
113
|
+
* when provided.
|
|
114
|
+
*/
|
|
115
|
+
taxIdValidationService?: OrganizationTaxIdValidationService;
|
|
116
|
+
/** Feature 055 — validates + reads organization custom-field values on the admin edit path. */
|
|
117
|
+
customFieldValues?: CustomFieldValuePort;
|
|
118
|
+
/**
|
|
119
|
+
* Feature 056 — Command Bus for the org-hierarchy tree mutations
|
|
120
|
+
* (`organization.set_parent` / `organization.move`). When present alongside
|
|
121
|
+
* `requireAdmin`, the hierarchy admin endpoints are mounted (Principle XIII).
|
|
122
|
+
*/
|
|
123
|
+
commandBus?: CommandBus;
|
|
124
|
+
}
|
|
125
|
+
export declare function organizationsModule(options: OrganizationsModuleOptions): (app: FastifyInstance) => Promise<void>;
|
|
126
|
+
//# sourceMappingURL=plugin.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../src/backend/plugin.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { RegistrationService, } from './services/registration-service.js';
|
|
2
|
+
import { EmailVerificationService } from './services/email-verification-service.js';
|
|
3
|
+
import { InvitationService } from './services/invitation-service.js';
|
|
4
|
+
import { noopOrgTemplateEmail } from './services/org-template-email.js';
|
|
5
|
+
import { registerOrganizationsPublicRoutes } from './routes.public.js';
|
|
6
|
+
import { registerOrganizationsCustomerRoutes } from './routes.customer.js';
|
|
7
|
+
import { registerOrganizationsStorefrontRoutes } from './routes.storefront.js';
|
|
8
|
+
import { OrganizationContextService } from './services/organization-context-service.js';
|
|
9
|
+
import { registerMembersRoutes } from './routes.members.js';
|
|
10
|
+
import { registerOrganizationsAdminRoutes } from './routes.admin.js';
|
|
11
|
+
import { OrganizationTreeService } from './services/organization-tree-service.js';
|
|
12
|
+
export function organizationsModule(options) {
|
|
13
|
+
return async (app) => {
|
|
14
|
+
const mailer = options.mailer;
|
|
15
|
+
// Feature 072 (T120) — supplied rather than assembled. This used to build
|
|
16
|
+
// its own adapter from three options; `transactional_emails` owns the
|
|
17
|
+
// implementation now and every module that sends template-routed mail
|
|
18
|
+
// resolves the same one.
|
|
19
|
+
const orgTemplateEmail = options.templateEmail ?? noopOrgTemplateEmail;
|
|
20
|
+
const storefrontBaseUrl = options.storefrontBaseUrl ?? 'http://localhost:3000';
|
|
21
|
+
const latestTokenByEmail = new Map();
|
|
22
|
+
const accountPorts = {
|
|
23
|
+
read: options.customerAccountRead,
|
|
24
|
+
write: options.customerAccountWrite,
|
|
25
|
+
};
|
|
26
|
+
const registrationService = new RegistrationService(options.emFactory, options.eventBus, accountPorts, options.dictionaryValidator, options.auditLogService);
|
|
27
|
+
const verificationService = new EmailVerificationService(options.emFactory, options.eventBus, accountPorts, options.auditLogService);
|
|
28
|
+
const customerAuthService = options.customerAuthService;
|
|
29
|
+
const invitationService = new InvitationService(options.emFactory, accountPorts, mailer, { acceptBaseUrl: storefrontBaseUrl }, options.eventBus, orgTemplateEmail, options.auditLogService);
|
|
30
|
+
const roleService = options.customerRoleService;
|
|
31
|
+
const passwordResetService = options.passwordResetService;
|
|
32
|
+
const addressService = options.addressService;
|
|
33
|
+
const latestInvitationToken = { value: null };
|
|
34
|
+
await registerOrganizationsPublicRoutes(app, {
|
|
35
|
+
registrationService,
|
|
36
|
+
verificationService,
|
|
37
|
+
customerAuthService,
|
|
38
|
+
passwordResetService,
|
|
39
|
+
exposeTestProbe: options.exposeTestProbe ?? false,
|
|
40
|
+
latestTokenByEmail,
|
|
41
|
+
mailer,
|
|
42
|
+
templateEmail: orgTemplateEmail,
|
|
43
|
+
storefrontBaseUrl,
|
|
44
|
+
...(options.onLogin ? { onLogin: options.onLogin } : {}),
|
|
45
|
+
});
|
|
46
|
+
await registerOrganizationsCustomerRoutes(app, {
|
|
47
|
+
customerAuthService,
|
|
48
|
+
addressService,
|
|
49
|
+
customerAccountRead: options.customerAccountRead,
|
|
50
|
+
requireCustomer: options.requireCustomer,
|
|
51
|
+
resolveCustomerContext: options.resolveCustomerContext,
|
|
52
|
+
resolveCustomerActorOptionalOrg: resolveOptionalOrgContext,
|
|
53
|
+
emFactory: options.emFactory,
|
|
54
|
+
});
|
|
55
|
+
if (options.restrictionService) {
|
|
56
|
+
await registerOrganizationsStorefrontRoutes(app, {
|
|
57
|
+
contextService: new OrganizationContextService(options.emFactory),
|
|
58
|
+
restrictionService: options.restrictionService,
|
|
59
|
+
requireCustomer: options.requireCustomer,
|
|
60
|
+
// The preflight endpoint must accept no-org Customers (they receive
|
|
61
|
+
// platform defaults). We read the actor decoration directly rather
|
|
62
|
+
// than going through `resolveCustomerContext`, which throws 422 for
|
|
63
|
+
// no-org callers — that behavior is correct for order placement and
|
|
64
|
+
// RFQ submission but wrong here.
|
|
65
|
+
resolveCustomerContext: resolveOptionalOrgContext,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
await registerMembersRoutes(app, {
|
|
69
|
+
invitationService,
|
|
70
|
+
roleService,
|
|
71
|
+
customerAccountRead: options.customerAccountRead,
|
|
72
|
+
requireCustomer: options.requireCustomer,
|
|
73
|
+
resolveCustomerContext: options.resolveCustomerContext,
|
|
74
|
+
exposeTestProbe: options.exposeTestProbe ?? false,
|
|
75
|
+
latestInvitationToken,
|
|
76
|
+
});
|
|
77
|
+
if (options.requireAdmin) {
|
|
78
|
+
if (!options.auditLogService) {
|
|
79
|
+
throw new Error('organizationsModule: auditLogService is required when requireAdmin is set');
|
|
80
|
+
}
|
|
81
|
+
if (!options.requireAdminAny) {
|
|
82
|
+
throw new Error('organizationsModule: requireAdminAny is required when requireAdmin is set');
|
|
83
|
+
}
|
|
84
|
+
await registerOrganizationsAdminRoutes(app, {
|
|
85
|
+
emFactory: options.emFactory,
|
|
86
|
+
requireAdmin: options.requireAdmin,
|
|
87
|
+
requireAdminAny: options.requireAdminAny,
|
|
88
|
+
invitationService,
|
|
89
|
+
roleService,
|
|
90
|
+
customerAccountRead: options.customerAccountRead,
|
|
91
|
+
customerAccountWrite: options.customerAccountWrite,
|
|
92
|
+
auditLogService: options.auditLogService,
|
|
93
|
+
eventBus: options.eventBus,
|
|
94
|
+
addressService,
|
|
95
|
+
...(options.moderationService ? { moderationService: options.moderationService } : {}),
|
|
96
|
+
...(options.restrictionService ? { restrictionService: options.restrictionService } : {}),
|
|
97
|
+
...(options.effectivePriceListsService
|
|
98
|
+
? { effectivePriceListsService: options.effectivePriceListsService }
|
|
99
|
+
: {}),
|
|
100
|
+
...(options.taxIdValidationService
|
|
101
|
+
? { taxIdValidationService: options.taxIdValidationService }
|
|
102
|
+
: {}),
|
|
103
|
+
...(options.customFieldValues ? { customFieldValues: options.customFieldValues } : {}),
|
|
104
|
+
...(options.commandBus
|
|
105
|
+
? {
|
|
106
|
+
commandBus: options.commandBus,
|
|
107
|
+
treeService: new OrganizationTreeService(options.emFactory),
|
|
108
|
+
}
|
|
109
|
+
: {}),
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Reads the customer context from whichever actor decoration is present —
|
|
116
|
+
* `request.actor` in production, `request.testActor` in the test harness.
|
|
117
|
+
* Returns `organizationId: null` for no-org Customer accounts (feature 026
|
|
118
|
+
* US2). Used by the storefront preflight endpoint which must accept both
|
|
119
|
+
* org-bound and no-org Customers.
|
|
120
|
+
*/
|
|
121
|
+
function resolveOptionalOrgContext(request) {
|
|
122
|
+
const r = request;
|
|
123
|
+
if (r.testActor?.kind === 'customer' && r.testActor.customerAccountId) {
|
|
124
|
+
return {
|
|
125
|
+
customerAccountId: r.testActor.customerAccountId,
|
|
126
|
+
organizationId: r.testActor.organizationId ?? null,
|
|
127
|
+
impersonatorAdminUserId: r.testActor.impersonatorAdminUserId ?? null,
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
if (r.actor?.kind === 'customer' && r.actor.customerAccountId) {
|
|
131
|
+
return {
|
|
132
|
+
customerAccountId: r.actor.customerAccountId,
|
|
133
|
+
organizationId: r.actor.organizationId ?? null,
|
|
134
|
+
impersonatorAdminUserId: r.actor.impersonatorAdminUserId ?? null,
|
|
135
|
+
};
|
|
136
|
+
}
|
|
137
|
+
throw new Error('resolveOptionalOrgContext: no Customer actor on the request — requireCustomer preHandler should have rejected.');
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../src/backend/plugin.ts"],"names":[],"mappings":"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"}
|