@open-mercato/core 0.6.6-develop.6551.1.1511bfa890 → 0.6.6

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 (304) hide show
  1. package/.turbo/turbo-build.log +2 -2
  2. package/dist/generated/entities.ids.generated.js +0 -1
  3. package/dist/generated/entities.ids.generated.js.map +2 -2
  4. package/dist/generated/entity-fields-registry.js +0 -12
  5. package/dist/generated/entity-fields-registry.js.map +2 -2
  6. package/dist/modules/api_keys/api/keys/route.js +13 -30
  7. package/dist/modules/api_keys/api/keys/route.js.map +2 -2
  8. package/dist/modules/api_keys/cli.js +1 -2
  9. package/dist/modules/api_keys/cli.js.map +2 -2
  10. package/dist/modules/attachments/api/file/[id]/route.js +7 -9
  11. package/dist/modules/attachments/api/file/[id]/route.js.map +2 -2
  12. package/dist/modules/attachments/api/image/[id]/[[...slug]]/route.js +7 -9
  13. package/dist/modules/attachments/api/image/[id]/[[...slug]]/route.js.map +2 -2
  14. package/dist/modules/attachments/api/route.js +17 -21
  15. package/dist/modules/attachments/api/route.js.map +2 -2
  16. package/dist/modules/attachments/components/AttachmentContentPreview.js +35 -6
  17. package/dist/modules/attachments/components/AttachmentContentPreview.js.map +2 -2
  18. package/dist/modules/audit_logs/backend/audit-logs/page.js +24 -14
  19. package/dist/modules/audit_logs/backend/audit-logs/page.js.map +2 -2
  20. package/dist/modules/auth/api/users/route.js +2 -6
  21. package/dist/modules/auth/api/users/route.js.map +2 -2
  22. package/dist/modules/auth/cli.js +2 -3
  23. package/dist/modules/auth/cli.js.map +2 -2
  24. package/dist/modules/configs/lib/upgrade-actions.js +0 -22
  25. package/dist/modules/configs/lib/upgrade-actions.js.map +2 -2
  26. package/dist/modules/customer_accounts/api/admin/roles/[id]/acl.js +0 -1
  27. package/dist/modules/customer_accounts/api/admin/roles/[id]/acl.js.map +2 -2
  28. package/dist/modules/customer_accounts/api/admin/roles/[id].js +3 -17
  29. package/dist/modules/customer_accounts/api/admin/roles/[id].js.map +2 -2
  30. package/dist/modules/customer_accounts/api/portal/users/[id]/roles.js +1 -6
  31. package/dist/modules/customer_accounts/api/portal/users/[id]/roles.js.map +2 -2
  32. package/dist/modules/customer_accounts/api/portal/users-invite.js +1 -6
  33. package/dist/modules/customer_accounts/api/portal/users-invite.js.map +2 -2
  34. package/dist/modules/customer_accounts/services/customerInvitationService.js +0 -1
  35. package/dist/modules/customer_accounts/services/customerInvitationService.js.map +2 -2
  36. package/dist/modules/customer_accounts/services/customerRbacService.js +1 -6
  37. package/dist/modules/customer_accounts/services/customerRbacService.js.map +2 -2
  38. package/dist/modules/customer_accounts/widgets/injection-table.js +2 -0
  39. package/dist/modules/customer_accounts/widgets/injection-table.js.map +2 -2
  40. package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js +1 -7
  41. package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js.map +2 -2
  42. package/dist/modules/customers/backend/customers/deals/pipeline/components/ViewTabsRow.js +2 -2
  43. package/dist/modules/customers/backend/customers/deals/pipeline/components/ViewTabsRow.js.map +2 -2
  44. package/dist/modules/customers/components/detail/CompanyDetailTabs.js +43 -37
  45. package/dist/modules/customers/components/detail/CompanyDetailTabs.js.map +2 -2
  46. package/dist/modules/customers/components/detail/DealDetailTabs.js +35 -23
  47. package/dist/modules/customers/components/detail/DealDetailTabs.js.map +2 -2
  48. package/dist/modules/customers/components/detail/DetailTabsLayout.js +21 -6
  49. package/dist/modules/customers/components/detail/DetailTabsLayout.js.map +2 -2
  50. package/dist/modules/customers/components/detail/MobilePersonDetail.js +32 -26
  51. package/dist/modules/customers/components/detail/MobilePersonDetail.js.map +2 -2
  52. package/dist/modules/customers/components/detail/PersonDetailTabs.js +39 -29
  53. package/dist/modules/customers/components/detail/PersonDetailTabs.js.map +2 -2
  54. package/dist/modules/dashboards/api/roles/widgets/route.js +3 -22
  55. package/dist/modules/dashboards/api/roles/widgets/route.js.map +2 -2
  56. package/dist/modules/dashboards/api/users/widgets/route.js +3 -22
  57. package/dist/modules/dashboards/api/users/widgets/route.js.map +2 -2
  58. package/dist/modules/dashboards/cli.js +3 -4
  59. package/dist/modules/dashboards/cli.js.map +2 -2
  60. package/dist/modules/dashboards/lib/widgetAssignmentScope.js +1 -9
  61. package/dist/modules/dashboards/lib/widgetAssignmentScope.js.map +2 -2
  62. package/dist/modules/dictionaries/commands/entries.js +14 -7
  63. package/dist/modules/dictionaries/commands/entries.js.map +2 -2
  64. package/dist/modules/dictionaries/commands/entry-operations.js +16 -7
  65. package/dist/modules/dictionaries/commands/entry-operations.js.map +2 -2
  66. package/dist/modules/dictionaries/commands/factory.js +3 -9
  67. package/dist/modules/dictionaries/commands/factory.js.map +2 -2
  68. package/dist/modules/dictionaries/fields/dictionary.js +41 -56
  69. package/dist/modules/dictionaries/fields/dictionary.js.map +2 -2
  70. package/dist/modules/directory/utils/organizationScope.js +3 -10
  71. package/dist/modules/directory/utils/organizationScope.js.map +2 -2
  72. package/dist/modules/entities/api/records.js +4 -5
  73. package/dist/modules/entities/api/records.js.map +2 -2
  74. package/dist/modules/entities/backend/entities/system/[entityId]/page.meta.js +0 -1
  75. package/dist/modules/entities/backend/entities/system/[entityId]/page.meta.js.map +2 -2
  76. package/dist/modules/entities/backend/entities/user/[entityId]/page.js +49 -49
  77. package/dist/modules/entities/backend/entities/user/[entityId]/page.js.map +2 -2
  78. package/dist/modules/entities/backend/entities/user/[entityId]/page.meta.js +0 -1
  79. package/dist/modules/entities/backend/entities/user/[entityId]/page.meta.js.map +2 -2
  80. package/dist/modules/entities/cli.js +1 -2
  81. package/dist/modules/entities/cli.js.map +2 -2
  82. package/dist/modules/feature_toggles/api/check/boolean/route.js +14 -0
  83. package/dist/modules/feature_toggles/api/check/boolean/route.js.map +2 -2
  84. package/dist/modules/feature_toggles/defaults.json +0 -8
  85. package/dist/modules/integrations/backend/integrations/[id]/page.js +80 -9
  86. package/dist/modules/integrations/backend/integrations/[id]/page.js.map +2 -2
  87. package/dist/modules/payment_gateways/data/entities.js +0 -45
  88. package/dist/modules/payment_gateways/data/entities.js.map +2 -2
  89. package/dist/modules/payment_gateways/lib/gateway-service.js +38 -173
  90. package/dist/modules/payment_gateways/lib/gateway-service.js.map +3 -3
  91. package/dist/modules/planner/backend/planner/availability-rulesets/[id]/page.js +14 -16
  92. package/dist/modules/planner/backend/planner/availability-rulesets/[id]/page.js.map +2 -2
  93. package/dist/modules/planner/components/AvailabilityRulesEditor.js +30 -18
  94. package/dist/modules/planner/components/AvailabilityRulesEditor.js.map +2 -2
  95. package/dist/modules/query_index/api/status.js +8 -2
  96. package/dist/modules/query_index/api/status.js.map +2 -2
  97. package/dist/modules/resources/backend/resources/resources/[id]/page.js +24 -24
  98. package/dist/modules/resources/backend/resources/resources/[id]/page.js.map +2 -2
  99. package/dist/modules/sales/backend/sales/channels/create/page.js +0 -6
  100. package/dist/modules/sales/backend/sales/channels/create/page.js.map +2 -2
  101. package/dist/modules/sales/backend/sales/channels/create/page.meta.js +0 -2
  102. package/dist/modules/sales/backend/sales/channels/create/page.meta.js.map +2 -2
  103. package/dist/modules/sales/backend/sales/channels/offers/page.js +0 -6
  104. package/dist/modules/sales/backend/sales/channels/offers/page.js.map +2 -2
  105. package/dist/modules/sales/backend/sales/channels/offers/page.meta.js +0 -2
  106. package/dist/modules/sales/backend/sales/channels/offers/page.meta.js.map +2 -2
  107. package/dist/modules/sales/backend/sales/channels/page.js +0 -6
  108. package/dist/modules/sales/backend/sales/channels/page.js.map +2 -2
  109. package/dist/modules/sales/backend/sales/channels/page.meta.js +0 -2
  110. package/dist/modules/sales/backend/sales/channels/page.meta.js.map +2 -2
  111. package/dist/modules/sales/backend/sales/documents/[id]/page.js +4 -6
  112. package/dist/modules/sales/backend/sales/documents/[id]/page.js.map +2 -2
  113. package/dist/modules/sales/commands/documents.js +0 -44
  114. package/dist/modules/sales/commands/documents.js.map +2 -2
  115. package/dist/modules/sales/commands/returns.js +27 -2
  116. package/dist/modules/sales/commands/returns.js.map +2 -2
  117. package/dist/modules/sales/components/documents/AddressesSection.js +2 -6
  118. package/dist/modules/sales/components/documents/AddressesSection.js.map +2 -2
  119. package/dist/modules/sales/components/documents/ItemsSection.js +0 -1
  120. package/dist/modules/sales/components/documents/ItemsSection.js.map +2 -2
  121. package/dist/modules/sales/components/documents/LineItemDialog.js +0 -9
  122. package/dist/modules/sales/components/documents/LineItemDialog.js.map +2 -2
  123. package/dist/modules/sales/components/documents/SalesDocumentForm.js +3 -51
  124. package/dist/modules/sales/components/documents/SalesDocumentForm.js.map +2 -2
  125. package/dist/modules/sales/components/documents/SalesDocumentsTable.js +8 -10
  126. package/dist/modules/sales/components/documents/SalesDocumentsTable.js.map +2 -2
  127. package/dist/modules/sales/components/documents/ShipmentDialog.js +38 -59
  128. package/dist/modules/sales/components/documents/ShipmentDialog.js.map +2 -2
  129. package/dist/modules/sales/lib/shipments/snapshots.js +1 -27
  130. package/dist/modules/sales/lib/shipments/snapshots.js.map +2 -2
  131. package/dist/modules/staff/backend/staff/team-members/[id]/page.js +25 -22
  132. package/dist/modules/staff/backend/staff/team-members/[id]/page.js.map +2 -2
  133. package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js +14 -12
  134. package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js.map +2 -2
  135. package/dist/modules/staff/lib/timesheets-projects-ui/SavedViewTabs.js +29 -10
  136. package/dist/modules/staff/lib/timesheets-projects-ui/SavedViewTabs.js.map +2 -2
  137. package/dist/modules/sync_excel/lib/adapters/customers.js +20 -19
  138. package/dist/modules/sync_excel/lib/adapters/customers.js.map +2 -2
  139. package/dist/modules/sync_excel/lib/parser.js +0 -185
  140. package/dist/modules/sync_excel/lib/parser.js.map +2 -2
  141. package/dist/modules/sync_excel/lib/upload-storage.js +1 -20
  142. package/dist/modules/sync_excel/lib/upload-storage.js.map +2 -2
  143. package/dist/modules/workflows/frontend/checkout-demo/page.js +8 -1
  144. package/dist/modules/workflows/frontend/checkout-demo/page.js.map +2 -2
  145. package/dist/modules/workflows/lib/activity-executor.js +1 -1
  146. package/dist/modules/workflows/lib/activity-executor.js.map +2 -2
  147. package/dist/modules/workflows/lib/find-definition.js +18 -2
  148. package/dist/modules/workflows/lib/find-definition.js.map +2 -2
  149. package/dist/modules/workflows/lib/signal-handler.js +3 -2
  150. package/dist/modules/workflows/lib/signal-handler.js.map +2 -2
  151. package/dist/modules/workflows/lib/step-handler.js +4 -8
  152. package/dist/modules/workflows/lib/step-handler.js.map +2 -2
  153. package/dist/modules/workflows/lib/task-handler.js +3 -5
  154. package/dist/modules/workflows/lib/task-handler.js.map +2 -2
  155. package/dist/modules/workflows/lib/timer-handler.js +2 -1
  156. package/dist/modules/workflows/lib/timer-handler.js.map +2 -2
  157. package/dist/modules/workflows/lib/transition-handler.js +5 -13
  158. package/dist/modules/workflows/lib/transition-handler.js.map +2 -2
  159. package/dist/modules/workflows/lib/workflow-executor.js +11 -9
  160. package/dist/modules/workflows/lib/workflow-executor.js.map +2 -2
  161. package/dist/modules/workflows/migrations/Migration20260715120000.js +68 -0
  162. package/dist/modules/workflows/migrations/Migration20260715120000.js.map +7 -0
  163. package/dist/modules/workflows/migrations/Migration20260716120000.js +24 -0
  164. package/dist/modules/workflows/migrations/Migration20260716120000.js.map +7 -0
  165. package/dist/modules/workflows/workflows.js +2 -0
  166. package/dist/modules/workflows/workflows.js.map +2 -2
  167. package/generated/entities.ids.generated.ts +0 -1
  168. package/generated/entity-fields-registry.ts +0 -12
  169. package/package.json +8 -9
  170. package/src/modules/api_keys/api/keys/route.ts +13 -36
  171. package/src/modules/api_keys/cli.ts +3 -2
  172. package/src/modules/attachments/api/file/[id]/route.ts +7 -11
  173. package/src/modules/attachments/api/image/[id]/[[...slug]]/route.ts +7 -11
  174. package/src/modules/attachments/api/route.ts +21 -26
  175. package/src/modules/attachments/components/AttachmentContentPreview.tsx +44 -9
  176. package/src/modules/audit_logs/backend/audit-logs/page.tsx +22 -12
  177. package/src/modules/auth/api/users/route.ts +2 -11
  178. package/src/modules/auth/cli.ts +2 -3
  179. package/src/modules/configs/i18n/de.json +1 -5
  180. package/src/modules/configs/i18n/en.json +1 -5
  181. package/src/modules/configs/i18n/es.json +1 -5
  182. package/src/modules/configs/i18n/pl.json +1 -5
  183. package/src/modules/configs/lib/upgrade-actions.ts +0 -24
  184. package/src/modules/customer_accounts/AGENTS.md +6 -8
  185. package/src/modules/customer_accounts/api/admin/roles/[id]/acl.ts +0 -1
  186. package/src/modules/customer_accounts/api/admin/roles/[id].ts +3 -17
  187. package/src/modules/customer_accounts/api/portal/users/[id]/roles.ts +1 -6
  188. package/src/modules/customer_accounts/api/portal/users-invite.ts +1 -6
  189. package/src/modules/customer_accounts/services/customerInvitationService.ts +0 -1
  190. package/src/modules/customer_accounts/services/customerRbacService.ts +2 -9
  191. package/src/modules/customer_accounts/widgets/injection-table.ts +2 -0
  192. package/src/modules/customers/backend/customers/companies-v2/[id]/page.tsx +1 -11
  193. package/src/modules/customers/backend/customers/deals/pipeline/components/ViewTabsRow.tsx +2 -6
  194. package/src/modules/customers/components/detail/CompanyDetailTabs.tsx +55 -39
  195. package/src/modules/customers/components/detail/DealDetailTabs.tsx +49 -24
  196. package/src/modules/customers/components/detail/DetailTabsLayout.tsx +24 -13
  197. package/src/modules/customers/components/detail/MobilePersonDetail.tsx +31 -25
  198. package/src/modules/customers/components/detail/PersonDetailTabs.tsx +50 -29
  199. package/src/modules/dashboards/api/roles/widgets/route.ts +3 -22
  200. package/src/modules/dashboards/api/users/widgets/route.ts +3 -22
  201. package/src/modules/dashboards/cli.ts +9 -4
  202. package/src/modules/dashboards/lib/widgetAssignmentScope.ts +0 -18
  203. package/src/modules/dictionaries/commands/entries.ts +16 -7
  204. package/src/modules/dictionaries/commands/entry-operations.ts +18 -8
  205. package/src/modules/dictionaries/commands/factory.ts +2 -8
  206. package/src/modules/dictionaries/fields/dictionary.tsx +32 -55
  207. package/src/modules/dictionaries/i18n/de.json +0 -2
  208. package/src/modules/dictionaries/i18n/en.json +0 -2
  209. package/src/modules/dictionaries/i18n/es.json +0 -2
  210. package/src/modules/dictionaries/i18n/pl.json +0 -2
  211. package/src/modules/directory/utils/organizationScope.ts +2 -36
  212. package/src/modules/entities/api/records.ts +7 -5
  213. package/src/modules/entities/backend/entities/system/[entityId]/page.meta.ts +0 -1
  214. package/src/modules/entities/backend/entities/user/[entityId]/page.meta.ts +0 -1
  215. package/src/modules/entities/backend/entities/user/[entityId]/page.tsx +49 -51
  216. package/src/modules/entities/cli.ts +1 -2
  217. package/src/modules/entities/i18n/de.json +0 -34
  218. package/src/modules/entities/i18n/en.json +0 -34
  219. package/src/modules/entities/i18n/es.json +0 -34
  220. package/src/modules/entities/i18n/pl.json +0 -34
  221. package/src/modules/feature_toggles/api/check/boolean/route.ts +15 -0
  222. package/src/modules/feature_toggles/defaults.json +0 -8
  223. package/src/modules/integrations/backend/integrations/[id]/page.tsx +59 -16
  224. package/src/modules/payment_gateways/data/entities.ts +0 -39
  225. package/src/modules/payment_gateways/lib/gateway-service.ts +40 -211
  226. package/src/modules/payment_gateways/migrations/.snapshot-open-mercato.json +0 -236
  227. package/src/modules/planner/backend/planner/availability-rulesets/[id]/page.tsx +20 -14
  228. package/src/modules/planner/components/AvailabilityRulesEditor.tsx +34 -16
  229. package/src/modules/query_index/api/status.ts +8 -2
  230. package/src/modules/resources/backend/resources/resources/[id]/page.tsx +37 -27
  231. package/src/modules/sales/backend/sales/channels/create/page.meta.ts +0 -3
  232. package/src/modules/sales/backend/sales/channels/create/page.tsx +0 -7
  233. package/src/modules/sales/backend/sales/channels/offers/page.meta.ts +0 -3
  234. package/src/modules/sales/backend/sales/channels/offers/page.tsx +0 -7
  235. package/src/modules/sales/backend/sales/channels/page.meta.ts +0 -4
  236. package/src/modules/sales/backend/sales/channels/page.tsx +0 -7
  237. package/src/modules/sales/backend/sales/documents/[id]/page.tsx +5 -7
  238. package/src/modules/sales/commands/documents.ts +0 -65
  239. package/src/modules/sales/commands/returns.ts +32 -2
  240. package/src/modules/sales/components/documents/AddressesSection.tsx +2 -6
  241. package/src/modules/sales/components/documents/ItemsSection.tsx +0 -5
  242. package/src/modules/sales/components/documents/LineItemDialog.tsx +0 -10
  243. package/src/modules/sales/components/documents/SalesDocumentForm.tsx +3 -53
  244. package/src/modules/sales/components/documents/SalesDocumentsTable.tsx +8 -10
  245. package/src/modules/sales/components/documents/ShipmentDialog.tsx +40 -65
  246. package/src/modules/sales/i18n/de.json +0 -5
  247. package/src/modules/sales/i18n/en.json +0 -5
  248. package/src/modules/sales/i18n/es.json +0 -5
  249. package/src/modules/sales/i18n/pl.json +0 -5
  250. package/src/modules/sales/lib/shipments/snapshots.ts +0 -30
  251. package/src/modules/staff/backend/staff/team-members/[id]/page.tsx +34 -25
  252. package/src/modules/staff/backend/staff/teams/[id]/edit/page.tsx +17 -11
  253. package/src/modules/staff/lib/timesheets-projects-ui/SavedViewTabs.tsx +28 -11
  254. package/src/modules/sync_excel/lib/adapters/customers.ts +22 -20
  255. package/src/modules/sync_excel/lib/parser.ts +0 -245
  256. package/src/modules/sync_excel/lib/upload-storage.ts +1 -23
  257. package/src/modules/workflows/frontend/checkout-demo/page.tsx +12 -1
  258. package/src/modules/workflows/lib/activity-executor.ts +22 -2
  259. package/src/modules/workflows/lib/find-definition.ts +53 -1
  260. package/src/modules/workflows/lib/signal-handler.ts +5 -4
  261. package/src/modules/workflows/lib/step-handler.ts +4 -8
  262. package/src/modules/workflows/lib/task-handler.ts +2 -4
  263. package/src/modules/workflows/lib/timer-handler.ts +3 -2
  264. package/src/modules/workflows/lib/transition-handler.ts +5 -13
  265. package/src/modules/workflows/lib/workflow-executor.ts +11 -8
  266. package/src/modules/workflows/migrations/Migration20260715120000.ts +114 -0
  267. package/src/modules/workflows/migrations/Migration20260716120000.ts +57 -0
  268. package/src/modules/workflows/workflows.ts +2 -0
  269. package/dist/generated/entities/gateway_session_initialization/index.js +0 -23
  270. package/dist/generated/entities/gateway_session_initialization/index.js.map +0 -7
  271. package/dist/modules/attachments/lib/reconcileOrganization.js +0 -110
  272. package/dist/modules/attachments/lib/reconcileOrganization.js.map +0 -7
  273. package/dist/modules/attachments/lib/requestScope.js +0 -10
  274. package/dist/modules/attachments/lib/requestScope.js.map +0 -7
  275. package/dist/modules/auth/api/autologin.js +0 -85
  276. package/dist/modules/auth/api/autologin.js.map +0 -7
  277. package/dist/modules/auth/lib/autologin.js +0 -19
  278. package/dist/modules/auth/lib/autologin.js.map +0 -7
  279. package/dist/modules/customers/components/detail/useDealsAccess.js +0 -16
  280. package/dist/modules/customers/components/detail/useDealsAccess.js.map +0 -7
  281. package/dist/modules/payment_gateways/lib/session-idempotency.js +0 -104
  282. package/dist/modules/payment_gateways/lib/session-idempotency.js.map +0 -7
  283. package/dist/modules/payment_gateways/migrations/Migration20260709220938_payment_gateways.js +0 -11
  284. package/dist/modules/payment_gateways/migrations/Migration20260709220938_payment_gateways.js.map +0 -7
  285. package/dist/modules/sales/components/SalesChannelsDisabledNotice.js +0 -15
  286. package/dist/modules/sales/components/SalesChannelsDisabledNotice.js.map +0 -7
  287. package/dist/modules/sales/components/useSalesChannelsEnabled.js +0 -44
  288. package/dist/modules/sales/components/useSalesChannelsEnabled.js.map +0 -7
  289. package/dist/modules/sales/lib/salesChannelsToggle.js +0 -18
  290. package/dist/modules/sales/lib/salesChannelsToggle.js.map +0 -7
  291. package/dist/modules/sales/lib/salesChannelsToggleId.js +0 -5
  292. package/dist/modules/sales/lib/salesChannelsToggleId.js.map +0 -7
  293. package/generated/entities/gateway_session_initialization/index.ts +0 -10
  294. package/src/modules/attachments/lib/reconcileOrganization.ts +0 -188
  295. package/src/modules/attachments/lib/requestScope.ts +0 -27
  296. package/src/modules/auth/api/autologin.ts +0 -100
  297. package/src/modules/auth/lib/autologin.ts +0 -36
  298. package/src/modules/customers/components/detail/useDealsAccess.ts +0 -19
  299. package/src/modules/payment_gateways/lib/session-idempotency.ts +0 -142
  300. package/src/modules/payment_gateways/migrations/Migration20260709220938_payment_gateways.ts +0 -10
  301. package/src/modules/sales/components/SalesChannelsDisabledNotice.tsx +0 -21
  302. package/src/modules/sales/components/useSalesChannelsEnabled.ts +0 -59
  303. package/src/modules/sales/lib/salesChannelsToggle.ts +0 -26
  304. package/src/modules/sales/lib/salesChannelsToggleId.ts +0 -1
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/modules/workflows/migrations/Migration20260716120000.ts"],
4
+ "sourcesContent": ["import { Migration } from '@mikro-orm/migrations'\n\nconst CODE_WORKFLOW_ID = 'workflows.checkout-demo'\n\n/**\n * Retires the persisted checkout-demo seed rows so runtime resolves the\n * maintained CODE definition instead (issue #4211).\n *\n * Background: `workflows.checkout-demo` is now code-defined\n * (`packages/core/src/modules/workflows/workflows.ts`), and only the code\n * definition forwards the cart's line items + shipping/tax adjustments to\n * `POST /api/sales/orders`. But existing tenants still carry a persisted\n * `workflow_definitions` row from the old seed \u2014 originally seeded under ids\n * like `checkout_simple_v1` / names like `Simple Checkout Flow` and later\n * `Checkout with Payment Webhook`, then renamed to `workflows.checkout-demo`\n * by Migration20260428102318. Its `create_order` body never sent `lines`, and\n * because `findWorkflowDefinition` resolves the DB row first, that stale row\n * SHADOWS the code definition \u2014 so orders come out with zero line items and\n * $0.00 totals. Patching the persisted body is unreliable: the seed's name and\n * body shape vary across historical versions, so a fingerprint on either misses\n * whole cohorts of tenants (the defect QA hit).\n *\n * Instead, soft-delete the seeded rows. This is body/name-agnostic, so it fixes\n * every historical seed variant:\n * - New instances: `findWorkflowDefinition` filters `deleted_at IS NULL`, so\n * the retired row is skipped and the code definition is used (correct body).\n * - In-flight instances: `findDefinitionForInstance` loads the definition by\n * `id` with no soft-delete filter (WorkflowDefinition has no global filter),\n * so instances that reference the row keep resolving and advancing.\n *\n * Scope is limited to `code_workflow_id IS NULL` rows \u2014 user customizations of\n * the code definition set `code_workflow_id` and MUST NOT be retired. The\n * `deleted_at IS NULL` guard makes the migration idempotent.\n */\nexport function buildRetireSeededCheckoutDemoSql(): string {\n return `\n update \"workflow_definitions\" as \"wf\"\n set \"deleted_at\" = current_timestamp,\n \"updated_at\" = current_timestamp\n where \"wf\".\"workflow_id\" = '${CODE_WORKFLOW_ID}'\n and \"wf\".\"code_workflow_id\" is null\n and \"wf\".\"deleted_at\" is null;\n `.trim()\n}\n\nexport class Migration20260716120000 extends Migration {\n override async up(): Promise<void> {\n this.addSql(buildRetireSeededCheckoutDemoSql())\n }\n\n override async down(): Promise<void> {\n // Forward-only. Restoring `deleted_at = null` would re-shadow the maintained\n // code definition with the stale seed body and re-introduce zero-line orders\n // (#4211). The code definition supersedes the seed, so there is nothing to\n // restore.\n }\n}\n"],
5
+ "mappings": "AAAA,SAAS,iBAAiB;AAE1B,MAAM,mBAAmB;AAgClB,SAAS,mCAA2C;AACzD,SAAO;AAAA;AAAA;AAAA;AAAA,kCAIyB,gBAAgB;AAAA;AAAA;AAAA,IAG9C,KAAK;AACT;AAEO,MAAM,gCAAgC,UAAU;AAAA,EACrD,MAAe,KAAoB;AACjC,SAAK,OAAO,iCAAiC,CAAC;AAAA,EAChD;AAAA,EAEA,MAAe,OAAsB;AAAA,EAKrC;AACF;",
6
+ "names": []
7
+ }
@@ -222,6 +222,8 @@ const checkoutDemo = defineWorkflow({
222
222
  customerEntityId: "{{context.customer.id}}",
223
223
  currencyCode: "{{context.cart.currency}}",
224
224
  placedAt: "{{now}}",
225
+ lines: "{{context.cart.orderLines}}",
226
+ adjustments: "{{context.cart.orderAdjustments}}",
225
227
  grandTotalGrossAmount: "{{context.cart.total}}"
226
228
  },
227
229
  validateTenantMatch: true
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/modules/workflows/workflows.ts"],
4
- "sourcesContent": ["/**\n * Workflows Module \u2014 Code-Based Workflow Definitions\n *\n * Demo workflows shipped with the workflows module.\n * These are auto-discovered by the generator and loaded into the in-memory registry.\n */\n\nimport { defineWorkflow, createWorkflowsModuleConfig } from '@open-mercato/shared/modules/workflows'\n\n// ============================================================================\n// Simple Approval Workflow\n// ============================================================================\n\nconst simpleApproval = defineWorkflow({\n workflowId: 'workflows.simple-approval',\n workflowName: 'Simple Approval Workflow',\n description: 'Basic three-step approval workflow: Start \u2192 Approval \u2192 End',\n metadata: { category: 'Testing', tags: ['test', 'approval', 'simple'], icon: 'check-circle' },\n steps: [\n { stepId: 'start', stepName: 'Start', stepType: 'START', description: 'Initialize workflow' },\n {\n stepId: 'approval',\n stepName: 'Pending Approval',\n stepType: 'USER_TASK',\n description: 'Approve or reject request',\n userTaskConfig: { assignedTo: 'approver', slaDuration: 'PT1H' },\n },\n { stepId: 'end', stepName: 'Complete', stepType: 'END', description: 'Workflow complete' },\n ] as const,\n transitions: [\n {\n transitionId: 'start_to_approval',\n transitionName: 'Submit for Approval',\n fromStepId: 'start',\n toStepId: 'approval',\n trigger: 'auto',\n priority: 100,\n activities: [\n {\n activityId: 'notify_approver',\n activityName: 'Notify Approver',\n activityType: 'SEND_EMAIL',\n config: {\n to: '{{context.approver.email}}',\n subject: 'Approval Required: {{context.request.title}}',\n template: 'approval_request',\n data: {\n requestId: '{{context.request.id}}',\n title: '{{context.request.title}}',\n requester: '{{context.requester.name}}',\n },\n },\n timeout: 'PT10S',\n async: true,\n retryPolicy: { maxAttempts: 3, initialIntervalMs: 2000, backoffCoefficient: 2, maxIntervalMs: 20000 },\n },\n {\n activityId: 'emit_approval_requested',\n activityName: 'Emit Approval Requested Event',\n activityType: 'EMIT_EVENT',\n config: {\n eventType: 'approval.requested',\n payload: { requestId: '{{context.request.id}}', workflowInstanceId: '{{workflow.instanceId}}' },\n },\n async: true,\n },\n ],\n },\n {\n transitionId: 'approval_to_end',\n transitionName: 'Approval Decision',\n fromStepId: 'approval',\n toStepId: 'end',\n trigger: 'manual',\n priority: 100,\n activities: [\n {\n activityId: 'notify_requester',\n activityName: 'Notify Requester of Decision',\n activityType: 'SEND_EMAIL',\n config: {\n to: '{{context.requester.email}}',\n subject: 'Approval Decision: {{context.request.title}}',\n template: 'approval_decision',\n data: {\n requestId: '{{context.request.id}}',\n title: '{{context.request.title}}',\n decision: '{{task.result.approved}}',\n comments: '{{task.result.comments}}',\n approver: '{{task.completedBy}}',\n },\n },\n timeout: 'PT10S',\n async: true,\n },\n {\n activityId: 'emit_approval_completed',\n activityName: 'Emit Approval Completed Event',\n activityType: 'EMIT_EVENT',\n config: {\n eventType: 'approval.completed',\n payload: {\n requestId: '{{context.request.id}}',\n approved: '{{task.result.approved}}',\n approvedBy: '{{task.completedBy}}',\n timestamp: '{{now}}',\n },\n },\n async: true,\n },\n ],\n },\n ],\n})\n\n// ============================================================================\n// Checkout Demo Workflow\n// ============================================================================\n\nconst checkoutDemo = defineWorkflow({\n workflowId: 'workflows.checkout-demo',\n workflowName: 'Checkout with Payment Webhook',\n description: 'Realistic checkout workflow with signal-based payment confirmation',\n metadata: { category: 'E-commerce', tags: ['checkout', 'demo', 'payments', 'signals'], icon: 'ShoppingCart' },\n steps: [\n {\n stepId: 'start',\n stepName: 'Start',\n stepType: 'START',\n description: 'Checkout process initiated',\n preConditions: [{\n ruleId: 'workflow_checkout_cart_not_empty',\n required: true,\n validationMessage: {\n en: 'Your shopping cart is empty. Please add items before starting checkout.',\n pl: 'Tw\u00F3j koszyk jest pusty. Dodaj produkty przed rozpocz\u0119ciem zakupu.',\n },\n }],\n },\n { stepId: 'cart_validation', stepName: 'Cart Validation', stepType: 'AUTOMATED', description: 'Validate cart has items and inventory is available', timeout: 'PT10S' },\n {\n stepId: 'customer_info',\n stepName: 'Customer Information',\n stepType: 'USER_TASK',\n description: 'Collect customer shipping and contact information',\n userTaskConfig: {\n formSchema: {\n type: 'object',\n properties: {\n fullName: { type: 'string', title: 'Full Name', description: \"Customer's full legal name\" },\n email: { type: 'string', format: 'email', title: 'Email Address', description: 'Email for order confirmation' },\n phone: { type: 'string', title: 'Phone Number', description: 'Contact number for delivery' },\n comment: { type: 'string', title: 'Order Comment', maxLength: 500, description: 'Special instructions or notes' },\n },\n required: ['fullName', 'email'],\n },\n slaDuration: 'PT24H',\n },\n },\n { stepId: 'payment_initiation', stepName: 'Initiate Payment', stepType: 'AUTOMATED', description: 'Send payment request to payment provider', timeout: 'PT10S' },\n {\n stepId: 'wait_payment_confirmation',\n stepName: 'Wait for Payment Confirmation',\n stepType: 'WAIT_FOR_SIGNAL',\n description: 'Waiting for payment provider webhook confirmation',\n signalConfig: { signalName: 'payment_confirmed', timeout: 'PT5M' },\n },\n { stepId: 'order_confirmation', stepName: 'Order Confirmation', stepType: 'AUTOMATED', description: 'Create order record and send confirmation', timeout: 'PT15S' },\n { stepId: 'end', stepName: 'Complete', stepType: 'END', description: 'Checkout completed successfully' },\n ] as const,\n transitions: [\n {\n transitionId: 'start_to_cart',\n transitionName: 'Initialize Checkout',\n fromStepId: 'start',\n toStepId: 'cart_validation',\n trigger: 'auto',\n priority: 100,\n activities: [{\n activityId: 'log_checkout_start',\n activityName: 'Log Checkout Start',\n activityType: 'EMIT_EVENT',\n config: {\n eventName: 'checkout.started',\n payload: { customerId: '{{context.customerId}}', cartId: '{{context.cartId}}', currency: '{{context.currency}}', timestamp: '{{now}}' },\n },\n async: false,\n }],\n },\n {\n transitionId: 'cart_to_customer_info',\n transitionName: 'Collect Customer Information',\n fromStepId: 'cart_validation',\n toStepId: 'customer_info',\n trigger: 'auto',\n priority: 100,\n preConditions: [{ ruleId: 'workflow_checkout_cart_not_empty', required: true }],\n },\n {\n transitionId: 'customer_info_to_payment',\n transitionName: 'Initiate Payment',\n fromStepId: 'customer_info',\n toStepId: 'payment_initiation',\n trigger: 'auto',\n priority: 100,\n },\n {\n transitionId: 'payment_to_wait_confirmation',\n transitionName: 'Wait for Confirmation',\n fromStepId: 'payment_initiation',\n toStepId: 'wait_payment_confirmation',\n trigger: 'auto',\n priority: 100,\n },\n {\n transitionId: 'confirmation_to_order',\n transitionName: 'Payment Confirmed',\n fromStepId: 'wait_payment_confirmation',\n toStepId: 'order_confirmation',\n trigger: 'auto',\n priority: 100,\n },\n {\n transitionId: 'confirmation_to_end',\n transitionName: 'Finalize Order',\n fromStepId: 'order_confirmation',\n toStepId: 'end',\n trigger: 'auto',\n priority: 100,\n activities: [\n {\n activityId: 'create_order',\n activityName: 'Create Order Record',\n activityType: 'CALL_API',\n config: {\n endpoint: '/api/sales/orders',\n method: 'POST',\n body: {\n customerEntityId: '{{context.customer.id}}',\n currencyCode: '{{context.cart.currency}}',\n placedAt: '{{now}}',\n grandTotalGrossAmount: '{{context.cart.total}}',\n },\n validateTenantMatch: true,\n },\n timeout: 'PT10S',\n async: false,\n retryPolicy: { maxAttempts: 3, initialIntervalMs: 2000, backoffCoefficient: 2, maxIntervalMs: 10000 },\n },\n {\n activityId: 'send_confirmation_email',\n activityName: 'Send Order Confirmation Email',\n activityType: 'SEND_EMAIL',\n config: {\n to: '{{context.customer.email}}',\n subject: 'Order Confirmation',\n template: 'order_confirmation',\n data: { customerName: '{{context.customer.name}}', total: '{{context.cart.total}}' },\n },\n timeout: 'PT15S',\n async: true,\n retryPolicy: { maxAttempts: 3, initialIntervalMs: 2000, backoffCoefficient: 2, maxIntervalMs: 20000 },\n },\n ],\n },\n ],\n})\n\n// ============================================================================\n// Module Export\n// ============================================================================\n\nexport const workflowsConfig = createWorkflowsModuleConfig({\n moduleId: 'workflows',\n workflows: [simpleApproval, checkoutDemo],\n})\n\nexport default workflowsConfig\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * Workflows Module \u2014 Code-Based Workflow Definitions\n *\n * Demo workflows shipped with the workflows module.\n * These are auto-discovered by the generator and loaded into the in-memory registry.\n */\n\nimport { defineWorkflow, createWorkflowsModuleConfig } from '@open-mercato/shared/modules/workflows'\n\n// ============================================================================\n// Simple Approval Workflow\n// ============================================================================\n\nconst simpleApproval = defineWorkflow({\n workflowId: 'workflows.simple-approval',\n workflowName: 'Simple Approval Workflow',\n description: 'Basic three-step approval workflow: Start \u2192 Approval \u2192 End',\n metadata: { category: 'Testing', tags: ['test', 'approval', 'simple'], icon: 'check-circle' },\n steps: [\n { stepId: 'start', stepName: 'Start', stepType: 'START', description: 'Initialize workflow' },\n {\n stepId: 'approval',\n stepName: 'Pending Approval',\n stepType: 'USER_TASK',\n description: 'Approve or reject request',\n userTaskConfig: { assignedTo: 'approver', slaDuration: 'PT1H' },\n },\n { stepId: 'end', stepName: 'Complete', stepType: 'END', description: 'Workflow complete' },\n ] as const,\n transitions: [\n {\n transitionId: 'start_to_approval',\n transitionName: 'Submit for Approval',\n fromStepId: 'start',\n toStepId: 'approval',\n trigger: 'auto',\n priority: 100,\n activities: [\n {\n activityId: 'notify_approver',\n activityName: 'Notify Approver',\n activityType: 'SEND_EMAIL',\n config: {\n to: '{{context.approver.email}}',\n subject: 'Approval Required: {{context.request.title}}',\n template: 'approval_request',\n data: {\n requestId: '{{context.request.id}}',\n title: '{{context.request.title}}',\n requester: '{{context.requester.name}}',\n },\n },\n timeout: 'PT10S',\n async: true,\n retryPolicy: { maxAttempts: 3, initialIntervalMs: 2000, backoffCoefficient: 2, maxIntervalMs: 20000 },\n },\n {\n activityId: 'emit_approval_requested',\n activityName: 'Emit Approval Requested Event',\n activityType: 'EMIT_EVENT',\n config: {\n eventType: 'approval.requested',\n payload: { requestId: '{{context.request.id}}', workflowInstanceId: '{{workflow.instanceId}}' },\n },\n async: true,\n },\n ],\n },\n {\n transitionId: 'approval_to_end',\n transitionName: 'Approval Decision',\n fromStepId: 'approval',\n toStepId: 'end',\n trigger: 'manual',\n priority: 100,\n activities: [\n {\n activityId: 'notify_requester',\n activityName: 'Notify Requester of Decision',\n activityType: 'SEND_EMAIL',\n config: {\n to: '{{context.requester.email}}',\n subject: 'Approval Decision: {{context.request.title}}',\n template: 'approval_decision',\n data: {\n requestId: '{{context.request.id}}',\n title: '{{context.request.title}}',\n decision: '{{task.result.approved}}',\n comments: '{{task.result.comments}}',\n approver: '{{task.completedBy}}',\n },\n },\n timeout: 'PT10S',\n async: true,\n },\n {\n activityId: 'emit_approval_completed',\n activityName: 'Emit Approval Completed Event',\n activityType: 'EMIT_EVENT',\n config: {\n eventType: 'approval.completed',\n payload: {\n requestId: '{{context.request.id}}',\n approved: '{{task.result.approved}}',\n approvedBy: '{{task.completedBy}}',\n timestamp: '{{now}}',\n },\n },\n async: true,\n },\n ],\n },\n ],\n})\n\n// ============================================================================\n// Checkout Demo Workflow\n// ============================================================================\n\nconst checkoutDemo = defineWorkflow({\n workflowId: 'workflows.checkout-demo',\n workflowName: 'Checkout with Payment Webhook',\n description: 'Realistic checkout workflow with signal-based payment confirmation',\n metadata: { category: 'E-commerce', tags: ['checkout', 'demo', 'payments', 'signals'], icon: 'ShoppingCart' },\n steps: [\n {\n stepId: 'start',\n stepName: 'Start',\n stepType: 'START',\n description: 'Checkout process initiated',\n preConditions: [{\n ruleId: 'workflow_checkout_cart_not_empty',\n required: true,\n validationMessage: {\n en: 'Your shopping cart is empty. Please add items before starting checkout.',\n pl: 'Tw\u00F3j koszyk jest pusty. Dodaj produkty przed rozpocz\u0119ciem zakupu.',\n },\n }],\n },\n { stepId: 'cart_validation', stepName: 'Cart Validation', stepType: 'AUTOMATED', description: 'Validate cart has items and inventory is available', timeout: 'PT10S' },\n {\n stepId: 'customer_info',\n stepName: 'Customer Information',\n stepType: 'USER_TASK',\n description: 'Collect customer shipping and contact information',\n userTaskConfig: {\n formSchema: {\n type: 'object',\n properties: {\n fullName: { type: 'string', title: 'Full Name', description: \"Customer's full legal name\" },\n email: { type: 'string', format: 'email', title: 'Email Address', description: 'Email for order confirmation' },\n phone: { type: 'string', title: 'Phone Number', description: 'Contact number for delivery' },\n comment: { type: 'string', title: 'Order Comment', maxLength: 500, description: 'Special instructions or notes' },\n },\n required: ['fullName', 'email'],\n },\n slaDuration: 'PT24H',\n },\n },\n { stepId: 'payment_initiation', stepName: 'Initiate Payment', stepType: 'AUTOMATED', description: 'Send payment request to payment provider', timeout: 'PT10S' },\n {\n stepId: 'wait_payment_confirmation',\n stepName: 'Wait for Payment Confirmation',\n stepType: 'WAIT_FOR_SIGNAL',\n description: 'Waiting for payment provider webhook confirmation',\n signalConfig: { signalName: 'payment_confirmed', timeout: 'PT5M' },\n },\n { stepId: 'order_confirmation', stepName: 'Order Confirmation', stepType: 'AUTOMATED', description: 'Create order record and send confirmation', timeout: 'PT15S' },\n { stepId: 'end', stepName: 'Complete', stepType: 'END', description: 'Checkout completed successfully' },\n ] as const,\n transitions: [\n {\n transitionId: 'start_to_cart',\n transitionName: 'Initialize Checkout',\n fromStepId: 'start',\n toStepId: 'cart_validation',\n trigger: 'auto',\n priority: 100,\n activities: [{\n activityId: 'log_checkout_start',\n activityName: 'Log Checkout Start',\n activityType: 'EMIT_EVENT',\n config: {\n eventName: 'checkout.started',\n payload: { customerId: '{{context.customerId}}', cartId: '{{context.cartId}}', currency: '{{context.currency}}', timestamp: '{{now}}' },\n },\n async: false,\n }],\n },\n {\n transitionId: 'cart_to_customer_info',\n transitionName: 'Collect Customer Information',\n fromStepId: 'cart_validation',\n toStepId: 'customer_info',\n trigger: 'auto',\n priority: 100,\n preConditions: [{ ruleId: 'workflow_checkout_cart_not_empty', required: true }],\n },\n {\n transitionId: 'customer_info_to_payment',\n transitionName: 'Initiate Payment',\n fromStepId: 'customer_info',\n toStepId: 'payment_initiation',\n trigger: 'auto',\n priority: 100,\n },\n {\n transitionId: 'payment_to_wait_confirmation',\n transitionName: 'Wait for Confirmation',\n fromStepId: 'payment_initiation',\n toStepId: 'wait_payment_confirmation',\n trigger: 'auto',\n priority: 100,\n },\n {\n transitionId: 'confirmation_to_order',\n transitionName: 'Payment Confirmed',\n fromStepId: 'wait_payment_confirmation',\n toStepId: 'order_confirmation',\n trigger: 'auto',\n priority: 100,\n },\n {\n transitionId: 'confirmation_to_end',\n transitionName: 'Finalize Order',\n fromStepId: 'order_confirmation',\n toStepId: 'end',\n trigger: 'auto',\n priority: 100,\n activities: [\n {\n activityId: 'create_order',\n activityName: 'Create Order Record',\n activityType: 'CALL_API',\n config: {\n endpoint: '/api/sales/orders',\n method: 'POST',\n body: {\n customerEntityId: '{{context.customer.id}}',\n currencyCode: '{{context.cart.currency}}',\n placedAt: '{{now}}',\n lines: '{{context.cart.orderLines}}',\n adjustments: '{{context.cart.orderAdjustments}}',\n grandTotalGrossAmount: '{{context.cart.total}}',\n },\n validateTenantMatch: true,\n },\n timeout: 'PT10S',\n async: false,\n retryPolicy: { maxAttempts: 3, initialIntervalMs: 2000, backoffCoefficient: 2, maxIntervalMs: 10000 },\n },\n {\n activityId: 'send_confirmation_email',\n activityName: 'Send Order Confirmation Email',\n activityType: 'SEND_EMAIL',\n config: {\n to: '{{context.customer.email}}',\n subject: 'Order Confirmation',\n template: 'order_confirmation',\n data: { customerName: '{{context.customer.name}}', total: '{{context.cart.total}}' },\n },\n timeout: 'PT15S',\n async: true,\n retryPolicy: { maxAttempts: 3, initialIntervalMs: 2000, backoffCoefficient: 2, maxIntervalMs: 20000 },\n },\n ],\n },\n ],\n})\n\n// ============================================================================\n// Module Export\n// ============================================================================\n\nexport const workflowsConfig = createWorkflowsModuleConfig({\n moduleId: 'workflows',\n workflows: [simpleApproval, checkoutDemo],\n})\n\nexport default workflowsConfig\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -267,7 +267,6 @@ export const M = {
267
267
  },
268
268
  "payment_gateways": {
269
269
  "gateway_transaction": "payment_gateways:gateway_transaction",
270
- "gateway_session_initialization": "payment_gateways:gateway_session_initialization",
271
270
  "webhook_processed_event": "payment_gateways:webhook_processed_event"
272
271
  },
273
272
  "shipping_carriers": {
@@ -1225,18 +1225,6 @@ export const entityFieldsRegistry: Record<string, Record<string, string>> = {
1225
1225
  "updated_at": "updated_at",
1226
1226
  "value": "value"
1227
1227
  },
1228
- "gateway_session_initialization": {
1229
- "id": "id",
1230
- "operation_key": "operation_key",
1231
- "provider_key": "provider_key",
1232
- "claim_token": "claim_token",
1233
- "claimed_at": "claimed_at",
1234
- "gateway_transaction_id": "gateway_transaction_id",
1235
- "organization_id": "organization_id",
1236
- "tenant_id": "tenant_id",
1237
- "created_at": "created_at",
1238
- "updated_at": "updated_at"
1239
- },
1240
1228
  "gateway_transaction": {
1241
1229
  "id": "id",
1242
1230
  "payment_id": "payment_id",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-mercato/core",
3
- "version": "0.6.6-develop.6551.1.1511bfa890",
3
+ "version": "0.6.6",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -253,16 +253,16 @@
253
253
  "zod": "^4.4.3"
254
254
  },
255
255
  "peerDependencies": {
256
- "@open-mercato/ai-assistant": "0.6.6-develop.6551.1.1511bfa890",
257
- "@open-mercato/shared": "0.6.6-develop.6551.1.1511bfa890",
258
- "@open-mercato/ui": "0.6.6-develop.6551.1.1511bfa890",
256
+ "@open-mercato/ai-assistant": "0.6.6",
257
+ "@open-mercato/shared": "0.6.6",
258
+ "@open-mercato/ui": "0.6.6",
259
259
  "react": "^19.0.0",
260
260
  "react-dom": "^19.0.0"
261
261
  },
262
262
  "devDependencies": {
263
- "@open-mercato/ai-assistant": "0.6.6-develop.6551.1.1511bfa890",
264
- "@open-mercato/shared": "0.6.6-develop.6551.1.1511bfa890",
265
- "@open-mercato/ui": "0.6.6-develop.6551.1.1511bfa890",
263
+ "@open-mercato/ai-assistant": "0.6.6",
264
+ "@open-mercato/shared": "0.6.6",
265
+ "@open-mercato/ui": "0.6.6",
266
266
  "@testing-library/dom": "^10.4.1",
267
267
  "@testing-library/jest-dom": "^6.9.1",
268
268
  "@testing-library/react": "^16.3.1",
@@ -285,6 +285,5 @@
285
285
  "type": "git",
286
286
  "url": "https://github.com/open-mercato/open-mercato",
287
287
  "directory": "packages/core"
288
- },
289
- "stableVersion": "0.6.5"
288
+ }
290
289
  }
@@ -13,8 +13,6 @@ import { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'
13
13
  import { enforceTenantSelection, resolveIsSuperAdmin } from '@open-mercato/core/modules/auth/lib/tenantAccess'
14
14
  import { escapeLikePattern } from '@open-mercato/shared/lib/db/escapeLikePattern'
15
15
  import { assertActorCanGrantRoles } from '@open-mercato/core/modules/auth/lib/grantChecks'
16
- import { isOrganizationAccessAllowed } from '@open-mercato/shared/lib/auth/organizationAccess'
17
- import { findOneWithDecryption } from '@open-mercato/shared/lib/encryption/find'
18
16
 
19
17
  type ApiKeyCrudCtx = CrudCtx & {
20
18
  __apiKeySecret?: { secret: string; prefix: string }
@@ -299,15 +297,10 @@ const crud = makeCrudRoute<
299
297
 
300
298
  const allowedIds = ctx.organizationScope?.allowedIds ?? null
301
299
  const organizationId = input.organizationId ?? ctx.selectedOrganizationId ?? auth.orgId ?? null
302
- const isSuperAdmin = await resolveIsSuperAdmin(scopedCtx)
303
- if (
304
- !isOrganizationAccessAllowed({
305
- isSuperAdmin,
306
- allowedOrganizationIds: allowedIds,
307
- targetOrganizationId: organizationId,
308
- })
309
- ) {
310
- throw json({ error: translate('api_keys.errors.organizationOutOfScope', 'Organization out of scope') }, { status: 403 })
300
+ if (organizationId && Array.isArray(allowedIds) && allowedIds.length > 0) {
301
+ if (!allowedIds.includes(organizationId)) {
302
+ throw json({ error: translate('api_keys.errors.organizationOutOfScope', 'Organization out of scope') }, { status: 403 })
303
+ }
311
304
  }
312
305
  scopedCtx.__apiKeyOrganizationId = organizationId ?? null
313
306
 
@@ -329,34 +322,18 @@ const crud = makeCrudRoute<
329
322
  const { translate } = await resolveTranslations()
330
323
  if (!auth?.tenantId) throw json({ error: translate('api_keys.errors.tenantRequired', 'Tenant context required') }, { status: 400 })
331
324
  const em = (ctx.container.resolve('em') as EntityManager)
325
+ const record = await em.findOne(ApiKey, { id, deletedAt: null })
326
+ if (!record) throw json({ error: translate('api_keys.errors.notFound', 'Not found') }, { status: 404 })
332
327
  const scopedCtx = ctx as ApiKeyCrudCtx
333
328
  const isSuperAdmin = await resolveIsSuperAdmin(scopedCtx)
334
- const allowedIds = ctx.organizationScope?.allowedIds ?? null
335
- const recordFilter: FilterQuery<ApiKey> = {
336
- id,
337
- tenantId: auth.tenantId,
338
- deletedAt: null,
339
- }
340
- if (!isSuperAdmin && Array.isArray(allowedIds)) {
341
- recordFilter.organizationId = { $in: allowedIds }
329
+ if (!isSuperAdmin && record.tenantId && record.tenantId !== auth.tenantId) {
330
+ throw json({ error: translate('api_keys.errors.forbidden', 'Forbidden') }, { status: 403 })
342
331
  }
343
- const record = await findOneWithDecryption(
344
- em,
345
- ApiKey,
346
- recordFilter,
347
- undefined,
348
- { tenantId: auth.tenantId, organizationId: null },
349
- )
350
- if (
351
- !record ||
352
- record.tenantId !== auth.tenantId ||
353
- !isOrganizationAccessAllowed({
354
- isSuperAdmin,
355
- allowedOrganizationIds: allowedIds,
356
- targetOrganizationId: record.organizationId ?? null,
357
- })
358
- ) {
359
- throw json({ error: translate('api_keys.errors.notFound', 'Not found') }, { status: 404 })
332
+ const allowedIds = ctx.organizationScope?.allowedIds ?? null
333
+ if (record.organizationId && Array.isArray(allowedIds) && allowedIds.length > 0) {
334
+ if (!allowedIds.includes(record.organizationId)) {
335
+ throw json({ error: translate('api_keys.errors.organizationOutOfScope', 'Organization out of scope') }, { status: 403 })
336
+ }
360
337
  }
361
338
  scopedCtx.__apiKeyOrganizationId = record.organizationId ?? null
362
339
  },
@@ -3,7 +3,6 @@ import { createRequestContainer } from '@open-mercato/shared/lib/di/container'
3
3
  import { createApiKey } from './services/apiKeyService'
4
4
  import { Organization } from '@open-mercato/core/modules/directory/data/entities'
5
5
  import { Role } from '@open-mercato/core/modules/auth/data/entities'
6
- import { parseCommaSeparatedList } from '@open-mercato/shared/lib/string'
7
6
 
8
7
  function parseArgs(rest: string[]): Record<string, string> {
9
8
  const args: Record<string, string> = {}
@@ -48,7 +47,9 @@ const addApiKey: ModuleCli = {
48
47
  return
49
48
  }
50
49
 
51
- const roleInputs = parseCommaSeparatedList(rolesCsv)
50
+ const roleInputs = rolesCsv
51
+ ? rolesCsv.split(',').map((value) => value.trim()).filter(Boolean)
52
+ : []
52
53
  const roleIds: string[] = []
53
54
  if (roleInputs.length) {
54
55
  for (const token of roleInputs) {
@@ -15,7 +15,6 @@ import {
15
15
  canRenderInlineAttachment,
16
16
  } from "@open-mercato/core/modules/attachments/lib/security";
17
17
  import { StorageDriverFactory } from '../../../lib/drivers';
18
- import { resolveAttachmentOrganizationId } from '@open-mercato/core/modules/attachments/lib/requestScope';
19
18
 
20
19
  export const metadata = {
21
20
  GET: { requireAuth: false },
@@ -33,19 +32,16 @@ export async function GET(
33
32
  );
34
33
  }
35
34
  const auth = await getAuthFromRequest(req);
36
- const container = await createRequestContainer();
37
- const em = container.resolve("em") as EntityManager;
35
+ const { resolve } = await createRequestContainer();
36
+ const em = resolve("em") as EntityManager;
38
37
  const storageDriverFactory =
39
- (container.resolve("storageDriverFactory") as StorageDriverFactory | null) ??
38
+ (resolve("storageDriverFactory") as StorageDriverFactory | null) ??
40
39
  new StorageDriverFactory(em);
41
40
 
42
- const scopedAuth = auth
43
- ? { ...auth, orgId: await resolveAttachmentOrganizationId(container, auth, req) }
44
- : auth;
45
41
  const findFilter: Record<string, unknown> = { id };
46
- if (scopedAuth && !isSuperAdminAuth(scopedAuth)) {
47
- if (scopedAuth.tenantId) findFilter.tenantId = scopedAuth.tenantId;
48
- if (scopedAuth.orgId) findFilter.organizationId = scopedAuth.orgId;
42
+ if (auth && !isSuperAdminAuth(auth)) {
43
+ if (auth.tenantId) findFilter.tenantId = auth.tenantId;
44
+ if (auth.orgId) findFilter.organizationId = auth.orgId;
49
45
  }
50
46
  const attachment = await em.findOne(Attachment, findFilter);
51
47
  if (!attachment) {
@@ -64,7 +60,7 @@ export async function GET(
64
60
  );
65
61
  }
66
62
 
67
- const access = checkAttachmentAccess(scopedAuth, attachment, partition);
63
+ const access = checkAttachmentAccess(auth, attachment, partition);
68
64
  if (!access.ok) {
69
65
  const message = access.status === 401 ? "Unauthorized" : "Forbidden";
70
66
  return NextResponse.json({ error: message }, { status: access.status });
@@ -20,7 +20,6 @@ import {
20
20
  validateImageMagicBytes,
21
21
  } from '@open-mercato/core/modules/attachments/lib/imageSafety'
22
22
  import { StorageDriverFactory } from '../../../../lib/drivers'
23
- import { resolveAttachmentOrganizationId } from '@open-mercato/core/modules/attachments/lib/requestScope'
24
23
  import { createLogger } from '@open-mercato/shared/lib/logger'
25
24
 
26
25
  const logger = createLogger('attachments').child({ component: 'image' })
@@ -52,18 +51,15 @@ export async function GET(
52
51
  }
53
52
  const { width, height, cropType } = parsedQuery.data
54
53
 
55
- const container = await createRequestContainer()
56
- const em = container.resolve('em') as EntityManager
54
+ const { resolve } = await createRequestContainer()
55
+ const em = resolve('em') as EntityManager
57
56
  const storageDriverFactory =
58
- (container.resolve('storageDriverFactory') as StorageDriverFactory | null) ?? new StorageDriverFactory(em)
57
+ (resolve('storageDriverFactory') as StorageDriverFactory | null) ?? new StorageDriverFactory(em)
59
58
 
60
- const scopedAuth = auth
61
- ? { ...auth, orgId: await resolveAttachmentOrganizationId(container, auth, req) }
62
- : auth
63
59
  const findFilter: Record<string, unknown> = { id }
64
- if (scopedAuth && !isSuperAdminAuth(scopedAuth)) {
65
- if (scopedAuth.tenantId) findFilter.tenantId = scopedAuth.tenantId
66
- if (scopedAuth.orgId) findFilter.organizationId = scopedAuth.orgId
60
+ if (auth && !isSuperAdminAuth(auth)) {
61
+ if (auth.tenantId) findFilter.tenantId = auth.tenantId
62
+ if (auth.orgId) findFilter.organizationId = auth.orgId
67
63
  }
68
64
  const attachment = await em.findOne(Attachment, findFilter)
69
65
  if (!attachment) {
@@ -76,7 +72,7 @@ export async function GET(
76
72
  if (!partition) {
77
73
  return NextResponse.json({ error: 'Partition misconfigured' }, { status: 500 })
78
74
  }
79
- const access = checkAttachmentAccess(scopedAuth, attachment, partition)
75
+ const access = checkAttachmentAccess(auth, attachment, partition)
80
76
  if (!access.ok) {
81
77
  const message = access.status === 401 ? 'Unauthorized' : 'Forbidden'
82
78
  return NextResponse.json({ error: message }, { status: access.status })
@@ -13,7 +13,6 @@ import { StorageDriverFactory } from '../lib/drivers'
13
13
  import { OcrService, shouldUseLlmOcr } from '../lib/ocrService'
14
14
  import { clearAttachmentThumbnailCache } from '../lib/thumbnailCache'
15
15
  import { assertAttachmentScopeInvariant } from '../lib/access'
16
- import { resolveAttachmentOrganizationId } from '../lib/requestScope'
17
16
  import {
18
17
  mergeAttachmentMetadata,
19
18
  normalizeAttachmentAssignments,
@@ -199,11 +198,10 @@ export async function GET(req: Request) {
199
198
  }
200
199
  const { entityId, recordId, page, pageSize } = parsedQuery.data
201
200
 
202
- const container = await createRequestContainer()
203
- const em = container.resolve('em') as EntityManager
204
- const orgId = await resolveAttachmentOrganizationId(container, auth, req)
201
+ const { resolve } = await createRequestContainer()
202
+ const em = resolve('em') as EntityManager
205
203
  const filter: Record<string, unknown> = { entityId, recordId, tenantId: auth.tenantId! }
206
- if (orgId) filter.organizationId = orgId
204
+ if (auth.orgId) filter.organizationId = auth.orgId
207
205
  const orderBy: Record<string, 'ASC' | 'DESC'> = { createdAt: 'DESC' }
208
206
  const usePaging = typeof page === 'number' && typeof pageSize === 'number'
209
207
  const total = usePaging ? await em.count(Attachment, filter) : null
@@ -226,7 +224,7 @@ export async function GET(req: Request) {
226
224
  },
227
225
  {
228
226
  tenantId: auth.tenantId ?? null,
229
- organizationId: orgId ?? null,
227
+ organizationId: auth.orgId ?? null,
230
228
  },
231
229
  )
232
230
  return NextResponse.json({
@@ -277,6 +275,7 @@ export async function POST(req: Request) {
277
275
  }, { status: 400 })
278
276
  }
279
277
  const tenantId = auth.tenantId
278
+ const orgId = auth.orgId
280
279
 
281
280
  const contentType = req.headers.get('content-type') || ''
282
281
  if (!contentType.toLowerCase().includes('multipart/form-data')) {
@@ -302,13 +301,11 @@ export async function POST(req: Request) {
302
301
  const tags = parseFormTags(form.get('tags'))
303
302
  const assignmentsFromForm = parseFormAssignments(form.get('assignments'))
304
303
 
305
- const container = await createRequestContainer()
306
- const em = container.resolve('em') as EntityManager
307
- const dataEngine = container.resolve('dataEngine')
304
+ const { resolve } = await createRequestContainer()
305
+ const em = resolve('em') as EntityManager
306
+ const dataEngine = resolve('dataEngine')
308
307
  const storageDriverFactory =
309
- (container.resolve('storageDriverFactory') as StorageDriverFactory | null) ?? new StorageDriverFactory(em)
310
- const orgId = await resolveAttachmentOrganizationId(container, auth, req)
311
- if (!orgId) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
308
+ (resolve('storageDriverFactory') as StorageDriverFactory | null) ?? new StorageDriverFactory(em)
312
309
  await ensureDefaultPartitions(em)
313
310
  // Optional per-field validations
314
311
  let partitionFromField: string | null = null
@@ -439,12 +436,12 @@ export async function POST(req: Request) {
439
436
  }
440
437
  const metadata = mergeAttachmentMetadata(null, { assignments, tags })
441
438
  const attachmentId = randomUUID()
442
- assertAttachmentScopeInvariant({ tenantId: auth.tenantId, organizationId: orgId })
439
+ assertAttachmentScopeInvariant({ tenantId: auth.tenantId, organizationId: auth.orgId })
443
440
  const att = em.create(Attachment, {
444
441
  id: attachmentId,
445
442
  entityId,
446
443
  recordId,
447
- organizationId: orgId,
444
+ organizationId: auth.orgId!,
448
445
  tenantId: auth.tenantId!,
449
446
  fileName: safeName,
450
447
  mimeType: fileMimeType,
@@ -548,19 +545,17 @@ export async function DELETE(req: Request) {
548
545
  const url = new URL(req.url)
549
546
  const id = url.searchParams.get('id') || ''
550
547
  if (!id) return NextResponse.json({ error: 'Attachment id is required' }, { status: 400 })
551
- const container = await createRequestContainer()
552
- const em = container.resolve('em') as EntityManager
553
- const dataEngine = container.resolve('dataEngine')
548
+ const { resolve } = await createRequestContainer()
549
+ const em = resolve('em') as EntityManager
550
+ const dataEngine = resolve('dataEngine')
554
551
  const storageDriverFactory =
555
- (container.resolve('storageDriverFactory') as StorageDriverFactory | null) ?? new StorageDriverFactory(em)
556
- // Resolve the currently selected organization (#3765) so a multi-org admin who
557
- // switched the header org deletes within that org, not their pinned home org.
558
- // A superadmin browsing with "All organizations" selected has no concrete org,
559
- // so resolution returns null and the delete falls back to a tenant-only scope
560
- // (#3764) — letting them remove any attachment in the tenant.
561
- const orgId = await resolveAttachmentOrganizationId(container, auth, req)
552
+ (resolve('storageDriverFactory') as StorageDriverFactory | null) ?? new StorageDriverFactory(em)
553
+ // Mirror the GET handler's superadmin bypass: a superadmin browsing with "All
554
+ // organizations" selected has no concrete org, so scope the delete by tenant
555
+ // only and let them remove any attachment in the tenant. Non-superadmins stay
556
+ // scoped to their own organization (#3764).
562
557
  const deleteFilter: Record<string, unknown> = { id, tenantId: auth.tenantId! }
563
- if (orgId) deleteFilter.organizationId = orgId
558
+ if (auth.orgId) deleteFilter.organizationId = auth.orgId
564
559
  const record = await em.findOne(Attachment, deleteFilter)
565
560
  if (!record) return NextResponse.json({ error: 'Attachment not found' }, { status: 404 })
566
561
  await em.remove(record).flush()
@@ -570,7 +565,7 @@ export async function DELETE(req: Request) {
570
565
  if (record.storagePath) {
571
566
  const delDriver = await storageDriverFactory.resolveForPartition(record.partitionCode, {
572
567
  tenantId: record.tenantId ?? auth.tenantId!,
573
- organizationId: record.organizationId ?? orgId ?? '',
568
+ organizationId: record.organizationId ?? auth.orgId ?? '',
574
569
  })
575
570
  await delDriver.delete(record.partitionCode, record.storagePath)
576
571
  }
@@ -1,7 +1,6 @@
1
1
  import * as React from 'react'
2
2
  import { MarkdownContent } from '@open-mercato/ui/backend/markdown'
3
3
  import { Button } from '@open-mercato/ui/primitives/button'
4
- import { Tabs, TabsList, TabsTrigger } from '@open-mercato/ui/primitives/tabs'
5
4
 
6
5
  type Props = {
7
6
  content?: string | null
@@ -26,6 +25,12 @@ export function AttachmentContentPreview({
26
25
  const [tab, setTab] = React.useState<'source' | 'preview'>('source')
27
26
  const text = (content ?? '').trim()
28
27
 
28
+ // ARIA IDs for accessibility
29
+ const sourceTabId = 'attachment-content-preview-tab-source'
30
+ const previewTabId = 'attachment-content-preview-tab-preview'
31
+ const sourcePanelId = 'attachment-content-preview-panel-source'
32
+ const previewPanelId = 'attachment-content-preview-panel-preview'
33
+
29
34
  if (!text) {
30
35
  return <div className="text-xs text-muted-foreground italic">{emptyLabel}</div>
31
36
  }
@@ -36,18 +41,47 @@ export function AttachmentContentPreview({
36
41
  return (
37
42
  <div className="space-y-2">
38
43
  {/* Tab Navigation */}
39
- <Tabs value={tab} onValueChange={(value) => setTab(value as 'source' | 'preview')} variant="underline">
40
- <TabsList className="w-full">
41
- <TabsTrigger value="source">{sourceLabel}</TabsTrigger>
42
- <TabsTrigger value="preview">{previewLabel}</TabsTrigger>
43
- </TabsList>
44
- </Tabs>
44
+ <div className="border-b border-border">
45
+ <nav className="flex items-center gap-4 text-xs" role="tablist" aria-label="Content preview mode">
46
+ <button
47
+ type="button"
48
+ id={sourceTabId}
49
+ role="tab"
50
+ aria-selected={tab === 'source'}
51
+ aria-controls={sourcePanelId}
52
+ className={`-mb-px border-b-2 px-0 pb-2 font-medium transition-colors ${
53
+ tab === 'source'
54
+ ? 'border-accent-indigo text-foreground'
55
+ : 'border-transparent text-muted-foreground hover:text-foreground'
56
+ }`}
57
+ onClick={() => setTab('source')}
58
+ >
59
+ {sourceLabel}
60
+ </button>
61
+ <button
62
+ type="button"
63
+ id={previewTabId}
64
+ role="tab"
65
+ aria-selected={tab === 'preview'}
66
+ aria-controls={previewPanelId}
67
+ className={`-mb-px border-b-2 px-0 pb-2 font-medium transition-colors ${
68
+ tab === 'preview'
69
+ ? 'border-accent-indigo text-foreground'
70
+ : 'border-transparent text-muted-foreground hover:text-foreground'
71
+ }`}
72
+ onClick={() => setTab('preview')}
73
+ >
74
+ {previewLabel}
75
+ </button>
76
+ </nav>
77
+ </div>
45
78
 
46
79
  {/* Tab Panels */}
47
80
  {tab === 'source' ? (
48
81
  <div
49
82
  role="tabpanel"
50
- aria-label={sourceLabel}
83
+ id={sourcePanelId}
84
+ aria-labelledby={sourceTabId}
51
85
  data-testid="attachment-content-preview"
52
86
  className="whitespace-pre-wrap text-sm text-muted-foreground"
53
87
  >
@@ -56,7 +90,8 @@ export function AttachmentContentPreview({
56
90
  ) : (
57
91
  <div
58
92
  role="tabpanel"
59
- aria-label={previewLabel}
93
+ id={previewPanelId}
94
+ aria-labelledby={previewTabId}
60
95
  data-testid="markdown-preview"
61
96
  >
62
97
  <MarkdownContent
@@ -4,7 +4,6 @@ import React from 'react'
4
4
  import { Page, PageBody } from '@open-mercato/ui/backend/Page'
5
5
  import { readApiResultOrThrow } from '@open-mercato/ui/backend/utils/apiCall'
6
6
  import { Button } from '@open-mercato/ui/primitives/button'
7
- import { Tabs, TabsList, TabsTrigger } from '@open-mercato/ui/primitives/tabs'
8
7
  import { useT } from '@open-mercato/shared/lib/i18n/context'
9
8
  import type { ActionLogItem } from '../../components/AuditLogsActions'
10
9
  import { AuditLogsActions } from '../../components/AuditLogsActions'
@@ -183,17 +182,28 @@ export default function AuditLogsPage() {
183
182
  return (
184
183
  <Page>
185
184
  <PageBody>
186
- <Tabs
187
- value={tab}
188
- onValueChange={(value) => setTab(value as TabOption)}
189
- variant="underline"
190
- className="mb-6"
191
- >
192
- <TabsList className="w-full flex-wrap" aria-label={t('audit_logs.tabs.label')}>
193
- <TabsTrigger value="actions">{t('audit_logs.actions.title')}</TabsTrigger>
194
- <TabsTrigger value="access">{t('audit_logs.access.title')}</TabsTrigger>
195
- </TabsList>
196
- </Tabs>
185
+ <div className="mb-6 border-b border-border">
186
+ <nav className="flex items-center gap-6 text-sm" role="tablist" aria-label={t('audit_logs.tabs.label')}>
187
+ <button
188
+ type="button"
189
+ role="tab"
190
+ aria-selected={tab === 'actions'}
191
+ className={`relative -mb-px border-b-2 px-0 pb-3 pt-2 font-medium transition-colors ${tab === 'actions' ? 'border-accent-indigo text-foreground' : 'border-transparent text-muted-foreground hover:text-foreground'}`}
192
+ onClick={() => setTab('actions')}
193
+ >
194
+ {t('audit_logs.actions.title')}
195
+ </button>
196
+ <button
197
+ type="button"
198
+ role="tab"
199
+ aria-selected={tab === 'access'}
200
+ className={`relative -mb-px border-b-2 px-0 pb-3 pt-2 font-medium transition-colors ${tab === 'access' ? 'border-accent-indigo text-foreground' : 'border-transparent text-muted-foreground hover:text-foreground'}`}
201
+ onClick={() => setTab('access')}
202
+ >
203
+ {t('audit_logs.access.title')}
204
+ </button>
205
+ </nav>
206
+ </div>
197
207
 
198
208
  {error && <div className="mb-4 rounded-md border border-status-error-border bg-status-error-bg p-3 text-sm text-status-error-text">{error}</div>}
199
209