@open-mercato/core 0.8.1-develop.7274.1.21a0083828 → 0.8.1-develop.7294.1.0ef99fc518

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 (261) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/dist/modules/auth/api/users/acl/route.js.map +2 -2
  3. package/dist/modules/auth/components/AclEditor.js +21 -3
  4. package/dist/modules/auth/components/AclEditor.js.map +2 -2
  5. package/dist/modules/customers/backend/customers/companies/page.js +6 -4
  6. package/dist/modules/customers/backend/customers/companies/page.js.map +2 -2
  7. package/dist/modules/customers/backend/customers/deals/map/components/DealsMapView.js +6 -4
  8. package/dist/modules/customers/backend/customers/deals/map/components/DealsMapView.js.map +2 -2
  9. package/dist/modules/customers/backend/customers/deals/page.js +6 -4
  10. package/dist/modules/customers/backend/customers/deals/page.js.map +2 -2
  11. package/dist/modules/customers/backend/customers/deals/pipeline/components/ChangeOwnerDialog.js +5 -3
  12. package/dist/modules/customers/backend/customers/deals/pipeline/components/ChangeOwnerDialog.js.map +2 -2
  13. package/dist/modules/customers/backend/customers/deals/pipeline/page.js +6 -4
  14. package/dist/modules/customers/backend/customers/deals/pipeline/page.js.map +2 -2
  15. package/dist/modules/customers/backend/customers/people/page.js +6 -4
  16. package/dist/modules/customers/backend/customers/people/page.js.map +2 -2
  17. package/dist/modules/customers/components/calendar/editor/PeopleField.js +9 -2
  18. package/dist/modules/customers/components/calendar/editor/PeopleField.js.map +2 -2
  19. package/dist/modules/customers/components/calendar/editor/hooks.js +4 -2
  20. package/dist/modules/customers/components/calendar/editor/hooks.js.map +2 -2
  21. package/dist/modules/customers/components/calendar/editor/lookups.js +7 -3
  22. package/dist/modules/customers/components/calendar/editor/lookups.js.map +2 -2
  23. package/dist/modules/customers/components/detail/AssignRoleDialog.js +5 -2
  24. package/dist/modules/customers/components/detail/AssignRoleDialog.js.map +2 -2
  25. package/dist/modules/customers/components/detail/RoleAssignmentRow.js +4 -2
  26. package/dist/modules/customers/components/detail/RoleAssignmentRow.js.map +2 -2
  27. package/dist/modules/customers/components/detail/ScheduleActivityDialog.js +8 -5
  28. package/dist/modules/customers/components/detail/ScheduleActivityDialog.js.map +2 -2
  29. package/dist/modules/customers/components/detail/schedule/DateTimeFields.js +10 -7
  30. package/dist/modules/customers/components/detail/schedule/DateTimeFields.js.map +2 -2
  31. package/dist/modules/customers/components/detail/schedule/ParticipantsField.js +4 -2
  32. package/dist/modules/customers/components/detail/schedule/ParticipantsField.js.map +2 -2
  33. package/dist/modules/customers/components/detail/schedule/fieldConfig.js +9 -0
  34. package/dist/modules/customers/components/detail/schedule/fieldConfig.js.map +2 -2
  35. package/dist/modules/customers/components/detail/schedule/index.js +3 -1
  36. package/dist/modules/customers/components/detail/schedule/index.js.map +2 -2
  37. package/dist/modules/customers/components/detail/schedule/useScheduleFormState.js +11 -4
  38. package/dist/modules/customers/components/detail/schedule/useScheduleFormState.js.map +2 -2
  39. package/dist/modules/customers/components/formConfig.js +17 -9
  40. package/dist/modules/customers/components/formConfig.js.map +2 -2
  41. package/dist/modules/customers/data/validators.js +12 -7
  42. package/dist/modules/customers/data/validators.js.map +2 -2
  43. package/dist/modules/customers/lib/assignableStaff.js +103 -22
  44. package/dist/modules/customers/lib/assignableStaff.js.map +2 -2
  45. package/dist/modules/customers/setup.js +10 -2
  46. package/dist/modules/customers/setup.js.map +2 -2
  47. package/dist/modules/data_sync/api/schedules/[id]/route.js +5 -0
  48. package/dist/modules/data_sync/api/schedules/[id]/route.js.map +2 -2
  49. package/dist/modules/data_sync/api/schedules/route.js +5 -0
  50. package/dist/modules/data_sync/api/schedules/route.js.map +2 -2
  51. package/dist/modules/data_sync/backend/data-sync/page.js +29 -5
  52. package/dist/modules/data_sync/backend/data-sync/page.js.map +2 -2
  53. package/dist/modules/data_sync/components/IntegrationScheduleTab.js +48 -11
  54. package/dist/modules/data_sync/components/IntegrationScheduleTab.js.map +2 -2
  55. package/dist/modules/data_sync/data/validators.js +13 -2
  56. package/dist/modules/data_sync/data/validators.js.map +2 -2
  57. package/dist/modules/data_sync/lib/schedule-value.js +30 -0
  58. package/dist/modules/data_sync/lib/schedule-value.js.map +7 -0
  59. package/dist/modules/eudr/data/validators.js.map +2 -2
  60. package/dist/modules/portal/frontend/[orgSlug]/portal/dashboard/page.js +3 -4
  61. package/dist/modules/portal/frontend/[orgSlug]/portal/dashboard/page.js.map +2 -2
  62. package/dist/modules/portal/frontend/[orgSlug]/portal/invite/page.js +3 -1
  63. package/dist/modules/portal/frontend/[orgSlug]/portal/invite/page.js.map +2 -2
  64. package/dist/modules/portal/frontend/[orgSlug]/portal/login/page.js +2 -1
  65. package/dist/modules/portal/frontend/[orgSlug]/portal/login/page.js.map +2 -2
  66. package/dist/modules/portal/frontend/[orgSlug]/portal/page.js +3 -4
  67. package/dist/modules/portal/frontend/[orgSlug]/portal/page.js.map +2 -2
  68. package/dist/modules/portal/frontend/[orgSlug]/portal/profile/page.js +3 -4
  69. package/dist/modules/portal/frontend/[orgSlug]/portal/profile/page.js.map +2 -2
  70. package/dist/modules/portal/lib/navigation.js +3 -4
  71. package/dist/modules/portal/lib/navigation.js.map +2 -2
  72. package/dist/modules/query_index/lib/engine.js +79 -14
  73. package/dist/modules/query_index/lib/engine.js.map +2 -2
  74. package/dist/modules/staff/backend/staff/time-tracking/page.js +122 -86
  75. package/dist/modules/staff/backend/staff/time-tracking/page.js.map +2 -2
  76. package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/page.js +38 -17
  77. package/dist/modules/staff/backend/staff/time-tracking/projects/[id]/page.js.map +2 -2
  78. package/dist/modules/staff/backend/staff/time-tracking/reports/[id]/page.js +45 -18
  79. package/dist/modules/staff/backend/staff/time-tracking/reports/[id]/page.js.map +2 -2
  80. package/dist/modules/staff/extension-points.js +16 -0
  81. package/dist/modules/staff/extension-points.js.map +2 -2
  82. package/dist/modules/staff/frontend/[orgSlug]/portal/time-reports/[id]/page.js +3 -4
  83. package/dist/modules/staff/frontend/[orgSlug]/portal/time-reports/[id]/page.js.map +2 -2
  84. package/dist/modules/staff/frontend/[orgSlug]/portal/time-reports/page.js +3 -4
  85. package/dist/modules/staff/frontend/[orgSlug]/portal/time-reports/page.js.map +2 -2
  86. package/dist/modules/staff/lib/time-tracking-ui/ReportSheet.js +14 -13
  87. package/dist/modules/staff/lib/time-tracking-ui/ReportSheet.js.map +2 -2
  88. package/dist/modules/staff/lib/time-tracking-ui/TaskListView.js +60 -41
  89. package/dist/modules/staff/lib/time-tracking-ui/TaskListView.js.map +2 -2
  90. package/dist/modules/warranty_claims/api/ai/assess/route.js +2 -2
  91. package/dist/modules/warranty_claims/api/ai/assess/route.js.map +2 -2
  92. package/dist/modules/warranty_claims/api/ai/draft-reply/route.js +3 -4
  93. package/dist/modules/warranty_claims/api/ai/draft-reply/route.js.map +3 -3
  94. package/dist/modules/warranty_claims/api/ai/suggest/route.js +3 -3
  95. package/dist/modules/warranty_claims/api/ai/suggest/route.js.map +2 -2
  96. package/dist/modules/warranty_claims/api/assign/route.js +3 -3
  97. package/dist/modules/warranty_claims/api/assign/route.js.map +2 -2
  98. package/dist/modules/warranty_claims/api/credit-memo/route.js +2 -2
  99. package/dist/modules/warranty_claims/api/credit-memo/route.js.map +2 -2
  100. package/dist/modules/warranty_claims/api/entitlement/route.js +2 -2
  101. package/dist/modules/warranty_claims/api/entitlement/route.js.map +2 -2
  102. package/dist/modules/warranty_claims/api/events/route.js +4 -4
  103. package/dist/modules/warranty_claims/api/events/route.js.map +2 -2
  104. package/dist/modules/warranty_claims/api/external/claims/route.js +3 -3
  105. package/dist/modules/warranty_claims/api/external/claims/route.js.map +2 -2
  106. package/dist/modules/warranty_claims/api/portal/claims/[id]/submit/route.js +2 -2
  107. package/dist/modules/warranty_claims/api/portal/claims/[id]/submit/route.js.map +2 -2
  108. package/dist/modules/warranty_claims/api/portal/claims/[id]/withdraw/route.js +2 -2
  109. package/dist/modules/warranty_claims/api/portal/claims/[id]/withdraw/route.js.map +2 -2
  110. package/dist/modules/warranty_claims/api/portal/claims/route.js +2 -2
  111. package/dist/modules/warranty_claims/api/portal/claims/route.js.map +2 -2
  112. package/dist/modules/warranty_claims/api/portal/events/route.js +2 -2
  113. package/dist/modules/warranty_claims/api/portal/events/route.js.map +2 -2
  114. package/dist/modules/warranty_claims/api/receiving/route.js +2 -2
  115. package/dist/modules/warranty_claims/api/receiving/route.js.map +2 -2
  116. package/dist/modules/warranty_claims/api/replacement-order/route.js +2 -2
  117. package/dist/modules/warranty_claims/api/replacement-order/route.js.map +2 -2
  118. package/dist/modules/warranty_claims/api/return-label/route.js +2 -2
  119. package/dist/modules/warranty_claims/api/return-label/route.js.map +2 -2
  120. package/dist/modules/warranty_claims/api/risk/route.js +2 -2
  121. package/dist/modules/warranty_claims/api/risk/route.js.map +2 -2
  122. package/dist/modules/warranty_claims/api/sales-return/route.js +2 -2
  123. package/dist/modules/warranty_claims/api/sales-return/route.js.map +2 -2
  124. package/dist/modules/warranty_claims/api/settings-general/route.js +4 -4
  125. package/dist/modules/warranty_claims/api/settings-general/route.js.map +2 -2
  126. package/dist/modules/warranty_claims/api/stats/route.js +2 -2
  127. package/dist/modules/warranty_claims/api/stats/route.js.map +2 -2
  128. package/dist/modules/warranty_claims/api/submit/route.js +3 -3
  129. package/dist/modules/warranty_claims/api/submit/route.js.map +2 -2
  130. package/dist/modules/warranty_claims/api/transition/route.js +3 -3
  131. package/dist/modules/warranty_claims/api/transition/route.js.map +2 -2
  132. package/dist/modules/warranty_claims/api/vendor-recovery/route.js +3 -3
  133. package/dist/modules/warranty_claims/api/vendor-recovery/route.js.map +2 -2
  134. package/dist/modules/warranty_claims/api/vendor-recovery-suggestions/route.js +2 -2
  135. package/dist/modules/warranty_claims/api/vendor-recovery-suggestions/route.js.map +2 -2
  136. package/dist/modules/warranty_claims/backend/page.js +4 -2
  137. package/dist/modules/warranty_claims/backend/page.js.map +2 -2
  138. package/dist/modules/warranty_claims/backend/warranty_claims/[id]/page.js +9 -2
  139. package/dist/modules/warranty_claims/backend/warranty_claims/[id]/page.js.map +2 -2
  140. package/dist/modules/warranty_claims/backend/warranty_claims/settings/page.js +4 -2
  141. package/dist/modules/warranty_claims/backend/warranty_claims/settings/page.js.map +2 -2
  142. package/dist/modules/warranty_claims/frontend/[orgSlug]/portal/claims/[id]/page.js +3 -4
  143. package/dist/modules/warranty_claims/frontend/[orgSlug]/portal/claims/[id]/page.js.map +2 -2
  144. package/dist/modules/warranty_claims/frontend/[orgSlug]/portal/claims/new/page.js +3 -2
  145. package/dist/modules/warranty_claims/frontend/[orgSlug]/portal/claims/new/page.js.map +2 -2
  146. package/dist/modules/warranty_claims/frontend/[orgSlug]/portal/claims/page.js +3 -2
  147. package/dist/modules/warranty_claims/frontend/[orgSlug]/portal/claims/page.js.map +2 -2
  148. package/dist/modules/workflows/components/DefinitionTriggersEditor.js +1 -1
  149. package/dist/modules/workflows/components/DefinitionTriggersEditor.js.map +2 -2
  150. package/dist/modules/workflows/frontend/[orgSlug]/portal/tasks/[id]/page.js +2 -2
  151. package/dist/modules/workflows/frontend/[orgSlug]/portal/tasks/[id]/page.js.map +2 -2
  152. package/dist/modules/workflows/lib/event-trigger-service.js +56 -1
  153. package/dist/modules/workflows/lib/event-trigger-service.js.map +2 -2
  154. package/package.json +7 -7
  155. package/src/modules/auth/api/users/acl/route.ts +4 -3
  156. package/src/modules/auth/components/AclEditor.tsx +38 -2
  157. package/src/modules/auth/i18n/de.json +5 -1
  158. package/src/modules/auth/i18n/en.json +5 -1
  159. package/src/modules/auth/i18n/es.json +5 -1
  160. package/src/modules/auth/i18n/ko.json +5 -1
  161. package/src/modules/auth/i18n/pl.json +5 -1
  162. package/src/modules/customers/backend/customers/companies/page.tsx +6 -4
  163. package/src/modules/customers/backend/customers/deals/map/components/DealsMapView.tsx +6 -4
  164. package/src/modules/customers/backend/customers/deals/page.tsx +6 -4
  165. package/src/modules/customers/backend/customers/deals/pipeline/components/ChangeOwnerDialog.tsx +5 -3
  166. package/src/modules/customers/backend/customers/deals/pipeline/page.tsx +6 -4
  167. package/src/modules/customers/backend/customers/people/page.tsx +6 -4
  168. package/src/modules/customers/components/calendar/editor/PeopleField.tsx +9 -2
  169. package/src/modules/customers/components/calendar/editor/hooks.ts +4 -2
  170. package/src/modules/customers/components/calendar/editor/lookups.ts +12 -4
  171. package/src/modules/customers/components/detail/AssignRoleDialog.tsx +4 -1
  172. package/src/modules/customers/components/detail/RoleAssignmentRow.tsx +4 -2
  173. package/src/modules/customers/components/detail/ScheduleActivityDialog.tsx +15 -7
  174. package/src/modules/customers/components/detail/schedule/DateTimeFields.tsx +16 -7
  175. package/src/modules/customers/components/detail/schedule/ParticipantsField.tsx +4 -2
  176. package/src/modules/customers/components/detail/schedule/fieldConfig.ts +15 -0
  177. package/src/modules/customers/components/detail/schedule/index.ts +1 -1
  178. package/src/modules/customers/components/detail/schedule/useScheduleFormState.ts +16 -9
  179. package/src/modules/customers/components/formConfig.tsx +35 -12
  180. package/src/modules/customers/data/validators.ts +14 -8
  181. package/src/modules/customers/i18n/de.json +1 -0
  182. package/src/modules/customers/i18n/en.json +1 -0
  183. package/src/modules/customers/i18n/es.json +1 -0
  184. package/src/modules/customers/i18n/ko.json +1 -0
  185. package/src/modules/customers/i18n/pl.json +1 -0
  186. package/src/modules/customers/lib/assignableStaff.ts +172 -34
  187. package/src/modules/customers/setup.ts +8 -0
  188. package/src/modules/data_sync/api/schedules/[id]/route.ts +5 -0
  189. package/src/modules/data_sync/api/schedules/route.ts +5 -0
  190. package/src/modules/data_sync/backend/data-sync/page.tsx +48 -4
  191. package/src/modules/data_sync/components/IntegrationScheduleTab.tsx +61 -2
  192. package/src/modules/data_sync/data/validators.ts +26 -2
  193. package/src/modules/data_sync/i18n/de.json +2 -0
  194. package/src/modules/data_sync/i18n/en.json +2 -0
  195. package/src/modules/data_sync/i18n/es.json +2 -0
  196. package/src/modules/data_sync/i18n/ko.json +2 -0
  197. package/src/modules/data_sync/i18n/pl.json +2 -0
  198. package/src/modules/data_sync/lib/schedule-value.ts +45 -0
  199. package/src/modules/eudr/data/validators.ts +3 -4
  200. package/src/modules/portal/frontend/[orgSlug]/portal/dashboard/page.tsx +5 -4
  201. package/src/modules/portal/frontend/[orgSlug]/portal/invite/page.tsx +3 -1
  202. package/src/modules/portal/frontend/[orgSlug]/portal/login/page.tsx +2 -1
  203. package/src/modules/portal/frontend/[orgSlug]/portal/page.tsx +5 -5
  204. package/src/modules/portal/frontend/[orgSlug]/portal/profile/page.tsx +5 -4
  205. package/src/modules/portal/i18n/de.json +1 -0
  206. package/src/modules/portal/i18n/en.json +1 -0
  207. package/src/modules/portal/i18n/es.json +1 -0
  208. package/src/modules/portal/i18n/ko.json +1 -0
  209. package/src/modules/portal/i18n/pl.json +1 -0
  210. package/src/modules/portal/lib/navigation.ts +8 -3
  211. package/src/modules/query_index/lib/engine.ts +111 -16
  212. package/src/modules/staff/backend/staff/time-tracking/page.tsx +161 -130
  213. package/src/modules/staff/backend/staff/time-tracking/projects/[id]/page.tsx +55 -43
  214. package/src/modules/staff/backend/staff/time-tracking/reports/[id]/page.tsx +61 -38
  215. package/src/modules/staff/extension-points.ts +16 -0
  216. package/src/modules/staff/frontend/[orgSlug]/portal/time-reports/[id]/page.tsx +3 -4
  217. package/src/modules/staff/frontend/[orgSlug]/portal/time-reports/page.tsx +3 -4
  218. package/src/modules/staff/i18n/de.json +3 -0
  219. package/src/modules/staff/i18n/en.json +3 -0
  220. package/src/modules/staff/i18n/es.json +3 -0
  221. package/src/modules/staff/i18n/ko.json +3 -0
  222. package/src/modules/staff/i18n/pl.json +3 -0
  223. package/src/modules/staff/lib/time-tracking-ui/ReportSheet.tsx +32 -29
  224. package/src/modules/staff/lib/time-tracking-ui/TaskListView.tsx +89 -79
  225. package/src/modules/warranty_claims/api/ai/assess/route.ts +2 -2
  226. package/src/modules/warranty_claims/api/ai/draft-reply/route.ts +2 -3
  227. package/src/modules/warranty_claims/api/ai/suggest/route.ts +3 -3
  228. package/src/modules/warranty_claims/api/assign/route.ts +3 -3
  229. package/src/modules/warranty_claims/api/credit-memo/route.ts +2 -2
  230. package/src/modules/warranty_claims/api/entitlement/route.ts +2 -2
  231. package/src/modules/warranty_claims/api/events/route.ts +4 -4
  232. package/src/modules/warranty_claims/api/external/claims/route.ts +3 -3
  233. package/src/modules/warranty_claims/api/portal/claims/[id]/submit/route.ts +2 -2
  234. package/src/modules/warranty_claims/api/portal/claims/[id]/withdraw/route.ts +2 -2
  235. package/src/modules/warranty_claims/api/portal/claims/route.ts +2 -2
  236. package/src/modules/warranty_claims/api/portal/events/route.ts +2 -2
  237. package/src/modules/warranty_claims/api/receiving/route.ts +2 -2
  238. package/src/modules/warranty_claims/api/replacement-order/route.ts +2 -2
  239. package/src/modules/warranty_claims/api/return-label/route.ts +2 -2
  240. package/src/modules/warranty_claims/api/risk/route.ts +2 -2
  241. package/src/modules/warranty_claims/api/sales-return/route.ts +2 -2
  242. package/src/modules/warranty_claims/api/settings-general/route.ts +4 -4
  243. package/src/modules/warranty_claims/api/stats/route.ts +2 -2
  244. package/src/modules/warranty_claims/api/submit/route.ts +3 -3
  245. package/src/modules/warranty_claims/api/transition/route.ts +3 -3
  246. package/src/modules/warranty_claims/api/vendor-recovery/route.ts +3 -3
  247. package/src/modules/warranty_claims/api/vendor-recovery-suggestions/route.ts +2 -2
  248. package/src/modules/warranty_claims/backend/page.tsx +4 -2
  249. package/src/modules/warranty_claims/backend/warranty_claims/[id]/page.tsx +9 -2
  250. package/src/modules/warranty_claims/backend/warranty_claims/settings/page.tsx +4 -2
  251. package/src/modules/warranty_claims/frontend/[orgSlug]/portal/claims/[id]/page.tsx +5 -4
  252. package/src/modules/warranty_claims/frontend/[orgSlug]/portal/claims/new/page.tsx +5 -2
  253. package/src/modules/warranty_claims/frontend/[orgSlug]/portal/claims/page.tsx +5 -2
  254. package/src/modules/workflows/components/DefinitionTriggersEditor.tsx +1 -1
  255. package/src/modules/workflows/frontend/[orgSlug]/portal/tasks/[id]/page.tsx +2 -2
  256. package/src/modules/workflows/i18n/de.json +1 -1
  257. package/src/modules/workflows/i18n/en.json +1 -1
  258. package/src/modules/workflows/i18n/es.json +1 -1
  259. package/src/modules/workflows/i18n/ko.json +1 -1
  260. package/src/modules/workflows/i18n/pl.json +1 -1
  261. package/src/modules/workflows/lib/event-trigger-service.ts +139 -0
@@ -4,7 +4,7 @@ import type { EntityManager } from '@mikro-orm/postgresql'
4
4
  import type { AuthContext } from '@open-mercato/shared/lib/auth/server'
5
5
  import { createRequestContainer } from '@open-mercato/shared/lib/di/container'
6
6
  import type { CommandBus, CommandRuntimeContext } from '@open-mercato/shared/lib/commands'
7
- import { isCrudHttpError } from '@open-mercato/shared/lib/crud/errors'
7
+ import { isCrudHttpError, translateCrudErrorBody } from '@open-mercato/shared/lib/crud/errors'
8
8
  import { getCommandInterceptorHttpRejection } from '@open-mercato/shared/lib/commands/errors'
9
9
  import { runRouteMutationGuards, type RouteMutationGuardResult } from '@open-mercato/shared/lib/crud/route-mutation-guard'
10
10
  import { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'
@@ -212,7 +212,7 @@ export async function POST(req: Request) {
212
212
  await guarded.runAfterSuccess()
213
213
  } catch (err) {
214
214
  if (isCrudHttpError(err)) {
215
- return NextResponse.json(err.body, { status: err.status })
215
+ return NextResponse.json(translateCrudErrorBody(err.body, translate), { status: err.status })
216
216
  }
217
217
  const interceptorRejection = getCommandInterceptorHttpRejection(err)
218
218
  if (interceptorRejection) {
@@ -4,7 +4,7 @@ import { createRequestContainer } from '@open-mercato/shared/lib/di/container'
4
4
  import { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'
5
5
  import { resolveOrganizationScopeForRequest } from '@open-mercato/core/modules/directory/utils/organizationScope'
6
6
  import type { CommandBus, CommandRuntimeContext } from '@open-mercato/shared/lib/commands'
7
- import { CrudHttpError, isCrudHttpError } from '@open-mercato/shared/lib/crud/errors'
7
+ import { CrudHttpError, isCrudHttpError, translateCrudErrorBody } from '@open-mercato/shared/lib/crud/errors'
8
8
  import { getCommandInterceptorHttpRejection } from '@open-mercato/shared/lib/commands/errors'
9
9
  import { readJsonSafe } from '@open-mercato/shared/lib/http/readJsonSafe'
10
10
  import { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'
@@ -186,7 +186,7 @@ export async function POST(req: Request) {
186
186
 
187
187
  return NextResponse.json({ ok: true, lineId: result.lineId, claimId: result.claimId })
188
188
  } catch (err) {
189
- if (isCrudHttpError(err)) return NextResponse.json(err.body, { status: err.status })
189
+ if (isCrudHttpError(err)) return NextResponse.json(translateCrudErrorBody(err.body, translate), { status: err.status })
190
190
  const interceptorRejection = getCommandInterceptorHttpRejection(err)
191
191
  if (interceptorRejection) {
192
192
  return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status })
@@ -4,7 +4,7 @@ import { createRequestContainer } from '@open-mercato/shared/lib/di/container'
4
4
  import { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'
5
5
  import { resolveOrganizationScopeForRequest } from '@open-mercato/core/modules/directory/utils/organizationScope'
6
6
  import type { CommandBus, CommandRuntimeContext } from '@open-mercato/shared/lib/commands'
7
- import { CrudHttpError, isCrudHttpError } from '@open-mercato/shared/lib/crud/errors'
7
+ import { CrudHttpError, isCrudHttpError, translateCrudErrorBody } from '@open-mercato/shared/lib/crud/errors'
8
8
  import { getCommandInterceptorHttpRejection } from '@open-mercato/shared/lib/commands/errors'
9
9
  import { readJsonSafe } from '@open-mercato/shared/lib/http/readJsonSafe'
10
10
  import { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'
@@ -157,7 +157,7 @@ export async function POST(req: Request) {
157
157
  skippedLineIds: result.skippedLineIds,
158
158
  })
159
159
  } catch (err) {
160
- if (isCrudHttpError(err)) return NextResponse.json(err.body, { status: err.status })
160
+ if (isCrudHttpError(err)) return NextResponse.json(translateCrudErrorBody(err.body, translate), { status: err.status })
161
161
  const interceptorRejection = getCommandInterceptorHttpRejection(err)
162
162
  if (interceptorRejection) {
163
163
  return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status })
@@ -5,7 +5,7 @@ import { createRequestContainer } from '@open-mercato/shared/lib/di/container'
5
5
  import { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'
6
6
  import { resolveOrganizationScopeForRequest } from '@open-mercato/core/modules/directory/utils/organizationScope'
7
7
  import type { CommandBus, CommandRuntimeContext } from '@open-mercato/shared/lib/commands'
8
- import { CrudHttpError, isCrudHttpError } from '@open-mercato/shared/lib/crud/errors'
8
+ import { CrudHttpError, isCrudHttpError, translateCrudErrorBody } from '@open-mercato/shared/lib/crud/errors'
9
9
  import { getCommandInterceptorHttpRejection } from '@open-mercato/shared/lib/commands/errors'
10
10
  import { readJsonSafe } from '@open-mercato/shared/lib/http/readJsonSafe'
11
11
  import { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'
@@ -268,7 +268,7 @@ export async function POST(req: Request) {
268
268
  await guarded.runAfterSuccess()
269
269
  return NextResponse.json(response)
270
270
  } catch (err) {
271
- if (isCrudHttpError(err)) return NextResponse.json(err.body, { status: err.status })
271
+ if (isCrudHttpError(err)) return NextResponse.json(translateCrudErrorBody(err.body, translate), { status: err.status })
272
272
  const interceptorRejection = getCommandInterceptorHttpRejection(err)
273
273
  if (interceptorRejection) {
274
274
  return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status })
@@ -4,7 +4,7 @@ import type { EntityManager } from '@mikro-orm/postgresql'
4
4
  import { createRequestContainer } from '@open-mercato/shared/lib/di/container'
5
5
  import { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'
6
6
  import { resolveOrganizationScopeForRequest } from '@open-mercato/core/modules/directory/utils/organizationScope'
7
- import { CrudHttpError, isCrudHttpError } from '@open-mercato/shared/lib/crud/errors'
7
+ import { CrudHttpError, isCrudHttpError, translateCrudErrorBody } from '@open-mercato/shared/lib/crud/errors'
8
8
  import { findWithDecryption } from '@open-mercato/shared/lib/encryption/find'
9
9
  import { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'
10
10
  import type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'
@@ -85,8 +85,8 @@ export async function GET(req: Request) {
85
85
  const result = await evaluateClaimRisk(context.em, claim, lines)
86
86
  return NextResponse.json({ ok: true, result })
87
87
  } catch (err) {
88
- if (isCrudHttpError(err)) return NextResponse.json(err.body, { status: err.status })
89
88
  const { translate } = await resolveTranslations()
89
+ if (isCrudHttpError(err)) return NextResponse.json(translateCrudErrorBody(err.body, translate), { status: err.status })
90
90
  if (err instanceof z.ZodError) {
91
91
  return NextResponse.json({ error: translate('warranty_claims.errors.invalidInput', 'Invalid input') }, { status: 400 })
92
92
  }
@@ -4,7 +4,7 @@ import { createRequestContainer } from '@open-mercato/shared/lib/di/container'
4
4
  import { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'
5
5
  import { resolveOrganizationScopeForRequest } from '@open-mercato/core/modules/directory/utils/organizationScope'
6
6
  import type { CommandBus, CommandRuntimeContext } from '@open-mercato/shared/lib/commands'
7
- import { CrudHttpError, isCrudHttpError } from '@open-mercato/shared/lib/crud/errors'
7
+ import { CrudHttpError, isCrudHttpError, translateCrudErrorBody } from '@open-mercato/shared/lib/crud/errors'
8
8
  import { getCommandInterceptorHttpRejection } from '@open-mercato/shared/lib/commands/errors'
9
9
  import { readJsonSafe } from '@open-mercato/shared/lib/http/readJsonSafe'
10
10
  import { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'
@@ -149,7 +149,7 @@ export async function POST(req: Request) {
149
149
  await guarded.runAfterSuccess()
150
150
  return NextResponse.json({ salesReturnId: result.salesReturnId, skippedLineIds: result.skippedLineIds })
151
151
  } catch (err) {
152
- if (isCrudHttpError(err)) return NextResponse.json(err.body, { status: err.status })
152
+ if (isCrudHttpError(err)) return NextResponse.json(translateCrudErrorBody(err.body, translate), { status: err.status })
153
153
  const interceptorRejection = getCommandInterceptorHttpRejection(err)
154
154
  if (interceptorRejection) {
155
155
  return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status })
@@ -6,7 +6,7 @@ import { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'
6
6
  import { resolveOrganizationScopeForRequest } from '@open-mercato/core/modules/directory/utils/organizationScope'
7
7
  import type { CommandBus, CommandRuntimeContext } from '@open-mercato/shared/lib/commands'
8
8
  import { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'
9
- import { CrudHttpError, isCrudHttpError } from '@open-mercato/shared/lib/crud/errors'
9
+ import { CrudHttpError, isCrudHttpError, translateCrudErrorBody } from '@open-mercato/shared/lib/crud/errors'
10
10
  import { getCommandInterceptorHttpRejection } from '@open-mercato/shared/lib/commands/errors'
11
11
  import { readJsonSafe } from '@open-mercato/shared/lib/http/readJsonSafe'
12
12
  import { runRouteMutationGuards } from '@open-mercato/shared/lib/crud/route-mutation-guard'
@@ -105,8 +105,8 @@ export async function GET(req: Request) {
105
105
  const result = await buildSettingsResult(em, { tenantId, organizationId })
106
106
  return NextResponse.json({ ok: true, result })
107
107
  } catch (err) {
108
- if (isCrudHttpError(err)) return NextResponse.json(err.body, { status: err.status })
109
108
  const { translate } = await resolveTranslations()
109
+ if (isCrudHttpError(err)) return NextResponse.json(translateCrudErrorBody(err.body, translate), { status: err.status })
110
110
  logger.error('warranty_claims.settings-general.get failed', { err })
111
111
  return NextResponse.json({ error: translate('warranty_claims.errors.load_failed', 'Failed to load warranty claim data.') }, { status: 500 })
112
112
  }
@@ -165,12 +165,12 @@ export async function PUT(req: Request) {
165
165
  },
166
166
  })
167
167
  } catch (err) {
168
- if (isCrudHttpError(err)) return NextResponse.json(err.body, { status: err.status })
168
+ const { translate } = await resolveTranslations()
169
+ if (isCrudHttpError(err)) return NextResponse.json(translateCrudErrorBody(err.body, translate), { status: err.status })
169
170
  const interceptorRejection = getCommandInterceptorHttpRejection(err)
170
171
  if (interceptorRejection) {
171
172
  return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status })
172
173
  }
173
- const { translate } = await resolveTranslations()
174
174
  if (err instanceof z.ZodError) {
175
175
  return NextResponse.json({ error: translate('warranty_claims.errors.invalidInput', 'Invalid input') }, { status: 400 })
176
176
  }
@@ -5,7 +5,7 @@ import { sql, type SelectQueryBuilder } from 'kysely'
5
5
  import { createRequestContainer } from '@open-mercato/shared/lib/di/container'
6
6
  import { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'
7
7
  import { resolveOrganizationScopeForRequest } from '@open-mercato/core/modules/directory/utils/organizationScope'
8
- import { CrudHttpError, isCrudHttpError } from '@open-mercato/shared/lib/crud/errors'
8
+ import { CrudHttpError, isCrudHttpError, translateCrudErrorBody } from '@open-mercato/shared/lib/crud/errors'
9
9
  import { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'
10
10
  import type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'
11
11
  import { resolveEffectiveWarrantyClaimSettings } from '../../lib/settings'
@@ -277,8 +277,8 @@ export async function GET(req: Request) {
277
277
  },
278
278
  })
279
279
  } catch (err) {
280
- if (isCrudHttpError(err)) return NextResponse.json(err.body, { status: err.status })
281
280
  const { translate } = await resolveTranslations()
281
+ if (isCrudHttpError(err)) return NextResponse.json(translateCrudErrorBody(err.body, translate), { status: err.status })
282
282
  if (err instanceof z.ZodError) {
283
283
  return NextResponse.json({ error: translate('warranty_claims.errors.invalidInput', 'Invalid input') }, { status: 400 })
284
284
  }
@@ -5,7 +5,7 @@ import { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'
5
5
  import { resolveOrganizationScopeForRequest } from '@open-mercato/core/modules/directory/utils/organizationScope'
6
6
  import type { CommandBus, CommandRuntimeContext } from '@open-mercato/shared/lib/commands'
7
7
  import { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'
8
- import { CrudHttpError, isCrudHttpError } from '@open-mercato/shared/lib/crud/errors'
8
+ import { CrudHttpError, isCrudHttpError, translateCrudErrorBody } from '@open-mercato/shared/lib/crud/errors'
9
9
  import { getCommandInterceptorHttpRejection } from '@open-mercato/shared/lib/commands/errors'
10
10
  import { readJsonSafe } from '@open-mercato/shared/lib/http/readJsonSafe'
11
11
  import { runRouteMutationGuards, type RouteMutationGuardResult } from '@open-mercato/shared/lib/crud/route-mutation-guard'
@@ -118,12 +118,12 @@ export async function POST(req: Request) {
118
118
 
119
119
  return NextResponse.json({ ok: true, claimId: result?.claimId ?? commandInput.id })
120
120
  } catch (err) {
121
- if (isCrudHttpError(err)) return NextResponse.json(err.body, { status: err.status })
121
+ const { translate } = await resolveTranslations()
122
+ if (isCrudHttpError(err)) return NextResponse.json(translateCrudErrorBody(err.body, translate), { status: err.status })
122
123
  const interceptorRejection = getCommandInterceptorHttpRejection(err)
123
124
  if (interceptorRejection) {
124
125
  return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status })
125
126
  }
126
- const { translate } = await resolveTranslations()
127
127
  if (err instanceof z.ZodError) {
128
128
  return NextResponse.json({ error: translate('warranty_claims.errors.invalidInput', 'Invalid input') }, { status: 400 })
129
129
  }
@@ -5,7 +5,7 @@ import { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'
5
5
  import { resolveOrganizationScopeForRequest } from '@open-mercato/core/modules/directory/utils/organizationScope'
6
6
  import type { CommandBus, CommandRuntimeContext } from '@open-mercato/shared/lib/commands'
7
7
  import { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'
8
- import { CrudHttpError, isCrudHttpError } from '@open-mercato/shared/lib/crud/errors'
8
+ import { CrudHttpError, isCrudHttpError, translateCrudErrorBody } from '@open-mercato/shared/lib/crud/errors'
9
9
  import { getCommandInterceptorHttpRejection } from '@open-mercato/shared/lib/commands/errors'
10
10
  import { readJsonSafe } from '@open-mercato/shared/lib/http/readJsonSafe'
11
11
  import { runRouteMutationGuards, type RouteMutationGuardResult } from '@open-mercato/shared/lib/crud/route-mutation-guard'
@@ -116,12 +116,12 @@ export async function POST(req: Request) {
116
116
 
117
117
  return NextResponse.json({ ok: true, claimId: result?.claimId ?? commandInput.id })
118
118
  } catch (err) {
119
- if (isCrudHttpError(err)) return NextResponse.json(err.body, { status: err.status })
119
+ const { translate } = await resolveTranslations()
120
+ if (isCrudHttpError(err)) return NextResponse.json(translateCrudErrorBody(err.body, translate), { status: err.status })
120
121
  const interceptorRejection = getCommandInterceptorHttpRejection(err)
121
122
  if (interceptorRejection) {
122
123
  return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status })
123
124
  }
124
- const { translate } = await resolveTranslations()
125
125
  if (err instanceof z.ZodError) {
126
126
  return NextResponse.json({ error: translate('warranty_claims.errors.invalidInput', 'Invalid input') }, { status: 400 })
127
127
  }
@@ -5,7 +5,7 @@ import { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'
5
5
  import { resolveOrganizationScopeForRequest } from '@open-mercato/core/modules/directory/utils/organizationScope'
6
6
  import type { CommandBus, CommandRuntimeContext } from '@open-mercato/shared/lib/commands'
7
7
  import { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'
8
- import { CrudHttpError, isCrudHttpError } from '@open-mercato/shared/lib/crud/errors'
8
+ import { CrudHttpError, isCrudHttpError, translateCrudErrorBody } from '@open-mercato/shared/lib/crud/errors'
9
9
  import { getCommandInterceptorHttpRejection } from '@open-mercato/shared/lib/commands/errors'
10
10
  import { readJsonSafe } from '@open-mercato/shared/lib/http/readJsonSafe'
11
11
  import { runRouteMutationGuards, type RouteMutationGuardResult } from '@open-mercato/shared/lib/crud/route-mutation-guard'
@@ -120,12 +120,12 @@ export async function POST(req: Request) {
120
120
 
121
121
  return NextResponse.json({ ok: true, claimId: createdClaimId })
122
122
  } catch (err) {
123
- if (isCrudHttpError(err)) return NextResponse.json(err.body, { status: err.status })
123
+ const { translate } = await resolveTranslations()
124
+ if (isCrudHttpError(err)) return NextResponse.json(translateCrudErrorBody(err.body, translate), { status: err.status })
124
125
  const interceptorRejection = getCommandInterceptorHttpRejection(err)
125
126
  if (interceptorRejection) {
126
127
  return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status })
127
128
  }
128
- const { translate } = await resolveTranslations()
129
129
  if (err instanceof z.ZodError) {
130
130
  return NextResponse.json({ error: translate('warranty_claims.errors.invalidInput', 'Invalid input') }, { status: 400 })
131
131
  }
@@ -4,7 +4,7 @@ import type { EntityManager } from '@mikro-orm/postgresql'
4
4
  import { createRequestContainer } from '@open-mercato/shared/lib/di/container'
5
5
  import { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'
6
6
  import { resolveOrganizationScopeForRequest } from '@open-mercato/core/modules/directory/utils/organizationScope'
7
- import { CrudHttpError, isCrudHttpError } from '@open-mercato/shared/lib/crud/errors'
7
+ import { CrudHttpError, isCrudHttpError, translateCrudErrorBody } from '@open-mercato/shared/lib/crud/errors'
8
8
  import { findWithDecryption } from '@open-mercato/shared/lib/encryption/find'
9
9
  import { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'
10
10
  import type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'
@@ -140,8 +140,8 @@ export async function GET(req: Request) {
140
140
  }))
141
141
  return NextResponse.json({ ok: true, result: { claimId: claim.id, suggestions } })
142
142
  } catch (err) {
143
- if (isCrudHttpError(err)) return NextResponse.json(err.body, { status: err.status })
144
143
  const { translate } = await resolveTranslations()
144
+ if (isCrudHttpError(err)) return NextResponse.json(translateCrudErrorBody(err.body, translate), { status: err.status })
145
145
  if (err instanceof z.ZodError) {
146
146
  return NextResponse.json({ error: translate('warranty_claims.errors.invalidInput', 'Invalid input') }, { status: 400 })
147
147
  }
@@ -23,6 +23,7 @@ import { buildCrudExportUrl } from '@open-mercato/ui/backend/utils/crud'
23
23
  import { buildOptimisticLockHeader } from '@open-mercato/ui/backend/utils/optimisticLock'
24
24
  import { surfaceRecordConflict } from '@open-mercato/ui/backend/conflicts'
25
25
  import { useCurrentUserId } from '@open-mercato/ui/backend/utils/useCurrentUserId'
26
+ import { useCurrentOrganization } from '@open-mercato/ui/backend/BackendChromeProvider'
26
27
  import { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'
27
28
  import { emitProgressUpdate } from '@open-mercato/shared/lib/frontend/progressEvents'
28
29
  import { useLocale, useT } from '@open-mercato/shared/lib/i18n/context'
@@ -411,6 +412,7 @@ export default function WarrantyClaimsPage() {
411
412
  const pathname = usePathname()
412
413
  const searchParams = useSearchParams()
413
414
  const scopeVersion = useOrganizationScopeVersion()
415
+ const activeOrgId = useCurrentOrganization()?.id ?? null
414
416
  const { confirm, ConfirmDialogElement } = useConfirmDialog()
415
417
  const currentUserId = useCurrentUserId()
416
418
  const initialUrlStateRef = React.useRef<RestoredClaimListState | null>(null)
@@ -617,7 +619,7 @@ export default function WarrantyClaimsPage() {
617
619
  )
618
620
 
619
621
  const loadAssignableStaffOptions = React.useCallback(async (query?: string): Promise<CrudFieldOption[]> => {
620
- const page = await fetchAssignableStaffMembersPage(query ?? '', { pageSize: 24 })
622
+ const page = await fetchAssignableStaffMembersPage(query ?? '', { pageSize: 24, activeOrgId })
621
623
  const options = page.items.map((member) => ({
622
624
  value: member.userId,
623
625
  label: staffOptionLabel(member),
@@ -629,7 +631,7 @@ export default function WarrantyClaimsPage() {
629
631
  },
630
632
  ...options,
631
633
  ]
632
- }, [t])
634
+ }, [activeOrgId, t])
633
635
 
634
636
  const formatAssigneeFilterValue = React.useCallback((value: string) => {
635
637
  if (value === UNASSIGNED_ASSIGNEE_VALUE) return t('warranty_claims.form.assigneeUserId.unassigned', 'Unassigned')
@@ -45,6 +45,7 @@ import { surfaceRecordConflict } from '@open-mercato/ui/backend/conflicts'
45
45
  import { mapCrudServerErrorToFormErrors } from '@open-mercato/ui/backend/utils/serverErrors'
46
46
  import { useCurrentUserId } from '@open-mercato/ui/backend/utils/useCurrentUserId'
47
47
  import { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'
48
+ import { useCurrentOrganization } from '@open-mercato/ui/backend/BackendChromeProvider'
48
49
  import { AttachmentInput } from '@open-mercato/core/modules/attachments/fields/attachment'
49
50
  import {
50
51
  fetchAssignableStaffMembersPage,
@@ -766,6 +767,7 @@ export default function WarrantyClaimDetailPage({ params }: { params?: { id?: st
766
767
  const { confirm, ConfirmDialogElement } = useConfirmDialog()
767
768
  const currentUserId = useCurrentUserId()
768
769
  const scopeVersion = useOrganizationScopeVersion()
770
+ const activeOrgId = useCurrentOrganization()?.id ?? null
769
771
  const [claim, setClaim] = React.useState<ClaimRecord | null>(null)
770
772
  const [lines, setLines] = React.useState<ClaimLine[]>([])
771
773
  const [events, setEvents] = React.useState<ClaimEvent[]>([])
@@ -1007,14 +1009,19 @@ export default function WarrantyClaimDetailPage({ params }: { params?: { id?: st
1007
1009
  if (!assignDialogOpen) return
1008
1010
  const controller = new AbortController()
1009
1011
  setAssignLoading(true)
1010
- fetchAssignableStaffMembersPage(assignSearch, { page: 1, pageSize: 24, signal: controller.signal })
1012
+ fetchAssignableStaffMembersPage(assignSearch, {
1013
+ page: 1,
1014
+ pageSize: 24,
1015
+ activeOrgId,
1016
+ signal: controller.signal,
1017
+ })
1011
1018
  .then((page) => setAssignOptions(page.items))
1012
1019
  .catch(() => setAssignOptions([]))
1013
1020
  .finally(() => {
1014
1021
  if (!controller.signal.aborted) setAssignLoading(false)
1015
1022
  })
1016
1023
  return () => controller.abort()
1017
- }, [assignDialogOpen, assignSearch])
1024
+ }, [activeOrgId, assignDialogOpen, assignSearch])
1018
1025
 
1019
1026
  const claimCustomerId = claim?.customerId ?? null
1020
1027
  React.useEffect(() => {
@@ -22,6 +22,7 @@ import { Switch } from '@open-mercato/ui/primitives/switch'
22
22
  import { Textarea } from '@open-mercato/ui/primitives/textarea'
23
23
  import { ComboboxInput, type ComboboxOption } from '@open-mercato/ui/backend/inputs/ComboboxInput'
24
24
  import { useOrganizationScopeVersion } from '@open-mercato/shared/lib/frontend/useOrganizationScope'
25
+ import { useCurrentOrganization } from '@open-mercato/ui/backend/BackendChromeProvider'
25
26
  import { useT } from '@open-mercato/shared/lib/i18n/context'
26
27
  import { ICON_SUGGESTIONS } from '@open-mercato/core/modules/dictionaries/components/dictionaryAppearance'
27
28
  import {
@@ -1006,6 +1007,7 @@ function GeneralSettingsSubsection({
1006
1007
  export default function WarrantyClaimSettingsPage() {
1007
1008
  const t = useT()
1008
1009
  const scopeVersion = useOrganizationScopeVersion()
1010
+ const activeOrgId = useCurrentOrganization()?.id ?? null
1009
1011
  const { confirm, ConfirmDialogElement } = useConfirmDialog()
1010
1012
  const [entriesByKind, setEntriesByKind] = React.useState<Record<WarrantyDictionaryKind, DictionaryTableEntry[]>>({
1011
1013
  'warranty-claim-fault-code': [],
@@ -1198,9 +1200,9 @@ export default function WarrantyClaimSettingsPage() {
1198
1200
  ), [])
1199
1201
 
1200
1202
  const loadEscalationStaffOptions = React.useCallback(async (query?: string): Promise<ComboboxOption[]> => {
1201
- const page = await fetchAssignableStaffMembersPage(query ?? '', { pageSize: 24 })
1203
+ const page = await fetchAssignableStaffMembersPage(query ?? '', { pageSize: 24, activeOrgId })
1202
1204
  return page.items.map((member) => ({ value: member.userId, label: staffOptionLabel(member) }))
1203
- }, [staffOptionLabel])
1205
+ }, [activeOrgId, staffOptionLabel])
1204
1206
 
1205
1207
  const resolveStaffUserLabel = React.useCallback(async (userId: string): Promise<string> => {
1206
1208
  const unknownUserLabel = t('warranty_claims.detail.unknownUser')
@@ -2,8 +2,8 @@
2
2
 
3
3
  import * as React from 'react'
4
4
  import Link from 'next/link'
5
- import { useRouter } from 'next/navigation'
6
5
  import { ArrowLeft, Check, CircleAlert, Info, Paperclip, RefreshCw, ShieldCheck, Trash2, TriangleAlert } from 'lucide-react'
6
+ import { replaceWithPageReload } from '@open-mercato/core/modules/portal/lib/navigation'
7
7
  import { useLocale, useT, type TranslateFn } from '@open-mercato/shared/lib/i18n/context'
8
8
  import { localizeDictionaryLabel } from '@open-mercato/core/modules/warranty_claims/lib/dictionaryLabels'
9
9
  import { formatQuantity } from '@open-mercato/core/modules/warranty_claims/lib/quantity'
@@ -330,7 +330,6 @@ const DARK_BUTTON_CLASS = 'rounded-md px-3 py-2 text-sm font-medium'
330
330
  export default function WarrantyClaimPortalDetailPage({ params }: Props) {
331
331
  const t = useT()
332
332
  const locale = useLocale()
333
- const router = useRouter()
334
333
  const { auth } = usePortalContext()
335
334
  const { user, loading } = auth
336
335
  const guardedMutation = useGuardedMutation<Record<string, unknown>>({
@@ -354,11 +353,13 @@ export default function WarrantyClaimPortalDetailPage({ params }: Props) {
354
353
  const replacementInputRef = React.useRef<HTMLInputElement | null>(null)
355
354
  const replacementTargetRef = React.useRef<PortalAttachment | null>(null)
356
355
 
356
+ // Leaving an authenticated page for the login page crosses the public/authenticated
357
+ // boundary, so it must be a full page load — see `replaceWithPageReload`.
357
358
  React.useEffect(() => {
358
359
  if (!loading && !user) {
359
- router.replace(`/${params.orgSlug}/portal/login`)
360
+ replaceWithPageReload(`/${params.orgSlug}/portal/login`)
360
361
  }
361
- }, [loading, user, router, params.orgSlug])
362
+ }, [loading, user, params.orgSlug])
362
363
 
363
364
  const refreshEvents = React.useCallback(async (claimId: string) => {
364
365
  const result = await apiCall<EventResponse>(`/api/warranty_claims/portal/events?claimId=${encodeURIComponent(claimId)}`)
@@ -4,6 +4,7 @@ import * as React from 'react'
4
4
  import Link from 'next/link'
5
5
  import { useRouter } from 'next/navigation'
6
6
  import { ArrowLeft, ArrowRight, FileText, Plus, Send, Trash2 } from 'lucide-react'
7
+ import { replaceWithPageReload } from '@open-mercato/core/modules/portal/lib/navigation'
7
8
  import { useLocale, useT } from '@open-mercato/shared/lib/i18n/context'
8
9
  import { Button } from '@open-mercato/ui/primitives/button'
9
10
  import { Checkbox } from '@open-mercato/ui/primitives/checkbox'
@@ -307,11 +308,13 @@ export default function WarrantyClaimPortalNewPage({ params }: Props) {
307
308
  const serialLookupTimers = React.useRef<Record<string, number>>({})
308
309
  const isMountedRef = React.useRef(true)
309
310
 
311
+ // Leaving an authenticated page for the login page crosses the public/authenticated
312
+ // boundary, so it must be a full page load — see `replaceWithPageReload`.
310
313
  React.useEffect(() => {
311
314
  if (!loading && !user) {
312
- router.replace(`/${params.orgSlug}/portal/login`)
315
+ replaceWithPageReload(`/${params.orgSlug}/portal/login`)
313
316
  }
314
- }, [loading, user, router, params.orgSlug])
317
+ }, [loading, user, params.orgSlug])
315
318
 
316
319
  React.useEffect(() => {
317
320
  isMountedRef.current = true
@@ -5,6 +5,7 @@ import Link from 'next/link'
5
5
  import { useRouter } from 'next/navigation'
6
6
  import type { LegacyColumnDef as ColumnDef } from '@tanstack/react-table/legacy'
7
7
  import { ChevronRight, Plus, ShieldCheck } from 'lucide-react'
8
+ import { replaceWithPageReload } from '@open-mercato/core/modules/portal/lib/navigation'
8
9
  import { useLocale, useT } from '@open-mercato/shared/lib/i18n/context'
9
10
  import { formatRelativeTime } from '@open-mercato/shared/lib/time'
10
11
  import { Button } from '@open-mercato/ui/primitives/button'
@@ -72,11 +73,13 @@ export default function WarrantyClaimsPortalListPage({ params }: Props) {
72
73
  const [stateGroup, setStateGroup] = React.useState<'all' | 'open' | 'resolved'>('all')
73
74
  const [tabCounts, setTabCounts] = React.useState<Partial<Record<'all' | 'open' | 'resolved', number>>>({})
74
75
 
76
+ // Leaving an authenticated page for the login page crosses the public/authenticated
77
+ // boundary, so it must be a full page load — see `replaceWithPageReload`.
75
78
  React.useEffect(() => {
76
79
  if (!loading && !user) {
77
- router.replace(`/${params.orgSlug}/portal/login`)
80
+ replaceWithPageReload(`/${params.orgSlug}/portal/login`)
78
81
  }
79
- }, [loading, user, router, params.orgSlug])
82
+ }, [loading, user, params.orgSlug])
80
83
 
81
84
  const statusFilter = typeof filterValues.status === 'string' ? filterValues.status : ''
82
85
 
@@ -628,7 +628,7 @@ export function DefinitionTriggersEditor({
628
628
  placeholder={t('workflows.triggers.placeholders.debounce', 'e.g. 1000')}
629
629
  />
630
630
  <p className="text-xs text-muted-foreground">
631
- {t('workflows.triggers.hints.debounce', 'Wait this many milliseconds after an event before starting, so a burst of similar events starts only one workflow. Leave empty to start immediately.')}
631
+ {t('workflows.triggers.hints.debounce', 'The first matching event starts an instance immediately; further events for the same record within this many milliseconds are skipped. Leave empty to start an instance for every event.')}
632
632
  </p>
633
633
  </div>
634
634
  <div className="space-y-1">
@@ -116,9 +116,9 @@ export default function PortalTaskDetailPage({ params }: Props) {
116
116
  setFailure('submit')
117
117
  return
118
118
  }
119
- router.push(listHref)
119
+ router.push(`/${params.orgSlug}/portal/tasks`)
120
120
  },
121
- [task, values, comments, router, listHref],
121
+ [task, values, comments, router, params.orgSlug],
122
122
  )
123
123
 
124
124
  if (notFound) {
@@ -1952,7 +1952,7 @@
1952
1952
  "workflows.triggers.fields.name": "Name",
1953
1953
  "workflows.triggers.fields.priority": "Priorität",
1954
1954
  "workflows.triggers.hints.contextMapping": "Werte aus der Ereignis-Nutzlast dem anfänglichen Workflow-Kontext zuordnen",
1955
- "workflows.triggers.hints.debounce": "So viele Millisekunden nach einem Ereignis warten, damit ein Schwall ähnlicher Ereignisse nur einen Workflow startet. Leer lassen, um sofort zu starten.",
1955
+ "workflows.triggers.hints.debounce": "Das erste passende Ereignis startet sofort eine Instanz; weitere Ereignisse für denselben Datensatz innerhalb dieser Millisekundenspanne werden übersprungen. Leer lassen, um für jedes Ereignis eine Instanz zu starten.",
1956
1956
  "workflows.triggers.hints.eventPattern": "Verwenden Sie * als Platzhalter: \"sales.orders.*\" passt auf jedes Bestellereignis",
1957
1957
  "workflows.triggers.hints.filterConditions": "Nur auslösen, wenn die Ereignis-Nutzlast diese Bedingungen erfüllt (alle müssen zutreffen)",
1958
1958
  "workflows.triggers.hints.maxConcurrent": "Begrenzt, wie viele Instanzen dieser Auslöser gleichzeitig laufen lassen darf; Ereignisse über dem Limit werden übersprungen. Leer lassen für kein Limit.",
@@ -1952,7 +1952,7 @@
1952
1952
  "workflows.triggers.fields.name": "Name",
1953
1953
  "workflows.triggers.fields.priority": "Priority",
1954
1954
  "workflows.triggers.hints.contextMapping": "Map values from the event payload to the workflow's initial context",
1955
- "workflows.triggers.hints.debounce": "Wait this many milliseconds after an event before starting, so a burst of similar events starts only one workflow. Leave empty to start immediately.",
1955
+ "workflows.triggers.hints.debounce": "The first matching event starts an instance immediately; further events for the same record within this many milliseconds are skipped. Leave empty to start an instance for every event.",
1956
1956
  "workflows.triggers.hints.eventPattern": "Use * as wildcard: \"sales.orders.*\" matches any order event",
1957
1957
  "workflows.triggers.hints.filterConditions": "Only trigger when the event payload matches these conditions (all must match)",
1958
1958
  "workflows.triggers.hints.maxConcurrent": "Cap how many instances this trigger can have running at the same time; events past the cap are skipped. Leave empty for no limit.",
@@ -1952,7 +1952,7 @@
1952
1952
  "workflows.triggers.fields.name": "Nombre",
1953
1953
  "workflows.triggers.fields.priority": "Prioridad",
1954
1954
  "workflows.triggers.hints.contextMapping": "Mapea valores de la carga del evento al contexto inicial del flujo de trabajo",
1955
- "workflows.triggers.hints.debounce": "Espera esta cantidad de milisegundos tras un evento antes de iniciar, para que una ráfaga de eventos similares inicie solo un flujo. Deja vacío para iniciar de inmediato.",
1955
+ "workflows.triggers.hints.debounce": "El primer evento coincidente inicia una instancia de inmediato; los eventos posteriores del mismo registro dentro de esta cantidad de milisegundos se omiten. Deja vacío para iniciar una instancia por cada evento.",
1956
1956
  "workflows.triggers.hints.eventPattern": "Usa * como comodin: \"sales.orders.*\" coincide con cualquier evento de pedido",
1957
1957
  "workflows.triggers.hints.filterConditions": "Solo se dispara cuando la carga del evento coincida con estas condiciones (todas deben coincidir)",
1958
1958
  "workflows.triggers.hints.maxConcurrent": "Limita cuántas instancias puede tener este disparador en ejecución a la vez; los eventos que superen el límite se omiten. Deja vacío para no limitar.",
@@ -1952,7 +1952,7 @@
1952
1952
  "workflows.triggers.fields.name": "이름",
1953
1953
  "workflows.triggers.fields.priority": "우선순위",
1954
1954
  "workflows.triggers.hints.contextMapping": "이벤트 페이로드의 값을 워크플로우의 초기 컨텍스트에 매핑합니다",
1955
- "workflows.triggers.hints.debounce": "잦은 재트리거를 방지하기 위한 지연 시간",
1955
+ "workflows.triggers.hints.debounce": "일치하는 첫 이벤트가 즉시 인스턴스를 시작합니다. 이 시간(밀리초) 이내에 동일한 레코드에 대한 후속 이벤트는 건너뜁니다. 비워두면 모든 이벤트마다 인스턴스가 시작됩니다.",
1956
1956
  "workflows.triggers.hints.eventPattern": "와일드카드로 *를 사용하세요: \"sales.orders.*\"는 모든 주문 이벤트와 일치합니다",
1957
1957
  "workflows.triggers.hints.filterConditions": "이벤트 페이로드가 이 조건들과 모두 일치할 때만 트리거됩니다",
1958
1958
  "workflows.triggers.hints.maxConcurrent": "동시에 실행되는 워크플로우 인스턴스 수를 제한합니다",
@@ -1952,7 +1952,7 @@
1952
1952
  "workflows.triggers.fields.name": "Nazwa",
1953
1953
  "workflows.triggers.fields.priority": "Priorytet",
1954
1954
  "workflows.triggers.hints.contextMapping": "Mapuj wartości z zawartości zdarzenia do początkowego kontekstu przepływu",
1955
- "workflows.triggers.hints.debounce": "Odczekaj tyle milisekund po zdarzeniu przed uruchomieniem, aby seria podobnych zdarzeń uruchomiła tylko jeden przepływ. Pozostaw puste, aby uruchamiać od razu.",
1955
+ "workflows.triggers.hints.debounce": "Pierwsze pasujące zdarzenie uruchamia instancję natychmiast; kolejne zdarzenia dla tego samego rekordu w tym oknie czasowym (w milisekundach) są pomijane. Pozostaw puste, aby uruchamiać instancję dla każdego zdarzenia.",
1956
1956
  "workflows.triggers.hints.eventPattern": "Użyj * jako znaku wieloznacznego: \"sales.orders.*\" pasuje do dowolnego zdarzenia zamówienia",
1957
1957
  "workflows.triggers.hints.filterConditions": "Wyzwalaj tylko wtedy, gdy zawartość zdarzenia pasuje do tych warunków (wszystkie muszą pasować)",
1958
1958
  "workflows.triggers.hints.maxConcurrent": "Ogranicz liczbę instancji uruchomionych jednocześnie przez ten wyzwalacz; zdarzenia ponad limit są pomijane. Pozostaw puste, aby nie ograniczać.",