@open-mercato/core 0.6.1-develop.3276.1.1fcd145078 → 0.6.1-develop.3287.1.450f4ffb56

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 (266) 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/auth.js +1 -1
  9. package/dist/helpers/integration/auth.js.map +2 -2
  10. package/dist/helpers/integration/authUi.js +1 -1
  11. package/dist/helpers/integration/authUi.js.map +2 -2
  12. package/dist/helpers/integration/salesUi.js +18 -17
  13. package/dist/helpers/integration/salesUi.js.map +2 -2
  14. package/dist/modules/auth/frontend/login.js +4 -4
  15. package/dist/modules/auth/frontend/login.js.map +2 -2
  16. package/dist/modules/auth/frontend/reset/[token]/page.js +5 -5
  17. package/dist/modules/auth/frontend/reset/[token]/page.js.map +2 -2
  18. package/dist/modules/auth/frontend/reset.js +2 -2
  19. package/dist/modules/auth/frontend/reset.js.map +2 -2
  20. package/dist/modules/customer_accounts/acl.js +2 -1
  21. package/dist/modules/customer_accounts/acl.js.map +2 -2
  22. package/dist/modules/customer_accounts/api/admin/domain-mappings/[id]/health-check.js +110 -0
  23. package/dist/modules/customer_accounts/api/admin/domain-mappings/[id]/health-check.js.map +7 -0
  24. package/dist/modules/customer_accounts/api/admin/domain-mappings/[id]/verify.js +114 -0
  25. package/dist/modules/customer_accounts/api/admin/domain-mappings/[id]/verify.js.map +7 -0
  26. package/dist/modules/customer_accounts/api/admin/domain-mappings.js +271 -0
  27. package/dist/modules/customer_accounts/api/admin/domain-mappings.js.map +7 -0
  28. package/dist/modules/customer_accounts/api/domain-check.js +70 -0
  29. package/dist/modules/customer_accounts/api/domain-check.js.map +7 -0
  30. package/dist/modules/customer_accounts/api/domain-resolve/all.js +128 -0
  31. package/dist/modules/customer_accounts/api/domain-resolve/all.js.map +7 -0
  32. package/dist/modules/customer_accounts/api/domain-resolve.js +84 -0
  33. package/dist/modules/customer_accounts/api/domain-resolve.js.map +7 -0
  34. package/dist/modules/customer_accounts/api/login.js +14 -3
  35. package/dist/modules/customer_accounts/api/login.js.map +2 -2
  36. package/dist/modules/customer_accounts/api/magic-link/request.js +14 -3
  37. package/dist/modules/customer_accounts/api/magic-link/request.js.map +2 -2
  38. package/dist/modules/customer_accounts/api/password/reset-request.js +14 -3
  39. package/dist/modules/customer_accounts/api/password/reset-request.js.map +2 -2
  40. package/dist/modules/customer_accounts/api/signup.js +32 -5
  41. package/dist/modules/customer_accounts/api/signup.js.map +2 -2
  42. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Actions.js +48 -0
  43. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Actions.js.map +7 -0
  44. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Diagnostics.js +43 -0
  45. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Diagnostics.js.map +7 -0
  46. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/DnsConfig.js +53 -0
  47. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/DnsConfig.js.map +7 -0
  48. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/DomainPanel.js +69 -0
  49. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/DomainPanel.js.map +7 -0
  50. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/OrgSwitcher.js +31 -0
  51. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/OrgSwitcher.js.map +7 -0
  52. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/RegisterDialog.js +147 -0
  53. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/RegisterDialog.js.map +7 -0
  54. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/StatusBadgeSection.js +39 -0
  55. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/StatusBadgeSection.js.map +7 -0
  56. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Stepper.js +60 -0
  57. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Stepper.js.map +7 -0
  58. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/domainStatusMap.js +11 -0
  59. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/domainStatusMap.js.map +7 -0
  60. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/types.js +1 -0
  61. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/components/types.js.map +7 -0
  62. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/page.js +361 -0
  63. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/page.js.map +7 -0
  64. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/page.meta.js +28 -0
  65. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/page.meta.js.map +7 -0
  66. package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/page.js +4 -3
  67. package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/page.js.map +2 -2
  68. package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js +6 -5
  69. package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js.map +2 -2
  70. package/dist/modules/customer_accounts/data/enrichers.js +78 -12
  71. package/dist/modules/customer_accounts/data/enrichers.js.map +2 -2
  72. package/dist/modules/customer_accounts/data/entities.js +85 -2
  73. package/dist/modules/customer_accounts/data/entities.js.map +2 -2
  74. package/dist/modules/customer_accounts/data/guards.js +130 -0
  75. package/dist/modules/customer_accounts/data/guards.js.map +7 -0
  76. package/dist/modules/customer_accounts/data/validators.js +19 -0
  77. package/dist/modules/customer_accounts/data/validators.js.map +2 -2
  78. package/dist/modules/customer_accounts/di.js +23 -1
  79. package/dist/modules/customer_accounts/di.js.map +2 -2
  80. package/dist/modules/customer_accounts/events.js +9 -2
  81. package/dist/modules/customer_accounts/events.js.map +2 -2
  82. package/dist/modules/customer_accounts/lib/customerAuthServer.js +27 -7
  83. package/dist/modules/customer_accounts/lib/customerAuthServer.js.map +2 -2
  84. package/dist/modules/customer_accounts/lib/customerUrl.js +48 -0
  85. package/dist/modules/customer_accounts/lib/customerUrl.js.map +7 -0
  86. package/dist/modules/customer_accounts/lib/hostname.js +55 -0
  87. package/dist/modules/customer_accounts/lib/hostname.js.map +7 -0
  88. package/dist/modules/customer_accounts/lib/platformDomains.js +7 -0
  89. package/dist/modules/customer_accounts/lib/platformDomains.js.map +7 -0
  90. package/dist/modules/customer_accounts/lib/proxyRanges.js +71 -0
  91. package/dist/modules/customer_accounts/lib/proxyRanges.js.map +7 -0
  92. package/dist/modules/customer_accounts/lib/rateLimiter.js +7 -0
  93. package/dist/modules/customer_accounts/lib/rateLimiter.js.map +2 -2
  94. package/dist/modules/customer_accounts/lib/resolveTenantContext.js +63 -0
  95. package/dist/modules/customer_accounts/lib/resolveTenantContext.js.map +7 -0
  96. package/dist/modules/customer_accounts/lib/secretCompare.js +13 -0
  97. package/dist/modules/customer_accounts/lib/secretCompare.js.map +7 -0
  98. package/dist/modules/customer_accounts/migrations/Migration20260430120000_customer_accounts.js +37 -0
  99. package/dist/modules/customer_accounts/migrations/Migration20260430120000_customer_accounts.js.map +7 -0
  100. package/dist/modules/customer_accounts/notifications.client.js +76 -0
  101. package/dist/modules/customer_accounts/notifications.client.js.map +2 -2
  102. package/dist/modules/customer_accounts/notifications.js +76 -0
  103. package/dist/modules/customer_accounts/notifications.js.map +2 -2
  104. package/dist/modules/customer_accounts/services/domainMappingService.js +497 -0
  105. package/dist/modules/customer_accounts/services/domainMappingService.js.map +7 -0
  106. package/dist/modules/customer_accounts/setup.js +48 -1
  107. package/dist/modules/customer_accounts/setup.js.map +2 -2
  108. package/dist/modules/customer_accounts/subscribers/invalidateDomainCache.js +29 -0
  109. package/dist/modules/customer_accounts/subscribers/invalidateDomainCache.js.map +7 -0
  110. package/dist/modules/customer_accounts/subscribers/notifyDomainActivated.js +29 -0
  111. package/dist/modules/customer_accounts/subscribers/notifyDomainActivated.js.map +7 -0
  112. package/dist/modules/customer_accounts/subscribers/notifyDomainDnsFailed.js +30 -0
  113. package/dist/modules/customer_accounts/subscribers/notifyDomainDnsFailed.js.map +7 -0
  114. package/dist/modules/customer_accounts/subscribers/notifyDomainTlsFailed.js +31 -0
  115. package/dist/modules/customer_accounts/subscribers/notifyDomainTlsFailed.js.map +7 -0
  116. package/dist/modules/customer_accounts/subscribers/notifyDomainVerified.js +29 -0
  117. package/dist/modules/customer_accounts/subscribers/notifyDomainVerified.js.map +7 -0
  118. package/dist/modules/customer_accounts/widgets/injection/account-status/widget.client.js +2 -2
  119. package/dist/modules/customer_accounts/widgets/injection/account-status/widget.client.js.map +2 -2
  120. package/dist/modules/customer_accounts/workers/domainTlsRetryWorker.js +67 -0
  121. package/dist/modules/customer_accounts/workers/domainTlsRetryWorker.js.map +7 -0
  122. package/dist/modules/customer_accounts/workers/domainVerificationWorker.js +34 -0
  123. package/dist/modules/customer_accounts/workers/domainVerificationWorker.js.map +7 -0
  124. package/dist/modules/customers/api/companies/route.js +4 -9
  125. package/dist/modules/customers/api/companies/route.js.map +2 -2
  126. package/dist/modules/customers/api/deals/route.js +4 -9
  127. package/dist/modules/customers/api/deals/route.js.map +2 -2
  128. package/dist/modules/customers/api/people/route.js +4 -9
  129. package/dist/modules/customers/api/people/route.js.map +2 -2
  130. package/dist/modules/customers/api/utils.js +0 -12
  131. package/dist/modules/customers/api/utils.js.map +2 -2
  132. package/dist/modules/customers/backend/customers/companies/page.js +361 -284
  133. package/dist/modules/customers/backend/customers/companies/page.js.map +2 -2
  134. package/dist/modules/customers/backend/customers/deals/page.js +378 -473
  135. package/dist/modules/customers/backend/customers/deals/page.js.map +2 -2
  136. package/dist/modules/customers/backend/customers/people/page.js +368 -286
  137. package/dist/modules/customers/backend/customers/people/page.js.map +2 -2
  138. package/dist/modules/customers/components/detail/assignableStaff.js +15 -1
  139. package/dist/modules/customers/components/detail/assignableStaff.js.map +2 -2
  140. package/dist/modules/customers/components/formConfig.js +2 -2
  141. package/dist/modules/customers/components/formConfig.js.map +2 -2
  142. package/dist/modules/customers/widgets/injection/ai-assistant-trigger/widget.client.js +188 -36
  143. package/dist/modules/customers/widgets/injection/ai-assistant-trigger/widget.client.js.map +2 -2
  144. package/dist/modules/customers/widgets/injection/ai-assistant-trigger/widget.js +2 -2
  145. package/dist/modules/customers/widgets/injection/ai-assistant-trigger/widget.js.map +2 -2
  146. package/dist/modules/customers/widgets/injection-table.js +6 -0
  147. package/dist/modules/customers/widgets/injection-table.js.map +2 -2
  148. package/dist/modules/integrations/backend/integrations/[id]/page.js +2 -3
  149. package/dist/modules/integrations/backend/integrations/[id]/page.js.map +2 -2
  150. package/dist/modules/perspectives/services/perspectiveService.js +16 -2
  151. package/dist/modules/perspectives/services/perspectiveService.js.map +2 -2
  152. package/dist/modules/portal/frontend/[orgSlug]/portal/login/page.js +5 -3
  153. package/dist/modules/portal/frontend/[orgSlug]/portal/login/page.js.map +2 -2
  154. package/dist/modules/portal/frontend/[orgSlug]/portal/reset-password/page.js +3 -3
  155. package/dist/modules/portal/frontend/[orgSlug]/portal/reset-password/page.js.map +2 -2
  156. package/dist/modules/portal/frontend/[orgSlug]/portal/signup/page.js +4 -2
  157. package/dist/modules/portal/frontend/[orgSlug]/portal/signup/page.js.map +2 -2
  158. package/dist/modules/query_index/lib/engine.js +31 -8
  159. package/dist/modules/query_index/lib/engine.js.map +2 -2
  160. package/dist/modules/sales/backend/sales/documents/[id]/page.js +3 -5
  161. package/dist/modules/sales/backend/sales/documents/[id]/page.js.map +2 -2
  162. package/dist/modules/sales/components/ProviderFieldInput.js +2 -2
  163. package/dist/modules/sales/components/ProviderFieldInput.js.map +2 -2
  164. package/dist/modules/sales/components/documents/SalesDocumentForm.js +3 -4
  165. package/dist/modules/sales/components/documents/SalesDocumentForm.js.map +2 -2
  166. package/dist/modules/shipping_carriers/lib/shipment-wizard/components/ConfigureStep.js +3 -4
  167. package/dist/modules/shipping_carriers/lib/shipment-wizard/components/ConfigureStep.js.map +2 -2
  168. package/dist/modules/workflows/backend/tasks/[id]/page.js +2 -2
  169. package/dist/modules/workflows/backend/tasks/[id]/page.js.map +2 -2
  170. package/dist/modules/workflows/frontend/checkout-demo/page.js +2 -2
  171. package/dist/modules/workflows/frontend/checkout-demo/page.js.map +2 -2
  172. package/generated/entities/domain_mapping/index.ts +14 -0
  173. package/generated/entities.ids.generated.ts +2 -1
  174. package/generated/entity-fields-registry.ts +16 -0
  175. package/package.json +5 -5
  176. package/src/helpers/integration/auth.ts +1 -1
  177. package/src/helpers/integration/authUi.ts +1 -1
  178. package/src/helpers/integration/salesUi.ts +27 -23
  179. package/src/modules/auth/frontend/login.tsx +4 -3
  180. package/src/modules/auth/frontend/reset/[token]/page.tsx +4 -4
  181. package/src/modules/auth/frontend/reset.tsx +2 -2
  182. package/src/modules/customer_accounts/acl.ts +1 -0
  183. package/src/modules/customer_accounts/api/admin/domain-mappings/[id]/health-check.ts +119 -0
  184. package/src/modules/customer_accounts/api/admin/domain-mappings/[id]/verify.ts +123 -0
  185. package/src/modules/customer_accounts/api/admin/domain-mappings.ts +303 -0
  186. package/src/modules/customer_accounts/api/domain-check.ts +83 -0
  187. package/src/modules/customer_accounts/api/domain-resolve/all.ts +139 -0
  188. package/src/modules/customer_accounts/api/domain-resolve.ts +91 -0
  189. package/src/modules/customer_accounts/api/login.ts +14 -3
  190. package/src/modules/customer_accounts/api/magic-link/request.ts +14 -3
  191. package/src/modules/customer_accounts/api/password/reset-request.ts +15 -3
  192. package/src/modules/customer_accounts/api/signup.ts +36 -5
  193. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Actions.tsx +70 -0
  194. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Diagnostics.tsx +66 -0
  195. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/DnsConfig.tsx +78 -0
  196. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/DomainPanel.tsx +90 -0
  197. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/OrgSwitcher.tsx +43 -0
  198. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/RegisterDialog.tsx +178 -0
  199. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/StatusBadgeSection.tsx +56 -0
  200. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/Stepper.tsx +69 -0
  201. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/domainStatusMap.ts +10 -0
  202. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/components/types.ts +31 -0
  203. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/page.meta.ts +26 -0
  204. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/page.tsx +411 -0
  205. package/src/modules/customer_accounts/backend/customer_accounts/users/[id]/page.tsx +3 -2
  206. package/src/modules/customer_accounts/backend/customer_accounts/users/page.tsx +5 -4
  207. package/src/modules/customer_accounts/data/enrichers.ts +95 -12
  208. package/src/modules/customer_accounts/data/entities.ts +80 -1
  209. package/src/modules/customer_accounts/data/guards.ts +155 -0
  210. package/src/modules/customer_accounts/data/validators.ts +26 -0
  211. package/src/modules/customer_accounts/di.ts +35 -1
  212. package/src/modules/customer_accounts/events.ts +8 -1
  213. package/src/modules/customer_accounts/i18n/de.json +78 -0
  214. package/src/modules/customer_accounts/i18n/en.json +78 -0
  215. package/src/modules/customer_accounts/i18n/es.json +78 -0
  216. package/src/modules/customer_accounts/i18n/pl.json +78 -0
  217. package/src/modules/customer_accounts/lib/customerAuthServer.ts +44 -8
  218. package/src/modules/customer_accounts/lib/customerUrl.ts +72 -0
  219. package/src/modules/customer_accounts/lib/hostname.ts +76 -0
  220. package/src/modules/customer_accounts/lib/platformDomains.ts +14 -0
  221. package/src/modules/customer_accounts/lib/proxyRanges.ts +85 -0
  222. package/src/modules/customer_accounts/lib/rateLimiter.ts +10 -0
  223. package/src/modules/customer_accounts/lib/resolveTenantContext.ts +96 -0
  224. package/src/modules/customer_accounts/lib/secretCompare.ts +20 -0
  225. package/src/modules/customer_accounts/migrations/.snapshot-open-mercato.json +341 -0
  226. package/src/modules/customer_accounts/migrations/Migration20260430120000_customer_accounts.ts +38 -0
  227. package/src/modules/customer_accounts/notifications.client.ts +76 -0
  228. package/src/modules/customer_accounts/notifications.ts +76 -0
  229. package/src/modules/customer_accounts/services/domainMappingService.ts +632 -0
  230. package/src/modules/customer_accounts/setup.ts +81 -1
  231. package/src/modules/customer_accounts/subscribers/invalidateDomainCache.ts +35 -0
  232. package/src/modules/customer_accounts/subscribers/notifyDomainActivated.ts +32 -0
  233. package/src/modules/customer_accounts/subscribers/notifyDomainDnsFailed.ts +33 -0
  234. package/src/modules/customer_accounts/subscribers/notifyDomainTlsFailed.ts +34 -0
  235. package/src/modules/customer_accounts/subscribers/notifyDomainVerified.ts +32 -0
  236. package/src/modules/customer_accounts/widgets/injection/account-status/widget.client.tsx +2 -2
  237. package/src/modules/customer_accounts/workers/domainTlsRetryWorker.ts +84 -0
  238. package/src/modules/customer_accounts/workers/domainVerificationWorker.ts +45 -0
  239. package/src/modules/customers/api/companies/route.ts +4 -9
  240. package/src/modules/customers/api/deals/route.ts +4 -9
  241. package/src/modules/customers/api/people/route.ts +4 -9
  242. package/src/modules/customers/api/utils.ts +0 -14
  243. package/src/modules/customers/backend/customers/companies/page.tsx +321 -237
  244. package/src/modules/customers/backend/customers/deals/page.tsx +321 -455
  245. package/src/modules/customers/backend/customers/people/page.tsx +331 -240
  246. package/src/modules/customers/components/detail/assignableStaff.ts +21 -0
  247. package/src/modules/customers/components/formConfig.tsx +2 -2
  248. package/src/modules/customers/i18n/de.json +31 -0
  249. package/src/modules/customers/i18n/en.json +31 -0
  250. package/src/modules/customers/i18n/es.json +31 -0
  251. package/src/modules/customers/i18n/pl.json +31 -0
  252. package/src/modules/customers/widgets/injection/ai-assistant-trigger/widget.client.tsx +197 -40
  253. package/src/modules/customers/widgets/injection/ai-assistant-trigger/widget.ts +13 -7
  254. package/src/modules/customers/widgets/injection-table.ts +6 -0
  255. package/src/modules/integrations/backend/integrations/[id]/page.tsx +2 -2
  256. package/src/modules/perspectives/services/perspectiveService.ts +30 -2
  257. package/src/modules/portal/frontend/[orgSlug]/portal/login/page.tsx +5 -3
  258. package/src/modules/portal/frontend/[orgSlug]/portal/reset-password/page.tsx +3 -3
  259. package/src/modules/portal/frontend/[orgSlug]/portal/signup/page.tsx +4 -2
  260. package/src/modules/query_index/lib/engine.ts +46 -8
  261. package/src/modules/sales/backend/sales/documents/[id]/page.tsx +3 -5
  262. package/src/modules/sales/components/ProviderFieldInput.tsx +2 -2
  263. package/src/modules/sales/components/documents/SalesDocumentForm.tsx +2 -3
  264. package/src/modules/shipping_carriers/lib/shipment-wizard/components/ConfigureStep.tsx +3 -4
  265. package/src/modules/workflows/backend/tasks/[id]/page.tsx +2 -2
  266. package/src/modules/workflows/frontend/checkout-demo/page.tsx +2 -2
@@ -0,0 +1,14 @@
1
+ export const id = "id";
2
+ export const hostname = "hostname";
3
+ export const tenant_id = "tenant_id";
4
+ export const organization_id = "organization_id";
5
+ export const replaces_domain = "replaces_domain";
6
+ export const provider = "provider";
7
+ export const status = "status";
8
+ export const verified_at = "verified_at";
9
+ export const last_dns_check_at = "last_dns_check_at";
10
+ export const dns_failure_reason = "dns_failure_reason";
11
+ export const tls_failure_reason = "tls_failure_reason";
12
+ export const tls_retry_count = "tls_retry_count";
13
+ export const created_at = "created_at";
14
+ export const updated_at = "updated_at";
@@ -262,7 +262,8 @@ export const M = {
262
262
  "customer_user_session": "customer_accounts:customer_user_session",
263
263
  "customer_user_email_verification": "customer_accounts:customer_user_email_verification",
264
264
  "customer_user_password_reset": "customer_accounts:customer_user_password_reset",
265
- "customer_user_invitation": "customer_accounts:customer_user_invitation"
265
+ "customer_user_invitation": "customer_accounts:customer_user_invitation",
266
+ "domain_mapping": "customer_accounts:domain_mapping"
266
267
  }
267
268
  } as const;
268
269
 
@@ -985,6 +985,22 @@ export const entityFieldsRegistry: Record<string, Record<string, string>> = {
985
985
  "created_at": "created_at",
986
986
  "updated_at": "updated_at"
987
987
  },
988
+ "domain_mapping": {
989
+ "id": "id",
990
+ "hostname": "hostname",
991
+ "tenant_id": "tenant_id",
992
+ "organization_id": "organization_id",
993
+ "replaces_domain": "replaces_domain",
994
+ "provider": "provider",
995
+ "status": "status",
996
+ "verified_at": "verified_at",
997
+ "last_dns_check_at": "last_dns_check_at",
998
+ "dns_failure_reason": "dns_failure_reason",
999
+ "tls_failure_reason": "tls_failure_reason",
1000
+ "tls_retry_count": "tls_retry_count",
1001
+ "created_at": "created_at",
1002
+ "updated_at": "updated_at"
1003
+ },
988
1004
  "encryption_map": {
989
1005
  "id": "id",
990
1006
  "entity_id": "entity_id",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-mercato/core",
3
- "version": "0.6.1-develop.3276.1.1fcd145078",
3
+ "version": "0.6.1-develop.3287.1.450f4ffb56",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "scripts": {
@@ -237,12 +237,12 @@
237
237
  "ts-pattern": "^5.0.0"
238
238
  },
239
239
  "peerDependencies": {
240
- "@open-mercato/ai-assistant": "0.6.1-develop.3276.1.1fcd145078",
241
- "@open-mercato/shared": "0.6.1-develop.3276.1.1fcd145078"
240
+ "@open-mercato/ai-assistant": "0.6.1-develop.3287.1.450f4ffb56",
241
+ "@open-mercato/shared": "0.6.1-develop.3287.1.450f4ffb56"
242
242
  },
243
243
  "devDependencies": {
244
- "@open-mercato/ai-assistant": "0.6.1-develop.3276.1.1fcd145078",
245
- "@open-mercato/shared": "0.6.1-develop.3276.1.1fcd145078",
244
+ "@open-mercato/ai-assistant": "0.6.1-develop.3287.1.450f4ffb56",
245
+ "@open-mercato/shared": "0.6.1-develop.3287.1.450f4ffb56",
246
246
  "@testing-library/dom": "^10.4.1",
247
247
  "@testing-library/jest-dom": "^6.9.1",
248
248
  "@testing-library/react": "^16.3.1",
@@ -207,7 +207,7 @@ export async function login(page: Page, role: Role = 'admin'): Promise<void> {
207
207
  }
208
208
  await page.getByLabel('Email').fill(creds.email);
209
209
 
210
- const passwordInput = page.getByLabel('Password').first();
210
+ const passwordInput = page.getByLabel('Password', { exact: true }).first();
211
211
  if (await passwordInput.isVisible().catch(() => false)) {
212
212
  await passwordInput.fill(creds.password);
213
213
  await passwordInput.press('Enter');
@@ -37,6 +37,6 @@ export async function createUserViaUi(page: Page, input: { email: string; passwo
37
37
 
38
38
  await page.getByRole('button', { name: 'Create' }).first().click();
39
39
  await expect(page).toHaveURL(/\/backend\/users(?:\?.*)?$/);
40
- await page.getByRole('textbox', { name: 'Search', exact: true }).fill(input.email);
40
+ await page.getByRole('searchbox', { name: 'Search', exact: true }).fill(input.email);
41
41
  await expect(page.getByRole('row', { name: new RegExp(input.email, 'i') })).toBeVisible();
42
42
  }
@@ -94,10 +94,6 @@ function parseCurrencyAmount(value: string): number {
94
94
  return Number.parseFloat(lastMatch.replace('$', ''));
95
95
  }
96
96
 
97
- function normalizeAdjustmentKindValue(kindLabel: string): string {
98
- return kindLabel.trim().toLowerCase().replace(/\s+/g, '_');
99
- }
100
-
101
97
  function readId(payload: unknown, keys: string[]): string | null {
102
98
  if (!payload || typeof payload !== 'object') return null;
103
99
  const map = payload as Record<string, unknown>;
@@ -1099,32 +1095,40 @@ export async function addAdjustment(page: Page, options: AddAdjustmentOptions):
1099
1095
  // Radix Select trigger — target by CrudForm field id (kind picker)
1100
1096
  const kindTrigger = dialog.locator('[data-crud-field-id="kind"] [role="combobox"]').first();
1101
1097
  await expect(kindTrigger).toBeVisible({ timeout: TEST_WAIT_TIMEOUT_MS });
1102
-
1103
- const labelInput = dialog.getByPlaceholder(/e\.g\. Shipping fee/i).first();
1104
- await expect(labelInput).toBeVisible({ timeout: TEST_WAIT_TIMEOUT_MS });
1105
- // Bumped toHaveValue timeout 2 s → 5 s — covers the worst-case reset race
1106
- // where the tax-rates fetch resolves *after* the networkidle window above
1107
- // (e.g. when a slow Docker host bundles the requests inconsistently).
1108
- await fillControlledInput(labelInput, options.label, 5_000);
1109
-
1110
- if ((await kindTrigger.count()) > 0) {
1111
- const expectedKindValue = normalizeAdjustmentKindValue(options.kindLabel ?? 'Surcharge');
1112
- const kindLabel = options.kindLabel ?? 'Surcharge';
1113
- await kindTrigger.click();
1114
- const option = page.getByRole('option', { name: new RegExp(`^${escapeRegExp(kindLabel)}$`, 'i') }).first();
1115
- const optionVisible = await option.waitFor({ state: 'visible', timeout: 2_000 }).then(
1116
- () => true,
1117
- () => false,
1098
+ const kindLabel = options.kindLabel ?? 'Surcharge';
1099
+ const selectKindOption = async (): Promise<void> => {
1100
+ if ((await kindTrigger.count()) === 0) return;
1101
+ await waitForOptionalTextToDisappear(
1102
+ dialog,
1103
+ /Loading adjustment kinds…|Loading adjustment kinds\.\.\./i,
1104
+ TEST_WAIT_TIMEOUT_MS,
1118
1105
  );
1106
+ await expect(kindTrigger).toBeEnabled({ timeout: TEST_WAIT_TIMEOUT_MS });
1107
+ await kindTrigger.click();
1108
+ const kindOption = page.getByRole('option', { name: new RegExp(`^${escapeRegExp(kindLabel)}$`, 'i') }).first();
1109
+ const optionVisible = await kindOption
1110
+ .waitFor({ state: 'visible', timeout: TEST_WAIT_TIMEOUT_MS })
1111
+ .then(() => true, () => false);
1119
1112
  if (optionVisible) {
1120
- await option.click({ force: true });
1113
+ await kindOption.click({ force: true });
1121
1114
  } else {
1115
+ // Fallback: drive selection via keyboard when modal-backdrop click interception
1116
+ // hides the rendered option. Brought forward from develop.
1122
1117
  await page.keyboard.type(kindLabel.charAt(0));
1123
1118
  await page.waitForTimeout(150);
1124
1119
  await page.keyboard.press('Enter');
1125
1120
  }
1126
- void expectedKindValue;
1127
- }
1121
+ await expect(kindTrigger).toContainText(kindLabel, { timeout: 2_000 });
1122
+ };
1123
+
1124
+ // Select kind first — the Radix Select interaction can trigger CrudForm re-renders that
1125
+ // clear inputs filled before it, so we run the dropdown sequence up front and then fill
1126
+ // the remaining fields once.
1127
+ await selectKindOption();
1128
+
1129
+ const labelInput = dialog.getByPlaceholder(/e\.g\. Shipping fee/i).first();
1130
+ await expect(labelInput).toBeVisible({ timeout: TEST_WAIT_TIMEOUT_MS });
1131
+ await fillControlledInput(labelInput, options.label);
1128
1132
 
1129
1133
  const fixedAmountButton = dialog.getByRole('button', { name: /^Fixed amount$/i }).first();
1130
1134
  if ((await fixedAmountButton.count()) > 0) {
@@ -6,6 +6,8 @@ import Link from 'next/link'
6
6
  import { useRouter, useSearchParams } from 'next/navigation'
7
7
  import { Card, CardContent, CardHeader, CardDescription } from '@open-mercato/ui/primitives/card'
8
8
  import { Input } from '@open-mercato/ui/primitives/input'
9
+ import { EmailInput } from '@open-mercato/ui/primitives/email-input'
10
+ import { PasswordInput } from '@open-mercato/ui/primitives/password-input'
9
11
  import { Label } from '@open-mercato/ui/primitives/label'
10
12
  import { Button } from '@open-mercato/ui/primitives/button'
11
13
  import { useT } from '@open-mercato/shared/lib/i18n/context'
@@ -352,10 +354,9 @@ export default function LoginPage() {
352
354
  )}
353
355
  <div className="grid gap-1">
354
356
  <Label htmlFor="email">{t('auth.email')}</Label>
355
- <Input
357
+ <EmailInput
356
358
  id="email"
357
359
  name="email"
358
- type="email"
359
360
  required
360
361
  aria-invalid={!!error}
361
362
  onChange={(e) => setEmail(e.target.value)}
@@ -369,7 +370,7 @@ export default function LoginPage() {
369
370
  {authOverride?.hidePassword ? null : (
370
371
  <div className="grid gap-1">
371
372
  <Label htmlFor="password">{t('auth.password')}</Label>
372
- <Input id="password" name="password" type="password" required={!authOverride} aria-invalid={!!error} />
373
+ <PasswordInput id="password" name="password" required={!authOverride} aria-invalid={!!error} autoComplete="current-password" />
373
374
  </div>
374
375
  )}
375
376
  {!authOverride?.hideRememberMe && !authOverride?.hidePassword && (
@@ -1,7 +1,7 @@
1
1
  "use client"
2
2
  import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@open-mercato/ui/primitives/card'
3
3
  import { Button } from '@open-mercato/ui/primitives/button'
4
- import { Input } from '@open-mercato/ui/primitives/input'
4
+ import { PasswordInput } from '@open-mercato/ui/primitives/password-input'
5
5
  import { Label } from '@open-mercato/ui/primitives/label'
6
6
  import { useState } from 'react'
7
7
  import { useRouter } from 'next/navigation'
@@ -69,19 +69,19 @@ export default function ResetWithTokenPage({ params }: { params: { token: string
69
69
  {error && <div className="text-sm text-status-error-text">{error}</div>}
70
70
  <div className="grid gap-1">
71
71
  <Label htmlFor="password">{t('auth.reset.form.password', 'New password')}</Label>
72
- <Input id="password" name="password" type="password" required minLength={passwordPolicy.minLength} />
72
+ <PasswordInput id="password" name="password" required minLength={passwordPolicy.minLength} autoComplete="new-password" />
73
73
  {passwordDescription ? (
74
74
  <p className="text-xs text-muted-foreground">{passwordDescription}</p>
75
75
  ) : null}
76
76
  </div>
77
77
  <div className="grid gap-1">
78
78
  <Label htmlFor="confirmPassword">{t('auth.profile.form.confirmPassword', 'Confirm new password')}</Label>
79
- <Input
79
+ <PasswordInput
80
80
  id="confirmPassword"
81
81
  name="confirmPassword"
82
- type="password"
83
82
  required
84
83
  minLength={passwordPolicy.minLength}
84
+ autoComplete="new-password"
85
85
  />
86
86
  </div>
87
87
  <Button type="submit" className="mt-2 w-full" disabled={submitting}>
@@ -3,7 +3,7 @@ import { useState } from 'react'
3
3
  import Link from 'next/link'
4
4
  import { Card, CardContent, CardHeader, CardTitle, CardDescription } from '@open-mercato/ui/primitives/card'
5
5
  import { Button } from '@open-mercato/ui/primitives/button'
6
- import { Input } from '@open-mercato/ui/primitives/input'
6
+ import { EmailInput } from '@open-mercato/ui/primitives/email-input'
7
7
  import { Label } from '@open-mercato/ui/primitives/label'
8
8
  import { useT } from '@open-mercato/shared/lib/i18n/context'
9
9
 
@@ -59,7 +59,7 @@ export default function ResetPage() {
59
59
  {error && <div className="text-sm text-red-600">{error}</div>}
60
60
  <div className="grid gap-1">
61
61
  <Label htmlFor="email">{t('auth.email')}</Label>
62
- <Input id="email" name="email" type="email" required aria-invalid={!!fieldError} aria-describedby={fieldError ? 'email-error' : undefined} />
62
+ <EmailInput id="email" name="email" required aria-invalid={!!fieldError} aria-describedby={fieldError ? 'email-error' : undefined} />
63
63
  {fieldError && <p id="email-error" className="text-sm text-red-600">{fieldError}</p>}
64
64
  </div>
65
65
  <Button type="submit" className="mt-2 w-full" disabled={submitting}>
@@ -3,6 +3,7 @@ export const features = [
3
3
  { id: 'customer_accounts.manage', title: 'Manage customer accounts', module: 'customer_accounts' },
4
4
  { id: 'customer_accounts.roles.manage', title: 'Manage customer roles', module: 'customer_accounts' },
5
5
  { id: 'customer_accounts.invite', title: 'Invite customer users', module: 'customer_accounts' },
6
+ { id: 'customer_accounts.domain.manage', title: 'Manage custom portal domains', module: 'customer_accounts' },
6
7
  ]
7
8
 
8
9
  export default features
@@ -0,0 +1,119 @@
1
+ import { NextResponse } from 'next/server'
2
+ import { z } from 'zod'
3
+ import type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'
4
+ import { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'
5
+ import { createRequestContainer } from '@open-mercato/shared/lib/di/container'
6
+ import { RbacService } from '@open-mercato/core/modules/auth/services/rbacService'
7
+ import {
8
+ validateCrudMutationGuard,
9
+ runCrudMutationGuardAfterSuccess,
10
+ } from '@open-mercato/shared/lib/crud/mutation-guard'
11
+ import { DomainMappingService } from '@open-mercato/core/modules/customer_accounts/services/domainMappingService'
12
+
13
+ const FEATURE = 'customer_accounts.domain.manage'
14
+
15
+ export const metadata = {
16
+ POST: { requireAuth: true, requireFeatures: [FEATURE] },
17
+ }
18
+
19
+ export async function POST(req: Request, ctx: { params: Promise<{ id: string }> }) {
20
+ const auth = await getAuthFromRequest(req)
21
+ if (!auth || !auth.tenantId) return NextResponse.json({ ok: false, error: 'Unauthorized' }, { status: 401 })
22
+
23
+ const container = await createRequestContainer()
24
+ const rbac = container.resolve('rbacService') as RbacService
25
+ const allowed = await rbac.userHasAllFeatures(auth.sub, [FEATURE], {
26
+ tenantId: auth.tenantId,
27
+ organizationId: auth.orgId,
28
+ })
29
+ if (!allowed) return NextResponse.json({ ok: false, error: 'Forbidden' }, { status: 403 })
30
+
31
+ const { id } = await ctx.params
32
+ const service = container.resolve('domainMappingService') as DomainMappingService
33
+ const record = await service.findById(id, { tenantId: auth.tenantId })
34
+ if (!record) return NextResponse.json({ ok: false, error: 'Not found' }, { status: 404 })
35
+
36
+ const guardResult = await validateCrudMutationGuard(container, {
37
+ tenantId: auth.tenantId,
38
+ organizationId: record.organizationId,
39
+ userId: auth.sub,
40
+ resourceKind: 'customer_accounts.domain_mapping',
41
+ resourceId: id,
42
+ operation: 'update',
43
+ requestMethod: req.method,
44
+ requestHeaders: req.headers,
45
+ })
46
+ if (guardResult && !guardResult.ok) {
47
+ return NextResponse.json(guardResult.body, { status: guardResult.status })
48
+ }
49
+
50
+ let updated
51
+ try {
52
+ updated = await service.healthCheck(id)
53
+ } catch (err) {
54
+ return NextResponse.json(
55
+ { ok: false, error: err instanceof Error ? err.message : 'Health check failed' },
56
+ { status: 500 },
57
+ )
58
+ }
59
+
60
+ if (guardResult?.ok && guardResult.shouldRunAfterSuccess) {
61
+ await runCrudMutationGuardAfterSuccess(container, {
62
+ tenantId: auth.tenantId,
63
+ organizationId: record.organizationId,
64
+ userId: auth.sub,
65
+ resourceKind: 'customer_accounts.domain_mapping',
66
+ resourceId: id,
67
+ operation: 'update',
68
+ requestMethod: req.method,
69
+ requestHeaders: req.headers,
70
+ metadata: guardResult.metadata ?? null,
71
+ })
72
+ }
73
+
74
+ return NextResponse.json({
75
+ ok: true,
76
+ domainMapping: {
77
+ id: updated.id,
78
+ hostname: updated.hostname,
79
+ status: updated.status,
80
+ tlsRetryCount: updated.tlsRetryCount,
81
+ tlsFailureReason: updated.tlsFailureReason ?? null,
82
+ },
83
+ })
84
+ }
85
+
86
+ const errorSchema = z.object({ ok: z.literal(false), error: z.string() })
87
+
88
+ export const openApi: OpenApiRouteDoc = {
89
+ tag: 'CustomerAccounts',
90
+ summary: 'TLS health check for a custom domain mapping',
91
+ methods: {
92
+ POST: {
93
+ summary: 'Trigger TLS health check',
94
+ description:
95
+ 'Runs an HTTPS probe to verify Traefik has provisioned a certificate. On success: transitions the mapping to active.',
96
+ responses: [
97
+ {
98
+ status: 200,
99
+ description: 'OK',
100
+ schema: z.object({
101
+ ok: z.literal(true),
102
+ domainMapping: z.object({
103
+ id: z.string().uuid(),
104
+ hostname: z.string(),
105
+ status: z.string(),
106
+ tlsRetryCount: z.number().int().nonnegative(),
107
+ tlsFailureReason: z.string().nullable(),
108
+ }),
109
+ }),
110
+ },
111
+ ],
112
+ errors: [
113
+ { status: 401, description: 'Unauthorized', schema: errorSchema },
114
+ { status: 403, description: 'Forbidden', schema: errorSchema },
115
+ { status: 404, description: 'Not found', schema: errorSchema },
116
+ ],
117
+ },
118
+ },
119
+ }
@@ -0,0 +1,123 @@
1
+ import { NextResponse } from 'next/server'
2
+ import { z } from 'zod'
3
+ import type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'
4
+ import { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'
5
+ import { createRequestContainer } from '@open-mercato/shared/lib/di/container'
6
+ import { RbacService } from '@open-mercato/core/modules/auth/services/rbacService'
7
+ import {
8
+ validateCrudMutationGuard,
9
+ runCrudMutationGuardAfterSuccess,
10
+ } from '@open-mercato/shared/lib/crud/mutation-guard'
11
+ import { DomainMappingService } from '@open-mercato/core/modules/customer_accounts/services/domainMappingService'
12
+
13
+ const FEATURE = 'customer_accounts.domain.manage'
14
+
15
+ export const metadata = {
16
+ POST: { requireAuth: true, requireFeatures: [FEATURE] },
17
+ }
18
+
19
+ export async function POST(req: Request, ctx: { params: Promise<{ id: string }> }) {
20
+ const auth = await getAuthFromRequest(req)
21
+ if (!auth || !auth.tenantId) return NextResponse.json({ ok: false, error: 'Unauthorized' }, { status: 401 })
22
+
23
+ const container = await createRequestContainer()
24
+ const rbac = container.resolve('rbacService') as RbacService
25
+ const allowed = await rbac.userHasAllFeatures(auth.sub, [FEATURE], {
26
+ tenantId: auth.tenantId,
27
+ organizationId: auth.orgId,
28
+ })
29
+ if (!allowed) return NextResponse.json({ ok: false, error: 'Forbidden' }, { status: 403 })
30
+
31
+ const { id } = await ctx.params
32
+ const service = container.resolve('domainMappingService') as DomainMappingService
33
+ const record = await service.findById(id, { tenantId: auth.tenantId })
34
+ if (!record) return NextResponse.json({ ok: false, error: 'Not found' }, { status: 404 })
35
+
36
+ const guardResult = await validateCrudMutationGuard(container, {
37
+ tenantId: auth.tenantId,
38
+ organizationId: record.organizationId,
39
+ userId: auth.sub,
40
+ resourceKind: 'customer_accounts.domain_mapping',
41
+ resourceId: id,
42
+ operation: 'update',
43
+ requestMethod: req.method,
44
+ requestHeaders: req.headers,
45
+ })
46
+ if (guardResult && !guardResult.ok) {
47
+ return NextResponse.json(guardResult.body, { status: guardResult.status })
48
+ }
49
+
50
+ let result
51
+ try {
52
+ result = await service.verify(id)
53
+ } catch (err) {
54
+ return NextResponse.json(
55
+ { ok: false, error: err instanceof Error ? err.message : 'DNS verification failed' },
56
+ { status: 500 },
57
+ )
58
+ }
59
+
60
+ if (guardResult?.ok && guardResult.shouldRunAfterSuccess) {
61
+ await runCrudMutationGuardAfterSuccess(container, {
62
+ tenantId: auth.tenantId,
63
+ organizationId: record.organizationId,
64
+ userId: auth.sub,
65
+ resourceKind: 'customer_accounts.domain_mapping',
66
+ resourceId: id,
67
+ operation: 'update',
68
+ requestMethod: req.method,
69
+ requestHeaders: req.headers,
70
+ metadata: guardResult.metadata ?? null,
71
+ })
72
+ }
73
+
74
+ return NextResponse.json({
75
+ ok: true,
76
+ domainMapping: {
77
+ id: result.domainMapping.id,
78
+ hostname: result.domainMapping.hostname,
79
+ status: result.domainMapping.status,
80
+ verifiedAt: result.domainMapping.verifiedAt?.toISOString() ?? null,
81
+ lastDnsCheckAt: result.domainMapping.lastDnsCheckAt?.toISOString() ?? null,
82
+ dnsFailureReason: result.domainMapping.dnsFailureReason ?? null,
83
+ },
84
+ diagnostics: result.diagnostics ?? null,
85
+ })
86
+ }
87
+
88
+ const errorSchema = z.object({ ok: z.literal(false), error: z.string() })
89
+
90
+ export const openApi: OpenApiRouteDoc = {
91
+ tag: 'CustomerAccounts',
92
+ summary: 'Verify a custom domain mapping (DNS check)',
93
+ methods: {
94
+ POST: {
95
+ summary: 'Trigger DNS verification',
96
+ description:
97
+ 'Runs DNS verification (CNAME → A → reverse-resolve fallback) for the domain mapping. Returns diagnostics on failure.',
98
+ responses: [
99
+ {
100
+ status: 200,
101
+ description: 'OK — see status',
102
+ schema: z.object({
103
+ ok: z.literal(true),
104
+ domainMapping: z.object({
105
+ id: z.string().uuid(),
106
+ hostname: z.string(),
107
+ status: z.string(),
108
+ verifiedAt: z.string().nullable(),
109
+ lastDnsCheckAt: z.string().nullable(),
110
+ dnsFailureReason: z.string().nullable(),
111
+ }),
112
+ diagnostics: z.unknown().nullable(),
113
+ }),
114
+ },
115
+ ],
116
+ errors: [
117
+ { status: 401, description: 'Unauthorized', schema: errorSchema },
118
+ { status: 403, description: 'Forbidden', schema: errorSchema },
119
+ { status: 404, description: 'Not found', schema: errorSchema },
120
+ ],
121
+ },
122
+ },
123
+ }