@open-mercato/core 0.7.1-develop.7130.1.fef2396fd8 → 0.7.1-develop.7135.1.19bf969756

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 (242) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/dist/helpers/integration/communicationChannelsFixtures.js.map +2 -2
  3. package/dist/modules/audit_logs/api/audit-logs/actions/redo/route.js +5 -0
  4. package/dist/modules/audit_logs/api/audit-logs/actions/redo/route.js.map +2 -2
  5. package/dist/modules/auth/api/profile/route.js +5 -0
  6. package/dist/modules/auth/api/profile/route.js.map +2 -2
  7. package/dist/modules/communication_channels/api/post/test-seed/route.js +40 -2
  8. package/dist/modules/communication_channels/api/post/test-seed/route.js.map +2 -2
  9. package/dist/modules/communication_channels/lib/access-control.js +6 -1
  10. package/dist/modules/communication_channels/lib/access-control.js.map +2 -2
  11. package/dist/modules/communication_channels/lib/system-user.js +8 -3
  12. package/dist/modules/communication_channels/lib/system-user.js.map +2 -2
  13. package/dist/modules/customers/api/activities/route.js +13 -0
  14. package/dist/modules/customers/api/activities/route.js.map +2 -2
  15. package/dist/modules/customers/api/dictionaries/[kind]/[id]/route.js +9 -0
  16. package/dist/modules/customers/api/dictionaries/[kind]/[id]/route.js.map +2 -2
  17. package/dist/modules/customers/api/dictionaries/[kind]/route.js +5 -0
  18. package/dist/modules/customers/api/dictionaries/[kind]/route.js.map +2 -2
  19. package/dist/modules/customers/api/dictionaries/kind-settings/route.js +5 -0
  20. package/dist/modules/customers/api/dictionaries/kind-settings/route.js.map +2 -2
  21. package/dist/modules/customers/api/interactions/cancel/route.js +5 -0
  22. package/dist/modules/customers/api/interactions/cancel/route.js.map +2 -2
  23. package/dist/modules/customers/api/interactions/complete/route.js +5 -0
  24. package/dist/modules/customers/api/interactions/complete/route.js.map +2 -2
  25. package/dist/modules/customers/api/labels/assign/route.js +5 -0
  26. package/dist/modules/customers/api/labels/assign/route.js.map +2 -2
  27. package/dist/modules/customers/api/labels/route.js +5 -0
  28. package/dist/modules/customers/api/labels/route.js.map +2 -2
  29. package/dist/modules/customers/api/labels/unassign/route.js +5 -0
  30. package/dist/modules/customers/api/labels/unassign/route.js.map +2 -2
  31. package/dist/modules/customers/api/people/[id]/companies/[linkId]/route.js +9 -0
  32. package/dist/modules/customers/api/people/[id]/companies/[linkId]/route.js.map +2 -2
  33. package/dist/modules/customers/api/people/[id]/companies/route.js +5 -0
  34. package/dist/modules/customers/api/people/[id]/companies/route.js.map +2 -2
  35. package/dist/modules/customers/api/pipeline-stages/reorder/route.js +5 -0
  36. package/dist/modules/customers/api/pipeline-stages/reorder/route.js.map +2 -2
  37. package/dist/modules/customers/api/pipeline-stages/route.js +13 -0
  38. package/dist/modules/customers/api/pipeline-stages/route.js.map +2 -2
  39. package/dist/modules/customers/api/pipelines/route.js +13 -0
  40. package/dist/modules/customers/api/pipelines/route.js.map +2 -2
  41. package/dist/modules/customers/api/settings/address-format/route.js +5 -0
  42. package/dist/modules/customers/api/settings/address-format/route.js.map +2 -2
  43. package/dist/modules/customers/api/settings/dictionary-sort-modes/route.js +5 -0
  44. package/dist/modules/customers/api/settings/dictionary-sort-modes/route.js.map +2 -2
  45. package/dist/modules/customers/api/settings/stuck-threshold/route.js +5 -0
  46. package/dist/modules/customers/api/settings/stuck-threshold/route.js.map +2 -2
  47. package/dist/modules/customers/api/tags/assign/route.js +5 -0
  48. package/dist/modules/customers/api/tags/assign/route.js.map +2 -2
  49. package/dist/modules/customers/api/tags/unassign/route.js +5 -0
  50. package/dist/modules/customers/api/tags/unassign/route.js.map +2 -2
  51. package/dist/modules/customers/api/todos/route.js +13 -0
  52. package/dist/modules/customers/api/todos/route.js.map +2 -2
  53. package/dist/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.js +9 -0
  54. package/dist/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.js.map +2 -2
  55. package/dist/modules/dictionaries/api/[dictionaryId]/entries/reorder/route.js +5 -0
  56. package/dist/modules/dictionaries/api/[dictionaryId]/entries/reorder/route.js.map +2 -2
  57. package/dist/modules/dictionaries/api/[dictionaryId]/entries/route.js +5 -0
  58. package/dist/modules/dictionaries/api/[dictionaryId]/entries/route.js.map +2 -2
  59. package/dist/modules/dictionaries/api/[dictionaryId]/entries/set-default/route.js +5 -0
  60. package/dist/modules/dictionaries/api/[dictionaryId]/entries/set-default/route.js.map +2 -2
  61. package/dist/modules/directory/api/organization-branding/route.js +5 -0
  62. package/dist/modules/directory/api/organization-branding/route.js.map +2 -2
  63. package/dist/modules/eudr/api/plots/import/route.js.map +2 -2
  64. package/dist/modules/eudr/api/product-mappings/suggestions/apply/route.js.map +2 -2
  65. package/dist/modules/feature_toggles/api/overrides/route.js +5 -0
  66. package/dist/modules/feature_toggles/api/overrides/route.js.map +2 -2
  67. package/dist/modules/messages/api/[id]/actions/[actionId]/route.js +5 -0
  68. package/dist/modules/messages/api/[id]/actions/[actionId]/route.js.map +2 -2
  69. package/dist/modules/messages/api/[id]/conversation/archive/route.js +5 -0
  70. package/dist/modules/messages/api/[id]/conversation/archive/route.js.map +2 -2
  71. package/dist/modules/messages/api/[id]/conversation/read/route.js +5 -0
  72. package/dist/modules/messages/api/[id]/conversation/read/route.js.map +2 -2
  73. package/dist/modules/messages/api/[id]/conversation/route.js +5 -0
  74. package/dist/modules/messages/api/[id]/conversation/route.js.map +2 -2
  75. package/dist/modules/messages/api/[id]/forward/route.js +5 -0
  76. package/dist/modules/messages/api/[id]/forward/route.js.map +2 -2
  77. package/dist/modules/messages/api/[id]/reply/route.js +5 -0
  78. package/dist/modules/messages/api/[id]/reply/route.js.map +2 -2
  79. package/dist/modules/messages/api/[id]/route.js +9 -0
  80. package/dist/modules/messages/api/[id]/route.js.map +2 -2
  81. package/dist/modules/messages/api/token/[token]/route.js +5 -0
  82. package/dist/modules/messages/api/token/[token]/route.js.map +2 -2
  83. package/dist/modules/resources/api/resources/tags/assign/route.js +5 -0
  84. package/dist/modules/resources/api/resources/tags/assign/route.js.map +2 -2
  85. package/dist/modules/resources/api/resources/tags/unassign/route.js +5 -0
  86. package/dist/modules/resources/api/resources/tags/unassign/route.js.map +2 -2
  87. package/dist/modules/sales/api/quotes/accept/route.js +5 -0
  88. package/dist/modules/sales/api/quotes/accept/route.js.map +2 -2
  89. package/dist/modules/sales/api/quotes/convert/route.js +5 -0
  90. package/dist/modules/sales/api/quotes/convert/route.js.map +2 -2
  91. package/dist/modules/sales/api/settings/document-numbers/route.js +5 -0
  92. package/dist/modules/sales/api/settings/document-numbers/route.js.map +2 -2
  93. package/dist/modules/sales/api/settings/order-editing/route.js +5 -0
  94. package/dist/modules/sales/api/settings/order-editing/route.js.map +2 -2
  95. package/dist/modules/staff/api/leave-requests/accept/route.js +5 -0
  96. package/dist/modules/staff/api/leave-requests/accept/route.js.map +2 -2
  97. package/dist/modules/staff/api/leave-requests/reject/route.js +5 -0
  98. package/dist/modules/staff/api/leave-requests/reject/route.js.map +2 -2
  99. package/dist/modules/staff/api/team-members/self/route.js +5 -0
  100. package/dist/modules/staff/api/team-members/self/route.js.map +2 -2
  101. package/dist/modules/staff/api/team-members/tags/assign/route.js +5 -0
  102. package/dist/modules/staff/api/team-members/tags/assign/route.js.map +2 -2
  103. package/dist/modules/staff/api/team-members/tags/unassign/route.js +5 -0
  104. package/dist/modules/staff/api/team-members/tags/unassign/route.js.map +2 -2
  105. package/dist/modules/staff/api/timesheets/time-entries/start-timer/route.js +5 -0
  106. package/dist/modules/staff/api/timesheets/time-entries/start-timer/route.js.map +2 -2
  107. package/dist/modules/translations/api/[entityType]/[entityId]/route.js +9 -0
  108. package/dist/modules/translations/api/[entityType]/[entityId]/route.js.map +2 -2
  109. package/dist/modules/warranty_claims/api/ai/assess/route.js +25 -18
  110. package/dist/modules/warranty_claims/api/ai/assess/route.js.map +2 -2
  111. package/dist/modules/warranty_claims/api/assign/route.js +5 -0
  112. package/dist/modules/warranty_claims/api/assign/route.js.map +2 -2
  113. package/dist/modules/warranty_claims/api/credit-memo/route.js +16 -12
  114. package/dist/modules/warranty_claims/api/credit-memo/route.js.map +2 -2
  115. package/dist/modules/warranty_claims/api/events/route.js +6 -1
  116. package/dist/modules/warranty_claims/api/events/route.js.map +2 -2
  117. package/dist/modules/warranty_claims/api/portal/attachments/route.js +24 -27
  118. package/dist/modules/warranty_claims/api/portal/attachments/route.js.map +2 -2
  119. package/dist/modules/warranty_claims/api/portal/claims/[id]/route.js +8 -10
  120. package/dist/modules/warranty_claims/api/portal/claims/[id]/route.js.map +2 -2
  121. package/dist/modules/warranty_claims/api/portal/claims/[id]/shared.js +4 -9
  122. package/dist/modules/warranty_claims/api/portal/claims/[id]/shared.js.map +2 -2
  123. package/dist/modules/warranty_claims/api/portal/claims/[id]/submit/route.js +8 -3
  124. package/dist/modules/warranty_claims/api/portal/claims/[id]/submit/route.js.map +2 -2
  125. package/dist/modules/warranty_claims/api/portal/claims/[id]/withdraw/route.js +8 -3
  126. package/dist/modules/warranty_claims/api/portal/claims/[id]/withdraw/route.js.map +2 -2
  127. package/dist/modules/warranty_claims/api/portal/claims/route.js +9 -9
  128. package/dist/modules/warranty_claims/api/portal/claims/route.js.map +2 -2
  129. package/dist/modules/warranty_claims/api/portal/events/route.js +17 -13
  130. package/dist/modules/warranty_claims/api/portal/events/route.js.map +2 -2
  131. package/dist/modules/warranty_claims/api/receiving/route.js +19 -15
  132. package/dist/modules/warranty_claims/api/receiving/route.js.map +2 -2
  133. package/dist/modules/warranty_claims/api/registrations/route.js +9 -4
  134. package/dist/modules/warranty_claims/api/registrations/route.js.map +2 -2
  135. package/dist/modules/warranty_claims/api/replacement-order/route.js +16 -12
  136. package/dist/modules/warranty_claims/api/replacement-order/route.js.map +2 -2
  137. package/dist/modules/warranty_claims/api/return-label/route.js +25 -19
  138. package/dist/modules/warranty_claims/api/return-label/route.js.map +2 -2
  139. package/dist/modules/warranty_claims/api/risk/route.js +2 -1
  140. package/dist/modules/warranty_claims/api/risk/route.js.map +2 -2
  141. package/dist/modules/warranty_claims/api/sales-return/route.js +16 -12
  142. package/dist/modules/warranty_claims/api/sales-return/route.js.map +2 -2
  143. package/dist/modules/warranty_claims/api/settings-general/route.js +5 -0
  144. package/dist/modules/warranty_claims/api/settings-general/route.js.map +2 -2
  145. package/dist/modules/warranty_claims/api/submit/route.js +5 -0
  146. package/dist/modules/warranty_claims/api/submit/route.js.map +2 -2
  147. package/dist/modules/warranty_claims/api/transition/route.js +5 -0
  148. package/dist/modules/warranty_claims/api/transition/route.js.map +2 -2
  149. package/dist/modules/warranty_claims/api/troubleshooting-guides/route.js +22 -1
  150. package/dist/modules/warranty_claims/api/troubleshooting-guides/route.js.map +2 -2
  151. package/dist/modules/warranty_claims/api/vendor-recovery/route.js +5 -0
  152. package/dist/modules/warranty_claims/api/vendor-recovery/route.js.map +2 -2
  153. package/dist/modules/warranty_claims/api/vendor-recovery-suggestions/route.js +2 -1
  154. package/dist/modules/warranty_claims/api/vendor-recovery-suggestions/route.js.map +2 -2
  155. package/dist/modules/warranty_claims/commands/shared.js +2 -2
  156. package/dist/modules/warranty_claims/commands/shared.js.map +2 -2
  157. package/dist/modules/warranty_claims/lib/portalAuthGuard.js +31 -0
  158. package/dist/modules/warranty_claims/lib/portalAuthGuard.js.map +7 -0
  159. package/dist/modules/wms/api/sales-orders/[salesOrderId]/warehouse-assignment/route.js +5 -0
  160. package/dist/modules/wms/api/sales-orders/[salesOrderId]/warehouse-assignment/route.js.map +2 -2
  161. package/package.json +7 -7
  162. package/src/helpers/integration/communicationChannelsFixtures.ts +13 -0
  163. package/src/modules/audit_logs/api/audit-logs/actions/redo/route.ts +5 -0
  164. package/src/modules/auth/api/profile/route.ts +5 -0
  165. package/src/modules/communication_channels/api/post/test-seed/route.ts +47 -2
  166. package/src/modules/communication_channels/lib/access-control.ts +28 -0
  167. package/src/modules/communication_channels/lib/system-user.ts +40 -22
  168. package/src/modules/customers/api/activities/route.ts +13 -0
  169. package/src/modules/customers/api/dictionaries/[kind]/[id]/route.ts +9 -0
  170. package/src/modules/customers/api/dictionaries/[kind]/route.ts +5 -0
  171. package/src/modules/customers/api/dictionaries/kind-settings/route.ts +5 -0
  172. package/src/modules/customers/api/interactions/cancel/route.ts +5 -0
  173. package/src/modules/customers/api/interactions/complete/route.ts +5 -0
  174. package/src/modules/customers/api/labels/assign/route.ts +5 -0
  175. package/src/modules/customers/api/labels/route.ts +5 -0
  176. package/src/modules/customers/api/labels/unassign/route.ts +5 -0
  177. package/src/modules/customers/api/people/[id]/companies/[linkId]/route.ts +9 -0
  178. package/src/modules/customers/api/people/[id]/companies/route.ts +5 -0
  179. package/src/modules/customers/api/pipeline-stages/reorder/route.ts +5 -0
  180. package/src/modules/customers/api/pipeline-stages/route.ts +13 -0
  181. package/src/modules/customers/api/pipelines/route.ts +13 -0
  182. package/src/modules/customers/api/settings/address-format/route.ts +5 -0
  183. package/src/modules/customers/api/settings/dictionary-sort-modes/route.ts +5 -0
  184. package/src/modules/customers/api/settings/stuck-threshold/route.ts +5 -0
  185. package/src/modules/customers/api/tags/assign/route.ts +5 -0
  186. package/src/modules/customers/api/tags/unassign/route.ts +5 -0
  187. package/src/modules/customers/api/todos/route.ts +13 -0
  188. package/src/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.ts +9 -0
  189. package/src/modules/dictionaries/api/[dictionaryId]/entries/reorder/route.ts +5 -0
  190. package/src/modules/dictionaries/api/[dictionaryId]/entries/route.ts +5 -0
  191. package/src/modules/dictionaries/api/[dictionaryId]/entries/set-default/route.ts +5 -0
  192. package/src/modules/directory/api/organization-branding/route.ts +5 -0
  193. package/src/modules/eudr/api/plots/import/route.ts +7 -0
  194. package/src/modules/eudr/api/product-mappings/suggestions/apply/route.ts +7 -0
  195. package/src/modules/feature_toggles/api/overrides/route.ts +5 -0
  196. package/src/modules/messages/api/[id]/actions/[actionId]/route.ts +5 -0
  197. package/src/modules/messages/api/[id]/conversation/archive/route.ts +5 -0
  198. package/src/modules/messages/api/[id]/conversation/read/route.ts +5 -0
  199. package/src/modules/messages/api/[id]/conversation/route.ts +5 -0
  200. package/src/modules/messages/api/[id]/forward/route.ts +5 -0
  201. package/src/modules/messages/api/[id]/reply/route.ts +5 -0
  202. package/src/modules/messages/api/[id]/route.ts +9 -0
  203. package/src/modules/messages/api/token/[token]/route.ts +5 -0
  204. package/src/modules/resources/api/resources/tags/assign/route.ts +5 -0
  205. package/src/modules/resources/api/resources/tags/unassign/route.ts +5 -0
  206. package/src/modules/sales/api/quotes/accept/route.ts +5 -0
  207. package/src/modules/sales/api/quotes/convert/route.ts +5 -0
  208. package/src/modules/sales/api/settings/document-numbers/route.ts +5 -0
  209. package/src/modules/sales/api/settings/order-editing/route.ts +5 -0
  210. package/src/modules/staff/api/leave-requests/accept/route.ts +5 -0
  211. package/src/modules/staff/api/leave-requests/reject/route.ts +5 -0
  212. package/src/modules/staff/api/team-members/self/route.ts +5 -0
  213. package/src/modules/staff/api/team-members/tags/assign/route.ts +5 -0
  214. package/src/modules/staff/api/team-members/tags/unassign/route.ts +5 -0
  215. package/src/modules/staff/api/timesheets/time-entries/start-timer/route.ts +5 -0
  216. package/src/modules/translations/api/[entityType]/[entityId]/route.ts +9 -0
  217. package/src/modules/warranty_claims/api/ai/assess/route.ts +28 -17
  218. package/src/modules/warranty_claims/api/assign/route.ts +5 -0
  219. package/src/modules/warranty_claims/api/credit-memo/route.ts +19 -13
  220. package/src/modules/warranty_claims/api/events/route.ts +6 -1
  221. package/src/modules/warranty_claims/api/portal/attachments/route.ts +29 -27
  222. package/src/modules/warranty_claims/api/portal/claims/[id]/route.ts +9 -10
  223. package/src/modules/warranty_claims/api/portal/claims/[id]/shared.ts +5 -9
  224. package/src/modules/warranty_claims/api/portal/claims/[id]/submit/route.ts +8 -3
  225. package/src/modules/warranty_claims/api/portal/claims/[id]/withdraw/route.ts +8 -3
  226. package/src/modules/warranty_claims/api/portal/claims/route.ts +10 -9
  227. package/src/modules/warranty_claims/api/portal/events/route.ts +18 -13
  228. package/src/modules/warranty_claims/api/receiving/route.ts +22 -15
  229. package/src/modules/warranty_claims/api/registrations/route.ts +9 -3
  230. package/src/modules/warranty_claims/api/replacement-order/route.ts +19 -13
  231. package/src/modules/warranty_claims/api/return-label/route.ts +26 -17
  232. package/src/modules/warranty_claims/api/risk/route.ts +3 -1
  233. package/src/modules/warranty_claims/api/sales-return/route.ts +19 -13
  234. package/src/modules/warranty_claims/api/settings-general/route.ts +5 -0
  235. package/src/modules/warranty_claims/api/submit/route.ts +5 -0
  236. package/src/modules/warranty_claims/api/transition/route.ts +5 -0
  237. package/src/modules/warranty_claims/api/troubleshooting-guides/route.ts +23 -1
  238. package/src/modules/warranty_claims/api/vendor-recovery/route.ts +5 -0
  239. package/src/modules/warranty_claims/api/vendor-recovery-suggestions/route.ts +3 -1
  240. package/src/modules/warranty_claims/commands/shared.ts +7 -1
  241. package/src/modules/warranty_claims/lib/portalAuthGuard.ts +30 -0
  242. package/src/modules/wms/api/sales-orders/[salesOrderId]/warehouse-assignment/route.ts +5 -0
@@ -15,6 +15,7 @@ import {
15
15
  } from '@open-mercato/shared/lib/crud/mutation-guard'
16
16
  import type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'
17
17
  import { createLogger } from '@open-mercato/shared/lib/logger'
18
+ import { getCommandInterceptorHttpRejection } from '@open-mercato/shared/lib/commands/errors'
18
19
 
19
20
  const logger = createLogger('customers')
20
21
 
@@ -108,6 +109,10 @@ export async function POST(req: Request) {
108
109
  if (isCrudHttpError(err)) {
109
110
  return NextResponse.json(err.body, { status: err.status })
110
111
  }
112
+ const interceptorRejection = getCommandInterceptorHttpRejection(err)
113
+ if (interceptorRejection) {
114
+ return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status })
115
+ }
111
116
  const { translate } = await resolveTranslations()
112
117
  logger.error('customers.tags.unassign failed', { err })
113
118
  return NextResponse.json({ error: translate('customers.errors.unassign_failed', 'Failed to unassign tag') }, { status: 400 })
@@ -37,6 +37,7 @@ import {
37
37
  resolveLegacyTodoDetails,
38
38
  } from '../../lib/todoCompatibility'
39
39
  import { createLogger } from '@open-mercato/shared/lib/logger'
40
+ import { getCommandInterceptorHttpRejection } from '@open-mercato/shared/lib/commands/errors'
40
41
 
41
42
  const logger = createLogger('customers')
42
43
 
@@ -439,6 +440,10 @@ export async function POST(request: Request): Promise<Response> {
439
440
  if (isCrudHttpError(err)) {
440
441
  return withAdapterHeaders(NextResponse.json(err.body, { status: err.status }))
441
442
  }
443
+ const interceptorRejection = getCommandInterceptorHttpRejection(err)
444
+ if (interceptorRejection) {
445
+ return withAdapterHeaders(NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status }))
446
+ }
442
447
  if (err instanceof z.ZodError) {
443
448
  return withAdapterHeaders(
444
449
  NextResponse.json({ error: 'Validation failed', details: err.issues }, { status: 400 }),
@@ -536,6 +541,10 @@ export async function PUT(request: Request): Promise<Response> {
536
541
  if (isCrudHttpError(err)) {
537
542
  return withAdapterHeaders(NextResponse.json(err.body, { status: err.status }))
538
543
  }
544
+ const interceptorRejection = getCommandInterceptorHttpRejection(err)
545
+ if (interceptorRejection) {
546
+ return withAdapterHeaders(NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status }))
547
+ }
539
548
  if (err instanceof z.ZodError) {
540
549
  return withAdapterHeaders(
541
550
  NextResponse.json({ error: 'Validation failed', details: err.issues }, { status: 400 }),
@@ -616,6 +625,10 @@ export async function DELETE(request: Request): Promise<Response> {
616
625
  if (isCrudHttpError(err)) {
617
626
  return withAdapterHeaders(NextResponse.json(err.body, { status: err.status }))
618
627
  }
628
+ const interceptorRejection = getCommandInterceptorHttpRejection(err)
629
+ if (interceptorRejection) {
630
+ return withAdapterHeaders(NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status }))
631
+ }
619
632
  if (err instanceof z.ZodError) {
620
633
  return withAdapterHeaders(
621
634
  NextResponse.json({ error: 'Validation failed', details: err.issues }, { status: 400 }),
@@ -22,6 +22,7 @@ import {
22
22
  updateDictionaryEntrySchema as updateEntryDocSchema,
23
23
  } from '../../../openapi'
24
24
  import { createLogger } from '@open-mercato/shared/lib/logger'
25
+ import { getCommandInterceptorHttpRejection } from '@open-mercato/shared/lib/commands/errors'
25
26
 
26
27
  const logger = createLogger('dictionaries').child({ component: 'entries-api' })
27
28
  const paramsSchema = z.object({
@@ -167,6 +168,10 @@ export async function PATCH(req: Request, ctx: { params?: { dictionaryId?: strin
167
168
  if (isCrudHttpError(err)) {
168
169
  return NextResponse.json(err.body, { status: err.status })
169
170
  }
171
+ const interceptorRejection = getCommandInterceptorHttpRejection(err)
172
+ if (interceptorRejection) {
173
+ return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status })
174
+ }
170
175
  if (err instanceof z.ZodError) {
171
176
  return NextResponse.json({ error: 'Invalid input', details: err.issues }, { status: 400 })
172
177
  }
@@ -244,6 +249,10 @@ export async function DELETE(req: Request, ctx: { params?: { dictionaryId?: stri
244
249
  if (isCrudHttpError(err)) {
245
250
  return NextResponse.json(err.body, { status: err.status })
246
251
  }
252
+ const interceptorRejection = getCommandInterceptorHttpRejection(err)
253
+ if (interceptorRejection) {
254
+ return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status })
255
+ }
247
256
  if (err instanceof z.ZodError) {
248
257
  return NextResponse.json({ error: 'Invalid input', details: err.issues }, { status: 400 })
249
258
  }
@@ -26,6 +26,7 @@ import {
26
26
  } from '../../../openapi'
27
27
  import { resolveDictionaryActorId } from '../../../context'
28
28
  import { createLogger } from '@open-mercato/shared/lib/logger'
29
+ import { getCommandInterceptorHttpRejection } from '@open-mercato/shared/lib/commands/errors'
29
30
 
30
31
  const logger = createLogger('dictionaries').child({ component: 'entries-api' })
31
32
 
@@ -130,6 +131,10 @@ export async function POST(req: Request, ctx: { params?: { dictionaryId?: string
130
131
  if (isCrudHttpError(err)) {
131
132
  return NextResponse.json(err.body, { status: err.status })
132
133
  }
134
+ const interceptorRejection = getCommandInterceptorHttpRejection(err)
135
+ if (interceptorRejection) {
136
+ return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status })
137
+ }
133
138
  if (err instanceof z.ZodError) {
134
139
  return NextResponse.json({ error: 'Invalid input', details: err.issues }, { status: 400 })
135
140
  }
@@ -37,6 +37,7 @@ import {
37
37
  sortDictionaryEntries,
38
38
  } from '@open-mercato/core/modules/dictionaries/lib/entrySort'
39
39
  import { createLogger } from '@open-mercato/shared/lib/logger'
40
+ import { getCommandInterceptorHttpRejection } from '@open-mercato/shared/lib/commands/errors'
40
41
 
41
42
  const logger = createLogger('dictionaries').child({ component: 'entries-api' })
42
43
 
@@ -282,6 +283,10 @@ export async function POST(req: Request, ctx: { params?: { dictionaryId?: string
282
283
  if (isCrudHttpError(err)) {
283
284
  return NextResponse.json(err.body, { status: err.status })
284
285
  }
286
+ const interceptorRejection = getCommandInterceptorHttpRejection(err)
287
+ if (interceptorRejection) {
288
+ return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status })
289
+ }
285
290
  if (err instanceof z.ZodError) {
286
291
  return NextResponse.json({ error: 'Invalid input', details: err.issues }, { status: 400 })
287
292
  }
@@ -26,6 +26,7 @@ import {
26
26
  } from '../../../openapi'
27
27
  import { resolveDictionaryActorId } from '../../../context'
28
28
  import { createLogger } from '@open-mercato/shared/lib/logger'
29
+ import { getCommandInterceptorHttpRejection } from '@open-mercato/shared/lib/commands/errors'
29
30
 
30
31
  const logger = createLogger('dictionaries').child({ component: 'entries-api' })
31
32
 
@@ -130,6 +131,10 @@ export async function POST(req: Request, ctx: { params?: { dictionaryId?: string
130
131
  if (isCrudHttpError(err)) {
131
132
  return NextResponse.json(err.body, { status: err.status })
132
133
  }
134
+ const interceptorRejection = getCommandInterceptorHttpRejection(err)
135
+ if (interceptorRejection) {
136
+ return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status })
137
+ }
133
138
  if (err instanceof z.ZodError) {
134
139
  return NextResponse.json({ error: 'Invalid input', details: err.issues }, { status: 400 })
135
140
  }
@@ -19,6 +19,7 @@ import { organizationUpdateSchema } from '@open-mercato/core/modules/directory/d
19
19
  import { resolveOrganizationScopeForRequest } from '@open-mercato/core/modules/directory/utils/organizationScope'
20
20
  import '@open-mercato/core/modules/directory/commands/organizations'
21
21
  import { createLogger } from '@open-mercato/shared/lib/logger'
22
+ import { getCommandInterceptorHttpRejection } from '@open-mercato/shared/lib/commands/errors'
22
23
 
23
24
  const logger = createLogger('directory').child({ component: 'organization-branding' })
24
25
 
@@ -268,6 +269,10 @@ export async function PUT(req: Request) {
268
269
  if (isCrudHttpError(err)) {
269
270
  return NextResponse.json(err.body, { status: err.status })
270
271
  }
272
+ const interceptorRejection = getCommandInterceptorHttpRejection(err)
273
+ if (interceptorRejection) {
274
+ return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status })
275
+ }
271
276
  logger.error('Organization branding update failed', { err })
272
277
  return NextResponse.json(
273
278
  { error: resolved.translate('directory.branding.errors.save', 'Failed to update organization branding.') },
@@ -323,6 +323,13 @@ export async function POST(req: Request) {
323
323
  if (isCrudHttpError(error)) {
324
324
  return Response.json(error.body, { status: error.status })
325
325
  }
326
+ // No command-interceptor mapping here (issue #5097): every `commandBus.execute`
327
+ // in this route runs inside the per-item loop above, whose catch records the
328
+ // failure in `failed[]` and continues, so an interceptor rejection can never
329
+ // reach this handler. The batch contract — HTTP 200 with a per-item failure
330
+ // list — is deliberately unchanged; the route is listed in
331
+ // `ROUTES_WITH_BATCH_ITEM_ERROR_HANDLING` in
332
+ // `packages/core/src/__tests__/command-interceptor-http-coverage.test.ts`.
326
333
  const { translate } = await resolveTranslations()
327
334
  if (error instanceof z.ZodError) {
328
335
  return Response.json(
@@ -337,6 +337,13 @@ export async function POST(req: Request) {
337
337
  if (isCrudHttpError(error)) {
338
338
  return Response.json(error.body, { status: error.status })
339
339
  }
340
+ // No command-interceptor mapping here (issue #5097): every `commandBus.execute`
341
+ // in this route runs inside the per-item loop above, whose catch records the
342
+ // failure in `failed[]` and continues, so an interceptor rejection can never
343
+ // reach this handler. The batch contract — HTTP 200 with a per-item failure
344
+ // list — is deliberately unchanged; the route is listed in
345
+ // `ROUTES_WITH_BATCH_ITEM_ERROR_HANDLING` in
346
+ // `packages/core/src/__tests__/command-interceptor-http-coverage.test.ts`.
340
347
  const { translate } = await resolveTranslations()
341
348
  if (error instanceof z.ZodError) {
342
349
  return Response.json(
@@ -25,6 +25,7 @@ import {
25
25
  } from '../openapi'
26
26
  import type { OpenApiRouteDoc, OpenApiMethodDoc } from '@open-mercato/shared/lib/openapi'
27
27
  import { createLogger } from '@open-mercato/shared/lib/logger'
28
+ import { getCommandInterceptorHttpRejection } from '@open-mercato/shared/lib/commands/errors'
28
29
 
29
30
  const logger = createLogger('feature_toggles').child({ component: 'overrides' })
30
31
 
@@ -186,6 +187,10 @@ export async function PUT(req: Request) {
186
187
  if (isCrudHttpError(error)) {
187
188
  return NextResponse.json(error.body, { status: error.status })
188
189
  }
190
+ const interceptorRejection = getCommandInterceptorHttpRejection(error)
191
+ if (interceptorRejection) {
192
+ return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status })
193
+ }
189
194
  const message = error instanceof Error ? error.message : 'Unknown error'
190
195
  if (message === 'NOT_FOUND') return NextResponse.json({ error: 'Not found' }, { status: 404 })
191
196
  if (message === 'INVALID_STATE' || message === 'INVALID_TOGGLE_ID' || message === 'INVALID_TENANT_ID') {
@@ -6,6 +6,7 @@ import { resolveMessageContext } from '../../../../lib/routeHelpers'
6
6
  import { resolveUserFeatures, runMessageMutationGuardAfterSuccess, runMessageMutationGuards } from '../../../guards'
7
7
  import type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi/types'
8
8
  import { actionResultResponseSchema } from '../../../openapi'
9
+ import { getCommandInterceptorHttpRejection } from '@open-mercato/shared/lib/commands/errors'
9
10
 
10
11
  export const metadata = {
11
12
  POST: { requireAuth: true, requireFeatures: ['messages.actions'] },
@@ -95,6 +96,10 @@ export async function POST(
95
96
  if (isCrudHttpError(error)) {
96
97
  return Response.json(error.body, { status: error.status })
97
98
  }
99
+ const interceptorRejection = getCommandInterceptorHttpRejection(error)
100
+ if (interceptorRejection) {
101
+ return Response.json(interceptorRejection.body, { status: interceptorRejection.status })
102
+ }
98
103
  if (error instanceof Error) {
99
104
  if (error.message === 'Message not found') {
100
105
  return Response.json({ error: 'Message not found' }, { status: 404 })
@@ -7,6 +7,7 @@ import {
7
7
  conversationMutationResponseSchema,
8
8
  errorResponseSchema,
9
9
  } from '../../../openapi'
10
+ import { getCommandInterceptorHttpRejection } from '@open-mercato/shared/lib/commands/errors'
10
11
 
11
12
  export const metadata = {
12
13
  PUT: { requireAuth: true, requireFeatures: ['messages.view'] },
@@ -78,6 +79,10 @@ async function runConversationArchiveMutation(
78
79
  })
79
80
  return response
80
81
  } catch (error) {
82
+ const interceptorRejection = getCommandInterceptorHttpRejection(error)
83
+ if (interceptorRejection) {
84
+ return Response.json(interceptorRejection.body, { status: interceptorRejection.status })
85
+ }
81
86
  if (error instanceof Error) {
82
87
  if (error.message === 'Message not found') {
83
88
  return Response.json({ error: error.message }, { status: 404 })
@@ -7,6 +7,7 @@ import {
7
7
  conversationMutationResponseSchema,
8
8
  errorResponseSchema,
9
9
  } from '../../../openapi'
10
+ import { getCommandInterceptorHttpRejection } from '@open-mercato/shared/lib/commands/errors'
10
11
 
11
12
  export const metadata = {
12
13
  PUT: { requireAuth: true, requireFeatures: ['messages.view'] },
@@ -78,6 +79,10 @@ async function runConversationReadMutation(
78
79
  })
79
80
  return response
80
81
  } catch (error) {
82
+ const interceptorRejection = getCommandInterceptorHttpRejection(error)
83
+ if (interceptorRejection) {
84
+ return Response.json(interceptorRejection.body, { status: interceptorRejection.status })
85
+ }
81
86
  if (error instanceof Error) {
82
87
  if (error.message === 'Message not found') {
83
88
  return Response.json({ error: error.message }, { status: 404 })
@@ -7,6 +7,7 @@ import {
7
7
  conversationMutationResponseSchema,
8
8
  errorResponseSchema,
9
9
  } from '../../openapi'
10
+ import { getCommandInterceptorHttpRejection } from '@open-mercato/shared/lib/commands/errors'
10
11
 
11
12
  export const metadata = {
12
13
  DELETE: { requireAuth: true, requireFeatures: ['messages.view'] },
@@ -73,6 +74,10 @@ export async function DELETE(req: Request, { params }: { params: { id: string }
73
74
  })
74
75
  return response
75
76
  } catch (error) {
77
+ const interceptorRejection = getCommandInterceptorHttpRejection(error)
78
+ if (interceptorRejection) {
79
+ return Response.json(interceptorRejection.body, { status: interceptorRejection.status })
80
+ }
76
81
  if (error instanceof Error) {
77
82
  if (error.message === 'Message not found') {
78
83
  return Response.json({ error: error.message }, { status: 404 })
@@ -6,6 +6,7 @@ import { resolveUserFeatures, runMessageMutationGuardAfterSuccess, runMessageMut
6
6
  import type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi/types'
7
7
  import { forwardResponseSchema, forwardMessageSchema as forwardSchema } from '../../openapi'
8
8
  import { MessageCommandExecuteResult } from '../../../commands/shared'
9
+ import { getCommandInterceptorHttpRejection } from '@open-mercato/shared/lib/commands/errors'
9
10
 
10
11
  export const metadata = {
11
12
  POST: { requireAuth: true, requireFeatures: ['messages.compose'] },
@@ -62,6 +63,10 @@ export async function POST(req: Request, { params }: { params: { id: string } })
62
63
  },
63
64
  })
64
65
  } catch (error) {
66
+ const interceptorRejection = getCommandInterceptorHttpRejection(error)
67
+ if (interceptorRejection) {
68
+ return Response.json(interceptorRejection.body, { status: interceptorRejection.status })
69
+ }
65
70
  if (error instanceof Error) {
66
71
  if (error.message === 'Message not found') {
67
72
  return Response.json({ error: 'Message not found' }, { status: 404 })
@@ -10,6 +10,7 @@ import {
10
10
  replyMessageSchema as replyOpenApiSchema,
11
11
  } from '../../openapi'
12
12
  import { MessageCommandExecuteResult } from '../../../commands/shared'
13
+ import { getCommandInterceptorHttpRejection } from '@open-mercato/shared/lib/commands/errors'
13
14
 
14
15
  export const metadata = {
15
16
  POST: { requireAuth: true, requireFeatures: ['messages.compose'] },
@@ -66,6 +67,10 @@ export async function POST(req: Request, { params }: { params: { id: string } })
66
67
  },
67
68
  })
68
69
  } catch (error) {
70
+ const interceptorRejection = getCommandInterceptorHttpRejection(error)
71
+ if (interceptorRejection) {
72
+ return Response.json(interceptorRejection.body, { status: interceptorRejection.status })
73
+ }
69
74
  if (error instanceof Error) {
70
75
  if (error.message === 'Message not found') {
71
76
  return Response.json({ error: 'Message not found' }, { status: 404 })
@@ -22,6 +22,7 @@ import {
22
22
  updateDraftSchema as updateDraftOpenApiSchema,
23
23
  } from '../openapi'
24
24
  import { createLogger } from '@open-mercato/shared/lib/logger'
25
+ import { getCommandInterceptorHttpRejection } from '@open-mercato/shared/lib/commands/errors'
25
26
 
26
27
  const logger = createLogger('messages').child({ component: 'api' })
27
28
 
@@ -421,6 +422,10 @@ export async function PATCH(req: Request, { params }: { params: { id: string } }
421
422
  if (isCrudHttpError(error)) {
422
423
  return Response.json(error.body, { status: error.status })
423
424
  }
425
+ const interceptorRejection = getCommandInterceptorHttpRejection(error)
426
+ if (interceptorRejection) {
427
+ return Response.json(interceptorRejection.body, { status: interceptorRejection.status })
428
+ }
424
429
  if (error instanceof Error) {
425
430
  if (error.message === 'Message type cannot be created by users') {
426
431
  return Response.json({ error: error.message }, { status: 400 })
@@ -546,6 +551,10 @@ export async function DELETE(req: Request, { params }: { params: { id: string }
546
551
  if (isCrudHttpError(error)) {
547
552
  return Response.json(error.body, { status: error.status })
548
553
  }
554
+ const interceptorRejection = getCommandInterceptorHttpRejection(error)
555
+ if (interceptorRejection) {
556
+ return Response.json(interceptorRejection.body, { status: interceptorRejection.status })
557
+ }
549
558
  if (error instanceof Error && error.message === 'Access denied') {
550
559
  return Response.json({ error: 'Access denied' }, { status: 403 })
551
560
  }
@@ -8,6 +8,7 @@ import { Message, MessageAccessToken, MessageObject, MessageRecipient } from '..
8
8
  import { MAX_TOKEN_USE_COUNT } from '../../../commands/tokens'
9
9
  import { messageTokenResponseSchema } from '../../openapi'
10
10
  import { hashAuthToken } from '../../../../auth/lib/tokenHash'
11
+ import { getCommandInterceptorHttpRejection } from '@open-mercato/shared/lib/commands/errors'
11
12
 
12
13
  export const metadata = {
13
14
  GET: { requireAuth: false },
@@ -134,6 +135,10 @@ export async function GET(req: Request, { params }: { params: { token: string }
134
135
  })
135
136
  commandResult = executed.result
136
137
  } catch (error) {
138
+ const interceptorRejection = getCommandInterceptorHttpRejection(error)
139
+ if (interceptorRejection) {
140
+ return Response.json(interceptorRejection.body, { status: interceptorRejection.status })
141
+ }
137
142
  const errorResponse = responseForTokenError(error)
138
143
  if (errorResponse) return errorResponse
139
144
  throw error
@@ -18,6 +18,7 @@ import {
18
18
  type ResourcesResourceTagAssignmentInput,
19
19
  } from '../../../../data/validators'
20
20
  import { createLogger } from '@open-mercato/shared/lib/logger'
21
+ import { getCommandInterceptorHttpRejection } from '@open-mercato/shared/lib/commands/errors'
21
22
 
22
23
  const logger = createLogger('resources').child({ component: 'tags' })
23
24
 
@@ -112,6 +113,10 @@ export async function POST(req: Request) {
112
113
  if (isCrudHttpError(err)) {
113
114
  return NextResponse.json(err.body, { status: err.status })
114
115
  }
116
+ const interceptorRejection = getCommandInterceptorHttpRejection(err)
117
+ if (interceptorRejection) {
118
+ return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status })
119
+ }
115
120
  const { translate } = await resolveTranslations()
116
121
  logger.error('Tag assign failed', { err })
117
122
  return NextResponse.json({ error: translate('resources.resources.tags.updateError', 'Failed to update tags.') }, { status: 400 })
@@ -18,6 +18,7 @@ import {
18
18
  type ResourcesResourceTagAssignmentInput,
19
19
  } from '../../../../data/validators'
20
20
  import { createLogger } from '@open-mercato/shared/lib/logger'
21
+ import { getCommandInterceptorHttpRejection } from '@open-mercato/shared/lib/commands/errors'
21
22
 
22
23
  const logger = createLogger('resources').child({ component: 'tags' })
23
24
 
@@ -112,6 +113,10 @@ export async function POST(req: Request) {
112
113
  if (isCrudHttpError(err)) {
113
114
  return NextResponse.json(err.body, { status: err.status })
114
115
  }
116
+ const interceptorRejection = getCommandInterceptorHttpRejection(err)
117
+ if (interceptorRejection) {
118
+ return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status })
119
+ }
115
120
  const { translate } = await resolveTranslations()
116
121
  logger.error('Tag unassign failed', { err })
117
122
  return NextResponse.json({ error: translate('resources.resources.tags.updateError', 'Failed to update tags.') }, { status: 400 })
@@ -21,6 +21,7 @@ import { resolveStatusEntryIdByValue } from '../../../lib/statusHelpers'
21
21
  import { resolveEffectiveTenantId } from '../../../lib/publicQuoteTenantScope'
22
22
  import { QuoteAcceptedAdminEmail } from '../../../emails/QuoteAcceptedAdminEmail'
23
23
  import { createLogger } from '@open-mercato/shared/lib/logger'
24
+ import { getCommandInterceptorHttpRejection } from '@open-mercato/shared/lib/commands/errors'
24
25
 
25
26
  const logger = createLogger('sales')
26
27
 
@@ -179,6 +180,10 @@ export async function POST(req: Request) {
179
180
  if (isCrudHttpError(err)) {
180
181
  return NextResponse.json(err.body, { status: err.status })
181
182
  }
183
+ const interceptorRejection = getCommandInterceptorHttpRejection(err)
184
+ if (interceptorRejection) {
185
+ return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status })
186
+ }
182
187
  const { translate } = await resolveTranslations()
183
188
  logger.error('sales.quotes.accept failed', { err })
184
189
  return NextResponse.json({ error: translate('sales.quotes.accept.failed', 'Failed to accept quote.') }, { status: 400 })
@@ -16,6 +16,7 @@ import {
16
16
  } from '@open-mercato/shared/lib/crud/mutation-guard-registry'
17
17
  import { withScopedPayload } from '../../utils'
18
18
  import { createLogger } from '@open-mercato/shared/lib/logger'
19
+ import { getCommandInterceptorHttpRejection } from '@open-mercato/shared/lib/commands/errors'
19
20
 
20
21
  const logger = createLogger('sales')
21
22
 
@@ -175,6 +176,10 @@ export async function POST(req: Request) {
175
176
  if (isCrudHttpError(err)) {
176
177
  return NextResponse.json(err.body, { status: err.status })
177
178
  }
179
+ const interceptorRejection = getCommandInterceptorHttpRejection(err)
180
+ if (interceptorRejection) {
181
+ return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status })
182
+ }
178
183
  const { translate } = await resolveTranslations()
179
184
  logger.error('sales.quotes.convert failed', { err })
180
185
  return NextResponse.json(
@@ -19,6 +19,7 @@ import {
19
19
  validateCrudMutationGuard,
20
20
  } from '@open-mercato/shared/lib/crud/mutation-guard'
21
21
  import { createLogger } from '@open-mercato/shared/lib/logger'
22
+ import { getCommandInterceptorHttpRejection } from '@open-mercato/shared/lib/commands/errors'
22
23
 
23
24
  const logger = createLogger('sales')
24
25
 
@@ -160,6 +161,10 @@ export async function PUT(req: Request) {
160
161
  if (isCrudHttpError(err)) {
161
162
  return NextResponse.json(err.body, { status: err.status })
162
163
  }
164
+ const interceptorRejection = getCommandInterceptorHttpRejection(err)
165
+ if (interceptorRejection) {
166
+ return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status })
167
+ }
163
168
  const { translate } = await resolveTranslations()
164
169
  logger.error('sales.settings.document-numbers.put failed', { err })
165
170
  return NextResponse.json(
@@ -20,6 +20,7 @@ import {
20
20
  import { ensureSalesDictionary } from '../../../lib/dictionaries'
21
21
  import { DictionaryEntry } from '@open-mercato/core/modules/dictionaries/data/entities'
22
22
  import { createLogger } from '@open-mercato/shared/lib/logger'
23
+ import { getCommandInterceptorHttpRejection } from '@open-mercato/shared/lib/commands/errors'
23
24
 
24
25
  const logger = createLogger('sales')
25
26
 
@@ -179,6 +180,10 @@ export async function PUT(req: Request) {
179
180
  if (isCrudHttpError(err)) {
180
181
  return NextResponse.json(err.body, { status: err.status })
181
182
  }
183
+ const interceptorRejection = getCommandInterceptorHttpRejection(err)
184
+ if (interceptorRejection) {
185
+ return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status })
186
+ }
182
187
  const { translate } = await resolveTranslations()
183
188
  logger.error('sales.settings.order-editing.put failed', { err })
184
189
  return NextResponse.json(
@@ -16,6 +16,7 @@ import {
16
16
  runStaffMutationGuards,
17
17
  } from '../../guards'
18
18
  import { createLogger } from '@open-mercato/shared/lib/logger'
19
+ import { getCommandInterceptorHttpRejection } from '@open-mercato/shared/lib/commands/errors'
19
20
 
20
21
  const logger = createLogger('staff')
21
22
 
@@ -112,6 +113,10 @@ export async function POST(req: Request) {
112
113
  if (isCrudHttpError(err)) {
113
114
  return NextResponse.json(err.body, { status: err.status })
114
115
  }
116
+ const interceptorRejection = getCommandInterceptorHttpRejection(err)
117
+ if (interceptorRejection) {
118
+ return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status })
119
+ }
115
120
  const { translate } = await resolveTranslations()
116
121
  logger.error('staff.leave-requests.accept failed', { err })
117
122
  return NextResponse.json({ error: translate('staff.leaveRequests.errors.accept', 'Failed to approve leave request.') }, { status: 400 })
@@ -16,6 +16,7 @@ import {
16
16
  runStaffMutationGuards,
17
17
  } from '../../guards'
18
18
  import { createLogger } from '@open-mercato/shared/lib/logger'
19
+ import { getCommandInterceptorHttpRejection } from '@open-mercato/shared/lib/commands/errors'
19
20
 
20
21
  const logger = createLogger('staff')
21
22
 
@@ -112,6 +113,10 @@ export async function POST(req: Request) {
112
113
  if (isCrudHttpError(err)) {
113
114
  return NextResponse.json(err.body, { status: err.status })
114
115
  }
116
+ const interceptorRejection = getCommandInterceptorHttpRejection(err)
117
+ if (interceptorRejection) {
118
+ return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status })
119
+ }
115
120
  const { translate } = await resolveTranslations()
116
121
  logger.error('staff.leave-requests.reject failed', { err })
117
122
  return NextResponse.json({ error: translate('staff.leaveRequests.errors.reject', 'Failed to reject leave request.') }, { status: 400 })
@@ -22,6 +22,7 @@ import {
22
22
  runStaffMutationGuards,
23
23
  } from '../../guards'
24
24
  import { createLogger } from '@open-mercato/shared/lib/logger'
25
+ import { getCommandInterceptorHttpRejection } from '@open-mercato/shared/lib/commands/errors'
25
26
 
26
27
  const logger = createLogger('staff')
27
28
 
@@ -185,6 +186,10 @@ export async function POST(req: Request) {
185
186
  if (isCrudHttpError(err)) {
186
187
  return NextResponse.json(err.body, { status: err.status })
187
188
  }
189
+ const interceptorRejection = getCommandInterceptorHttpRejection(err)
190
+ if (interceptorRejection) {
191
+ return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status })
192
+ }
188
193
  const { translate } = await resolveTranslations()
189
194
  logger.error('staff.teamMembers.self.create failed', { err })
190
195
  return NextResponse.json({ error: translate('staff.teamMembers.form.errors.create', 'Failed to create team member.') }, { status: 400 })
@@ -19,6 +19,7 @@ import {
19
19
  runStaffMutationGuards,
20
20
  } from '../../../guards'
21
21
  import { createLogger } from '@open-mercato/shared/lib/logger'
22
+ import { getCommandInterceptorHttpRejection } from '@open-mercato/shared/lib/commands/errors'
22
23
 
23
24
  const logger = createLogger('staff')
24
25
 
@@ -115,6 +116,10 @@ export async function POST(req: Request) {
115
116
  if (isCrudHttpError(err)) {
116
117
  return NextResponse.json(err.body, { status: err.status })
117
118
  }
119
+ const interceptorRejection = getCommandInterceptorHttpRejection(err)
120
+ if (interceptorRejection) {
121
+ return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status })
122
+ }
118
123
  const { translate } = await resolveTranslations()
119
124
  logger.error('staff.teamMembers.tags.assign failed', { err })
120
125
  return NextResponse.json({ error: translate('staff.teamMembers.tags.updateError', 'Failed to update tags.') }, { status: 400 })
@@ -19,6 +19,7 @@ import {
19
19
  runStaffMutationGuards,
20
20
  } from '../../../guards'
21
21
  import { createLogger } from '@open-mercato/shared/lib/logger'
22
+ import { getCommandInterceptorHttpRejection } from '@open-mercato/shared/lib/commands/errors'
22
23
 
23
24
  const logger = createLogger('staff')
24
25
 
@@ -115,6 +116,10 @@ export async function POST(req: Request) {
115
116
  if (isCrudHttpError(err)) {
116
117
  return NextResponse.json(err.body, { status: err.status })
117
118
  }
119
+ const interceptorRejection = getCommandInterceptorHttpRejection(err)
120
+ if (interceptorRejection) {
121
+ return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status })
122
+ }
118
123
  const { translate } = await resolveTranslations()
119
124
  logger.error('staff.teamMembers.tags.unassign failed', { err })
120
125
  return NextResponse.json({ error: translate('staff.teamMembers.tags.updateError', 'Failed to update tags.') }, { status: 400 })
@@ -11,6 +11,7 @@ import { parseScopedCommandInput } from '@open-mercato/shared/lib/api/scoped'
11
11
  import type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'
12
12
  import { staffTimeEntryStartTimerSchema, type StaffTimeEntryStartTimerInput } from '../../../../data/validators'
13
13
  import { createLogger } from '@open-mercato/shared/lib/logger'
14
+ import { getCommandInterceptorHttpRejection } from '@open-mercato/shared/lib/commands/errors'
14
15
 
15
16
  const logger = createLogger('staff')
16
17
 
@@ -67,6 +68,10 @@ export async function POST(req: Request) {
67
68
  if (isCrudHttpError(err)) {
68
69
  return NextResponse.json(err.body, { status: err.status })
69
70
  }
71
+ const interceptorRejection = getCommandInterceptorHttpRejection(err)
72
+ if (interceptorRejection) {
73
+ return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status })
74
+ }
70
75
  const { translate } = await resolveTranslations()
71
76
  logger.error('staff.timesheets.time-entries.start-timer failed', { err })
72
77
  return NextResponse.json(