@open-mercato/core 0.6.7-develop.6788.1.c2a1520a30 → 0.6.7-develop.6814.1.0627c7e9f1

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 (394) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/dist/generated/entities/customer_deal_person_link/index.js +2 -0
  3. package/dist/generated/entities/customer_deal_person_link/index.js.map +2 -2
  4. package/dist/generated/entities/customer_user_invitation/index.js +2 -0
  5. package/dist/generated/entities/customer_user_invitation/index.js.map +2 -2
  6. package/dist/generated/entities.ids.generated.js +1 -0
  7. package/dist/generated/entities.ids.generated.js.map +2 -2
  8. package/dist/generated/entity-fields-registry.js +2 -0
  9. package/dist/generated/entity-fields-registry.js.map +2 -2
  10. package/dist/modules/business_rules/api/openmercato-call-options/route.js +85 -0
  11. package/dist/modules/business_rules/api/openmercato-call-options/route.js.map +7 -0
  12. package/dist/modules/business_rules/api/rules/route.js +71 -4
  13. package/dist/modules/business_rules/api/rules/route.js.map +2 -2
  14. package/dist/modules/business_rules/components/ActionBuilder.js +47 -4
  15. package/dist/modules/business_rules/components/ActionBuilder.js.map +3 -3
  16. package/dist/modules/business_rules/components/ActionRow.js +106 -16
  17. package/dist/modules/business_rules/components/ActionRow.js.map +2 -2
  18. package/dist/modules/business_rules/components/utils/actionValidation.js +6 -0
  19. package/dist/modules/business_rules/components/utils/actionValidation.js.map +2 -2
  20. package/dist/modules/business_rules/lib/action-executor.js +148 -0
  21. package/dist/modules/business_rules/lib/action-executor.js.map +2 -2
  22. package/dist/modules/business_rules/lib/openmercato-call-options-types.js +5 -0
  23. package/dist/modules/business_rules/lib/openmercato-call-options-types.js.map +7 -0
  24. package/dist/modules/business_rules/lib/openmercato-call-options.js +231 -0
  25. package/dist/modules/business_rules/lib/openmercato-call-options.js.map +7 -0
  26. package/dist/modules/business_rules/lib/rule-engine.js +5 -1
  27. package/dist/modules/business_rules/lib/rule-engine.js.map +2 -2
  28. package/dist/modules/communication_channels/api/post/webhook/[provider]/route.js +11 -1
  29. package/dist/modules/communication_channels/api/post/webhook/[provider]/route.js.map +2 -2
  30. package/dist/modules/communication_channels/api/post/webhooks/gmail/route.js +11 -6
  31. package/dist/modules/communication_channels/api/post/webhooks/gmail/route.js.map +2 -2
  32. package/dist/modules/configs/lib/upgrade-actions.js +12 -0
  33. package/dist/modules/configs/lib/upgrade-actions.js.map +2 -2
  34. package/dist/modules/customer_accounts/api/admin/users/[id].js +10 -1
  35. package/dist/modules/customer_accounts/api/admin/users/[id].js.map +2 -2
  36. package/dist/modules/customer_accounts/api/admin/users-invite.js +61 -4
  37. package/dist/modules/customer_accounts/api/admin/users-invite.js.map +2 -2
  38. package/dist/modules/customer_accounts/api/portal/users-invite.js +20 -2
  39. package/dist/modules/customer_accounts/api/portal/users-invite.js.map +2 -2
  40. package/dist/modules/customer_accounts/data/entities.js +3 -0
  41. package/dist/modules/customer_accounts/data/entities.js.map +2 -2
  42. package/dist/modules/customer_accounts/data/validators.js +1 -0
  43. package/dist/modules/customer_accounts/data/validators.js.map +2 -2
  44. package/dist/modules/customer_accounts/emails/CustomerInvitationEmail.js +26 -0
  45. package/dist/modules/customer_accounts/emails/CustomerInvitationEmail.js.map +7 -0
  46. package/dist/modules/customer_accounts/lib/customerEntityOwnership.js +29 -3
  47. package/dist/modules/customer_accounts/lib/customerEntityOwnership.js.map +2 -2
  48. package/dist/modules/customer_accounts/lib/customerUrl.js +19 -10
  49. package/dist/modules/customer_accounts/lib/customerUrl.js.map +2 -2
  50. package/dist/modules/customer_accounts/lib/invitationEmail.js +35 -0
  51. package/dist/modules/customer_accounts/lib/invitationEmail.js.map +7 -0
  52. package/dist/modules/customer_accounts/migrations/Migration20260723120000_customer_accounts.js +13 -0
  53. package/dist/modules/customer_accounts/migrations/Migration20260723120000_customer_accounts.js.map +7 -0
  54. package/dist/modules/customer_accounts/services/customerInvitationService.js +32 -2
  55. package/dist/modules/customer_accounts/services/customerInvitationService.js.map +2 -2
  56. package/dist/modules/customer_accounts/subscribers/autoLinkCrm.js +47 -7
  57. package/dist/modules/customer_accounts/subscribers/autoLinkCrm.js.map +2 -2
  58. package/dist/modules/customer_accounts/widgets/injection/account-status/widget.client.js +2 -2
  59. package/dist/modules/customer_accounts/widgets/injection/account-status/widget.client.js.map +2 -2
  60. package/dist/modules/customer_accounts/widgets/injection-table.js +1 -1
  61. package/dist/modules/customer_accounts/widgets/injection-table.js.map +2 -2
  62. package/dist/modules/customers/api/deals/[id]/people/route.js +4 -2
  63. package/dist/modules/customers/api/deals/[id]/people/route.js.map +2 -2
  64. package/dist/modules/customers/api/deals/[id]/route.js +7 -3
  65. package/dist/modules/customers/api/deals/[id]/route.js.map +2 -2
  66. package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js +11 -1
  67. package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js.map +2 -2
  68. package/dist/modules/customers/backend/customers/deals/[id]/page.js +14 -8
  69. package/dist/modules/customers/backend/customers/deals/[id]/page.js.map +2 -2
  70. package/dist/modules/customers/backend/customers/people-v2/[id]/page.js +21 -6
  71. package/dist/modules/customers/backend/customers/people-v2/[id]/page.js.map +2 -2
  72. package/dist/modules/customers/cli.js +17 -7
  73. package/dist/modules/customers/cli.js.map +2 -2
  74. package/dist/modules/customers/commands/deals.js +48 -10
  75. package/dist/modules/customers/commands/deals.js.map +2 -2
  76. package/dist/modules/customers/commands/people.js +2 -0
  77. package/dist/modules/customers/commands/people.js.map +2 -2
  78. package/dist/modules/customers/components/detail/CompanyDetailTabs.js +26 -6
  79. package/dist/modules/customers/components/detail/CompanyDetailTabs.js.map +2 -2
  80. package/dist/modules/customers/components/detail/DealDetailTabs.js +30 -8
  81. package/dist/modules/customers/components/detail/DealDetailTabs.js.map +2 -2
  82. package/dist/modules/customers/components/detail/PersonDetailTabs.js +30 -8
  83. package/dist/modules/customers/components/detail/PersonDetailTabs.js.map +2 -2
  84. package/dist/modules/customers/data/entities.js +8 -0
  85. package/dist/modules/customers/data/entities.js.map +2 -2
  86. package/dist/modules/customers/data/validators.js +2 -1
  87. package/dist/modules/customers/data/validators.js.map +2 -2
  88. package/dist/modules/customers/migrations/Migration20260723210000_customers.js +15 -0
  89. package/dist/modules/customers/migrations/Migration20260723210000_customers.js.map +7 -0
  90. package/dist/modules/customers/search.js +50 -29
  91. package/dist/modules/customers/search.js.map +2 -2
  92. package/dist/modules/data_sync/api/mappings/[id]/route.js +22 -9
  93. package/dist/modules/data_sync/api/mappings/[id]/route.js.map +2 -2
  94. package/dist/modules/data_sync/api/mappings/route.js +13 -4
  95. package/dist/modules/data_sync/api/mappings/route.js.map +2 -2
  96. package/dist/modules/data_sync/api/options.js +7 -2
  97. package/dist/modules/data_sync/api/options.js.map +2 -2
  98. package/dist/modules/data_sync/api/run.js +7 -2
  99. package/dist/modules/data_sync/api/run.js.map +2 -2
  100. package/dist/modules/data_sync/api/runs/[id]/cancel.js +8 -3
  101. package/dist/modules/data_sync/api/runs/[id]/cancel.js.map +2 -2
  102. package/dist/modules/data_sync/api/runs/[id]/retry.js +7 -2
  103. package/dist/modules/data_sync/api/runs/[id]/retry.js.map +2 -2
  104. package/dist/modules/data_sync/api/runs/[id]/route.js +8 -3
  105. package/dist/modules/data_sync/api/runs/[id]/route.js.map +2 -2
  106. package/dist/modules/data_sync/api/runs.js +7 -2
  107. package/dist/modules/data_sync/api/runs.js.map +2 -2
  108. package/dist/modules/data_sync/api/schedules/[id]/route.js +19 -6
  109. package/dist/modules/data_sync/api/schedules/[id]/route.js.map +2 -2
  110. package/dist/modules/data_sync/api/schedules/route.js +13 -4
  111. package/dist/modules/data_sync/api/schedules/route.js.map +2 -2
  112. package/dist/modules/data_sync/api/validate.js +9 -4
  113. package/dist/modules/data_sync/api/validate.js.map +2 -2
  114. package/dist/modules/design_system/acl.js +9 -0
  115. package/dist/modules/design_system/acl.js.map +7 -0
  116. package/dist/modules/design_system/backend/design-system/page.js +11 -0
  117. package/dist/modules/design_system/backend/design-system/page.js.map +7 -0
  118. package/dist/modules/design_system/backend/design-system/page.meta.js +15 -0
  119. package/dist/modules/design_system/backend/design-system/page.meta.js.map +7 -0
  120. package/dist/modules/design_system/gallery/components/CodeSnippet.js +52 -0
  121. package/dist/modules/design_system/gallery/components/CodeSnippet.js.map +7 -0
  122. package/dist/modules/design_system/gallery/components/EntryCard.js +63 -0
  123. package/dist/modules/design_system/gallery/components/EntryCard.js.map +7 -0
  124. package/dist/modules/design_system/gallery/components/GalleryShell.js +163 -0
  125. package/dist/modules/design_system/gallery/components/GalleryShell.js.map +7 -0
  126. package/dist/modules/design_system/gallery/components/VariantPreview.js +9 -0
  127. package/dist/modules/design_system/gallery/components/VariantPreview.js.map +7 -0
  128. package/dist/modules/design_system/gallery/entries/banners.js +186 -0
  129. package/dist/modules/design_system/gallery/entries/banners.js.map +7 -0
  130. package/dist/modules/design_system/gallery/entries/buttons.js +361 -0
  131. package/dist/modules/design_system/gallery/entries/buttons.js.map +7 -0
  132. package/dist/modules/design_system/gallery/entries/charts.js +457 -0
  133. package/dist/modules/design_system/gallery/entries/charts.js.map +7 -0
  134. package/dist/modules/design_system/gallery/entries/dates.js +306 -0
  135. package/dist/modules/design_system/gallery/entries/dates.js.map +7 -0
  136. package/dist/modules/design_system/gallery/entries/detail.js +358 -0
  137. package/dist/modules/design_system/gallery/entries/detail.js.map +7 -0
  138. package/dist/modules/design_system/gallery/entries/display.js +785 -0
  139. package/dist/modules/design_system/gallery/entries/display.js.map +7 -0
  140. package/dist/modules/design_system/gallery/entries/feedback.js +658 -0
  141. package/dist/modules/design_system/gallery/entries/feedback.js.map +7 -0
  142. package/dist/modules/design_system/gallery/entries/filters.js +505 -0
  143. package/dist/modules/design_system/gallery/entries/filters.js.map +7 -0
  144. package/dist/modules/design_system/gallery/entries/foundations.js +453 -0
  145. package/dist/modules/design_system/gallery/entries/foundations.js.map +7 -0
  146. package/dist/modules/design_system/gallery/entries/icons.js +140 -0
  147. package/dist/modules/design_system/gallery/entries/icons.js.map +7 -0
  148. package/dist/modules/design_system/gallery/entries/inputs.js +1217 -0
  149. package/dist/modules/design_system/gallery/entries/inputs.js.map +7 -0
  150. package/dist/modules/design_system/gallery/entries/messages.js +334 -0
  151. package/dist/modules/design_system/gallery/entries/messages.js.map +7 -0
  152. package/dist/modules/design_system/gallery/entries/navigation.js +475 -0
  153. package/dist/modules/design_system/gallery/entries/navigation.js.map +7 -0
  154. package/dist/modules/design_system/gallery/entries/notifications.js +257 -0
  155. package/dist/modules/design_system/gallery/entries/notifications.js.map +7 -0
  156. package/dist/modules/design_system/gallery/entries/overlays.js +576 -0
  157. package/dist/modules/design_system/gallery/entries/overlays.js.map +7 -0
  158. package/dist/modules/design_system/gallery/entries/scaffolding.js +378 -0
  159. package/dist/modules/design_system/gallery/entries/scaffolding.js.map +7 -0
  160. package/dist/modules/design_system/gallery/entries/schedule.js +297 -0
  161. package/dist/modules/design_system/gallery/entries/schedule.js.map +7 -0
  162. package/dist/modules/design_system/gallery/registry.js +139 -0
  163. package/dist/modules/design_system/gallery/registry.js.map +7 -0
  164. package/dist/modules/design_system/gallery/types.js +1 -0
  165. package/dist/modules/design_system/gallery/types.js.map +7 -0
  166. package/dist/modules/design_system/index.js +9 -0
  167. package/dist/modules/design_system/index.js.map +7 -0
  168. package/dist/modules/design_system/setup.js +14 -0
  169. package/dist/modules/design_system/setup.js.map +7 -0
  170. package/dist/modules/entities/api/entity-settings.js +59 -9
  171. package/dist/modules/entities/api/entity-settings.js.map +2 -2
  172. package/dist/modules/entities/backend/config/settings/page.js +10 -0
  173. package/dist/modules/entities/backend/config/settings/page.js.map +7 -0
  174. package/dist/modules/entities/backend/config/settings/page.meta.js +36 -0
  175. package/dist/modules/entities/backend/config/settings/page.meta.js.map +7 -0
  176. package/dist/modules/entities/backend/entities/user/create/page.js +16 -7
  177. package/dist/modules/entities/backend/entities/user/create/page.js.map +2 -2
  178. package/dist/modules/entities/components/EntitySettingsManager.js +136 -0
  179. package/dist/modules/entities/components/EntitySettingsManager.js.map +7 -0
  180. package/dist/modules/inbox_ops/api/webhook/inbound.js +14 -10
  181. package/dist/modules/inbox_ops/api/webhook/inbound.js.map +2 -2
  182. package/dist/modules/inbox_ops/search.js +15 -4
  183. package/dist/modules/inbox_ops/search.js.map +2 -2
  184. package/dist/modules/integrations/api/[id]/credentials/route.js +11 -5
  185. package/dist/modules/integrations/api/[id]/credentials/route.js.map +2 -2
  186. package/dist/modules/integrations/api/[id]/health/route.js +6 -3
  187. package/dist/modules/integrations/api/[id]/health/route.js.map +2 -2
  188. package/dist/modules/integrations/api/[id]/route.js +6 -3
  189. package/dist/modules/integrations/api/[id]/route.js.map +2 -2
  190. package/dist/modules/integrations/api/[id]/state/route.js +6 -3
  191. package/dist/modules/integrations/api/[id]/state/route.js.map +2 -2
  192. package/dist/modules/integrations/api/[id]/version/route.js +6 -3
  193. package/dist/modules/integrations/api/[id]/version/route.js.map +2 -2
  194. package/dist/modules/integrations/api/logs/route.js +6 -3
  195. package/dist/modules/integrations/api/logs/route.js.map +2 -2
  196. package/dist/modules/integrations/api/route.js +6 -3
  197. package/dist/modules/integrations/api/route.js.map +2 -2
  198. package/dist/modules/integrations/api/umes-read.js +2 -2
  199. package/dist/modules/integrations/api/umes-read.js.map +2 -2
  200. package/dist/modules/integrations/lib/organization-scope.js +2 -9
  201. package/dist/modules/integrations/lib/organization-scope.js.map +2 -2
  202. package/dist/modules/messages/search.js +10 -5
  203. package/dist/modules/messages/search.js.map +2 -2
  204. package/dist/modules/payment_gateways/api/webhook/[provider]/route.js +11 -1
  205. package/dist/modules/payment_gateways/api/webhook/[provider]/route.js.map +2 -2
  206. package/dist/modules/payment_gateways/data/entities.js +4 -0
  207. package/dist/modules/payment_gateways/data/entities.js.map +2 -2
  208. package/dist/modules/payment_gateways/lib/gateway-service.js +12 -2
  209. package/dist/modules/payment_gateways/lib/gateway-service.js.map +2 -2
  210. package/dist/modules/payment_gateways/lib/session-idempotency.js +33 -0
  211. package/dist/modules/payment_gateways/lib/session-idempotency.js.map +2 -2
  212. package/dist/modules/payment_gateways/migrations/Migration20260803103035_payment_gateways.js +18 -0
  213. package/dist/modules/payment_gateways/migrations/Migration20260803103035_payment_gateways.js.map +7 -0
  214. package/dist/modules/payment_gateways/setup.js +47 -0
  215. package/dist/modules/payment_gateways/setup.js.map +2 -2
  216. package/dist/modules/payment_gateways/workers/session-initialization-prune.js +50 -0
  217. package/dist/modules/payment_gateways/workers/session-initialization-prune.js.map +7 -0
  218. package/dist/modules/portal/frontend/[orgSlug]/portal/invite/page.js +134 -0
  219. package/dist/modules/portal/frontend/[orgSlug]/portal/invite/page.js.map +7 -0
  220. package/dist/modules/portal/frontend/[orgSlug]/portal/invite/page.meta.js +11 -0
  221. package/dist/modules/portal/frontend/[orgSlug]/portal/invite/page.meta.js.map +7 -0
  222. package/dist/modules/portal/lib/navigation.js +7 -0
  223. package/dist/modules/portal/lib/navigation.js.map +7 -0
  224. package/dist/modules/query_index/data/entities.js +2 -1
  225. package/dist/modules/query_index/data/entities.js.map +2 -2
  226. package/dist/modules/query_index/lib/engine.js +75 -50
  227. package/dist/modules/query_index/lib/engine.js.map +2 -2
  228. package/dist/modules/query_index/lib/search-tokens.js +15 -5
  229. package/dist/modules/query_index/lib/search-tokens.js.map +2 -2
  230. package/dist/modules/query_index/migrations/Migration20260731105052_query_index.js +17 -0
  231. package/dist/modules/query_index/migrations/Migration20260731105052_query_index.js.map +7 -0
  232. package/dist/modules/shipping_carriers/api/webhook/[provider]/route.js +11 -1
  233. package/dist/modules/shipping_carriers/api/webhook/[provider]/route.js.map +2 -2
  234. package/generated/entities/customer_deal_person_link/index.ts +1 -0
  235. package/generated/entities/customer_user_invitation/index.ts +1 -0
  236. package/generated/entities.ids.generated.ts +1 -0
  237. package/generated/entity-fields-registry.ts +2 -0
  238. package/package.json +16 -16
  239. package/src/modules/business_rules/api/openmercato-call-options/route.ts +94 -0
  240. package/src/modules/business_rules/api/rules/route.ts +92 -4
  241. package/src/modules/business_rules/components/ActionBuilder.tsx +54 -5
  242. package/src/modules/business_rules/components/ActionRow.tsx +156 -18
  243. package/src/modules/business_rules/components/utils/actionValidation.ts +6 -0
  244. package/src/modules/business_rules/i18n/de.json +12 -0
  245. package/src/modules/business_rules/i18n/en.json +12 -0
  246. package/src/modules/business_rules/i18n/es.json +12 -0
  247. package/src/modules/business_rules/i18n/pl.json +12 -0
  248. package/src/modules/business_rules/lib/action-executor.ts +198 -0
  249. package/src/modules/business_rules/lib/openmercato-call-options-types.ts +31 -0
  250. package/src/modules/business_rules/lib/openmercato-call-options.ts +297 -0
  251. package/src/modules/business_rules/lib/rule-engine.ts +4 -0
  252. package/src/modules/communication_channels/api/post/webhook/[provider]/route.ts +11 -1
  253. package/src/modules/communication_channels/api/post/webhooks/gmail/route.ts +17 -11
  254. package/src/modules/configs/lib/upgrade-actions.ts +14 -0
  255. package/src/modules/customer_accounts/api/admin/users/[id].ts +16 -1
  256. package/src/modules/customer_accounts/api/admin/users-invite.ts +78 -3
  257. package/src/modules/customer_accounts/api/portal/users-invite.ts +22 -1
  258. package/src/modules/customer_accounts/data/entities.ts +3 -0
  259. package/src/modules/customer_accounts/data/validators.ts +1 -0
  260. package/src/modules/customer_accounts/emails/CustomerInvitationEmail.tsx +45 -0
  261. package/src/modules/customer_accounts/i18n/de.json +6 -0
  262. package/src/modules/customer_accounts/i18n/en.json +6 -0
  263. package/src/modules/customer_accounts/i18n/es.json +6 -0
  264. package/src/modules/customer_accounts/i18n/pl.json +6 -0
  265. package/src/modules/customer_accounts/lib/customerEntityOwnership.ts +68 -2
  266. package/src/modules/customer_accounts/lib/customerUrl.ts +27 -11
  267. package/src/modules/customer_accounts/lib/invitationEmail.ts +42 -0
  268. package/src/modules/customer_accounts/migrations/.snapshot-open-mercato.json +16 -0
  269. package/src/modules/customer_accounts/migrations/Migration20260723120000_customer_accounts.ts +13 -0
  270. package/src/modules/customer_accounts/services/customerInvitationService.ts +56 -3
  271. package/src/modules/customer_accounts/subscribers/autoLinkCrm.ts +75 -8
  272. package/src/modules/customer_accounts/widgets/injection/account-status/widget.client.tsx +2 -2
  273. package/src/modules/customer_accounts/widgets/injection-table.ts +4 -1
  274. package/src/modules/customers/api/deals/[id]/people/route.ts +3 -0
  275. package/src/modules/customers/api/deals/[id]/route.ts +10 -2
  276. package/src/modules/customers/backend/customers/companies-v2/[id]/page.tsx +12 -1
  277. package/src/modules/customers/backend/customers/deals/[id]/hooks/types.ts +1 -0
  278. package/src/modules/customers/backend/customers/deals/[id]/page.tsx +15 -9
  279. package/src/modules/customers/backend/customers/people-v2/[id]/page.tsx +24 -6
  280. package/src/modules/customers/cli.ts +17 -7
  281. package/src/modules/customers/commands/deals.ts +50 -9
  282. package/src/modules/customers/commands/people.ts +3 -0
  283. package/src/modules/customers/components/detail/CompanyDetailTabs.tsx +30 -7
  284. package/src/modules/customers/components/detail/DealDetailTabs.tsx +34 -9
  285. package/src/modules/customers/components/detail/PersonDetailTabs.tsx +34 -9
  286. package/src/modules/customers/data/entities.ts +9 -1
  287. package/src/modules/customers/data/validators.ts +1 -0
  288. package/src/modules/customers/i18n/de.json +18 -0
  289. package/src/modules/customers/i18n/en.json +18 -0
  290. package/src/modules/customers/i18n/es.json +18 -0
  291. package/src/modules/customers/i18n/pl.json +18 -0
  292. package/src/modules/customers/migrations/.snapshot-open-mercato.json +27 -1
  293. package/src/modules/customers/migrations/Migration20260723210000_customers.ts +15 -0
  294. package/src/modules/customers/search.ts +59 -27
  295. package/src/modules/data_sync/AGENTS.md +1 -0
  296. package/src/modules/data_sync/api/mappings/[id]/route.ts +22 -9
  297. package/src/modules/data_sync/api/mappings/route.ts +13 -4
  298. package/src/modules/data_sync/api/options.ts +7 -2
  299. package/src/modules/data_sync/api/run.ts +7 -2
  300. package/src/modules/data_sync/api/runs/[id]/cancel.ts +8 -3
  301. package/src/modules/data_sync/api/runs/[id]/retry.ts +7 -2
  302. package/src/modules/data_sync/api/runs/[id]/route.ts +8 -3
  303. package/src/modules/data_sync/api/runs.ts +7 -2
  304. package/src/modules/data_sync/api/schedules/[id]/route.ts +19 -6
  305. package/src/modules/data_sync/api/schedules/route.ts +13 -4
  306. package/src/modules/data_sync/api/validate.ts +9 -4
  307. package/src/modules/design_system/AGENTS.md +34 -0
  308. package/src/modules/design_system/acl.ts +5 -0
  309. package/src/modules/design_system/backend/design-system/page.meta.ts +11 -0
  310. package/src/modules/design_system/backend/design-system/page.tsx +14 -0
  311. package/src/modules/design_system/gallery/components/CodeSnippet.tsx +55 -0
  312. package/src/modules/design_system/gallery/components/EntryCard.tsx +95 -0
  313. package/src/modules/design_system/gallery/components/GalleryShell.tsx +206 -0
  314. package/src/modules/design_system/gallery/components/VariantPreview.tsx +15 -0
  315. package/src/modules/design_system/gallery/entries/banners.tsx +226 -0
  316. package/src/modules/design_system/gallery/entries/buttons.tsx +422 -0
  317. package/src/modules/design_system/gallery/entries/charts.tsx +518 -0
  318. package/src/modules/design_system/gallery/entries/dates.tsx +325 -0
  319. package/src/modules/design_system/gallery/entries/detail.tsx +403 -0
  320. package/src/modules/design_system/gallery/entries/display.tsx +893 -0
  321. package/src/modules/design_system/gallery/entries/feedback.tsx +746 -0
  322. package/src/modules/design_system/gallery/entries/filters.tsx +570 -0
  323. package/src/modules/design_system/gallery/entries/foundations.tsx +529 -0
  324. package/src/modules/design_system/gallery/entries/icons.tsx +168 -0
  325. package/src/modules/design_system/gallery/entries/inputs.tsx +1516 -0
  326. package/src/modules/design_system/gallery/entries/messages.tsx +339 -0
  327. package/src/modules/design_system/gallery/entries/navigation.tsx +573 -0
  328. package/src/modules/design_system/gallery/entries/notifications.tsx +285 -0
  329. package/src/modules/design_system/gallery/entries/overlays.tsx +677 -0
  330. package/src/modules/design_system/gallery/entries/scaffolding.tsx +430 -0
  331. package/src/modules/design_system/gallery/entries/schedule.tsx +307 -0
  332. package/src/modules/design_system/gallery/registry.ts +152 -0
  333. package/src/modules/design_system/gallery/types.ts +32 -0
  334. package/src/modules/design_system/i18n/.hardcoded-allowlist.json +71 -0
  335. package/src/modules/design_system/i18n/de.json +46 -0
  336. package/src/modules/design_system/i18n/en.json +46 -0
  337. package/src/modules/design_system/i18n/es.json +46 -0
  338. package/src/modules/design_system/i18n/pl.json +46 -0
  339. package/src/modules/design_system/index.ts +7 -0
  340. package/src/modules/design_system/setup.ts +12 -0
  341. package/src/modules/entities/api/entity-settings.ts +66 -22
  342. package/src/modules/entities/backend/config/settings/page.meta.ts +34 -0
  343. package/src/modules/entities/backend/config/settings/page.tsx +12 -0
  344. package/src/modules/entities/backend/entities/user/create/page.tsx +16 -7
  345. package/src/modules/entities/components/EntitySettingsManager.tsx +160 -0
  346. package/src/modules/entities/i18n/de.json +9 -0
  347. package/src/modules/entities/i18n/en.json +9 -0
  348. package/src/modules/entities/i18n/es.json +9 -0
  349. package/src/modules/entities/i18n/pl.json +9 -0
  350. package/src/modules/inbox_ops/api/webhook/inbound.ts +14 -12
  351. package/src/modules/inbox_ops/i18n/de.json +3 -0
  352. package/src/modules/inbox_ops/i18n/en.json +3 -0
  353. package/src/modules/inbox_ops/i18n/es.json +3 -0
  354. package/src/modules/inbox_ops/i18n/pl.json +3 -0
  355. package/src/modules/inbox_ops/search.ts +20 -4
  356. package/src/modules/integrations/api/[id]/credentials/route.ts +11 -5
  357. package/src/modules/integrations/api/[id]/health/route.ts +6 -3
  358. package/src/modules/integrations/api/[id]/route.ts +6 -3
  359. package/src/modules/integrations/api/[id]/state/route.ts +6 -3
  360. package/src/modules/integrations/api/[id]/version/route.ts +6 -3
  361. package/src/modules/integrations/api/logs/route.ts +6 -3
  362. package/src/modules/integrations/api/route.ts +6 -3
  363. package/src/modules/integrations/api/umes-read.ts +2 -2
  364. package/src/modules/integrations/lib/organization-scope.ts +5 -25
  365. package/src/modules/messages/i18n/de.json +2 -0
  366. package/src/modules/messages/i18n/en.json +2 -0
  367. package/src/modules/messages/i18n/es.json +2 -0
  368. package/src/modules/messages/i18n/pl.json +2 -0
  369. package/src/modules/messages/search.ts +11 -5
  370. package/src/modules/payment_gateways/api/webhook/[provider]/route.ts +13 -1
  371. package/src/modules/payment_gateways/data/entities.ts +5 -0
  372. package/src/modules/payment_gateways/i18n/de.json +5 -1
  373. package/src/modules/payment_gateways/i18n/en.json +5 -1
  374. package/src/modules/payment_gateways/i18n/es.json +5 -1
  375. package/src/modules/payment_gateways/i18n/pl.json +5 -1
  376. package/src/modules/payment_gateways/lib/gateway-service.ts +12 -2
  377. package/src/modules/payment_gateways/lib/session-idempotency.ts +36 -0
  378. package/src/modules/payment_gateways/migrations/.snapshot-open-mercato.json +10 -1
  379. package/src/modules/payment_gateways/migrations/Migration20260803103035_payment_gateways.ts +17 -0
  380. package/src/modules/payment_gateways/setup.ts +62 -0
  381. package/src/modules/payment_gateways/workers/session-initialization-prune.ts +63 -0
  382. package/src/modules/portal/frontend/[orgSlug]/portal/invite/page.meta.ts +9 -0
  383. package/src/modules/portal/frontend/[orgSlug]/portal/invite/page.tsx +164 -0
  384. package/src/modules/portal/i18n/de.json +18 -0
  385. package/src/modules/portal/i18n/en.json +18 -0
  386. package/src/modules/portal/i18n/es.json +18 -0
  387. package/src/modules/portal/i18n/pl.json +18 -0
  388. package/src/modules/portal/lib/navigation.ts +3 -0
  389. package/src/modules/query_index/data/entities.ts +7 -0
  390. package/src/modules/query_index/lib/engine.ts +92 -63
  391. package/src/modules/query_index/lib/search-tokens.ts +16 -4
  392. package/src/modules/query_index/migrations/.snapshot-open-mercato.json +12 -0
  393. package/src/modules/query_index/migrations/Migration20260731105052_query_index.ts +35 -0
  394. package/src/modules/shipping_carriers/api/webhook/[provider]/route.ts +11 -1
@@ -537,6 +537,15 @@
537
537
  "primary": true,
538
538
  "unique": true
539
539
  },
540
+ {
541
+ "columnNames": [],
542
+ "composite": false,
543
+ "constraint": false,
544
+ "keyName": "gateway_session_initializations_prune_idx",
545
+ "primary": false,
546
+ "unique": false,
547
+ "expression": "create index \"gateway_session_initializations_prune_idx\" on \"gateway_session_initializations\" (\"tenant_id\", \"organization_id\", \"updated_at\") where \"gateway_transaction_id\" is not null"
548
+ },
540
549
  {
541
550
  "columnNames": [
542
551
  "operation_key",
@@ -1162,4 +1171,4 @@
1162
1171
  ],
1163
1172
  "views": [],
1164
1173
  "nativeEnums": {}
1165
- }
1174
+ }
@@ -0,0 +1,17 @@
1
+ import { Migration } from '@mikro-orm/migrations'
2
+
3
+ export class Migration20260803103035_payment_gateways extends Migration {
4
+ override isTransactional(): boolean {
5
+ return false
6
+ }
7
+
8
+ override up(): void | Promise<void> {
9
+ this.addSql(
10
+ 'create index concurrently if not exists "gateway_session_initializations_prune_idx" on "gateway_session_initializations" ("tenant_id", "organization_id", "updated_at") where "gateway_transaction_id" is not null;',
11
+ )
12
+ }
13
+
14
+ override down(): void | Promise<void> {
15
+ this.addSql('drop index concurrently if exists "gateway_session_initializations_prune_idx";')
16
+ }
17
+ }
@@ -1,4 +1,62 @@
1
+ import { createHash } from 'node:crypto'
2
+ import { createLogger } from '@open-mercato/shared/lib/logger'
1
3
  import type { ModuleSetupConfig } from '@open-mercato/shared/modules/setup'
4
+ import { PAYMENT_SESSION_INITIALIZATION_PRUNE_QUEUE } from './lib/session-idempotency'
5
+
6
+ type SchedulerServiceLike = {
7
+ register: (registration: Record<string, unknown>) => Promise<void>
8
+ }
9
+
10
+ const logger = createLogger('payment_gateways')
11
+
12
+ function stableScheduleUuid(stableKey: string): string {
13
+ const hex = createHash('sha256').update(stableKey).digest('hex')
14
+ return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20, 32)}`
15
+ }
16
+
17
+ export async function registerSessionInitializationPruneSchedule(
18
+ container: import('awilix').AwilixContainer | undefined,
19
+ scope: { tenantId: string; organizationId: string },
20
+ ): Promise<boolean> {
21
+ if (!container) return false
22
+ const cradle = container as { hasRegistration?: (name: string) => boolean }
23
+ if (typeof cradle.hasRegistration !== 'function' || !cradle.hasRegistration('schedulerService')) {
24
+ return false
25
+ }
26
+
27
+ const schedulerService = container.resolve('schedulerService') as SchedulerServiceLike
28
+ await schedulerService.register({
29
+ id: stableScheduleUuid(
30
+ `payment_gateways:session-initialization-prune:${scope.tenantId}:${scope.organizationId}`,
31
+ ),
32
+ name: 'Payment-session initialization prune',
33
+ description: 'Delete completed payment-session initialization claims after the 24-hour replay window.',
34
+ scopeType: 'organization',
35
+ tenantId: scope.tenantId,
36
+ organizationId: scope.organizationId,
37
+ scheduleType: 'interval',
38
+ scheduleValue: '24h',
39
+ timezone: 'UTC',
40
+ targetType: 'queue',
41
+ targetQueue: PAYMENT_SESSION_INITIALIZATION_PRUNE_QUEUE,
42
+ targetPayload: scope,
43
+ sourceType: 'module',
44
+ sourceModule: 'payment_gateways',
45
+ isEnabled: true,
46
+ })
47
+ return true
48
+ }
49
+
50
+ async function ensureSessionInitializationPruneSchedule(
51
+ container: import('awilix').AwilixContainer | undefined,
52
+ scope: { tenantId: string; organizationId: string },
53
+ ): Promise<void> {
54
+ try {
55
+ await registerSessionInitializationPruneSchedule(container, scope)
56
+ } catch (error) {
57
+ logger.warn('Failed to register payment-session initialization prune schedule', { err: error })
58
+ }
59
+ }
2
60
 
3
61
  export const setup: ModuleSetupConfig = {
4
62
  defaultRoleFeatures: {
@@ -6,6 +64,10 @@ export const setup: ModuleSetupConfig = {
6
64
  admin: ['payment_gateways.*'],
7
65
  employee: ['payment_gateways.view'],
8
66
  },
67
+
68
+ async seedDefaults({ container, tenantId, organizationId }) {
69
+ await ensureSessionInitializationPruneSchedule(container, { tenantId, organizationId })
70
+ },
9
71
  }
10
72
 
11
73
  export default setup
@@ -0,0 +1,63 @@
1
+ import type { EntityManager } from '@mikro-orm/postgresql'
2
+ import { createModuleQueue, type JobContext, type Queue, type QueuedJob, type WorkerMeta } from '@open-mercato/queue'
3
+ import { createLogger } from '@open-mercato/shared/lib/logger'
4
+ import {
5
+ PAYMENT_SESSION_INITIALIZATION_PRUNE_QUEUE,
6
+ PAYMENT_SESSION_INITIALIZATION_PRUNE_BATCH_SIZE,
7
+ pruneCompletedPaymentSessionInitializations,
8
+ } from '../lib/session-idempotency'
9
+
10
+ type PrunePayload = {
11
+ tenantId?: string
12
+ organizationId?: string
13
+ }
14
+
15
+ type HandlerContext = JobContext & {
16
+ resolve: <T = unknown>(name: string) => T
17
+ }
18
+
19
+ const logger = createLogger('payment_gateways')
20
+ let continuationQueue: Queue<PrunePayload> | null = null
21
+
22
+ function getContinuationQueue(): Queue<PrunePayload> {
23
+ continuationQueue ??= createModuleQueue<PrunePayload>(
24
+ PAYMENT_SESSION_INITIALIZATION_PRUNE_QUEUE,
25
+ { concurrency: 1 },
26
+ )
27
+ return continuationQueue
28
+ }
29
+
30
+ export const metadata: WorkerMeta = {
31
+ queue: PAYMENT_SESSION_INITIALIZATION_PRUNE_QUEUE,
32
+ id: 'payment_gateways:session-initialization-prune',
33
+ concurrency: 1,
34
+ }
35
+
36
+ export default async function handle(
37
+ job: QueuedJob<PrunePayload>,
38
+ ctx: HandlerContext,
39
+ ): Promise<void> {
40
+ const tenantId = job.payload?.tenantId
41
+ const organizationId = job.payload?.organizationId
42
+ if (!tenantId || !organizationId) {
43
+ logger.warn('Skipping payment-session initialization prune without tenant scope')
44
+ return
45
+ }
46
+
47
+ const em = ctx.resolve<EntityManager>('em').fork()
48
+ const deleted = await pruneCompletedPaymentSessionInitializations(
49
+ em,
50
+ { tenantId, organizationId },
51
+ { batchSize: PAYMENT_SESSION_INITIALIZATION_PRUNE_BATCH_SIZE },
52
+ )
53
+ if (deleted > 0) {
54
+ logger.info('Pruned completed payment-session initialization claims', {
55
+ deleted,
56
+ tenantId,
57
+ organizationId,
58
+ })
59
+ }
60
+ if (deleted >= PAYMENT_SESSION_INITIALIZATION_PRUNE_BATCH_SIZE) {
61
+ await getContinuationQueue().enqueue({ tenantId, organizationId }, { delayMs: 1_000 })
62
+ }
63
+ }
@@ -0,0 +1,9 @@
1
+ import type { PageMetadata } from '@open-mercato/shared/modules/registry'
2
+
3
+ export const metadata: PageMetadata = {
4
+ titleKey: 'portal.nav.invite',
5
+ title: 'Accept Invitation',
6
+ navHidden: true,
7
+ }
8
+
9
+ export default metadata
@@ -0,0 +1,164 @@
1
+ "use client"
2
+ import { useCallback, useMemo, useState, useEffect } from 'react'
3
+ import { useSearchParams } from 'next/navigation'
4
+ import Link from 'next/link'
5
+ import { useT } from '@open-mercato/shared/lib/i18n/context'
6
+ import { PasswordInput } from '@open-mercato/ui/primitives/password-input'
7
+ import { Input } from '@open-mercato/ui/primitives/input'
8
+ import { Label } from '@open-mercato/ui/primitives/label'
9
+ import { Button } from '@open-mercato/ui/primitives/button'
10
+ import { Alert, AlertDescription } from '@open-mercato/ui/primitives/alert'
11
+ import { EmptyState } from '@open-mercato/ui/primitives/empty-state'
12
+ import { SearchX } from 'lucide-react'
13
+ import { Spinner } from '@open-mercato/ui/primitives/spinner'
14
+ import { apiCall } from '@open-mercato/ui/backend/utils/apiCall'
15
+ import { usePortalContext } from '@open-mercato/ui/portal/PortalContext'
16
+ import { InjectionSpot } from '@open-mercato/ui/backend/injection/InjectionSpot'
17
+ import { PortalInjectionSpots } from '@open-mercato/ui/backend/injection/spotIds'
18
+ import { navigateWithPageReload } from '@open-mercato/core/modules/portal/lib/navigation'
19
+
20
+ type Props = { params: { orgSlug: string } }
21
+
22
+ export default function PortalInvitePage({ params }: Props) {
23
+ const t = useT()
24
+ const orgSlug = params.orgSlug
25
+ const { tenant } = usePortalContext()
26
+ const searchParams = useSearchParams()
27
+
28
+ const [displayName, setDisplayName] = useState('')
29
+ const [password, setPassword] = useState('')
30
+ const [confirmPassword, setConfirmPassword] = useState('')
31
+ const [error, setError] = useState<string | null>(null)
32
+ const [submitting, setSubmitting] = useState(false)
33
+ const [token, setToken] = useState<string | null>(null)
34
+
35
+ useEffect(() => {
36
+ const tokenParam = searchParams.get('token')
37
+ if (!tokenParam) {
38
+ setError(t('portal.invite.error.noToken', 'Invalid or missing invitation token.'))
39
+ } else {
40
+ setToken(tokenParam)
41
+ }
42
+ }, [searchParams, t])
43
+
44
+ const handleSubmit = useCallback(
45
+ async (event: React.FormEvent) => {
46
+ event.preventDefault()
47
+ setError(null)
48
+
49
+ if (!token) {
50
+ setError(t('portal.invite.error.noToken', 'Invalid or missing invitation token.'))
51
+ return
52
+ }
53
+
54
+ if (!displayName.trim()) {
55
+ setError(t('portal.invite.error.displayNameRequired', 'Display name is required.'))
56
+ return
57
+ }
58
+
59
+ if (password !== confirmPassword) {
60
+ setError(t('portal.invite.error.passwordMismatch', 'Passwords do not match.'))
61
+ return
62
+ }
63
+
64
+ if (password.length < 8) {
65
+ setError(t('portal.invite.error.passwordTooShort', 'Password must be at least 8 characters long.'))
66
+ return
67
+ }
68
+
69
+ setSubmitting(true)
70
+ try {
71
+ const result = await apiCall<{ ok: boolean; error?: string }>('/api/customer_accounts/invitations/accept', {
72
+ method: 'POST',
73
+ headers: { 'Content-Type': 'application/json' },
74
+ body: JSON.stringify({ token, password, displayName: displayName.trim() }),
75
+ })
76
+
77
+ if (result.ok && result.result?.ok) {
78
+ navigateWithPageReload(`/${orgSlug}/portal/dashboard`)
79
+ return
80
+ }
81
+
82
+ if (result.status === 400) {
83
+ setError(t('portal.invite.error.invalidToken', 'Invalid or expired invitation.'))
84
+ } else {
85
+ setError(result.result?.error || t('portal.invite.error.generic', 'Invitation acceptance failed. Please try again.'))
86
+ }
87
+ } catch {
88
+ setError(t('portal.invite.error.generic', 'Invitation acceptance failed. Please try again.'))
89
+ } finally {
90
+ setSubmitting(false)
91
+ }
92
+ },
93
+ [token, password, confirmPassword, displayName, orgSlug, t],
94
+ )
95
+
96
+ const injectionContext = useMemo(
97
+ () => ({ orgSlug }),
98
+ [orgSlug],
99
+ )
100
+
101
+ if (tenant.loading) {
102
+ return <div className="flex items-center justify-center py-20"><Spinner /></div>
103
+ }
104
+
105
+ if (tenant.error) {
106
+ return (
107
+ <div className="mx-auto w-full max-w-md py-12">
108
+ <EmptyState
109
+ variant="subtle"
110
+ size="lg"
111
+ icon={<SearchX className="h-6 w-6" aria-hidden />}
112
+ title={t('portal.org.invalid', 'Organization not found.')}
113
+ />
114
+ </div>
115
+ )
116
+ }
117
+
118
+ return (
119
+ <div className="mx-auto w-full max-w-sm">
120
+ <div className="mb-8 text-center">
121
+ <h1 className="text-2xl font-bold tracking-tight">{t('portal.invite.title', 'Accept Invitation')}</h1>
122
+ <p className="mt-1.5 text-sm text-muted-foreground">{t('portal.invite.description', 'Create your portal account to accept this invitation.')}</p>
123
+ </div>
124
+
125
+ <InjectionSpot spotId={PortalInjectionSpots.pageBefore('invite')} context={injectionContext} />
126
+
127
+ <form onSubmit={handleSubmit} className="flex flex-col gap-4">
128
+ {error ? (
129
+ <Alert variant="destructive">
130
+ <AlertDescription>{error}</AlertDescription>
131
+ </Alert>
132
+ ) : null}
133
+
134
+ <div className="flex flex-col gap-1.5">
135
+ <Label htmlFor="invite-display-name" className="text-overline font-semibold uppercase tracking-wider text-muted-foreground/70">{t('portal.invite.displayName', 'Display Name')}</Label>
136
+ <Input id="invite-display-name" autoComplete="name" required value={displayName} onChange={(e) => setDisplayName(e.target.value)} disabled={submitting || !token} className="rounded-lg" />
137
+ </div>
138
+
139
+ <div className="flex flex-col gap-1.5">
140
+ <Label htmlFor="invite-password" className="text-overline font-semibold uppercase tracking-wider text-muted-foreground/70">{t('portal.invite.password', 'Password')}</Label>
141
+ <PasswordInput id="invite-password" autoComplete="new-password" required placeholder={t('portal.invite.password.placeholder', '••••••••')} value={password} onChange={(e) => setPassword(e.target.value)} disabled={submitting || !token} className="rounded-lg" />
142
+ </div>
143
+
144
+ <div className="flex flex-col gap-1.5">
145
+ <Label htmlFor="invite-confirm-password" className="text-overline font-semibold uppercase tracking-wider text-muted-foreground/70">{t('portal.invite.confirmPassword', 'Confirm Password')}</Label>
146
+ <PasswordInput id="invite-confirm-password" autoComplete="new-password" required placeholder={t('portal.invite.confirmPassword.placeholder', '••••••••')} value={confirmPassword} onChange={(e) => setConfirmPassword(e.target.value)} disabled={submitting || !token} className="rounded-lg" />
147
+ </div>
148
+
149
+ <Button type="submit" disabled={submitting || !token} className="mt-1 w-full rounded-lg">
150
+ {submitting ? t('portal.invite.submitting', 'Accepting invitation...') : t('portal.invite.submit', 'Accept Invitation')}
151
+ </Button>
152
+
153
+ <p className="text-center text-sm text-muted-foreground">
154
+ {t('portal.invite.backToLogin', 'Already have an account?')}{' '}
155
+ <Link href={`/${orgSlug}/portal/login`} className="font-medium text-foreground underline underline-offset-4 hover:opacity-80">
156
+ {t('portal.invite.loginLink', 'Sign in')}
157
+ </Link>
158
+ </p>
159
+ </form>
160
+
161
+ <InjectionSpot spotId={PortalInjectionSpots.pageAfter('invite')} context={injectionContext} />
162
+ </div>
163
+ )
164
+ }
@@ -22,6 +22,23 @@
22
22
  "portal.disabled.title": "Portal nicht verfügbar",
23
23
  "portal.footer.copyright": "© {year} Alle Rechte vorbehalten.",
24
24
  "portal.info.instructions": "Um auf das Portal Ihrer Organisation zuzugreifen, navigieren Sie zur eindeutigen URL Ihrer Organisation. Kontaktieren Sie Ihren Administrator, wenn Sie den Portal-Link nicht kennen.",
25
+ "portal.invite.backToLogin": "Already have an account?",
26
+ "portal.invite.confirmPassword": "Confirm Password",
27
+ "portal.invite.confirmPassword.placeholder": "••••••••",
28
+ "portal.invite.description": "Create your portal account to accept this invitation.",
29
+ "portal.invite.displayName": "Display Name",
30
+ "portal.invite.error.displayNameRequired": "Display name is required.",
31
+ "portal.invite.error.generic": "Invitation acceptance failed. Please try again.",
32
+ "portal.invite.error.invalidToken": "Invalid or expired invitation.",
33
+ "portal.invite.error.noToken": "Invalid or missing invitation token.",
34
+ "portal.invite.error.passwordMismatch": "Passwords do not match.",
35
+ "portal.invite.error.passwordTooShort": "Password must be at least 8 characters long.",
36
+ "portal.invite.loginLink": "Sign in",
37
+ "portal.invite.password": "Password",
38
+ "portal.invite.password.placeholder": "••••••••",
39
+ "portal.invite.submit": "Accept Invitation",
40
+ "portal.invite.submitting": "Accepting invitation…",
41
+ "portal.invite.title": "Accept Invitation",
25
42
  "portal.landing.cta.login": "Anmelden",
26
43
  "portal.landing.cta.signup": "Konto erstellen",
27
44
  "portal.landing.feature.account": "Account Management",
@@ -49,6 +66,7 @@
49
66
  "portal.nav.account": "Konto",
50
67
  "portal.nav.dashboard": "Dashboard",
51
68
  "portal.nav.home": "Portal",
69
+ "portal.nav.invite": "Accept Invitation",
52
70
  "portal.nav.login": "Anmelden",
53
71
  "portal.nav.logout": "Abmelden",
54
72
  "portal.nav.profile": "Profil",
@@ -22,6 +22,23 @@
22
22
  "portal.disabled.title": "Portal Not Available",
23
23
  "portal.footer.copyright": "© {year} All rights reserved.",
24
24
  "portal.info.instructions": "To access your organization's portal, navigate to your organization's unique URL. Contact your administrator if you don't know your portal link.",
25
+ "portal.invite.backToLogin": "Already have an account?",
26
+ "portal.invite.confirmPassword": "Confirm Password",
27
+ "portal.invite.confirmPassword.placeholder": "••••••••",
28
+ "portal.invite.description": "Create your portal account to accept this invitation.",
29
+ "portal.invite.displayName": "Display Name",
30
+ "portal.invite.error.displayNameRequired": "Display name is required.",
31
+ "portal.invite.error.generic": "Invitation acceptance failed. Please try again.",
32
+ "portal.invite.error.invalidToken": "Invalid or expired invitation.",
33
+ "portal.invite.error.noToken": "Invalid or missing invitation token.",
34
+ "portal.invite.error.passwordMismatch": "Passwords do not match.",
35
+ "portal.invite.error.passwordTooShort": "Password must be at least 8 characters long.",
36
+ "portal.invite.loginLink": "Sign in",
37
+ "portal.invite.password": "Password",
38
+ "portal.invite.password.placeholder": "••••••••",
39
+ "portal.invite.submit": "Accept Invitation",
40
+ "portal.invite.submitting": "Accepting invitation…",
41
+ "portal.invite.title": "Accept Invitation",
25
42
  "portal.landing.cta.login": "Log In",
26
43
  "portal.landing.cta.signup": "Create Account",
27
44
  "portal.landing.feature.account": "Account Management",
@@ -49,6 +66,7 @@
49
66
  "portal.nav.account": "Account",
50
67
  "portal.nav.dashboard": "Dashboard",
51
68
  "portal.nav.home": "Portal",
69
+ "portal.nav.invite": "Accept Invitation",
52
70
  "portal.nav.login": "Log In",
53
71
  "portal.nav.logout": "Log Out",
54
72
  "portal.nav.profile": "Profile",
@@ -22,6 +22,23 @@
22
22
  "portal.disabled.title": "Portal no disponible",
23
23
  "portal.footer.copyright": "© {year} Todos los derechos reservados.",
24
24
  "portal.info.instructions": "Para acceder al portal de su organización, navegue a la URL única de su organización. Contacte a su administrador si no conoce el enlace del portal.",
25
+ "portal.invite.backToLogin": "Already have an account?",
26
+ "portal.invite.confirmPassword": "Confirm Password",
27
+ "portal.invite.confirmPassword.placeholder": "••••••••",
28
+ "portal.invite.description": "Create your portal account to accept this invitation.",
29
+ "portal.invite.displayName": "Display Name",
30
+ "portal.invite.error.displayNameRequired": "Display name is required.",
31
+ "portal.invite.error.generic": "Invitation acceptance failed. Please try again.",
32
+ "portal.invite.error.invalidToken": "Invalid or expired invitation.",
33
+ "portal.invite.error.noToken": "Invalid or missing invitation token.",
34
+ "portal.invite.error.passwordMismatch": "Passwords do not match.",
35
+ "portal.invite.error.passwordTooShort": "Password must be at least 8 characters long.",
36
+ "portal.invite.loginLink": "Sign in",
37
+ "portal.invite.password": "Password",
38
+ "portal.invite.password.placeholder": "••••••••",
39
+ "portal.invite.submit": "Accept Invitation",
40
+ "portal.invite.submitting": "Accepting invitation…",
41
+ "portal.invite.title": "Accept Invitation",
25
42
  "portal.landing.cta.login": "Iniciar sesión",
26
43
  "portal.landing.cta.signup": "Crear cuenta",
27
44
  "portal.landing.feature.account": "Account Management",
@@ -49,6 +66,7 @@
49
66
  "portal.nav.account": "Cuenta",
50
67
  "portal.nav.dashboard": "Panel",
51
68
  "portal.nav.home": "Portal",
69
+ "portal.nav.invite": "Accept Invitation",
52
70
  "portal.nav.login": "Iniciar sesión",
53
71
  "portal.nav.logout": "Cerrar sesión",
54
72
  "portal.nav.profile": "Perfil",
@@ -22,6 +22,23 @@
22
22
  "portal.disabled.title": "Portal niedostępny",
23
23
  "portal.footer.copyright": "© {year} Wszelkie prawa zastrzeżone.",
24
24
  "portal.info.instructions": "Aby uzyskać dostęp do portalu organizacji, przejdź do unikalnego adresu URL swojej organizacji. Skontaktuj się z administratorem, jeśli nie znasz linku do portalu.",
25
+ "portal.invite.backToLogin": "Masz już konto?",
26
+ "portal.invite.confirmPassword": "Potwierdź hasło",
27
+ "portal.invite.confirmPassword.placeholder": "••••••••",
28
+ "portal.invite.description": "Utwórz konto w portalu, aby przyjąć to zaproszenie.",
29
+ "portal.invite.displayName": "Nazwa wyświetlana",
30
+ "portal.invite.error.displayNameRequired": "Nazwa wyświetlana jest wymagana.",
31
+ "portal.invite.error.generic": "Nie udało się przyjąć zaproszenia. Spróbuj ponownie.",
32
+ "portal.invite.error.invalidToken": "Nieprawidłowe lub wygasłe zaproszenie.",
33
+ "portal.invite.error.noToken": "Nieprawidłowy lub brakujący token zaproszenia.",
34
+ "portal.invite.error.passwordMismatch": "Hasła nie pasują do siebie.",
35
+ "portal.invite.error.passwordTooShort": "Hasło musi mieć co najmniej 8 znaków.",
36
+ "portal.invite.loginLink": "Zaloguj się",
37
+ "portal.invite.password": "Hasło",
38
+ "portal.invite.password.placeholder": "••••••••",
39
+ "portal.invite.submit": "Przyjmij zaproszenie",
40
+ "portal.invite.submitting": "Przyjmowanie zaproszenia…",
41
+ "portal.invite.title": "Przyjmij zaproszenie",
25
42
  "portal.landing.cta.login": "Zaloguj się",
26
43
  "portal.landing.cta.signup": "Utwórz konto",
27
44
  "portal.landing.feature.account": "Account Management",
@@ -49,6 +66,7 @@
49
66
  "portal.nav.account": "Konto",
50
67
  "portal.nav.dashboard": "Panel",
51
68
  "portal.nav.home": "Portal",
69
+ "portal.nav.invite": "Przyjmij zaproszenie",
52
70
  "portal.nav.login": "Zaloguj się",
53
71
  "portal.nav.logout": "Wyloguj się",
54
72
  "portal.nav.profile": "Profil",
@@ -0,0 +1,3 @@
1
+ export function navigateWithPageReload(path: string): void {
2
+ window.location.assign(path)
3
+ }
@@ -255,6 +255,13 @@ export class IndexerStatusLog {
255
255
  @Index({ name: 'search_tokens_lookup_idx', properties: ['entityType', 'field', 'tokenHash', 'tenantId', 'organizationId'] })
256
256
  @Index({ name: 'search_tokens_entity_idx', properties: ['entityType', 'entityId'] })
257
257
  @Index({ name: 'search_tokens_tenant_token_hash_idx', properties: ['tenantId', 'tokenHash'] })
258
+ // Serves the availability probe ("does this scope have any tokens?") as a pure
259
+ // B-tree prefix seek, making the MISS as cheap as the hit — neither existing
260
+ // index can (lookup_idx buries tenant_id behind field/token_hash), which is how
261
+ // the probe degraded to a seq scan on large tables (#4723). Requires the
262
+ // index-usable `= / IS NULL` predicates the availability resolver emits; see
263
+ // .ai/specs/2026-07-31-search-token-probe-index.md.
264
+ @Index({ name: 'search_tokens_presence_idx', properties: ['entityType', 'tenantId', 'organizationId'] })
258
265
  export class SearchToken {
259
266
  @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })
260
267
  id!: string