@open-mercato/core 0.6.1-develop.3260.1.dc719cac84 → 0.6.1-develop.3278.1.a4d26475e4

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 (212) hide show
  1. package/.turbo/turbo-build.log +2 -2
  2. package/dist/generated/entities/domain_mapping/index.js +31 -0
  3. package/dist/generated/entities/domain_mapping/index.js.map +7 -0
  4. package/dist/generated/entities.ids.generated.js +2 -1
  5. package/dist/generated/entities.ids.generated.js.map +2 -2
  6. package/dist/generated/entity-fields-registry.js +16 -0
  7. package/dist/generated/entity-fields-registry.js.map +2 -2
  8. package/dist/helpers/integration/salesUi.js +18 -17
  9. package/dist/helpers/integration/salesUi.js.map +2 -2
  10. package/dist/modules/customer_accounts/acl.js +2 -1
  11. package/dist/modules/customer_accounts/acl.js.map +2 -2
  12. package/dist/modules/customer_accounts/api/admin/domain-mappings/[id]/health-check.js +110 -0
  13. package/dist/modules/customer_accounts/api/admin/domain-mappings/[id]/health-check.js.map +7 -0
  14. package/dist/modules/customer_accounts/api/admin/domain-mappings/[id]/verify.js +114 -0
  15. package/dist/modules/customer_accounts/api/admin/domain-mappings/[id]/verify.js.map +7 -0
  16. package/dist/modules/customer_accounts/api/admin/domain-mappings.js +271 -0
  17. package/dist/modules/customer_accounts/api/admin/domain-mappings.js.map +7 -0
  18. package/dist/modules/customer_accounts/api/domain-check.js +70 -0
  19. package/dist/modules/customer_accounts/api/domain-check.js.map +7 -0
  20. package/dist/modules/customer_accounts/api/domain-resolve/all.js +128 -0
  21. package/dist/modules/customer_accounts/api/domain-resolve/all.js.map +7 -0
  22. package/dist/modules/customer_accounts/api/domain-resolve.js +84 -0
  23. package/dist/modules/customer_accounts/api/domain-resolve.js.map +7 -0
  24. package/dist/modules/customer_accounts/api/login.js +14 -3
  25. package/dist/modules/customer_accounts/api/login.js.map +2 -2
  26. package/dist/modules/customer_accounts/api/magic-link/request.js +14 -3
  27. package/dist/modules/customer_accounts/api/magic-link/request.js.map +2 -2
  28. package/dist/modules/customer_accounts/api/password/reset-request.js +14 -3
  29. package/dist/modules/customer_accounts/api/password/reset-request.js.map +2 -2
  30. package/dist/modules/customer_accounts/api/signup.js +32 -5
  31. package/dist/modules/customer_accounts/api/signup.js.map +2 -2
  32. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Actions.js +48 -0
  33. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Actions.js.map +7 -0
  34. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Diagnostics.js +43 -0
  35. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Diagnostics.js.map +7 -0
  36. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/DnsConfig.js +53 -0
  37. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/DnsConfig.js.map +7 -0
  38. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/DomainPanel.js +69 -0
  39. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/DomainPanel.js.map +7 -0
  40. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/OrgSwitcher.js +31 -0
  41. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/OrgSwitcher.js.map +7 -0
  42. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/RegisterDialog.js +147 -0
  43. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/RegisterDialog.js.map +7 -0
  44. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/StatusBadgeSection.js +39 -0
  45. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/StatusBadgeSection.js.map +7 -0
  46. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Stepper.js +60 -0
  47. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Stepper.js.map +7 -0
  48. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/domainStatusMap.js +11 -0
  49. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/domainStatusMap.js.map +7 -0
  50. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/types.js +1 -0
  51. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/types.js.map +7 -0
  52. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/page.js +361 -0
  53. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/page.js.map +7 -0
  54. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/page.meta.js +28 -0
  55. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/page.meta.js.map +7 -0
  56. package/dist/modules/customer_accounts/data/enrichers.js +78 -12
  57. package/dist/modules/customer_accounts/data/enrichers.js.map +2 -2
  58. package/dist/modules/customer_accounts/data/entities.js +85 -2
  59. package/dist/modules/customer_accounts/data/entities.js.map +2 -2
  60. package/dist/modules/customer_accounts/data/guards.js +130 -0
  61. package/dist/modules/customer_accounts/data/guards.js.map +7 -0
  62. package/dist/modules/customer_accounts/data/validators.js +19 -0
  63. package/dist/modules/customer_accounts/data/validators.js.map +2 -2
  64. package/dist/modules/customer_accounts/di.js +23 -1
  65. package/dist/modules/customer_accounts/di.js.map +2 -2
  66. package/dist/modules/customer_accounts/events.js +9 -2
  67. package/dist/modules/customer_accounts/events.js.map +2 -2
  68. package/dist/modules/customer_accounts/lib/customerAuthServer.js +27 -7
  69. package/dist/modules/customer_accounts/lib/customerAuthServer.js.map +2 -2
  70. package/dist/modules/customer_accounts/lib/customerUrl.js +48 -0
  71. package/dist/modules/customer_accounts/lib/customerUrl.js.map +7 -0
  72. package/dist/modules/customer_accounts/lib/hostname.js +55 -0
  73. package/dist/modules/customer_accounts/lib/hostname.js.map +7 -0
  74. package/dist/modules/customer_accounts/lib/platformDomains.js +7 -0
  75. package/dist/modules/customer_accounts/lib/platformDomains.js.map +7 -0
  76. package/dist/modules/customer_accounts/lib/proxyRanges.js +71 -0
  77. package/dist/modules/customer_accounts/lib/proxyRanges.js.map +7 -0
  78. package/dist/modules/customer_accounts/lib/rateLimiter.js +7 -0
  79. package/dist/modules/customer_accounts/lib/rateLimiter.js.map +2 -2
  80. package/dist/modules/customer_accounts/lib/resolveTenantContext.js +63 -0
  81. package/dist/modules/customer_accounts/lib/resolveTenantContext.js.map +7 -0
  82. package/dist/modules/customer_accounts/lib/secretCompare.js +13 -0
  83. package/dist/modules/customer_accounts/lib/secretCompare.js.map +7 -0
  84. package/dist/modules/customer_accounts/migrations/Migration20260430120000_customer_accounts.js +37 -0
  85. package/dist/modules/customer_accounts/migrations/Migration20260430120000_customer_accounts.js.map +7 -0
  86. package/dist/modules/customer_accounts/notifications.client.js +76 -0
  87. package/dist/modules/customer_accounts/notifications.client.js.map +2 -2
  88. package/dist/modules/customer_accounts/notifications.js +76 -0
  89. package/dist/modules/customer_accounts/notifications.js.map +2 -2
  90. package/dist/modules/customer_accounts/services/domainMappingService.js +497 -0
  91. package/dist/modules/customer_accounts/services/domainMappingService.js.map +7 -0
  92. package/dist/modules/customer_accounts/setup.js +48 -1
  93. package/dist/modules/customer_accounts/setup.js.map +2 -2
  94. package/dist/modules/customer_accounts/subscribers/invalidateDomainCache.js +29 -0
  95. package/dist/modules/customer_accounts/subscribers/invalidateDomainCache.js.map +7 -0
  96. package/dist/modules/customer_accounts/subscribers/notifyDomainActivated.js +29 -0
  97. package/dist/modules/customer_accounts/subscribers/notifyDomainActivated.js.map +7 -0
  98. package/dist/modules/customer_accounts/subscribers/notifyDomainDnsFailed.js +30 -0
  99. package/dist/modules/customer_accounts/subscribers/notifyDomainDnsFailed.js.map +7 -0
  100. package/dist/modules/customer_accounts/subscribers/notifyDomainTlsFailed.js +31 -0
  101. package/dist/modules/customer_accounts/subscribers/notifyDomainTlsFailed.js.map +7 -0
  102. package/dist/modules/customer_accounts/subscribers/notifyDomainVerified.js +29 -0
  103. package/dist/modules/customer_accounts/subscribers/notifyDomainVerified.js.map +7 -0
  104. package/dist/modules/customer_accounts/workers/domainTlsRetryWorker.js +67 -0
  105. package/dist/modules/customer_accounts/workers/domainTlsRetryWorker.js.map +7 -0
  106. package/dist/modules/customer_accounts/workers/domainVerificationWorker.js +34 -0
  107. package/dist/modules/customer_accounts/workers/domainVerificationWorker.js.map +7 -0
  108. package/dist/modules/customers/api/companies/route.js +4 -9
  109. package/dist/modules/customers/api/companies/route.js.map +2 -2
  110. package/dist/modules/customers/api/deals/route.js +4 -9
  111. package/dist/modules/customers/api/deals/route.js.map +2 -2
  112. package/dist/modules/customers/api/people/route.js +4 -9
  113. package/dist/modules/customers/api/people/route.js.map +2 -2
  114. package/dist/modules/customers/api/utils.js +0 -12
  115. package/dist/modules/customers/api/utils.js.map +2 -2
  116. package/dist/modules/customers/backend/customers/companies/page.js +361 -284
  117. package/dist/modules/customers/backend/customers/companies/page.js.map +2 -2
  118. package/dist/modules/customers/backend/customers/deals/page.js +378 -473
  119. package/dist/modules/customers/backend/customers/deals/page.js.map +2 -2
  120. package/dist/modules/customers/backend/customers/people/page.js +368 -286
  121. package/dist/modules/customers/backend/customers/people/page.js.map +2 -2
  122. package/dist/modules/customers/components/detail/assignableStaff.js +15 -1
  123. package/dist/modules/customers/components/detail/assignableStaff.js.map +2 -2
  124. package/dist/modules/customers/widgets/injection/ai-assistant-trigger/widget.client.js +188 -36
  125. package/dist/modules/customers/widgets/injection/ai-assistant-trigger/widget.client.js.map +2 -2
  126. package/dist/modules/customers/widgets/injection/ai-assistant-trigger/widget.js +2 -2
  127. package/dist/modules/customers/widgets/injection/ai-assistant-trigger/widget.js.map +2 -2
  128. package/dist/modules/customers/widgets/injection-table.js +6 -0
  129. package/dist/modules/customers/widgets/injection-table.js.map +2 -2
  130. package/dist/modules/perspectives/services/perspectiveService.js +16 -2
  131. package/dist/modules/perspectives/services/perspectiveService.js.map +2 -2
  132. package/dist/modules/portal/frontend/[orgSlug]/portal/login/page.js +1 -0
  133. package/dist/modules/portal/frontend/[orgSlug]/portal/login/page.js.map +2 -2
  134. package/dist/modules/query_index/lib/engine.js +31 -8
  135. package/dist/modules/query_index/lib/engine.js.map +2 -2
  136. package/generated/entities/domain_mapping/index.ts +14 -0
  137. package/generated/entities.ids.generated.ts +2 -1
  138. package/generated/entity-fields-registry.ts +16 -0
  139. package/package.json +5 -5
  140. package/src/helpers/integration/salesUi.ts +27 -23
  141. package/src/modules/customer_accounts/acl.ts +1 -0
  142. package/src/modules/customer_accounts/api/admin/domain-mappings/[id]/health-check.ts +119 -0
  143. package/src/modules/customer_accounts/api/admin/domain-mappings/[id]/verify.ts +123 -0
  144. package/src/modules/customer_accounts/api/admin/domain-mappings.ts +303 -0
  145. package/src/modules/customer_accounts/api/domain-check.ts +83 -0
  146. package/src/modules/customer_accounts/api/domain-resolve/all.ts +139 -0
  147. package/src/modules/customer_accounts/api/domain-resolve.ts +91 -0
  148. package/src/modules/customer_accounts/api/login.ts +14 -3
  149. package/src/modules/customer_accounts/api/magic-link/request.ts +14 -3
  150. package/src/modules/customer_accounts/api/password/reset-request.ts +15 -3
  151. package/src/modules/customer_accounts/api/signup.ts +36 -5
  152. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Actions.tsx +70 -0
  153. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Diagnostics.tsx +66 -0
  154. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/DnsConfig.tsx +78 -0
  155. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/DomainPanel.tsx +90 -0
  156. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/OrgSwitcher.tsx +43 -0
  157. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/RegisterDialog.tsx +178 -0
  158. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/StatusBadgeSection.tsx +56 -0
  159. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Stepper.tsx +69 -0
  160. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/domainStatusMap.ts +10 -0
  161. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/types.ts +31 -0
  162. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/page.meta.ts +26 -0
  163. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/page.tsx +411 -0
  164. package/src/modules/customer_accounts/data/enrichers.ts +95 -12
  165. package/src/modules/customer_accounts/data/entities.ts +80 -1
  166. package/src/modules/customer_accounts/data/guards.ts +155 -0
  167. package/src/modules/customer_accounts/data/validators.ts +26 -0
  168. package/src/modules/customer_accounts/di.ts +35 -1
  169. package/src/modules/customer_accounts/events.ts +8 -1
  170. package/src/modules/customer_accounts/i18n/de.json +78 -0
  171. package/src/modules/customer_accounts/i18n/en.json +78 -0
  172. package/src/modules/customer_accounts/i18n/es.json +78 -0
  173. package/src/modules/customer_accounts/i18n/pl.json +78 -0
  174. package/src/modules/customer_accounts/lib/customerAuthServer.ts +44 -8
  175. package/src/modules/customer_accounts/lib/customerUrl.ts +72 -0
  176. package/src/modules/customer_accounts/lib/hostname.ts +76 -0
  177. package/src/modules/customer_accounts/lib/platformDomains.ts +14 -0
  178. package/src/modules/customer_accounts/lib/proxyRanges.ts +85 -0
  179. package/src/modules/customer_accounts/lib/rateLimiter.ts +10 -0
  180. package/src/modules/customer_accounts/lib/resolveTenantContext.ts +96 -0
  181. package/src/modules/customer_accounts/lib/secretCompare.ts +20 -0
  182. package/src/modules/customer_accounts/migrations/.snapshot-open-mercato.json +341 -0
  183. package/src/modules/customer_accounts/migrations/Migration20260430120000_customer_accounts.ts +38 -0
  184. package/src/modules/customer_accounts/notifications.client.ts +76 -0
  185. package/src/modules/customer_accounts/notifications.ts +76 -0
  186. package/src/modules/customer_accounts/services/domainMappingService.ts +632 -0
  187. package/src/modules/customer_accounts/setup.ts +81 -1
  188. package/src/modules/customer_accounts/subscribers/invalidateDomainCache.ts +35 -0
  189. package/src/modules/customer_accounts/subscribers/notifyDomainActivated.ts +32 -0
  190. package/src/modules/customer_accounts/subscribers/notifyDomainDnsFailed.ts +33 -0
  191. package/src/modules/customer_accounts/subscribers/notifyDomainTlsFailed.ts +34 -0
  192. package/src/modules/customer_accounts/subscribers/notifyDomainVerified.ts +32 -0
  193. package/src/modules/customer_accounts/workers/domainTlsRetryWorker.ts +84 -0
  194. package/src/modules/customer_accounts/workers/domainVerificationWorker.ts +45 -0
  195. package/src/modules/customers/api/companies/route.ts +4 -9
  196. package/src/modules/customers/api/deals/route.ts +4 -9
  197. package/src/modules/customers/api/people/route.ts +4 -9
  198. package/src/modules/customers/api/utils.ts +0 -14
  199. package/src/modules/customers/backend/customers/companies/page.tsx +321 -237
  200. package/src/modules/customers/backend/customers/deals/page.tsx +321 -455
  201. package/src/modules/customers/backend/customers/people/page.tsx +331 -240
  202. package/src/modules/customers/components/detail/assignableStaff.ts +21 -0
  203. package/src/modules/customers/i18n/de.json +31 -0
  204. package/src/modules/customers/i18n/en.json +31 -0
  205. package/src/modules/customers/i18n/es.json +31 -0
  206. package/src/modules/customers/i18n/pl.json +31 -0
  207. package/src/modules/customers/widgets/injection/ai-assistant-trigger/widget.client.tsx +197 -40
  208. package/src/modules/customers/widgets/injection/ai-assistant-trigger/widget.ts +13 -7
  209. package/src/modules/customers/widgets/injection-table.ts +6 -0
  210. package/src/modules/perspectives/services/perspectiveService.ts +30 -2
  211. package/src/modules/portal/frontend/[orgSlug]/portal/login/page.tsx +1 -0
  212. package/src/modules/query_index/lib/engine.ts +46 -8
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/modules/customer_accounts/setup.ts"],
4
- "sourcesContent": ["import type { ModuleSetupConfig, DefaultCustomerRoleFeatures } from '@open-mercato/shared/modules/setup'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport type { Module } from '@open-mercato/shared/modules/registry'\nimport { hash } from 'bcryptjs'\nimport { hashForLookup } from '@open-mercato/shared/lib/encryption/aes'\nimport {\n CustomerRole,\n CustomerRoleAcl,\n CustomerUser,\n CustomerUserRole,\n} from '@open-mercato/core/modules/customer_accounts/data/entities'\n\ninterface SeedScope {\n tenantId: string\n organizationId: string\n}\n\nconst DEFAULT_ROLES = [\n {\n name: 'Portal Admin',\n slug: 'portal_admin',\n description: 'Full portal administration access',\n isSystem: true,\n customerAssignable: false,\n isDefault: false,\n acl: {\n isPortalAdmin: true,\n features: ['portal.*'],\n },\n },\n {\n name: 'Buyer',\n slug: 'buyer',\n description: 'Standard buyer access with ordering capabilities',\n isSystem: true,\n customerAssignable: true,\n isDefault: true,\n acl: {\n isPortalAdmin: false,\n features: [\n 'portal.account.manage',\n 'portal.orders.view',\n 'portal.orders.create',\n 'portal.quotes.view',\n 'portal.quotes.request',\n 'portal.invoices.view',\n 'portal.catalog.view',\n ],\n },\n },\n {\n name: 'Viewer',\n slug: 'viewer',\n description: 'Read-only portal access',\n isSystem: true,\n customerAssignable: true,\n isDefault: false,\n acl: {\n isPortalAdmin: false,\n features: [\n 'portal.account.manage',\n 'portal.orders.view',\n 'portal.invoices.view',\n 'portal.catalog.view',\n ],\n },\n },\n]\n\n/**\n * Collect defaultCustomerRoleFeatures from all enabled modules and merge\n * them into the corresponding CustomerRoleAcl records.\n */\nasync function ensureDefaultCustomerRoleAcls(\n em: EntityManager,\n tenantId: string,\n modules: Module[],\n): Promise<void> {\n const featuresByRole: Record<string, string[]> = {}\n\n for (const mod of modules) {\n const customerRoleFeatures = mod.setup?.defaultCustomerRoleFeatures\n if (!customerRoleFeatures) continue\n for (const [roleSlug, features] of Object.entries(customerRoleFeatures)) {\n if (!features || !features.length) continue\n if (!featuresByRole[roleSlug]) featuresByRole[roleSlug] = []\n featuresByRole[roleSlug].push(...features)\n }\n }\n\n const roleSlugs = Object.keys(featuresByRole)\n if (!roleSlugs.length) return\n\n for (const roleSlug of roleSlugs) {\n const role = await em.findOne(CustomerRole, { tenantId, slug: roleSlug, deletedAt: null })\n if (!role) continue\n\n const acl = await em.findOne(CustomerRoleAcl, { role: role.id as any, tenantId })\n if (!acl) continue\n\n const currentFeatures = Array.isArray(acl.featuresJson) ? acl.featuresJson : []\n const merged = Array.from(new Set([...currentFeatures, ...featuresByRole[roleSlug]]))\n const changed =\n merged.length !== currentFeatures.length ||\n merged.some((value, index) => value !== currentFeatures[index])\n if (changed) {\n acl.featuresJson = merged\n em.persist(acl)\n }\n }\n await em.flush()\n}\n\nasync function seedDefaultRoles(em: EntityManager, scope: SeedScope): Promise<void> {\n for (const roleDef of DEFAULT_ROLES) {\n const existing = await em.findOne(CustomerRole, {\n tenantId: scope.tenantId,\n slug: roleDef.slug,\n deletedAt: null,\n })\n if (existing) continue\n\n const role = em.create(CustomerRole, {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n name: roleDef.name,\n slug: roleDef.slug,\n description: roleDef.description,\n isSystem: roleDef.isSystem,\n customerAssignable: roleDef.customerAssignable,\n isDefault: roleDef.isDefault,\n createdAt: new Date(),\n } as any)\n em.persist(role)\n\n const acl = em.create(CustomerRoleAcl, {\n role,\n tenantId: scope.tenantId,\n featuresJson: roleDef.acl.features,\n isPortalAdmin: roleDef.acl.isPortalAdmin,\n createdAt: new Date(),\n } as any)\n em.persist(acl)\n }\n await em.flush()\n}\n\nexport const setup: ModuleSetupConfig = {\n defaultRoleFeatures: {\n superadmin: ['customer_accounts.*'],\n admin: ['customer_accounts.*'],\n },\n\n async onTenantCreated({ em, tenantId, organizationId }) {\n await seedDefaultRoles(em, { tenantId, organizationId })\n },\n\n async seedDefaults({ em, tenantId, organizationId }) {\n await seedDefaultRoles(em, { tenantId, organizationId })\n // Merge defaultCustomerRoleFeatures from all enabled modules\n try {\n const { getModules } = await import('@open-mercato/shared/lib/modules/registry')\n const allModules = getModules()\n await ensureDefaultCustomerRoleAcls(em, tenantId, allModules)\n } catch {\n // Modules may not be registered yet during initial setup\n }\n },\n\n async seedExamples({ em, tenantId, organizationId }) {\n const BCRYPT_COST = 10\n const exampleUsers = [\n { email: 'alice.johnson@example.com', displayName: 'Alice Johnson', password: 'Password123!', roleSlug: 'portal_admin' },\n { email: 'bob.smith@example.com', displayName: 'Bob Smith', password: 'Password123!', roleSlug: 'buyer' },\n { email: 'carol.white@example.com', displayName: 'Carol White', password: 'Password123!', roleSlug: 'viewer' },\n ]\n\n for (const entry of exampleUsers) {\n const emailHash = hashForLookup(entry.email)\n const existing = await em.findOne(CustomerUser, { emailHash, tenantId, deletedAt: null })\n if (existing) continue\n\n const passwordHash = await hash(entry.password, BCRYPT_COST)\n const user = em.create(CustomerUser, {\n email: entry.email,\n emailHash,\n passwordHash,\n displayName: entry.displayName,\n tenantId,\n organizationId,\n isActive: true,\n failedLoginAttempts: 0,\n emailVerifiedAt: new Date(),\n createdAt: new Date(),\n } as any)\n em.persist(user)\n\n const role = await em.findOne(CustomerRole, { tenantId, slug: entry.roleSlug, deletedAt: null })\n if (role) {\n const userRole = em.create(CustomerUserRole, {\n user,\n role,\n createdAt: new Date(),\n } as any)\n em.persist(userRole)\n }\n }\n await em.flush()\n },\n}\n\nexport default setup\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type { ModuleSetupConfig, DefaultCustomerRoleFeatures } from '@open-mercato/shared/modules/setup'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport type { Module } from '@open-mercato/shared/modules/registry'\nimport { hash } from 'bcryptjs'\nimport { hashForLookup } from '@open-mercato/shared/lib/encryption/aes'\nimport {\n CustomerRole,\n CustomerRoleAcl,\n CustomerUser,\n CustomerUserRole,\n} from '@open-mercato/core/modules/customer_accounts/data/entities'\n\ninterface SeedScope {\n tenantId: string\n organizationId: string\n}\n\ntype SchedulerServiceLike = {\n register: (registration: {\n id: string\n name: string\n description?: string\n scopeType: 'system'\n scheduleType: 'interval'\n scheduleValue: string\n timezone?: string\n targetType: 'queue'\n targetQueue: string\n targetPayload?: Record<string, unknown>\n sourceType: 'module'\n sourceModule: string\n isEnabled?: boolean\n }) => Promise<void>\n}\n\n// Stable, deterministic UUIDs for the two domain-routing system schedules so\n// re-running setup re-upserts the same rows instead of creating duplicates.\nconst DOMAIN_VERIFICATION_SCHEDULE_ID = '5e9ef5fc-1f4d-5b3d-8b58-8e1a5a4d1001'\nconst DOMAIN_TLS_RETRY_SCHEDULE_ID = '5e9ef5fc-1f4d-5b3d-8b58-8e1a5a4d1002'\n\nfunction intervalSecondsFromEnv(envName: string, fallbackSeconds: number): string {\n const parsed = Number.parseInt(process.env[envName] ?? '', 10)\n const seconds = Number.isFinite(parsed) && parsed > 0 ? parsed : fallbackSeconds\n return `${seconds}s`\n}\n\nasync function registerDomainSchedules(\n container: { hasRegistration?: (name: string) => boolean; resolve: (name: string) => unknown },\n): Promise<void> {\n if (typeof container.hasRegistration !== 'function' || !container.hasRegistration('schedulerService')) {\n return\n }\n const schedulerService = container.resolve('schedulerService') as SchedulerServiceLike\n\n await schedulerService.register({\n id: DOMAIN_VERIFICATION_SCHEDULE_ID,\n name: 'Custom domain \u2014 DNS auto-verification',\n description:\n 'Re-runs DNS verification for custom-domain mappings stuck in pending or dns_failed, and triggers TLS health checks on success.',\n scopeType: 'system',\n scheduleType: 'interval',\n scheduleValue: intervalSecondsFromEnv('DOMAIN_AUTO_VERIFY_INTERVAL_SECONDS', 300),\n timezone: 'UTC',\n targetType: 'queue',\n targetQueue: 'domain-verification',\n sourceType: 'module',\n sourceModule: 'customer_accounts',\n isEnabled: true,\n })\n\n await schedulerService.register({\n id: DOMAIN_TLS_RETRY_SCHEDULE_ID,\n name: 'Custom domain \u2014 TLS retry',\n description:\n 'Retries TLS certificate provisioning for verified or tls_failed custom-domain mappings, with batch cap and adaptive backoff on Let\\'s Encrypt rate limits.',\n scopeType: 'system',\n scheduleType: 'interval',\n scheduleValue: intervalSecondsFromEnv('DOMAIN_TLS_RETRY_INTERVAL_SECONDS', 1800),\n timezone: 'UTC',\n targetType: 'queue',\n targetQueue: 'domain-tls-retry',\n sourceType: 'module',\n sourceModule: 'customer_accounts',\n isEnabled: true,\n })\n}\n\nconst DEFAULT_ROLES = [\n {\n name: 'Portal Admin',\n slug: 'portal_admin',\n description: 'Full portal administration access',\n isSystem: true,\n customerAssignable: false,\n isDefault: false,\n acl: {\n isPortalAdmin: true,\n features: ['portal.*'],\n },\n },\n {\n name: 'Buyer',\n slug: 'buyer',\n description: 'Standard buyer access with ordering capabilities',\n isSystem: true,\n customerAssignable: true,\n isDefault: true,\n acl: {\n isPortalAdmin: false,\n features: [\n 'portal.account.manage',\n 'portal.orders.view',\n 'portal.orders.create',\n 'portal.quotes.view',\n 'portal.quotes.request',\n 'portal.invoices.view',\n 'portal.catalog.view',\n ],\n },\n },\n {\n name: 'Viewer',\n slug: 'viewer',\n description: 'Read-only portal access',\n isSystem: true,\n customerAssignable: true,\n isDefault: false,\n acl: {\n isPortalAdmin: false,\n features: [\n 'portal.account.manage',\n 'portal.orders.view',\n 'portal.invoices.view',\n 'portal.catalog.view',\n ],\n },\n },\n]\n\n/**\n * Collect defaultCustomerRoleFeatures from all enabled modules and merge\n * them into the corresponding CustomerRoleAcl records.\n */\nasync function ensureDefaultCustomerRoleAcls(\n em: EntityManager,\n tenantId: string,\n modules: Module[],\n): Promise<void> {\n const featuresByRole: Record<string, string[]> = {}\n\n for (const mod of modules) {\n const customerRoleFeatures = mod.setup?.defaultCustomerRoleFeatures\n if (!customerRoleFeatures) continue\n for (const [roleSlug, features] of Object.entries(customerRoleFeatures)) {\n if (!features || !features.length) continue\n if (!featuresByRole[roleSlug]) featuresByRole[roleSlug] = []\n featuresByRole[roleSlug].push(...features)\n }\n }\n\n const roleSlugs = Object.keys(featuresByRole)\n if (!roleSlugs.length) return\n\n for (const roleSlug of roleSlugs) {\n const role = await em.findOne(CustomerRole, { tenantId, slug: roleSlug, deletedAt: null })\n if (!role) continue\n\n const acl = await em.findOne(CustomerRoleAcl, { role: role.id as any, tenantId })\n if (!acl) continue\n\n const currentFeatures = Array.isArray(acl.featuresJson) ? acl.featuresJson : []\n const merged = Array.from(new Set([...currentFeatures, ...featuresByRole[roleSlug]]))\n const changed =\n merged.length !== currentFeatures.length ||\n merged.some((value, index) => value !== currentFeatures[index])\n if (changed) {\n acl.featuresJson = merged\n em.persist(acl)\n }\n }\n await em.flush()\n}\n\nasync function seedDefaultRoles(em: EntityManager, scope: SeedScope): Promise<void> {\n for (const roleDef of DEFAULT_ROLES) {\n const existing = await em.findOne(CustomerRole, {\n tenantId: scope.tenantId,\n slug: roleDef.slug,\n deletedAt: null,\n })\n if (existing) continue\n\n const role = em.create(CustomerRole, {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n name: roleDef.name,\n slug: roleDef.slug,\n description: roleDef.description,\n isSystem: roleDef.isSystem,\n customerAssignable: roleDef.customerAssignable,\n isDefault: roleDef.isDefault,\n createdAt: new Date(),\n } as any)\n em.persist(role)\n\n const acl = em.create(CustomerRoleAcl, {\n role,\n tenantId: scope.tenantId,\n featuresJson: roleDef.acl.features,\n isPortalAdmin: roleDef.acl.isPortalAdmin,\n createdAt: new Date(),\n } as any)\n em.persist(acl)\n }\n await em.flush()\n}\n\nexport const setup: ModuleSetupConfig = {\n defaultRoleFeatures: {\n superadmin: ['customer_accounts.*'],\n admin: ['customer_accounts.*'],\n },\n\n async onTenantCreated({ em, tenantId, organizationId }) {\n await seedDefaultRoles(em, { tenantId, organizationId })\n },\n\n async seedDefaults({ em, tenantId, organizationId, container }) {\n await seedDefaultRoles(em, { tenantId, organizationId })\n // Merge defaultCustomerRoleFeatures from all enabled modules\n try {\n const { getModules } = await import('@open-mercato/shared/lib/modules/registry')\n const allModules = getModules()\n await ensureDefaultCustomerRoleAcls(em, tenantId, allModules)\n } catch {\n // Modules may not be registered yet during initial setup\n }\n\n // System-scoped schedules: register is idempotent, so re-running setup\n // (or running it for additional tenants) just upserts the same two rows.\n try {\n await registerDomainSchedules(\n container as { hasRegistration?: (name: string) => boolean; resolve: (name: string) => unknown },\n )\n } catch {\n // Scheduler may not be installed in this deployment; ignore.\n }\n },\n\n async seedExamples({ em, tenantId, organizationId }) {\n const BCRYPT_COST = 10\n const exampleUsers = [\n { email: 'alice.johnson@example.com', displayName: 'Alice Johnson', password: 'Password123!', roleSlug: 'portal_admin' },\n { email: 'bob.smith@example.com', displayName: 'Bob Smith', password: 'Password123!', roleSlug: 'buyer' },\n { email: 'carol.white@example.com', displayName: 'Carol White', password: 'Password123!', roleSlug: 'viewer' },\n ]\n\n for (const entry of exampleUsers) {\n const emailHash = hashForLookup(entry.email)\n const existing = await em.findOne(CustomerUser, { emailHash, tenantId, deletedAt: null })\n if (existing) continue\n\n const passwordHash = await hash(entry.password, BCRYPT_COST)\n const user = em.create(CustomerUser, {\n email: entry.email,\n emailHash,\n passwordHash,\n displayName: entry.displayName,\n tenantId,\n organizationId,\n isActive: true,\n failedLoginAttempts: 0,\n emailVerifiedAt: new Date(),\n createdAt: new Date(),\n } as any)\n em.persist(user)\n\n const role = await em.findOne(CustomerRole, { tenantId, slug: entry.roleSlug, deletedAt: null })\n if (role) {\n const userRole = em.create(CustomerUserRole, {\n user,\n role,\n createdAt: new Date(),\n } as any)\n em.persist(userRole)\n }\n }\n await em.flush()\n },\n}\n\nexport default setup\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,29 @@
1
+ const metadata = {
2
+ event: "customer_accounts.domain_mapping.*",
3
+ persistent: false,
4
+ id: "customer_accounts:invalidate-domain-cache"
5
+ };
6
+ async function handle(payload, ctx) {
7
+ const data = payload ?? {};
8
+ const hostname = typeof data.hostname === "string" ? data.hostname : null;
9
+ const organizationId = typeof data.organizationId === "string" ? data.organizationId : null;
10
+ let cache = null;
11
+ try {
12
+ cache = ctx.resolve("cache");
13
+ } catch {
14
+ return;
15
+ }
16
+ if (!cache) return;
17
+ const tags = ["domain_routing"];
18
+ if (hostname) tags.push(`domain_routing:${hostname}`);
19
+ if (organizationId) tags.push(`domain_routing:org:${organizationId}`);
20
+ try {
21
+ await cache.deleteByTags(tags);
22
+ } catch {
23
+ }
24
+ }
25
+ export {
26
+ handle as default,
27
+ metadata
28
+ };
29
+ //# sourceMappingURL=invalidateDomainCache.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/modules/customer_accounts/subscribers/invalidateDomainCache.ts"],
4
+ "sourcesContent": ["type CacheService = {\n deleteByTags(tags: string[]): Promise<number>\n}\n\nexport const metadata = {\n event: 'customer_accounts.domain_mapping.*',\n persistent: false,\n id: 'customer_accounts:invalidate-domain-cache',\n}\n\nexport default async function handle(\n payload: unknown,\n ctx: { resolve: <T = unknown>(name: string) => T },\n): Promise<void> {\n const data = (payload ?? {}) as Record<string, unknown>\n const hostname = typeof data.hostname === 'string' ? data.hostname : null\n const organizationId = typeof data.organizationId === 'string' ? data.organizationId : null\n\n let cache: CacheService | null = null\n try {\n cache = ctx.resolve<CacheService>('cache')\n } catch {\n return\n }\n if (!cache) return\n\n const tags = ['domain_routing']\n if (hostname) tags.push(`domain_routing:${hostname}`)\n if (organizationId) tags.push(`domain_routing:org:${organizationId}`)\n try {\n await cache.deleteByTags(tags)\n } catch {\n // Best-effort cache invalidation. TTL is the backstop.\n }\n}\n"],
5
+ "mappings": "AAIO,MAAM,WAAW;AAAA,EACtB,OAAO;AAAA,EACP,YAAY;AAAA,EACZ,IAAI;AACN;AAEA,eAAO,OACL,SACA,KACe;AACf,QAAM,OAAQ,WAAW,CAAC;AAC1B,QAAM,WAAW,OAAO,KAAK,aAAa,WAAW,KAAK,WAAW;AACrE,QAAM,iBAAiB,OAAO,KAAK,mBAAmB,WAAW,KAAK,iBAAiB;AAEvF,MAAI,QAA6B;AACjC,MAAI;AACF,YAAQ,IAAI,QAAsB,OAAO;AAAA,EAC3C,QAAQ;AACN;AAAA,EACF;AACA,MAAI,CAAC,MAAO;AAEZ,QAAM,OAAO,CAAC,gBAAgB;AAC9B,MAAI,SAAU,MAAK,KAAK,kBAAkB,QAAQ,EAAE;AACpD,MAAI,eAAgB,MAAK,KAAK,sBAAsB,cAAc,EAAE;AACpE,MAAI;AACF,UAAM,MAAM,aAAa,IAAI;AAAA,EAC/B,QAAQ;AAAA,EAER;AACF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,29 @@
1
+ const metadata = {
2
+ event: "customer_accounts.domain_mapping.activated",
3
+ persistent: true,
4
+ id: "customer_accounts:notify-domain-activated"
5
+ };
6
+ async function handle(payload, ctx) {
7
+ const data = payload ?? {};
8
+ const id = typeof data.id === "string" ? data.id : null;
9
+ const tenantId = typeof data.tenantId === "string" ? data.tenantId : null;
10
+ const organizationId = typeof data.organizationId === "string" ? data.organizationId : null;
11
+ const hostname = typeof data.hostname === "string" ? data.hostname : "";
12
+ if (!id || !tenantId || !organizationId) return;
13
+ try {
14
+ const eventBus = ctx.resolve("eventBus");
15
+ await eventBus.emitEvent("notifications.create", {
16
+ type: "customer_accounts.domain_mapping.activated",
17
+ tenantId,
18
+ organizationId,
19
+ sourceEntityId: id,
20
+ data: { hostname }
21
+ });
22
+ } catch {
23
+ }
24
+ }
25
+ export {
26
+ handle as default,
27
+ metadata
28
+ };
29
+ //# sourceMappingURL=notifyDomainActivated.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/modules/customer_accounts/subscribers/notifyDomainActivated.ts"],
4
+ "sourcesContent": ["import type { EventBus } from '@open-mercato/events/types'\n\nexport const metadata = {\n event: 'customer_accounts.domain_mapping.activated',\n persistent: true,\n id: 'customer_accounts:notify-domain-activated',\n}\n\nexport default async function handle(\n payload: unknown,\n ctx: { resolve: <T = unknown>(name: string) => T },\n): Promise<void> {\n const data = (payload ?? {}) as Record<string, unknown>\n const id = typeof data.id === 'string' ? data.id : null\n const tenantId = typeof data.tenantId === 'string' ? data.tenantId : null\n const organizationId = typeof data.organizationId === 'string' ? data.organizationId : null\n const hostname = typeof data.hostname === 'string' ? data.hostname : ''\n if (!id || !tenantId || !organizationId) return\n\n try {\n const eventBus = ctx.resolve<EventBus>('eventBus')\n await eventBus.emitEvent('notifications.create', {\n type: 'customer_accounts.domain_mapping.activated',\n tenantId,\n organizationId,\n sourceEntityId: id,\n data: { hostname },\n })\n } catch {\n // Notifications module may be absent \u2014 best-effort.\n }\n}\n"],
5
+ "mappings": "AAEO,MAAM,WAAW;AAAA,EACtB,OAAO;AAAA,EACP,YAAY;AAAA,EACZ,IAAI;AACN;AAEA,eAAO,OACL,SACA,KACe;AACf,QAAM,OAAQ,WAAW,CAAC;AAC1B,QAAM,KAAK,OAAO,KAAK,OAAO,WAAW,KAAK,KAAK;AACnD,QAAM,WAAW,OAAO,KAAK,aAAa,WAAW,KAAK,WAAW;AACrE,QAAM,iBAAiB,OAAO,KAAK,mBAAmB,WAAW,KAAK,iBAAiB;AACvF,QAAM,WAAW,OAAO,KAAK,aAAa,WAAW,KAAK,WAAW;AACrE,MAAI,CAAC,MAAM,CAAC,YAAY,CAAC,eAAgB;AAEzC,MAAI;AACF,UAAM,WAAW,IAAI,QAAkB,UAAU;AACjD,UAAM,SAAS,UAAU,wBAAwB;AAAA,MAC/C,MAAM;AAAA,MACN;AAAA,MACA;AAAA,MACA,gBAAgB;AAAA,MAChB,MAAM,EAAE,SAAS;AAAA,IACnB,CAAC;AAAA,EACH,QAAQ;AAAA,EAER;AACF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,30 @@
1
+ const metadata = {
2
+ event: "customer_accounts.domain_mapping.dns_failed",
3
+ persistent: true,
4
+ id: "customer_accounts:notify-domain-dns-failed"
5
+ };
6
+ async function handle(payload, ctx) {
7
+ const data = payload ?? {};
8
+ const id = typeof data.id === "string" ? data.id : null;
9
+ const tenantId = typeof data.tenantId === "string" ? data.tenantId : null;
10
+ const organizationId = typeof data.organizationId === "string" ? data.organizationId : null;
11
+ const hostname = typeof data.hostname === "string" ? data.hostname : "";
12
+ const reason = typeof data.reason === "string" ? data.reason : "";
13
+ if (!id || !tenantId || !organizationId) return;
14
+ try {
15
+ const eventBus = ctx.resolve("eventBus");
16
+ await eventBus.emitEvent("notifications.create", {
17
+ type: "customer_accounts.domain_mapping.dns_failed",
18
+ tenantId,
19
+ organizationId,
20
+ sourceEntityId: id,
21
+ data: { hostname, reason }
22
+ });
23
+ } catch {
24
+ }
25
+ }
26
+ export {
27
+ handle as default,
28
+ metadata
29
+ };
30
+ //# sourceMappingURL=notifyDomainDnsFailed.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/modules/customer_accounts/subscribers/notifyDomainDnsFailed.ts"],
4
+ "sourcesContent": ["import type { EventBus } from '@open-mercato/events/types'\n\nexport const metadata = {\n event: 'customer_accounts.domain_mapping.dns_failed',\n persistent: true,\n id: 'customer_accounts:notify-domain-dns-failed',\n}\n\nexport default async function handle(\n payload: unknown,\n ctx: { resolve: <T = unknown>(name: string) => T },\n): Promise<void> {\n const data = (payload ?? {}) as Record<string, unknown>\n const id = typeof data.id === 'string' ? data.id : null\n const tenantId = typeof data.tenantId === 'string' ? data.tenantId : null\n const organizationId = typeof data.organizationId === 'string' ? data.organizationId : null\n const hostname = typeof data.hostname === 'string' ? data.hostname : ''\n const reason = typeof data.reason === 'string' ? data.reason : ''\n if (!id || !tenantId || !organizationId) return\n\n try {\n const eventBus = ctx.resolve<EventBus>('eventBus')\n await eventBus.emitEvent('notifications.create', {\n type: 'customer_accounts.domain_mapping.dns_failed',\n tenantId,\n organizationId,\n sourceEntityId: id,\n data: { hostname, reason },\n })\n } catch {\n // Notifications module may be absent \u2014 best-effort.\n }\n}\n"],
5
+ "mappings": "AAEO,MAAM,WAAW;AAAA,EACtB,OAAO;AAAA,EACP,YAAY;AAAA,EACZ,IAAI;AACN;AAEA,eAAO,OACL,SACA,KACe;AACf,QAAM,OAAQ,WAAW,CAAC;AAC1B,QAAM,KAAK,OAAO,KAAK,OAAO,WAAW,KAAK,KAAK;AACnD,QAAM,WAAW,OAAO,KAAK,aAAa,WAAW,KAAK,WAAW;AACrE,QAAM,iBAAiB,OAAO,KAAK,mBAAmB,WAAW,KAAK,iBAAiB;AACvF,QAAM,WAAW,OAAO,KAAK,aAAa,WAAW,KAAK,WAAW;AACrE,QAAM,SAAS,OAAO,KAAK,WAAW,WAAW,KAAK,SAAS;AAC/D,MAAI,CAAC,MAAM,CAAC,YAAY,CAAC,eAAgB;AAEzC,MAAI;AACF,UAAM,WAAW,IAAI,QAAkB,UAAU;AACjD,UAAM,SAAS,UAAU,wBAAwB;AAAA,MAC/C,MAAM;AAAA,MACN;AAAA,MACA;AAAA,MACA,gBAAgB;AAAA,MAChB,MAAM,EAAE,UAAU,OAAO;AAAA,IAC3B,CAAC;AAAA,EACH,QAAQ;AAAA,EAER;AACF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,31 @@
1
+ const metadata = {
2
+ event: "customer_accounts.domain_mapping.tls_failed",
3
+ persistent: true,
4
+ id: "customer_accounts:notify-domain-tls-failed"
5
+ };
6
+ async function handle(payload, ctx) {
7
+ const data = payload ?? {};
8
+ const id = typeof data.id === "string" ? data.id : null;
9
+ const tenantId = typeof data.tenantId === "string" ? data.tenantId : null;
10
+ const organizationId = typeof data.organizationId === "string" ? data.organizationId : null;
11
+ const hostname = typeof data.hostname === "string" ? data.hostname : "";
12
+ const reason = typeof data.reason === "string" ? data.reason : "";
13
+ const retryCount = typeof data.retryCount === "number" ? data.retryCount : 0;
14
+ if (!id || !tenantId || !organizationId) return;
15
+ try {
16
+ const eventBus = ctx.resolve("eventBus");
17
+ await eventBus.emitEvent("notifications.create", {
18
+ type: "customer_accounts.domain_mapping.tls_failed",
19
+ tenantId,
20
+ organizationId,
21
+ sourceEntityId: id,
22
+ data: { hostname, reason, retryCount }
23
+ });
24
+ } catch {
25
+ }
26
+ }
27
+ export {
28
+ handle as default,
29
+ metadata
30
+ };
31
+ //# sourceMappingURL=notifyDomainTlsFailed.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/modules/customer_accounts/subscribers/notifyDomainTlsFailed.ts"],
4
+ "sourcesContent": ["import type { EventBus } from '@open-mercato/events/types'\n\nexport const metadata = {\n event: 'customer_accounts.domain_mapping.tls_failed',\n persistent: true,\n id: 'customer_accounts:notify-domain-tls-failed',\n}\n\nexport default async function handle(\n payload: unknown,\n ctx: { resolve: <T = unknown>(name: string) => T },\n): Promise<void> {\n const data = (payload ?? {}) as Record<string, unknown>\n const id = typeof data.id === 'string' ? data.id : null\n const tenantId = typeof data.tenantId === 'string' ? data.tenantId : null\n const organizationId = typeof data.organizationId === 'string' ? data.organizationId : null\n const hostname = typeof data.hostname === 'string' ? data.hostname : ''\n const reason = typeof data.reason === 'string' ? data.reason : ''\n const retryCount = typeof data.retryCount === 'number' ? data.retryCount : 0\n if (!id || !tenantId || !organizationId) return\n\n try {\n const eventBus = ctx.resolve<EventBus>('eventBus')\n await eventBus.emitEvent('notifications.create', {\n type: 'customer_accounts.domain_mapping.tls_failed',\n tenantId,\n organizationId,\n sourceEntityId: id,\n data: { hostname, reason, retryCount },\n })\n } catch {\n // Notifications module may be absent \u2014 best-effort.\n }\n}\n"],
5
+ "mappings": "AAEO,MAAM,WAAW;AAAA,EACtB,OAAO;AAAA,EACP,YAAY;AAAA,EACZ,IAAI;AACN;AAEA,eAAO,OACL,SACA,KACe;AACf,QAAM,OAAQ,WAAW,CAAC;AAC1B,QAAM,KAAK,OAAO,KAAK,OAAO,WAAW,KAAK,KAAK;AACnD,QAAM,WAAW,OAAO,KAAK,aAAa,WAAW,KAAK,WAAW;AACrE,QAAM,iBAAiB,OAAO,KAAK,mBAAmB,WAAW,KAAK,iBAAiB;AACvF,QAAM,WAAW,OAAO,KAAK,aAAa,WAAW,KAAK,WAAW;AACrE,QAAM,SAAS,OAAO,KAAK,WAAW,WAAW,KAAK,SAAS;AAC/D,QAAM,aAAa,OAAO,KAAK,eAAe,WAAW,KAAK,aAAa;AAC3E,MAAI,CAAC,MAAM,CAAC,YAAY,CAAC,eAAgB;AAEzC,MAAI;AACF,UAAM,WAAW,IAAI,QAAkB,UAAU;AACjD,UAAM,SAAS,UAAU,wBAAwB;AAAA,MAC/C,MAAM;AAAA,MACN;AAAA,MACA;AAAA,MACA,gBAAgB;AAAA,MAChB,MAAM,EAAE,UAAU,QAAQ,WAAW;AAAA,IACvC,CAAC;AAAA,EACH,QAAQ;AAAA,EAER;AACF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,29 @@
1
+ const metadata = {
2
+ event: "customer_accounts.domain_mapping.verified",
3
+ persistent: true,
4
+ id: "customer_accounts:notify-domain-verified"
5
+ };
6
+ async function handle(payload, ctx) {
7
+ const data = payload ?? {};
8
+ const id = typeof data.id === "string" ? data.id : null;
9
+ const tenantId = typeof data.tenantId === "string" ? data.tenantId : null;
10
+ const organizationId = typeof data.organizationId === "string" ? data.organizationId : null;
11
+ const hostname = typeof data.hostname === "string" ? data.hostname : "";
12
+ if (!id || !tenantId || !organizationId) return;
13
+ try {
14
+ const eventBus = ctx.resolve("eventBus");
15
+ await eventBus.emitEvent("notifications.create", {
16
+ type: "customer_accounts.domain_mapping.verified",
17
+ tenantId,
18
+ organizationId,
19
+ sourceEntityId: id,
20
+ data: { hostname }
21
+ });
22
+ } catch {
23
+ }
24
+ }
25
+ export {
26
+ handle as default,
27
+ metadata
28
+ };
29
+ //# sourceMappingURL=notifyDomainVerified.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/modules/customer_accounts/subscribers/notifyDomainVerified.ts"],
4
+ "sourcesContent": ["import type { EventBus } from '@open-mercato/events/types'\n\nexport const metadata = {\n event: 'customer_accounts.domain_mapping.verified',\n persistent: true,\n id: 'customer_accounts:notify-domain-verified',\n}\n\nexport default async function handle(\n payload: unknown,\n ctx: { resolve: <T = unknown>(name: string) => T },\n): Promise<void> {\n const data = (payload ?? {}) as Record<string, unknown>\n const id = typeof data.id === 'string' ? data.id : null\n const tenantId = typeof data.tenantId === 'string' ? data.tenantId : null\n const organizationId = typeof data.organizationId === 'string' ? data.organizationId : null\n const hostname = typeof data.hostname === 'string' ? data.hostname : ''\n if (!id || !tenantId || !organizationId) return\n\n try {\n const eventBus = ctx.resolve<EventBus>('eventBus')\n await eventBus.emitEvent('notifications.create', {\n type: 'customer_accounts.domain_mapping.verified',\n tenantId,\n organizationId,\n sourceEntityId: id,\n data: { hostname },\n })\n } catch {\n // Notifications module may be absent \u2014 best-effort.\n }\n}\n"],
5
+ "mappings": "AAEO,MAAM,WAAW;AAAA,EACtB,OAAO;AAAA,EACP,YAAY;AAAA,EACZ,IAAI;AACN;AAEA,eAAO,OACL,SACA,KACe;AACf,QAAM,OAAQ,WAAW,CAAC;AAC1B,QAAM,KAAK,OAAO,KAAK,OAAO,WAAW,KAAK,KAAK;AACnD,QAAM,WAAW,OAAO,KAAK,aAAa,WAAW,KAAK,WAAW;AACrE,QAAM,iBAAiB,OAAO,KAAK,mBAAmB,WAAW,KAAK,iBAAiB;AACvF,QAAM,WAAW,OAAO,KAAK,aAAa,WAAW,KAAK,WAAW;AACrE,MAAI,CAAC,MAAM,CAAC,YAAY,CAAC,eAAgB;AAEzC,MAAI;AACF,UAAM,WAAW,IAAI,QAAkB,UAAU;AACjD,UAAM,SAAS,UAAU,wBAAwB;AAAA,MAC/C,MAAM;AAAA,MACN;AAAA,MACA;AAAA,MACA,gBAAgB;AAAA,MAChB,MAAM,EAAE,SAAS;AAAA,IACnB,CAAC;AAAA,EACH,QAAQ;AAAA,EAER;AACF;",
6
+ "names": []
7
+ }
@@ -0,0 +1,67 @@
1
+ const metadata = {
2
+ queue: "domain-tls-retry",
3
+ id: "customer_accounts:domain-tls-retry",
4
+ concurrency: 1
5
+ };
6
+ function parseInt32(value, fallback) {
7
+ const parsed = Number.parseInt(value ?? "", 10);
8
+ if (!Number.isFinite(parsed) || parsed <= 0) return fallback;
9
+ return parsed;
10
+ }
11
+ function parseFloat01(value, fallback) {
12
+ const parsed = Number.parseFloat(value ?? "");
13
+ if (!Number.isFinite(parsed) || parsed <= 0 || parsed > 1) return fallback;
14
+ return parsed;
15
+ }
16
+ let backoffMultiplier = 1;
17
+ let nextEligibleAt = 0;
18
+ const BACKOFF_CAP_HOURS = 6;
19
+ async function handle(_job, ctx) {
20
+ const baseIntervalSeconds = parseInt32(process.env.DOMAIN_TLS_RETRY_INTERVAL_SECONDS, 1800);
21
+ const batchSize = parseInt32(process.env.DOMAIN_TLS_RETRY_BATCH, 50);
22
+ const maxRetries = parseInt32(process.env.DOMAIN_TLS_MAX_RETRIES, 6);
23
+ const failureThreshold = parseFloat01(process.env.DOMAIN_TLS_RETRY_FAILURE_THRESHOLD, 0.8);
24
+ const capSeconds = BACKOFF_CAP_HOURS * 3600;
25
+ const maxMultiplier = Math.max(1, Math.floor(capSeconds / baseIntervalSeconds));
26
+ if (Date.now() < nextEligibleAt) return;
27
+ const service = ctx.resolve("domainMappingService");
28
+ const candidates = await service.findPendingTls({ maxRetries, batchSize });
29
+ if (candidates.length === 0) {
30
+ backoffMultiplier = 1;
31
+ nextEligibleAt = 0;
32
+ return;
33
+ }
34
+ let attempted = 0;
35
+ let failed = 0;
36
+ for (const mapping of candidates) {
37
+ attempted += 1;
38
+ try {
39
+ const updated = await service.healthCheck(mapping.id);
40
+ if (updated.status !== "active") failed += 1;
41
+ } catch {
42
+ failed += 1;
43
+ }
44
+ }
45
+ if (attempted === 0) return;
46
+ const failureRate = failed / attempted;
47
+ if (failureRate >= failureThreshold) {
48
+ backoffMultiplier = Math.min(backoffMultiplier * 2, maxMultiplier);
49
+ nextEligibleAt = Date.now() + backoffMultiplier * baseIntervalSeconds * 1e3;
50
+ } else {
51
+ backoffMultiplier = 1;
52
+ nextEligibleAt = 0;
53
+ }
54
+ }
55
+ const __testing__ = {
56
+ reset: () => {
57
+ backoffMultiplier = 1;
58
+ nextEligibleAt = 0;
59
+ },
60
+ getState: () => ({ backoffMultiplier, nextEligibleAt })
61
+ };
62
+ export {
63
+ __testing__,
64
+ handle as default,
65
+ metadata
66
+ };
67
+ //# sourceMappingURL=domainTlsRetryWorker.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/modules/customer_accounts/workers/domainTlsRetryWorker.ts"],
4
+ "sourcesContent": ["import type { JobContext, QueuedJob, WorkerMeta } from '@open-mercato/queue'\nimport type { DomainMappingService } from '@open-mercato/core/modules/customer_accounts/services/domainMappingService'\n\nexport const metadata: WorkerMeta = {\n queue: 'domain-tls-retry',\n id: 'customer_accounts:domain-tls-retry',\n concurrency: 1,\n}\n\ntype HandlerContext = JobContext & {\n resolve: <T = unknown>(name: string) => T\n}\n\nfunction parseInt32(value: string | undefined, fallback: number): number {\n const parsed = Number.parseInt(value ?? '', 10)\n if (!Number.isFinite(parsed) || parsed <= 0) return fallback\n return parsed\n}\n\nfunction parseFloat01(value: string | undefined, fallback: number): number {\n const parsed = Number.parseFloat(value ?? '')\n if (!Number.isFinite(parsed) || parsed <= 0 || parsed > 1) return fallback\n return parsed\n}\n\n// In-process adaptive-backoff state. Worker is concurrency=1, so a single\n// process owns this state. Surviving restarts is unnecessary because the\n// scheduler will simply re-evaluate on the next tick. See spec\n// \"Phase 5 \u2192 Worker-level backoff\" for the contract.\nlet backoffMultiplier = 1\nlet nextEligibleAt = 0\n\nconst BACKOFF_CAP_HOURS = 6\n\nexport default async function handle(_job: QueuedJob, ctx: HandlerContext): Promise<void> {\n const baseIntervalSeconds = parseInt32(process.env.DOMAIN_TLS_RETRY_INTERVAL_SECONDS, 1800)\n const batchSize = parseInt32(process.env.DOMAIN_TLS_RETRY_BATCH, 50)\n const maxRetries = parseInt32(process.env.DOMAIN_TLS_MAX_RETRIES, 6)\n const failureThreshold = parseFloat01(process.env.DOMAIN_TLS_RETRY_FAILURE_THRESHOLD, 0.8)\n const capSeconds = BACKOFF_CAP_HOURS * 3600\n const maxMultiplier = Math.max(1, Math.floor(capSeconds / baseIntervalSeconds))\n\n if (Date.now() < nextEligibleAt) return\n\n const service = ctx.resolve<DomainMappingService>('domainMappingService')\n const candidates = await service.findPendingTls({ maxRetries, batchSize })\n if (candidates.length === 0) {\n backoffMultiplier = 1\n nextEligibleAt = 0\n return\n }\n\n let attempted = 0\n let failed = 0\n for (const mapping of candidates) {\n attempted += 1\n try {\n const updated = await service.healthCheck(mapping.id)\n if (updated.status !== 'active') failed += 1\n } catch {\n failed += 1\n }\n }\n\n if (attempted === 0) return\n const failureRate = failed / attempted\n\n if (failureRate >= failureThreshold) {\n backoffMultiplier = Math.min(backoffMultiplier * 2, maxMultiplier)\n nextEligibleAt = Date.now() + backoffMultiplier * baseIntervalSeconds * 1000\n } else {\n backoffMultiplier = 1\n nextEligibleAt = 0\n }\n}\n\n// Test-only export so unit tests can reset state between runs.\nexport const __testing__ = {\n reset: () => {\n backoffMultiplier = 1\n nextEligibleAt = 0\n },\n getState: () => ({ backoffMultiplier, nextEligibleAt }),\n}\n"],
5
+ "mappings": "AAGO,MAAM,WAAuB;AAAA,EAClC,OAAO;AAAA,EACP,IAAI;AAAA,EACJ,aAAa;AACf;AAMA,SAAS,WAAW,OAA2B,UAA0B;AACvE,QAAM,SAAS,OAAO,SAAS,SAAS,IAAI,EAAE;AAC9C,MAAI,CAAC,OAAO,SAAS,MAAM,KAAK,UAAU,EAAG,QAAO;AACpD,SAAO;AACT;AAEA,SAAS,aAAa,OAA2B,UAA0B;AACzE,QAAM,SAAS,OAAO,WAAW,SAAS,EAAE;AAC5C,MAAI,CAAC,OAAO,SAAS,MAAM,KAAK,UAAU,KAAK,SAAS,EAAG,QAAO;AAClE,SAAO;AACT;AAMA,IAAI,oBAAoB;AACxB,IAAI,iBAAiB;AAErB,MAAM,oBAAoB;AAE1B,eAAO,OAA8B,MAAiB,KAAoC;AACxF,QAAM,sBAAsB,WAAW,QAAQ,IAAI,mCAAmC,IAAI;AAC1F,QAAM,YAAY,WAAW,QAAQ,IAAI,wBAAwB,EAAE;AACnE,QAAM,aAAa,WAAW,QAAQ,IAAI,wBAAwB,CAAC;AACnE,QAAM,mBAAmB,aAAa,QAAQ,IAAI,oCAAoC,GAAG;AACzF,QAAM,aAAa,oBAAoB;AACvC,QAAM,gBAAgB,KAAK,IAAI,GAAG,KAAK,MAAM,aAAa,mBAAmB,CAAC;AAE9E,MAAI,KAAK,IAAI,IAAI,eAAgB;AAEjC,QAAM,UAAU,IAAI,QAA8B,sBAAsB;AACxE,QAAM,aAAa,MAAM,QAAQ,eAAe,EAAE,YAAY,UAAU,CAAC;AACzE,MAAI,WAAW,WAAW,GAAG;AAC3B,wBAAoB;AACpB,qBAAiB;AACjB;AAAA,EACF;AAEA,MAAI,YAAY;AAChB,MAAI,SAAS;AACb,aAAW,WAAW,YAAY;AAChC,iBAAa;AACb,QAAI;AACF,YAAM,UAAU,MAAM,QAAQ,YAAY,QAAQ,EAAE;AACpD,UAAI,QAAQ,WAAW,SAAU,WAAU;AAAA,IAC7C,QAAQ;AACN,gBAAU;AAAA,IACZ;AAAA,EACF;AAEA,MAAI,cAAc,EAAG;AACrB,QAAM,cAAc,SAAS;AAE7B,MAAI,eAAe,kBAAkB;AACnC,wBAAoB,KAAK,IAAI,oBAAoB,GAAG,aAAa;AACjE,qBAAiB,KAAK,IAAI,IAAI,oBAAoB,sBAAsB;AAAA,EAC1E,OAAO;AACL,wBAAoB;AACpB,qBAAiB;AAAA,EACnB;AACF;AAGO,MAAM,cAAc;AAAA,EACzB,OAAO,MAAM;AACX,wBAAoB;AACpB,qBAAiB;AAAA,EACnB;AAAA,EACA,UAAU,OAAO,EAAE,mBAAmB,eAAe;AACvD;",
6
+ "names": []
7
+ }
@@ -0,0 +1,34 @@
1
+ const metadata = {
2
+ queue: "domain-verification",
3
+ id: "customer_accounts:domain-verification",
4
+ concurrency: 1
5
+ };
6
+ function parseSeconds(value, fallback) {
7
+ const parsed = Number.parseInt(value ?? "", 10);
8
+ if (!Number.isFinite(parsed) || parsed <= 0) return fallback;
9
+ return parsed;
10
+ }
11
+ async function handle(_job, ctx) {
12
+ const service = ctx.resolve("domainMappingService");
13
+ const intervalSeconds = parseSeconds(process.env.DOMAIN_AUTO_VERIFY_INTERVAL_SECONDS, 300);
14
+ const olderThanMs = intervalSeconds * 1e3;
15
+ const candidates = await service.findPendingVerification({ olderThanMs });
16
+ if (candidates.length === 0) return;
17
+ for (const mapping of candidates) {
18
+ try {
19
+ const result = await service.verify(mapping.id);
20
+ if (result.domainMapping.status === "verified") {
21
+ try {
22
+ await service.healthCheck(mapping.id);
23
+ } catch {
24
+ }
25
+ }
26
+ } catch {
27
+ }
28
+ }
29
+ }
30
+ export {
31
+ handle as default,
32
+ metadata
33
+ };
34
+ //# sourceMappingURL=domainVerificationWorker.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/modules/customer_accounts/workers/domainVerificationWorker.ts"],
4
+ "sourcesContent": ["import type { JobContext, QueuedJob, WorkerMeta } from '@open-mercato/queue'\nimport type { DomainMappingService } from '@open-mercato/core/modules/customer_accounts/services/domainMappingService'\n\nexport const metadata: WorkerMeta = {\n queue: 'domain-verification',\n id: 'customer_accounts:domain-verification',\n concurrency: 1,\n}\n\ntype HandlerContext = JobContext & {\n resolve: <T = unknown>(name: string) => T\n}\n\nfunction parseSeconds(value: string | undefined, fallback: number): number {\n const parsed = Number.parseInt(value ?? '', 10)\n if (!Number.isFinite(parsed) || parsed <= 0) return fallback\n return parsed\n}\n\nexport default async function handle(_job: QueuedJob, ctx: HandlerContext): Promise<void> {\n const service = ctx.resolve<DomainMappingService>('domainMappingService')\n\n const intervalSeconds = parseSeconds(process.env.DOMAIN_AUTO_VERIFY_INTERVAL_SECONDS, 300)\n const olderThanMs = intervalSeconds * 1000\n\n const candidates = await service.findPendingVerification({ olderThanMs })\n if (candidates.length === 0) return\n\n for (const mapping of candidates) {\n try {\n const result = await service.verify(mapping.id)\n if (result.domainMapping.status === 'verified') {\n try {\n await service.healthCheck(mapping.id)\n } catch {\n // healthCheck emits its own events on failure; swallow here so one\n // bad domain doesn't poison the rest of the batch.\n }\n }\n } catch {\n // verify() emits dns_failed events on negative results. A thrown error\n // here is unexpected (e.g. DB blip) \u2014 skip and let the next tick retry.\n }\n }\n}\n"],
5
+ "mappings": "AAGO,MAAM,WAAuB;AAAA,EAClC,OAAO;AAAA,EACP,IAAI;AAAA,EACJ,aAAa;AACf;AAMA,SAAS,aAAa,OAA2B,UAA0B;AACzE,QAAM,SAAS,OAAO,SAAS,SAAS,IAAI,EAAE;AAC9C,MAAI,CAAC,OAAO,SAAS,MAAM,KAAK,UAAU,EAAG,QAAO;AACpD,SAAO;AACT;AAEA,eAAO,OAA8B,MAAiB,KAAoC;AACxF,QAAM,UAAU,IAAI,QAA8B,sBAAsB;AAExE,QAAM,kBAAkB,aAAa,QAAQ,IAAI,qCAAqC,GAAG;AACzF,QAAM,cAAc,kBAAkB;AAEtC,QAAM,aAAa,MAAM,QAAQ,wBAAwB,EAAE,YAAY,CAAC;AACxE,MAAI,WAAW,WAAW,EAAG;AAE7B,aAAW,WAAW,YAAY;AAChC,QAAI;AACF,YAAM,SAAS,MAAM,QAAQ,OAAO,QAAQ,EAAE;AAC9C,UAAI,OAAO,cAAc,WAAW,YAAY;AAC9C,YAAI;AACF,gBAAM,QAAQ,YAAY,QAAQ,EAAE;AAAA,QACtC,QAAQ;AAAA,QAGR;AAAA,MACF;AAAA,IACF,QAAQ;AAAA,IAGR;AAAA,EACF;AACF;",
6
+ "names": []
7
+ }
@@ -13,7 +13,6 @@ import { resolveTranslations } from "@open-mercato/shared/lib/i18n/server";
13
13
  import {
14
14
  applyEntityIdExclusion,
15
15
  applyEntityIdRestriction,
16
- consumeAdvancedFilterState,
17
16
  findMatchingEntityIdsWithQueryEngine,
18
17
  findMatchingEntityIdsBySearchTokensAcrossSources,
19
18
  withScopedPayload
@@ -26,7 +25,7 @@ import {
26
25
  import { escapeLikePattern } from "@open-mercato/shared/lib/db/escapeLikePattern";
27
26
  import { parseBooleanToken } from "@open-mercato/shared/lib/boolean";
28
27
  import { findWithDecryption } from "@open-mercato/shared/lib/encryption/find";
29
- import { mergeAdvancedFilters } from "@open-mercato/shared/lib/crud/advanced-filter-integration";
28
+ import { consumeAdvancedFilterState, mergeAdvancedFilterTree } from "@open-mercato/shared/lib/crud/advanced-filter-integration";
30
29
  import {
31
30
  createCustomersCrudOpenApi,
32
31
  createPagedListResponseSchema,
@@ -111,8 +110,7 @@ const crud = makeCrudRoute({
111
110
  updatedAt: "updated_at"
112
111
  },
113
112
  buildFilters: async (query, ctx) => {
114
- const advancedQuery = { ...query };
115
- const advancedFilterState = consumeAdvancedFilterState(query);
113
+ const advancedFilterTree = consumeAdvancedFilterState(query);
116
114
  const filters = { kind: { $eq: "company" } };
117
115
  if (query.id) filters.id = { $eq: query.id };
118
116
  if (query.search) {
@@ -296,11 +294,8 @@ const crud = makeCrudRoute({
296
294
  console.warn("[customers.companies.list] custom field filter resolution failed; falling back to base filters", err);
297
295
  }
298
296
  }
299
- if (ctx && advancedFilterState) {
300
- const advancedFilters = mergeAdvancedFilters(
301
- { ...filters },
302
- advancedQuery
303
- );
297
+ if (ctx && advancedFilterTree) {
298
+ const advancedFilters = mergeAdvancedFilterTree({ ...filters }, advancedFilterTree);
304
299
  const matchedIds = await findMatchingEntityIdsWithQueryEngine({
305
300
  ctx,
306
301
  entityId: E.customers.customer_entity,