@open-mercato/core 0.7.1-develop.7130.1.fef2396fd8 → 0.7.1-develop.7131.1.20abf9e885

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 (203) hide show
  1. package/dist/modules/audit_logs/api/audit-logs/actions/redo/route.js +5 -0
  2. package/dist/modules/audit_logs/api/audit-logs/actions/redo/route.js.map +2 -2
  3. package/dist/modules/auth/api/profile/route.js +5 -0
  4. package/dist/modules/auth/api/profile/route.js.map +2 -2
  5. package/dist/modules/customers/api/activities/route.js +13 -0
  6. package/dist/modules/customers/api/activities/route.js.map +2 -2
  7. package/dist/modules/customers/api/dictionaries/[kind]/[id]/route.js +9 -0
  8. package/dist/modules/customers/api/dictionaries/[kind]/[id]/route.js.map +2 -2
  9. package/dist/modules/customers/api/dictionaries/[kind]/route.js +5 -0
  10. package/dist/modules/customers/api/dictionaries/[kind]/route.js.map +2 -2
  11. package/dist/modules/customers/api/dictionaries/kind-settings/route.js +5 -0
  12. package/dist/modules/customers/api/dictionaries/kind-settings/route.js.map +2 -2
  13. package/dist/modules/customers/api/interactions/cancel/route.js +5 -0
  14. package/dist/modules/customers/api/interactions/cancel/route.js.map +2 -2
  15. package/dist/modules/customers/api/interactions/complete/route.js +5 -0
  16. package/dist/modules/customers/api/interactions/complete/route.js.map +2 -2
  17. package/dist/modules/customers/api/labels/assign/route.js +5 -0
  18. package/dist/modules/customers/api/labels/assign/route.js.map +2 -2
  19. package/dist/modules/customers/api/labels/route.js +5 -0
  20. package/dist/modules/customers/api/labels/route.js.map +2 -2
  21. package/dist/modules/customers/api/labels/unassign/route.js +5 -0
  22. package/dist/modules/customers/api/labels/unassign/route.js.map +2 -2
  23. package/dist/modules/customers/api/people/[id]/companies/[linkId]/route.js +9 -0
  24. package/dist/modules/customers/api/people/[id]/companies/[linkId]/route.js.map +2 -2
  25. package/dist/modules/customers/api/people/[id]/companies/route.js +5 -0
  26. package/dist/modules/customers/api/people/[id]/companies/route.js.map +2 -2
  27. package/dist/modules/customers/api/pipeline-stages/reorder/route.js +5 -0
  28. package/dist/modules/customers/api/pipeline-stages/reorder/route.js.map +2 -2
  29. package/dist/modules/customers/api/pipeline-stages/route.js +13 -0
  30. package/dist/modules/customers/api/pipeline-stages/route.js.map +2 -2
  31. package/dist/modules/customers/api/pipelines/route.js +13 -0
  32. package/dist/modules/customers/api/pipelines/route.js.map +2 -2
  33. package/dist/modules/customers/api/settings/address-format/route.js +5 -0
  34. package/dist/modules/customers/api/settings/address-format/route.js.map +2 -2
  35. package/dist/modules/customers/api/settings/dictionary-sort-modes/route.js +5 -0
  36. package/dist/modules/customers/api/settings/dictionary-sort-modes/route.js.map +2 -2
  37. package/dist/modules/customers/api/settings/stuck-threshold/route.js +5 -0
  38. package/dist/modules/customers/api/settings/stuck-threshold/route.js.map +2 -2
  39. package/dist/modules/customers/api/tags/assign/route.js +5 -0
  40. package/dist/modules/customers/api/tags/assign/route.js.map +2 -2
  41. package/dist/modules/customers/api/tags/unassign/route.js +5 -0
  42. package/dist/modules/customers/api/tags/unassign/route.js.map +2 -2
  43. package/dist/modules/customers/api/todos/route.js +13 -0
  44. package/dist/modules/customers/api/todos/route.js.map +2 -2
  45. package/dist/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.js +9 -0
  46. package/dist/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.js.map +2 -2
  47. package/dist/modules/dictionaries/api/[dictionaryId]/entries/reorder/route.js +5 -0
  48. package/dist/modules/dictionaries/api/[dictionaryId]/entries/reorder/route.js.map +2 -2
  49. package/dist/modules/dictionaries/api/[dictionaryId]/entries/route.js +5 -0
  50. package/dist/modules/dictionaries/api/[dictionaryId]/entries/route.js.map +2 -2
  51. package/dist/modules/dictionaries/api/[dictionaryId]/entries/set-default/route.js +5 -0
  52. package/dist/modules/dictionaries/api/[dictionaryId]/entries/set-default/route.js.map +2 -2
  53. package/dist/modules/directory/api/organization-branding/route.js +5 -0
  54. package/dist/modules/directory/api/organization-branding/route.js.map +2 -2
  55. package/dist/modules/eudr/api/plots/import/route.js.map +2 -2
  56. package/dist/modules/eudr/api/product-mappings/suggestions/apply/route.js.map +2 -2
  57. package/dist/modules/feature_toggles/api/overrides/route.js +5 -0
  58. package/dist/modules/feature_toggles/api/overrides/route.js.map +2 -2
  59. package/dist/modules/messages/api/[id]/actions/[actionId]/route.js +5 -0
  60. package/dist/modules/messages/api/[id]/actions/[actionId]/route.js.map +2 -2
  61. package/dist/modules/messages/api/[id]/conversation/archive/route.js +5 -0
  62. package/dist/modules/messages/api/[id]/conversation/archive/route.js.map +2 -2
  63. package/dist/modules/messages/api/[id]/conversation/read/route.js +5 -0
  64. package/dist/modules/messages/api/[id]/conversation/read/route.js.map +2 -2
  65. package/dist/modules/messages/api/[id]/conversation/route.js +5 -0
  66. package/dist/modules/messages/api/[id]/conversation/route.js.map +2 -2
  67. package/dist/modules/messages/api/[id]/forward/route.js +5 -0
  68. package/dist/modules/messages/api/[id]/forward/route.js.map +2 -2
  69. package/dist/modules/messages/api/[id]/reply/route.js +5 -0
  70. package/dist/modules/messages/api/[id]/reply/route.js.map +2 -2
  71. package/dist/modules/messages/api/[id]/route.js +9 -0
  72. package/dist/modules/messages/api/[id]/route.js.map +2 -2
  73. package/dist/modules/messages/api/token/[token]/route.js +5 -0
  74. package/dist/modules/messages/api/token/[token]/route.js.map +2 -2
  75. package/dist/modules/resources/api/resources/tags/assign/route.js +5 -0
  76. package/dist/modules/resources/api/resources/tags/assign/route.js.map +2 -2
  77. package/dist/modules/resources/api/resources/tags/unassign/route.js +5 -0
  78. package/dist/modules/resources/api/resources/tags/unassign/route.js.map +2 -2
  79. package/dist/modules/sales/api/quotes/accept/route.js +5 -0
  80. package/dist/modules/sales/api/quotes/accept/route.js.map +2 -2
  81. package/dist/modules/sales/api/quotes/convert/route.js +5 -0
  82. package/dist/modules/sales/api/quotes/convert/route.js.map +2 -2
  83. package/dist/modules/sales/api/settings/document-numbers/route.js +5 -0
  84. package/dist/modules/sales/api/settings/document-numbers/route.js.map +2 -2
  85. package/dist/modules/sales/api/settings/order-editing/route.js +5 -0
  86. package/dist/modules/sales/api/settings/order-editing/route.js.map +2 -2
  87. package/dist/modules/staff/api/leave-requests/accept/route.js +5 -0
  88. package/dist/modules/staff/api/leave-requests/accept/route.js.map +2 -2
  89. package/dist/modules/staff/api/leave-requests/reject/route.js +5 -0
  90. package/dist/modules/staff/api/leave-requests/reject/route.js.map +2 -2
  91. package/dist/modules/staff/api/team-members/self/route.js +5 -0
  92. package/dist/modules/staff/api/team-members/self/route.js.map +2 -2
  93. package/dist/modules/staff/api/team-members/tags/assign/route.js +5 -0
  94. package/dist/modules/staff/api/team-members/tags/assign/route.js.map +2 -2
  95. package/dist/modules/staff/api/team-members/tags/unassign/route.js +5 -0
  96. package/dist/modules/staff/api/team-members/tags/unassign/route.js.map +2 -2
  97. package/dist/modules/staff/api/timesheets/time-entries/start-timer/route.js +5 -0
  98. package/dist/modules/staff/api/timesheets/time-entries/start-timer/route.js.map +2 -2
  99. package/dist/modules/translations/api/[entityType]/[entityId]/route.js +9 -0
  100. package/dist/modules/translations/api/[entityType]/[entityId]/route.js.map +2 -2
  101. package/dist/modules/warranty_claims/api/ai/assess/route.js +5 -0
  102. package/dist/modules/warranty_claims/api/ai/assess/route.js.map +2 -2
  103. package/dist/modules/warranty_claims/api/assign/route.js +5 -0
  104. package/dist/modules/warranty_claims/api/assign/route.js.map +2 -2
  105. package/dist/modules/warranty_claims/api/credit-memo/route.js +5 -0
  106. package/dist/modules/warranty_claims/api/credit-memo/route.js.map +2 -2
  107. package/dist/modules/warranty_claims/api/events/route.js +5 -0
  108. package/dist/modules/warranty_claims/api/events/route.js.map +2 -2
  109. package/dist/modules/warranty_claims/api/portal/claims/[id]/submit/route.js +5 -0
  110. package/dist/modules/warranty_claims/api/portal/claims/[id]/submit/route.js.map +2 -2
  111. package/dist/modules/warranty_claims/api/portal/claims/[id]/withdraw/route.js +5 -0
  112. package/dist/modules/warranty_claims/api/portal/claims/[id]/withdraw/route.js.map +2 -2
  113. package/dist/modules/warranty_claims/api/portal/claims/route.js +5 -0
  114. package/dist/modules/warranty_claims/api/portal/claims/route.js.map +2 -2
  115. package/dist/modules/warranty_claims/api/portal/events/route.js +5 -0
  116. package/dist/modules/warranty_claims/api/portal/events/route.js.map +2 -2
  117. package/dist/modules/warranty_claims/api/receiving/route.js +5 -0
  118. package/dist/modules/warranty_claims/api/receiving/route.js.map +2 -2
  119. package/dist/modules/warranty_claims/api/replacement-order/route.js +5 -0
  120. package/dist/modules/warranty_claims/api/replacement-order/route.js.map +2 -2
  121. package/dist/modules/warranty_claims/api/return-label/route.js +5 -0
  122. package/dist/modules/warranty_claims/api/return-label/route.js.map +2 -2
  123. package/dist/modules/warranty_claims/api/sales-return/route.js +5 -0
  124. package/dist/modules/warranty_claims/api/sales-return/route.js.map +2 -2
  125. package/dist/modules/warranty_claims/api/settings-general/route.js +5 -0
  126. package/dist/modules/warranty_claims/api/settings-general/route.js.map +2 -2
  127. package/dist/modules/warranty_claims/api/submit/route.js +5 -0
  128. package/dist/modules/warranty_claims/api/submit/route.js.map +2 -2
  129. package/dist/modules/warranty_claims/api/transition/route.js +5 -0
  130. package/dist/modules/warranty_claims/api/transition/route.js.map +2 -2
  131. package/dist/modules/warranty_claims/api/vendor-recovery/route.js +5 -0
  132. package/dist/modules/warranty_claims/api/vendor-recovery/route.js.map +2 -2
  133. package/dist/modules/wms/api/sales-orders/[salesOrderId]/warehouse-assignment/route.js +5 -0
  134. package/dist/modules/wms/api/sales-orders/[salesOrderId]/warehouse-assignment/route.js.map +2 -2
  135. package/package.json +7 -7
  136. package/src/modules/audit_logs/api/audit-logs/actions/redo/route.ts +5 -0
  137. package/src/modules/auth/api/profile/route.ts +5 -0
  138. package/src/modules/customers/api/activities/route.ts +13 -0
  139. package/src/modules/customers/api/dictionaries/[kind]/[id]/route.ts +9 -0
  140. package/src/modules/customers/api/dictionaries/[kind]/route.ts +5 -0
  141. package/src/modules/customers/api/dictionaries/kind-settings/route.ts +5 -0
  142. package/src/modules/customers/api/interactions/cancel/route.ts +5 -0
  143. package/src/modules/customers/api/interactions/complete/route.ts +5 -0
  144. package/src/modules/customers/api/labels/assign/route.ts +5 -0
  145. package/src/modules/customers/api/labels/route.ts +5 -0
  146. package/src/modules/customers/api/labels/unassign/route.ts +5 -0
  147. package/src/modules/customers/api/people/[id]/companies/[linkId]/route.ts +9 -0
  148. package/src/modules/customers/api/people/[id]/companies/route.ts +5 -0
  149. package/src/modules/customers/api/pipeline-stages/reorder/route.ts +5 -0
  150. package/src/modules/customers/api/pipeline-stages/route.ts +13 -0
  151. package/src/modules/customers/api/pipelines/route.ts +13 -0
  152. package/src/modules/customers/api/settings/address-format/route.ts +5 -0
  153. package/src/modules/customers/api/settings/dictionary-sort-modes/route.ts +5 -0
  154. package/src/modules/customers/api/settings/stuck-threshold/route.ts +5 -0
  155. package/src/modules/customers/api/tags/assign/route.ts +5 -0
  156. package/src/modules/customers/api/tags/unassign/route.ts +5 -0
  157. package/src/modules/customers/api/todos/route.ts +13 -0
  158. package/src/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.ts +9 -0
  159. package/src/modules/dictionaries/api/[dictionaryId]/entries/reorder/route.ts +5 -0
  160. package/src/modules/dictionaries/api/[dictionaryId]/entries/route.ts +5 -0
  161. package/src/modules/dictionaries/api/[dictionaryId]/entries/set-default/route.ts +5 -0
  162. package/src/modules/directory/api/organization-branding/route.ts +5 -0
  163. package/src/modules/eudr/api/plots/import/route.ts +7 -0
  164. package/src/modules/eudr/api/product-mappings/suggestions/apply/route.ts +7 -0
  165. package/src/modules/feature_toggles/api/overrides/route.ts +5 -0
  166. package/src/modules/messages/api/[id]/actions/[actionId]/route.ts +5 -0
  167. package/src/modules/messages/api/[id]/conversation/archive/route.ts +5 -0
  168. package/src/modules/messages/api/[id]/conversation/read/route.ts +5 -0
  169. package/src/modules/messages/api/[id]/conversation/route.ts +5 -0
  170. package/src/modules/messages/api/[id]/forward/route.ts +5 -0
  171. package/src/modules/messages/api/[id]/reply/route.ts +5 -0
  172. package/src/modules/messages/api/[id]/route.ts +9 -0
  173. package/src/modules/messages/api/token/[token]/route.ts +5 -0
  174. package/src/modules/resources/api/resources/tags/assign/route.ts +5 -0
  175. package/src/modules/resources/api/resources/tags/unassign/route.ts +5 -0
  176. package/src/modules/sales/api/quotes/accept/route.ts +5 -0
  177. package/src/modules/sales/api/quotes/convert/route.ts +5 -0
  178. package/src/modules/sales/api/settings/document-numbers/route.ts +5 -0
  179. package/src/modules/sales/api/settings/order-editing/route.ts +5 -0
  180. package/src/modules/staff/api/leave-requests/accept/route.ts +5 -0
  181. package/src/modules/staff/api/leave-requests/reject/route.ts +5 -0
  182. package/src/modules/staff/api/team-members/self/route.ts +5 -0
  183. package/src/modules/staff/api/team-members/tags/assign/route.ts +5 -0
  184. package/src/modules/staff/api/team-members/tags/unassign/route.ts +5 -0
  185. package/src/modules/staff/api/timesheets/time-entries/start-timer/route.ts +5 -0
  186. package/src/modules/translations/api/[entityType]/[entityId]/route.ts +9 -0
  187. package/src/modules/warranty_claims/api/ai/assess/route.ts +5 -0
  188. package/src/modules/warranty_claims/api/assign/route.ts +5 -0
  189. package/src/modules/warranty_claims/api/credit-memo/route.ts +5 -0
  190. package/src/modules/warranty_claims/api/events/route.ts +5 -0
  191. package/src/modules/warranty_claims/api/portal/claims/[id]/submit/route.ts +5 -0
  192. package/src/modules/warranty_claims/api/portal/claims/[id]/withdraw/route.ts +5 -0
  193. package/src/modules/warranty_claims/api/portal/claims/route.ts +5 -0
  194. package/src/modules/warranty_claims/api/portal/events/route.ts +5 -0
  195. package/src/modules/warranty_claims/api/receiving/route.ts +5 -0
  196. package/src/modules/warranty_claims/api/replacement-order/route.ts +5 -0
  197. package/src/modules/warranty_claims/api/return-label/route.ts +5 -0
  198. package/src/modules/warranty_claims/api/sales-return/route.ts +5 -0
  199. package/src/modules/warranty_claims/api/settings-general/route.ts +5 -0
  200. package/src/modules/warranty_claims/api/submit/route.ts +5 -0
  201. package/src/modules/warranty_claims/api/transition/route.ts +5 -0
  202. package/src/modules/warranty_claims/api/vendor-recovery/route.ts +5 -0
  203. package/src/modules/wms/api/sales-orders/[salesOrderId]/warehouse-assignment/route.ts +5 -0
@@ -14,6 +14,7 @@ import { createLogger } from "@open-mercato/shared/lib/logger";
14
14
  import { salesOrderWarehouseAssignBodySchema } from "../../../../data/validators.js";
15
15
  import { loadSalesOrderWarehouseAssignmentView } from "../../../../lib/salesOrderWarehouseAssignment.js";
16
16
  import { executeWmsCustomPostRoute } from "../../../inventory/helpers.js";
17
+ import { getCommandInterceptorHttpRejection } from "@open-mercato/shared/lib/commands/errors";
17
18
  const logger = createLogger("wms");
18
19
  const paramsSchema = z.object({
19
20
  salesOrderId: z.string().uuid()
@@ -208,6 +209,10 @@ async function DELETE(request, routeContext) {
208
209
  }
209
210
  return NextResponse.json(intercepted.body, { status: intercepted.statusCode });
210
211
  } catch (error) {
212
+ const interceptorRejection = getCommandInterceptorHttpRejection(error);
213
+ if (interceptorRejection) {
214
+ return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status });
215
+ }
211
216
  if (error instanceof CrudHttpError) {
212
217
  return NextResponse.json(error.body, { status: error.status });
213
218
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../../src/modules/wms/api/sales-orders/%5BsalesOrderId%5D/warehouse-assignment/route.ts"],
4
- "sourcesContent": ["import { NextResponse } from 'next/server'\nimport { z } from 'zod'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { resolveOrganizationScopeForRequest } from '@open-mercato/core/modules/directory/utils/organizationScope'\nimport type { CommandBus, CommandRuntimeContext } from '@open-mercato/shared/lib/commands'\nimport { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport { readJsonSafe } from '@open-mercato/shared/lib/http/readJsonSafe'\nimport {\n runCrudMutationGuardAfterSuccess,\n validateCrudMutationGuard,\n} from '@open-mercato/shared/lib/crud/mutation-guard'\nimport { runCustomRouteAfterInterceptors } from '@open-mercato/shared/lib/crud/custom-route-interceptor'\nimport { createLogger } from '@open-mercato/shared/lib/logger'\nimport { salesOrderWarehouseAssignBodySchema } from '../../../../data/validators'\nimport { loadSalesOrderWarehouseAssignmentView } from '../../../../lib/salesOrderWarehouseAssignment'\nimport { executeWmsCustomPostRoute } from '../../../inventory/helpers'\n\nconst logger = createLogger('wms')\n\nconst paramsSchema = z.object({\n salesOrderId: z.string().uuid(),\n})\n\nconst assignmentResponseSchema = z.object({\n assignment: z\n .object({\n id: z.string().uuid(),\n salesOrderId: z.string().uuid(),\n warehouseId: z.string().uuid(),\n warehouseName: z.string().nullable(),\n warehouseCode: z.string().nullable(),\n notes: z.string().nullable(),\n assignedBy: z.string().uuid().nullable(),\n })\n .nullable(),\n})\n\nconst assignSuccessSchema = z.object({\n ok: z.literal(true),\n assignmentId: z.string().uuid(),\n warehouseId: z.string().uuid(),\n})\n\nconst okSchema = z.object({ ok: z.literal(true) })\nconst errorSchema = z.object({ error: z.string() })\n\nexport const metadata = {\n GET: { requireAuth: true, requireFeatures: ['wms.view'] },\n PUT: { requireAuth: true, requireFeatures: ['wms.manage_reservations'] },\n PATCH: { requireAuth: true, requireFeatures: ['wms.manage_reservations'] },\n DELETE: { requireAuth: true, requireFeatures: ['wms.manage_reservations'] },\n}\n\nasync function resolveCommandContext(request: Request): Promise<CommandRuntimeContext> {\n const container = await createRequestContainer()\n const auth = await getAuthFromRequest(request)\n if (!auth || !auth.tenantId) {\n throw new CrudHttpError(401, { error: 'Unauthorized' })\n }\n const organizationScope = await resolveOrganizationScopeForRequest({\n container,\n auth,\n request,\n })\n return {\n container,\n auth,\n organizationScope,\n selectedOrganizationId: organizationScope?.selectedId ?? auth.orgId ?? null,\n organizationIds: organizationScope?.filterIds ?? (auth.orgId ? [auth.orgId] : null),\n request,\n }\n}\n\nfunction resolveScope(ctx: CommandRuntimeContext) {\n const organizationId = ctx.selectedOrganizationId ?? ctx.auth?.orgId ?? null\n const tenantId = ctx.auth?.tenantId ?? null\n if (!organizationId || !tenantId) {\n throw new CrudHttpError(401, { error: 'Unauthorized' })\n }\n return { organizationId, tenantId }\n}\n\nexport async function GET(\n request: Request,\n { params }: { params: { salesOrderId: string } },\n) {\n try {\n const parsedParams = paramsSchema.parse(params)\n const ctx = await resolveCommandContext(request)\n const scope = resolveScope(ctx)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const assignment = await loadSalesOrderWarehouseAssignmentView(\n em,\n parsedParams.salesOrderId,\n scope,\n )\n return NextResponse.json({ assignment })\n } catch (error) {\n if (error instanceof CrudHttpError) {\n return NextResponse.json(error.body, { status: error.status })\n }\n if (error instanceof z.ZodError) {\n return NextResponse.json({ error: 'Validation failed', details: error.issues }, { status: 400 })\n }\n logger.error('GET warehouse-assignment failed', { err: error })\n return NextResponse.json({ error: 'Internal server error' }, { status: 500 })\n }\n}\n\nasync function executeAssignMutation(request: Request, salesOrderId: string) {\n const body = await readJsonSafe<Record<string, unknown>>(request, {})\n const parsedBody = salesOrderWarehouseAssignBodySchema.parse(body)\n const scopedRequest = new Request(request.url, {\n method: 'POST',\n headers: request.headers,\n body: JSON.stringify({\n ...parsedBody,\n salesOrderId,\n }),\n })\n return executeWmsCustomPostRoute({\n request: scopedRequest,\n routePath: `wms/sales-orders/${salesOrderId}/warehouse-assignment`,\n inputSchema: z.object({\n salesOrderId: z.string().uuid(),\n warehouseId: z.string().uuid(),\n notes: z.string().trim().max(500).optional(),\n tenantId: z.string().uuid().optional(),\n organizationId: z.string().uuid().optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n }),\n commandId: 'wms.sales-order.assign-warehouse',\n describeResource: (input) => ({\n resourceKind: 'wms.sales_order_warehouse_assignment',\n resourceId: input.salesOrderId,\n }),\n mapSuccess: (result: { assignmentId: string; warehouseId: string }) => ({\n ok: true,\n assignmentId: result.assignmentId,\n warehouseId: result.warehouseId,\n }),\n })\n}\n\nexport async function PUT(\n request: Request,\n routeContext: { params: { salesOrderId: string } },\n) {\n const parsedParams = paramsSchema.parse(routeContext.params)\n return executeAssignMutation(request, parsedParams.salesOrderId)\n}\n\nexport async function PATCH(\n request: Request,\n routeContext: { params: { salesOrderId: string } },\n) {\n const parsedParams = paramsSchema.parse(routeContext.params)\n return executeAssignMutation(request, parsedParams.salesOrderId)\n}\n\nexport async function DELETE(\n request: Request,\n routeContext: { params: { salesOrderId: string } },\n) {\n try {\n const parsedParams = paramsSchema.parse(routeContext.params)\n const ctx = await resolveCommandContext(request)\n const scope = resolveScope(ctx)\n const resource = {\n resourceKind: 'wms.sales_order_warehouse_assignment',\n resourceId: parsedParams.salesOrderId,\n }\n const guardResult = await validateCrudMutationGuard(ctx.container, {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n userId: ctx.auth?.sub ?? '',\n resourceKind: resource.resourceKind,\n resourceId: resource.resourceId,\n operation: 'custom',\n requestMethod: request.method,\n requestHeaders: request.headers,\n mutationPayload: { salesOrderId: parsedParams.salesOrderId },\n })\n if (guardResult && !guardResult.ok) {\n return NextResponse.json(guardResult.body, { status: guardResult.status })\n }\n\n const commandBus = ctx.container.resolve('commandBus') as CommandBus\n await commandBus.execute('wms.sales-order.unassign-warehouse', {\n input: {\n salesOrderId: parsedParams.salesOrderId,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n },\n ctx,\n })\n\n if (guardResult?.ok && guardResult.shouldRunAfterSuccess) {\n await runCrudMutationGuardAfterSuccess(ctx.container, {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n userId: ctx.auth?.sub ?? '',\n resourceKind: resource.resourceKind,\n resourceId: resource.resourceId,\n operation: 'custom',\n requestMethod: request.method,\n requestHeaders: request.headers,\n metadata: guardResult.metadata ?? null,\n })\n }\n\n const responseBody = { ok: true as const }\n const intercepted = await runCustomRouteAfterInterceptors({\n routePath: `wms/sales-orders/${parsedParams.salesOrderId}/warehouse-assignment`,\n method: 'DELETE',\n request: {\n method: 'DELETE',\n url: request.url,\n body: { salesOrderId: parsedParams.salesOrderId },\n headers: Object.fromEntries(request.headers.entries()),\n },\n response: {\n statusCode: 200,\n body: responseBody,\n headers: {},\n },\n context: {\n em: ctx.container.resolve('em'),\n container: ctx.container,\n userId: ctx.auth?.sub ?? '',\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n },\n })\n if (!intercepted.ok) {\n return NextResponse.json(intercepted.body, { status: intercepted.statusCode })\n }\n return NextResponse.json(intercepted.body, { status: intercepted.statusCode })\n } catch (error) {\n if (error instanceof CrudHttpError) {\n return NextResponse.json(error.body, { status: error.status })\n }\n if (error instanceof z.ZodError) {\n return NextResponse.json({ error: 'Validation failed', details: error.issues }, { status: 400 })\n }\n logger.error('DELETE warehouse-assignment failed', { err: error })\n return NextResponse.json({ error: 'Internal server error' }, { status: 500 })\n }\n}\n\nexport const openApi: OpenApiRouteDoc = {\n tag: 'WMS',\n summary: 'Sales order warehouse assignment',\n methods: {\n GET: {\n summary: 'Get warehouse assignment for sales order',\n description:\n 'Returns the explicit WMS warehouse assignment for a sales order, or null when none is set.',\n responses: [\n { status: 200, description: 'Assignment state', schema: assignmentResponseSchema },\n ],\n errors: [\n { status: 400, description: 'Validation failed', schema: errorSchema },\n { status: 401, description: 'Unauthorized', schema: errorSchema },\n ],\n },\n PUT: {\n summary: 'Assign warehouse to sales order',\n description:\n 'Creates or replaces the explicit warehouse assignment for a sales order.',\n requestBody: { contentType: 'application/json', schema: salesOrderWarehouseAssignBodySchema },\n responses: [\n { status: 200, description: 'Warehouse assigned', schema: assignSuccessSchema },\n { status: 201, description: 'Warehouse assigned', schema: assignSuccessSchema },\n ],\n errors: [\n { status: 400, description: 'Validation failed', schema: errorSchema },\n { status: 401, description: 'Unauthorized', schema: errorSchema },\n { status: 404, description: 'Warehouse not found', schema: errorSchema },\n { status: 422, description: 'Warehouse is inactive', schema: errorSchema },\n ],\n },\n PATCH: {\n summary: 'Patch warehouse assignment for sales order',\n description: 'Same as PUT \u2014 upserts the explicit warehouse assignment.',\n requestBody: { contentType: 'application/json', schema: salesOrderWarehouseAssignBodySchema },\n responses: [{ status: 200, description: 'Warehouse assigned', schema: assignSuccessSchema }],\n errors: [\n { status: 400, description: 'Validation failed', schema: errorSchema },\n { status: 401, description: 'Unauthorized', schema: errorSchema },\n ],\n },\n DELETE: {\n summary: 'Remove warehouse assignment from sales order',\n description: 'Clears the explicit assignment so enricher and automation fall back again.',\n responses: [{ status: 200, description: 'Assignment removed', schema: okSchema }],\n errors: [\n { status: 401, description: 'Unauthorized', schema: errorSchema },\n ],\n },\n },\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { NextResponse } from 'next/server'\nimport { z } from 'zod'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { resolveOrganizationScopeForRequest } from '@open-mercato/core/modules/directory/utils/organizationScope'\nimport type { CommandBus, CommandRuntimeContext } from '@open-mercato/shared/lib/commands'\nimport { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport { readJsonSafe } from '@open-mercato/shared/lib/http/readJsonSafe'\nimport {\n runCrudMutationGuardAfterSuccess,\n validateCrudMutationGuard,\n} from '@open-mercato/shared/lib/crud/mutation-guard'\nimport { runCustomRouteAfterInterceptors } from '@open-mercato/shared/lib/crud/custom-route-interceptor'\nimport { createLogger } from '@open-mercato/shared/lib/logger'\nimport { salesOrderWarehouseAssignBodySchema } from '../../../../data/validators'\nimport { loadSalesOrderWarehouseAssignmentView } from '../../../../lib/salesOrderWarehouseAssignment'\nimport { executeWmsCustomPostRoute } from '../../../inventory/helpers'\nimport { getCommandInterceptorHttpRejection } from '@open-mercato/shared/lib/commands/errors'\n\nconst logger = createLogger('wms')\n\nconst paramsSchema = z.object({\n salesOrderId: z.string().uuid(),\n})\n\nconst assignmentResponseSchema = z.object({\n assignment: z\n .object({\n id: z.string().uuid(),\n salesOrderId: z.string().uuid(),\n warehouseId: z.string().uuid(),\n warehouseName: z.string().nullable(),\n warehouseCode: z.string().nullable(),\n notes: z.string().nullable(),\n assignedBy: z.string().uuid().nullable(),\n })\n .nullable(),\n})\n\nconst assignSuccessSchema = z.object({\n ok: z.literal(true),\n assignmentId: z.string().uuid(),\n warehouseId: z.string().uuid(),\n})\n\nconst okSchema = z.object({ ok: z.literal(true) })\nconst errorSchema = z.object({ error: z.string() })\n\nexport const metadata = {\n GET: { requireAuth: true, requireFeatures: ['wms.view'] },\n PUT: { requireAuth: true, requireFeatures: ['wms.manage_reservations'] },\n PATCH: { requireAuth: true, requireFeatures: ['wms.manage_reservations'] },\n DELETE: { requireAuth: true, requireFeatures: ['wms.manage_reservations'] },\n}\n\nasync function resolveCommandContext(request: Request): Promise<CommandRuntimeContext> {\n const container = await createRequestContainer()\n const auth = await getAuthFromRequest(request)\n if (!auth || !auth.tenantId) {\n throw new CrudHttpError(401, { error: 'Unauthorized' })\n }\n const organizationScope = await resolveOrganizationScopeForRequest({\n container,\n auth,\n request,\n })\n return {\n container,\n auth,\n organizationScope,\n selectedOrganizationId: organizationScope?.selectedId ?? auth.orgId ?? null,\n organizationIds: organizationScope?.filterIds ?? (auth.orgId ? [auth.orgId] : null),\n request,\n }\n}\n\nfunction resolveScope(ctx: CommandRuntimeContext) {\n const organizationId = ctx.selectedOrganizationId ?? ctx.auth?.orgId ?? null\n const tenantId = ctx.auth?.tenantId ?? null\n if (!organizationId || !tenantId) {\n throw new CrudHttpError(401, { error: 'Unauthorized' })\n }\n return { organizationId, tenantId }\n}\n\nexport async function GET(\n request: Request,\n { params }: { params: { salesOrderId: string } },\n) {\n try {\n const parsedParams = paramsSchema.parse(params)\n const ctx = await resolveCommandContext(request)\n const scope = resolveScope(ctx)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const assignment = await loadSalesOrderWarehouseAssignmentView(\n em,\n parsedParams.salesOrderId,\n scope,\n )\n return NextResponse.json({ assignment })\n } catch (error) {\n if (error instanceof CrudHttpError) {\n return NextResponse.json(error.body, { status: error.status })\n }\n if (error instanceof z.ZodError) {\n return NextResponse.json({ error: 'Validation failed', details: error.issues }, { status: 400 })\n }\n logger.error('GET warehouse-assignment failed', { err: error })\n return NextResponse.json({ error: 'Internal server error' }, { status: 500 })\n }\n}\n\nasync function executeAssignMutation(request: Request, salesOrderId: string) {\n const body = await readJsonSafe<Record<string, unknown>>(request, {})\n const parsedBody = salesOrderWarehouseAssignBodySchema.parse(body)\n const scopedRequest = new Request(request.url, {\n method: 'POST',\n headers: request.headers,\n body: JSON.stringify({\n ...parsedBody,\n salesOrderId,\n }),\n })\n return executeWmsCustomPostRoute({\n request: scopedRequest,\n routePath: `wms/sales-orders/${salesOrderId}/warehouse-assignment`,\n inputSchema: z.object({\n salesOrderId: z.string().uuid(),\n warehouseId: z.string().uuid(),\n notes: z.string().trim().max(500).optional(),\n tenantId: z.string().uuid().optional(),\n organizationId: z.string().uuid().optional(),\n metadata: z.record(z.string(), z.unknown()).optional(),\n }),\n commandId: 'wms.sales-order.assign-warehouse',\n describeResource: (input) => ({\n resourceKind: 'wms.sales_order_warehouse_assignment',\n resourceId: input.salesOrderId,\n }),\n mapSuccess: (result: { assignmentId: string; warehouseId: string }) => ({\n ok: true,\n assignmentId: result.assignmentId,\n warehouseId: result.warehouseId,\n }),\n })\n}\n\nexport async function PUT(\n request: Request,\n routeContext: { params: { salesOrderId: string } },\n) {\n const parsedParams = paramsSchema.parse(routeContext.params)\n return executeAssignMutation(request, parsedParams.salesOrderId)\n}\n\nexport async function PATCH(\n request: Request,\n routeContext: { params: { salesOrderId: string } },\n) {\n const parsedParams = paramsSchema.parse(routeContext.params)\n return executeAssignMutation(request, parsedParams.salesOrderId)\n}\n\nexport async function DELETE(\n request: Request,\n routeContext: { params: { salesOrderId: string } },\n) {\n try {\n const parsedParams = paramsSchema.parse(routeContext.params)\n const ctx = await resolveCommandContext(request)\n const scope = resolveScope(ctx)\n const resource = {\n resourceKind: 'wms.sales_order_warehouse_assignment',\n resourceId: parsedParams.salesOrderId,\n }\n const guardResult = await validateCrudMutationGuard(ctx.container, {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n userId: ctx.auth?.sub ?? '',\n resourceKind: resource.resourceKind,\n resourceId: resource.resourceId,\n operation: 'custom',\n requestMethod: request.method,\n requestHeaders: request.headers,\n mutationPayload: { salesOrderId: parsedParams.salesOrderId },\n })\n if (guardResult && !guardResult.ok) {\n return NextResponse.json(guardResult.body, { status: guardResult.status })\n }\n\n const commandBus = ctx.container.resolve('commandBus') as CommandBus\n await commandBus.execute('wms.sales-order.unassign-warehouse', {\n input: {\n salesOrderId: parsedParams.salesOrderId,\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n },\n ctx,\n })\n\n if (guardResult?.ok && guardResult.shouldRunAfterSuccess) {\n await runCrudMutationGuardAfterSuccess(ctx.container, {\n tenantId: scope.tenantId,\n organizationId: scope.organizationId,\n userId: ctx.auth?.sub ?? '',\n resourceKind: resource.resourceKind,\n resourceId: resource.resourceId,\n operation: 'custom',\n requestMethod: request.method,\n requestHeaders: request.headers,\n metadata: guardResult.metadata ?? null,\n })\n }\n\n const responseBody = { ok: true as const }\n const intercepted = await runCustomRouteAfterInterceptors({\n routePath: `wms/sales-orders/${parsedParams.salesOrderId}/warehouse-assignment`,\n method: 'DELETE',\n request: {\n method: 'DELETE',\n url: request.url,\n body: { salesOrderId: parsedParams.salesOrderId },\n headers: Object.fromEntries(request.headers.entries()),\n },\n response: {\n statusCode: 200,\n body: responseBody,\n headers: {},\n },\n context: {\n em: ctx.container.resolve('em'),\n container: ctx.container,\n userId: ctx.auth?.sub ?? '',\n organizationId: scope.organizationId,\n tenantId: scope.tenantId,\n },\n })\n if (!intercepted.ok) {\n return NextResponse.json(intercepted.body, { status: intercepted.statusCode })\n }\n return NextResponse.json(intercepted.body, { status: intercepted.statusCode })\n } catch (error) {\n const interceptorRejection = getCommandInterceptorHttpRejection(error)\n if (interceptorRejection) {\n return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status })\n }\n if (error instanceof CrudHttpError) {\n return NextResponse.json(error.body, { status: error.status })\n }\n if (error instanceof z.ZodError) {\n return NextResponse.json({ error: 'Validation failed', details: error.issues }, { status: 400 })\n }\n logger.error('DELETE warehouse-assignment failed', { err: error })\n return NextResponse.json({ error: 'Internal server error' }, { status: 500 })\n }\n}\n\nexport const openApi: OpenApiRouteDoc = {\n tag: 'WMS',\n summary: 'Sales order warehouse assignment',\n methods: {\n GET: {\n summary: 'Get warehouse assignment for sales order',\n description:\n 'Returns the explicit WMS warehouse assignment for a sales order, or null when none is set.',\n responses: [\n { status: 200, description: 'Assignment state', schema: assignmentResponseSchema },\n ],\n errors: [\n { status: 400, description: 'Validation failed', schema: errorSchema },\n { status: 401, description: 'Unauthorized', schema: errorSchema },\n ],\n },\n PUT: {\n summary: 'Assign warehouse to sales order',\n description:\n 'Creates or replaces the explicit warehouse assignment for a sales order.',\n requestBody: { contentType: 'application/json', schema: salesOrderWarehouseAssignBodySchema },\n responses: [\n { status: 200, description: 'Warehouse assigned', schema: assignSuccessSchema },\n { status: 201, description: 'Warehouse assigned', schema: assignSuccessSchema },\n ],\n errors: [\n { status: 400, description: 'Validation failed', schema: errorSchema },\n { status: 401, description: 'Unauthorized', schema: errorSchema },\n { status: 404, description: 'Warehouse not found', schema: errorSchema },\n { status: 422, description: 'Warehouse is inactive', schema: errorSchema },\n ],\n },\n PATCH: {\n summary: 'Patch warehouse assignment for sales order',\n description: 'Same as PUT \u2014 upserts the explicit warehouse assignment.',\n requestBody: { contentType: 'application/json', schema: salesOrderWarehouseAssignBodySchema },\n responses: [{ status: 200, description: 'Warehouse assigned', schema: assignSuccessSchema }],\n errors: [\n { status: 400, description: 'Validation failed', schema: errorSchema },\n { status: 401, description: 'Unauthorized', schema: errorSchema },\n ],\n },\n DELETE: {\n summary: 'Remove warehouse assignment from sales order',\n description: 'Clears the explicit assignment so enricher and automation fall back again.',\n responses: [{ status: 200, description: 'Assignment removed', schema: okSchema }],\n errors: [\n { status: 401, description: 'Unauthorized', schema: errorSchema },\n ],\n },\n },\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@open-mercato/core",
3
- "version": "0.7.1-develop.7130.1.fef2396fd8",
3
+ "version": "0.7.1-develop.7131.1.20abf9e885",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -252,16 +252,16 @@
252
252
  "zod": "^4.4.3"
253
253
  },
254
254
  "peerDependencies": {
255
- "@open-mercato/ai-assistant": "0.7.1-develop.7130.1.fef2396fd8",
256
- "@open-mercato/shared": "0.7.1-develop.7130.1.fef2396fd8",
257
- "@open-mercato/ui": "0.7.1-develop.7130.1.fef2396fd8",
255
+ "@open-mercato/ai-assistant": "0.7.1-develop.7131.1.20abf9e885",
256
+ "@open-mercato/shared": "0.7.1-develop.7131.1.20abf9e885",
257
+ "@open-mercato/ui": "0.7.1-develop.7131.1.20abf9e885",
258
258
  "react": "^19.0.0",
259
259
  "react-dom": "^19.0.0"
260
260
  },
261
261
  "devDependencies": {
262
- "@open-mercato/ai-assistant": "0.7.1-develop.7130.1.fef2396fd8",
263
- "@open-mercato/shared": "0.7.1-develop.7130.1.fef2396fd8",
264
- "@open-mercato/ui": "0.7.1-develop.7130.1.fef2396fd8",
262
+ "@open-mercato/ai-assistant": "0.7.1-develop.7131.1.20abf9e885",
263
+ "@open-mercato/shared": "0.7.1-develop.7131.1.20abf9e885",
264
+ "@open-mercato/ui": "0.7.1-develop.7131.1.20abf9e885",
265
265
  "@testing-library/dom": "^10.4.1",
266
266
  "@testing-library/jest-dom": "^7.0.0",
267
267
  "@testing-library/react": "^16.3.1",
@@ -13,6 +13,7 @@ import type { ActionLog } from '@open-mercato/core/modules/audit_logs/data/entit
13
13
  import { z } from 'zod'
14
14
  import type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'
15
15
  import { createLogger } from '@open-mercato/shared/lib/logger'
16
+ import { getCommandInterceptorHttpRejection } from '@open-mercato/shared/lib/commands/errors'
16
17
 
17
18
  const logger = createLogger('audit_logs').child({ component: 'redo' })
18
19
 
@@ -167,6 +168,10 @@ export async function POST(req: Request) {
167
168
  logger.warn('Redo rejected', { 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
  logger.error('Redo failed', { err })
171
176
  return NextResponse.json({ error: 'Redo failed' }, { status: 400 })
172
177
  }
@@ -13,6 +13,7 @@ import type { EntityManager } from '@mikro-orm/postgresql'
13
13
  import { findOneWithDecryption } from '@open-mercato/shared/lib/encryption/find'
14
14
  import { buildPasswordSchema } from '@open-mercato/shared/lib/auth/passwordPolicy'
15
15
  import { createLogger } from '@open-mercato/shared/lib/logger'
16
+ import { getCommandInterceptorHttpRejection } from '@open-mercato/shared/lib/commands/errors'
16
17
 
17
18
  const logger = createLogger('auth').child({ component: 'profile' })
18
19
 
@@ -202,6 +203,10 @@ export async function PUT(req: Request) {
202
203
  if (isCrudHttpError(err)) {
203
204
  return NextResponse.json(err.body, { status: err.status })
204
205
  }
206
+ const interceptorRejection = getCommandInterceptorHttpRejection(err)
207
+ if (interceptorRejection) {
208
+ return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status })
209
+ }
205
210
  logger.error('Profile update failed', { err })
206
211
  return NextResponse.json({ error: translate('auth.profile.form.errors.save', 'Failed to update profile.') }, { status: 400 })
207
212
  }
@@ -31,6 +31,7 @@ import { hydrateCanonicalInteractions } from '../../lib/interactionReadModel'
31
31
  import { resolveCanonicalActivityTargetId } from '../../lib/legacyActivityBridge'
32
32
  import { buildEmailVisibilityMikroFilter } from '../../lib/visibilityFilter'
33
33
  import { createLogger } from '@open-mercato/shared/lib/logger'
34
+ import { getCommandInterceptorHttpRejection } from '@open-mercato/shared/lib/commands/errors'
34
35
 
35
36
  const logger = createLogger('customers')
36
37
 
@@ -620,6 +621,10 @@ export async function POST(request: Request): Promise<Response> {
620
621
  if (isCrudHttpError(err)) {
621
622
  return withAdapterHeaders(NextResponse.json(err.body, { status: err.status }))
622
623
  }
624
+ const interceptorRejection = getCommandInterceptorHttpRejection(err)
625
+ if (interceptorRejection) {
626
+ return withAdapterHeaders(NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status }))
627
+ }
623
628
  if (err instanceof z.ZodError) {
624
629
  return withAdapterHeaders(
625
630
  NextResponse.json({ error: 'Validation failed', details: err.issues }, { status: 400 }),
@@ -703,6 +708,10 @@ export async function PUT(request: Request): Promise<Response> {
703
708
  if (isCrudHttpError(err)) {
704
709
  return withAdapterHeaders(NextResponse.json(err.body, { status: err.status }))
705
710
  }
711
+ const interceptorRejection = getCommandInterceptorHttpRejection(err)
712
+ if (interceptorRejection) {
713
+ return withAdapterHeaders(NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status }))
714
+ }
706
715
  if (err instanceof z.ZodError) {
707
716
  return withAdapterHeaders(
708
717
  NextResponse.json({ error: 'Validation failed', details: err.issues }, { status: 400 }),
@@ -771,6 +780,10 @@ export async function DELETE(request: Request): Promise<Response> {
771
780
  if (isCrudHttpError(err)) {
772
781
  return withAdapterHeaders(NextResponse.json(err.body, { status: err.status }))
773
782
  }
783
+ const interceptorRejection = getCommandInterceptorHttpRejection(err)
784
+ if (interceptorRejection) {
785
+ return withAdapterHeaders(NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status }))
786
+ }
774
787
  if (err instanceof z.ZodError) {
775
788
  return withAdapterHeaders(
776
789
  NextResponse.json({ error: 'Validation failed', details: err.issues }, { status: 400 }),
@@ -16,6 +16,7 @@ import {
16
16
  validateCrudMutationGuard,
17
17
  } from '@open-mercato/shared/lib/crud/mutation-guard'
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('customers')
21
22
 
@@ -175,6 +176,10 @@ export async function PATCH(req: Request, ctx: { params?: { kind?: string; id?:
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('customers.dictionaries.update failed', { err })
180
185
  return NextResponse.json({ error: translate('customers.errors.lookup_failed', 'Failed to save dictionary entry') }, { status: 400 })
@@ -276,6 +281,10 @@ export async function DELETE(req: Request, ctx: { params?: { kind?: string; id?:
276
281
  if (isCrudHttpError(err)) {
277
282
  return NextResponse.json(err.body, { status: err.status })
278
283
  }
284
+ const interceptorRejection = getCommandInterceptorHttpRejection(err)
285
+ if (interceptorRejection) {
286
+ return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status })
287
+ }
279
288
  const { translate } = await resolveTranslations()
280
289
  logger.error('customers.dictionaries.delete failed', { err })
281
290
  return NextResponse.json({ error: translate('customers.errors.lookup_failed', 'Failed to delete dictionary entry') }, { status: 400 })
@@ -23,6 +23,7 @@ import { findWithDecryption, findOneWithDecryption } from '@open-mercato/shared/
23
23
  import { readJsonSafe } from '@open-mercato/shared/lib/http/readJsonSafe'
24
24
  import { createLogger } from '@open-mercato/shared/lib/logger'
25
25
  import { CUSTOMER_DICTIONARY_ORGANIZATION_REQUIRED_CODE } from '../../../lib/dictionaries'
26
+ import { getCommandInterceptorHttpRejection } from '@open-mercato/shared/lib/commands/errors'
26
27
 
27
28
  const logger = createLogger('customers')
28
29
 
@@ -271,6 +272,10 @@ export async function POST(req: Request, ctx: { params?: { kind?: string } }) {
271
272
  if (isCrudHttpError(err)) {
272
273
  return NextResponse.json(err.body, { status: err.status })
273
274
  }
275
+ const interceptorRejection = getCommandInterceptorHttpRejection(err)
276
+ if (interceptorRejection) {
277
+ return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status })
278
+ }
274
279
  const { translate } = await resolveTranslations()
275
280
  logger.error('customers.dictionaries.create failed', { err })
276
281
  return NextResponse.json({ error: translate('customers.errors.lookup_failed', 'Failed to save dictionary entry') }, { status: 400 })
@@ -20,6 +20,7 @@ import {
20
20
  type CustomerKindSettingsUpsertInput,
21
21
  } from '../../../data/validators'
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('customers')
25
26
 
@@ -186,6 +187,10 @@ export async function PATCH(req: Request) {
186
187
  if (isCrudHttpError(err)) {
187
188
  return NextResponse.json(err.body, { status: err.status })
188
189
  }
190
+ const interceptorRejection = getCommandInterceptorHttpRejection(err)
191
+ if (interceptorRejection) {
192
+ return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status })
193
+ }
189
194
  logger.error('customers/dictionaries/kind-settings.PATCH', { err })
190
195
  return NextResponse.json({ error: 'Failed to update kind setting' }, { status: 500 })
191
196
  }
@@ -16,6 +16,7 @@ import {
16
16
  import { resolveAuthActorId } from '../../../lib/interactionRequestContext'
17
17
  import { withOperationMetadata } from '../../../lib/operationMetadata'
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('customers')
21
22
 
@@ -86,6 +87,10 @@ export async function POST(req: Request) {
86
87
  if (isCrudHttpError(err)) {
87
88
  return NextResponse.json(err.body, { status: err.status })
88
89
  }
90
+ const interceptorRejection = getCommandInterceptorHttpRejection(err)
91
+ if (interceptorRejection) {
92
+ return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status })
93
+ }
89
94
  if (err instanceof z.ZodError) {
90
95
  return NextResponse.json({ error: 'Validation failed', details: err.issues }, { status: 400 })
91
96
  }
@@ -16,6 +16,7 @@ import {
16
16
  import { resolveAuthActorId } from '../../../lib/interactionRequestContext'
17
17
  import { withOperationMetadata } from '../../../lib/operationMetadata'
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('customers')
21
22
 
@@ -86,6 +87,10 @@ export async function POST(req: Request) {
86
87
  if (isCrudHttpError(err)) {
87
88
  return NextResponse.json(err.body, { status: err.status })
88
89
  }
90
+ const interceptorRejection = getCommandInterceptorHttpRejection(err)
91
+ if (interceptorRejection) {
92
+ return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status })
93
+ }
89
94
  if (err instanceof z.ZodError) {
90
95
  return NextResponse.json({ error: 'Validation failed', details: err.issues }, { status: 400 })
91
96
  }
@@ -24,6 +24,7 @@ import {
24
24
  import { readJsonSafe } from '@open-mercato/shared/lib/http/readJsonSafe'
25
25
  import { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'
26
26
  import { createLogger } from '@open-mercato/shared/lib/logger'
27
+ import { getCommandInterceptorHttpRejection } from '@open-mercato/shared/lib/commands/errors'
27
28
 
28
29
  const logger = createLogger('customers')
29
30
 
@@ -174,6 +175,10 @@ export async function POST(req: Request) {
174
175
  if (isCrudHttpError(err)) {
175
176
  return NextResponse.json(err.body, { status: err.status })
176
177
  }
178
+ const interceptorRejection = getCommandInterceptorHttpRejection(err)
179
+ if (interceptorRejection) {
180
+ return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status })
181
+ }
177
182
  logger.error('customers/labels/assign.POST', { err })
178
183
  const { translate: fallbackTranslate } = await resolveTranslations()
179
184
  return NextResponse.json(
@@ -27,6 +27,7 @@ import {
27
27
  import { readJsonSafe } from '@open-mercato/shared/lib/http/readJsonSafe'
28
28
  import { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'
29
29
  import { createLogger } from '@open-mercato/shared/lib/logger'
30
+ import { getCommandInterceptorHttpRejection } from '@open-mercato/shared/lib/commands/errors'
30
31
 
31
32
  const logger = createLogger('customers')
32
33
 
@@ -287,6 +288,10 @@ export async function POST(req: Request) {
287
288
  if (isCrudHttpError(err)) {
288
289
  return NextResponse.json(err.body, { status: err.status })
289
290
  }
291
+ const interceptorRejection = getCommandInterceptorHttpRejection(err)
292
+ if (interceptorRejection) {
293
+ return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status })
294
+ }
290
295
  logger.error('customers/labels.POST', { err })
291
296
  return NextResponse.json({ error: 'Failed to create label' }, { status: 500 })
292
297
  }
@@ -24,6 +24,7 @@ import {
24
24
  import { readJsonSafe } from '@open-mercato/shared/lib/http/readJsonSafe'
25
25
  import { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'
26
26
  import { createLogger } from '@open-mercato/shared/lib/logger'
27
+ import { getCommandInterceptorHttpRejection } from '@open-mercato/shared/lib/commands/errors'
27
28
 
28
29
  const logger = createLogger('customers')
29
30
 
@@ -174,6 +175,10 @@ export async function POST(req: Request) {
174
175
  if (isCrudHttpError(err)) {
175
176
  return NextResponse.json(err.body, { status: err.status })
176
177
  }
178
+ const interceptorRejection = getCommandInterceptorHttpRejection(err)
179
+ if (interceptorRejection) {
180
+ return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status })
181
+ }
177
182
  logger.error('customers/labels/unassign.POST', { err })
178
183
  return NextResponse.json({ error: 'Failed to unassign label' }, { status: 500 })
179
184
  }
@@ -21,6 +21,7 @@ import {
21
21
  import { loadPersonContext } from '../context'
22
22
  import { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'
23
23
  import type { EntityManager, FilterQuery } from '@mikro-orm/postgresql'
24
+ import { getCommandInterceptorHttpRejection } from '@open-mercato/shared/lib/commands/errors'
24
25
 
25
26
  const paramsSchema = z.object({
26
27
  id: z.string().uuid(),
@@ -226,6 +227,10 @@ export async function PATCH(req: Request, ctx: { params?: { id?: string; linkId?
226
227
  if (isCrudHttpError(err)) {
227
228
  return NextResponse.json(err.body, { status: err.status })
228
229
  }
230
+ const interceptorRejection = getCommandInterceptorHttpRejection(err)
231
+ if (interceptorRejection) {
232
+ return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status })
233
+ }
229
234
  return NextResponse.json({ error: translate('customers.errors.internal', 'Internal server error') }, { status: 500 })
230
235
  }
231
236
  }
@@ -330,6 +335,10 @@ export async function DELETE(req: Request, ctx: { params?: { id?: string; linkId
330
335
  if (isCrudHttpError(err)) {
331
336
  return NextResponse.json(err.body, { status: err.status })
332
337
  }
338
+ const interceptorRejection = getCommandInterceptorHttpRejection(err)
339
+ if (interceptorRejection) {
340
+ return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status })
341
+ }
333
342
  return NextResponse.json({ error: translate('customers.errors.internal', 'Internal server error') }, { status: 500 })
334
343
  }
335
344
  }
@@ -26,6 +26,7 @@ import {
26
26
  import { loadPersonContext } from './context'
27
27
  import { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'
28
28
  import type { EntityManager } from '@mikro-orm/postgresql'
29
+ import { getCommandInterceptorHttpRejection } from '@open-mercato/shared/lib/commands/errors'
29
30
 
30
31
  const paramsSchema = z.object({
31
32
  id: z.string().uuid(),
@@ -210,6 +211,10 @@ export async function POST(req: Request, ctx: { params?: { id?: string } }) {
210
211
  if (isCrudHttpError(err)) {
211
212
  return NextResponse.json(err.body, { status: err.status })
212
213
  }
214
+ const interceptorRejection = getCommandInterceptorHttpRejection(err)
215
+ if (interceptorRejection) {
216
+ return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status })
217
+ }
213
218
  return NextResponse.json({ error: translate('customers.errors.internal', 'Internal server error') }, { status: 500 })
214
219
  }
215
220
  }
@@ -14,6 +14,7 @@ import {
14
14
  } from '@open-mercato/shared/lib/crud/mutation-guard'
15
15
  import type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'
16
16
  import { createLogger } from '@open-mercato/shared/lib/logger'
17
+ import { getCommandInterceptorHttpRejection } from '@open-mercato/shared/lib/commands/errors'
17
18
 
18
19
  const logger = createLogger('customers')
19
20
 
@@ -86,6 +87,10 @@ export async function POST(req: Request) {
86
87
  if (isCrudHttpError(err)) {
87
88
  return NextResponse.json(err.body, { status: err.status })
88
89
  }
90
+ const interceptorRejection = getCommandInterceptorHttpRejection(err)
91
+ if (interceptorRejection) {
92
+ return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status })
93
+ }
89
94
  logger.error('customers.pipeline-stages.reorder failed', { err })
90
95
  return NextResponse.json({ error: 'Failed to reorder pipeline stages' }, { status: 400 })
91
96
  }
@@ -25,6 +25,7 @@ import {
25
25
  } from '@open-mercato/shared/lib/crud/mutation-guard'
26
26
  import type { OpenApiRouteDoc } 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('customers')
30
31
 
@@ -174,6 +175,10 @@ export async function POST(req: Request) {
174
175
  if (isCrudHttpError(err)) {
175
176
  return NextResponse.json(err.body, { status: err.status })
176
177
  }
178
+ const interceptorRejection = getCommandInterceptorHttpRejection(err)
179
+ if (interceptorRejection) {
180
+ return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status })
181
+ }
177
182
  logger.error('customers.pipeline-stages POST failed', { err })
178
183
  return NextResponse.json({ error: 'Failed to create pipeline stage' }, { status: 400 })
179
184
  }
@@ -242,6 +247,10 @@ export async function PUT(req: Request) {
242
247
  if (isCrudHttpError(err)) {
243
248
  return NextResponse.json(err.body, { status: err.status })
244
249
  }
250
+ const interceptorRejection = getCommandInterceptorHttpRejection(err)
251
+ if (interceptorRejection) {
252
+ return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status })
253
+ }
245
254
  logger.error('customers.pipeline-stages PUT failed', { err })
246
255
  return NextResponse.json({ error: 'Failed to update pipeline stage' }, { status: 400 })
247
256
  }
@@ -295,6 +304,10 @@ export async function DELETE(req: Request) {
295
304
  if (isCrudHttpError(err)) {
296
305
  return NextResponse.json(err.body, { status: err.status })
297
306
  }
307
+ const interceptorRejection = getCommandInterceptorHttpRejection(err)
308
+ if (interceptorRejection) {
309
+ return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status })
310
+ }
298
311
  logger.error('customers.pipeline-stages DELETE failed', { err })
299
312
  return NextResponse.json({ error: 'Failed to delete pipeline stage' }, { status: 400 })
300
313
  }
@@ -25,6 +25,7 @@ import {
25
25
  } from '@open-mercato/shared/lib/crud/mutation-guard'
26
26
  import type { OpenApiRouteDoc } 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('customers')
30
31
 
@@ -156,6 +157,10 @@ export async function POST(req: Request) {
156
157
  if (isCrudHttpError(err)) {
157
158
  return NextResponse.json(err.body, { status: err.status })
158
159
  }
160
+ const interceptorRejection = getCommandInterceptorHttpRejection(err)
161
+ if (interceptorRejection) {
162
+ return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status })
163
+ }
159
164
  logger.error('customers.pipelines POST failed', { err })
160
165
  return NextResponse.json({ error: 'Failed to create pipeline' }, { status: 400 })
161
166
  }
@@ -224,6 +229,10 @@ export async function PUT(req: Request) {
224
229
  if (isCrudHttpError(err)) {
225
230
  return NextResponse.json(err.body, { status: err.status })
226
231
  }
232
+ const interceptorRejection = getCommandInterceptorHttpRejection(err)
233
+ if (interceptorRejection) {
234
+ return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status })
235
+ }
227
236
  logger.error('customers.pipelines PUT failed', { err })
228
237
  return NextResponse.json({ error: 'Failed to update pipeline' }, { status: 400 })
229
238
  }
@@ -277,6 +286,10 @@ export async function DELETE(req: Request) {
277
286
  if (isCrudHttpError(err)) {
278
287
  return NextResponse.json(err.body, { status: err.status })
279
288
  }
289
+ const interceptorRejection = getCommandInterceptorHttpRejection(err)
290
+ if (interceptorRejection) {
291
+ return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status })
292
+ }
280
293
  logger.error('customers.pipelines DELETE failed', { err })
281
294
  return NextResponse.json({ error: 'Failed to delete pipeline' }, { status: 400 })
282
295
  }
@@ -17,6 +17,7 @@ import type { CustomerAddressFormat } from '../../../data/entities'
17
17
  import { withScopedPayload } from '../../utils'
18
18
  import type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'
19
19
  import { createLogger } from '@open-mercato/shared/lib/logger'
20
+ import { getCommandInterceptorHttpRejection } from '@open-mercato/shared/lib/commands/errors'
20
21
 
21
22
  const logger = createLogger('customers')
22
23
 
@@ -134,6 +135,10 @@ export async function PUT(req: Request) {
134
135
  if (isCrudHttpError(err)) {
135
136
  return NextResponse.json(err.body, { status: err.status })
136
137
  }
138
+ const interceptorRejection = getCommandInterceptorHttpRejection(err)
139
+ if (interceptorRejection) {
140
+ return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status })
141
+ }
137
142
  const { translate } = await resolveTranslations()
138
143
  logger.error('customers.settings.address-format.put failed', { err })
139
144
  return NextResponse.json({ error: translate('customers.errors.save_failed', 'Failed to save settings') }, { status: 400 })
@@ -31,6 +31,7 @@ import {
31
31
  import { invalidateDictionaryCache } from '../../dictionaries/cache'
32
32
  import type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'
33
33
  import { createLogger } from '@open-mercato/shared/lib/logger'
34
+ import { getCommandInterceptorHttpRejection } from '@open-mercato/shared/lib/commands/errors'
34
35
 
35
36
  const logger = createLogger('customers')
36
37
 
@@ -222,6 +223,10 @@ export async function PATCH(req: Request) {
222
223
  if (isCrudHttpError(err)) {
223
224
  return NextResponse.json(err.body, { status: err.status })
224
225
  }
226
+ const interceptorRejection = getCommandInterceptorHttpRejection(err)
227
+ if (interceptorRejection) {
228
+ return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status })
229
+ }
225
230
  const { translate } = await resolveTranslations()
226
231
  logger.error('customers.settings.dictionary-sort-modes.patch failed', { err })
227
232
  return NextResponse.json(
@@ -20,6 +20,7 @@ import { loadCustomerSettings } from '../../../commands/settings'
20
20
  import { withScopedPayload } from '../../utils'
21
21
  import type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'
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('customers')
25
26
 
@@ -151,6 +152,10 @@ export async function PUT(req: Request) {
151
152
  if (isCrudHttpError(err)) {
152
153
  return NextResponse.json(err.body, { status: err.status })
153
154
  }
155
+ const interceptorRejection = getCommandInterceptorHttpRejection(err)
156
+ if (interceptorRejection) {
157
+ return NextResponse.json(interceptorRejection.body, { status: interceptorRejection.status })
158
+ }
154
159
  const { translate } = await resolveTranslations()
155
160
  logger.error('customers.settings.stuck-threshold.put failed', { err })
156
161
  return NextResponse.json(
@@ -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.assign failed', { err })
113
118
  return NextResponse.json({ error: translate('customers.errors.assign_failed', 'Failed to assign tag') }, { status: 400 })