@open-mercato/core 0.6.6-develop.6431.1.g1037269810 → 0.6.6-develop.6450.1.b493fb430c

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 (84) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/dist/modules/planner/commands/shared.js +1 -8
  3. package/dist/modules/planner/commands/shared.js.map +2 -2
  4. package/dist/modules/resources/commands/shared.js +1 -7
  5. package/dist/modules/resources/commands/shared.js.map +2 -2
  6. package/dist/modules/shipping_carriers/api/cancel/route.js +2 -2
  7. package/dist/modules/shipping_carriers/api/cancel/route.js.map +2 -2
  8. package/dist/modules/shipping_carriers/api/points/route.js +2 -2
  9. package/dist/modules/shipping_carriers/api/points/route.js.map +2 -2
  10. package/dist/modules/shipping_carriers/api/rates/route.js +2 -2
  11. package/dist/modules/shipping_carriers/api/rates/route.js.map +2 -2
  12. package/dist/modules/shipping_carriers/api/shipments/route.js +2 -2
  13. package/dist/modules/shipping_carriers/api/shipments/route.js.map +2 -2
  14. package/dist/modules/shipping_carriers/api/tracking/refresh/route.js +2 -2
  15. package/dist/modules/shipping_carriers/api/tracking/refresh/route.js.map +2 -2
  16. package/dist/modules/shipping_carriers/api/tracking/route.js +2 -2
  17. package/dist/modules/shipping_carriers/api/tracking/route.js.map +2 -2
  18. package/dist/modules/shipping_carriers/lib/upstream-error-response.js +13 -0
  19. package/dist/modules/shipping_carriers/lib/upstream-error-response.js.map +7 -0
  20. package/dist/modules/staff/commands/activities.js +46 -8
  21. package/dist/modules/staff/commands/activities.js.map +2 -2
  22. package/dist/modules/staff/commands/addresses.js +40 -7
  23. package/dist/modules/staff/commands/addresses.js.map +2 -2
  24. package/dist/modules/staff/commands/comments.js +46 -8
  25. package/dist/modules/staff/commands/comments.js.map +2 -2
  26. package/dist/modules/staff/commands/job-histories.js +40 -7
  27. package/dist/modules/staff/commands/job-histories.js.map +2 -2
  28. package/dist/modules/staff/commands/leave-requests.js +31 -9
  29. package/dist/modules/staff/commands/leave-requests.js.map +2 -2
  30. package/dist/modules/staff/commands/shared.js +56 -7
  31. package/dist/modules/staff/commands/shared.js.map +2 -2
  32. package/dist/modules/staff/commands/tag-assignments.js +18 -7
  33. package/dist/modules/staff/commands/tag-assignments.js.map +2 -2
  34. package/dist/modules/staff/commands/team-members.js +16 -5
  35. package/dist/modules/staff/commands/team-members.js.map +2 -2
  36. package/dist/modules/staff/commands/team-roles.js +16 -5
  37. package/dist/modules/staff/commands/team-roles.js.map +2 -2
  38. package/dist/modules/staff/commands/teams.js +16 -5
  39. package/dist/modules/staff/commands/teams.js.map +2 -2
  40. package/dist/modules/staff/commands/timesheets-entries.js +17 -5
  41. package/dist/modules/staff/commands/timesheets-entries.js.map +2 -2
  42. package/dist/modules/staff/commands/timesheets-projects.js +22 -9
  43. package/dist/modules/staff/commands/timesheets-projects.js.map +2 -2
  44. package/dist/modules/sync_excel/lib/upload-storage.js +9 -6
  45. package/dist/modules/sync_excel/lib/upload-storage.js.map +2 -2
  46. package/dist/modules/translations/api/get/locales.js +2 -1
  47. package/dist/modules/translations/api/get/locales.js.map +2 -2
  48. package/dist/modules/translations/api/put/locales.js +1 -1
  49. package/dist/modules/translations/api/put/locales.js.map +2 -2
  50. package/dist/modules/workflows/examples/sales-pipeline-definition.json +8 -8
  51. package/dist/modules/workflows/lib/activity-executor.js +39 -3
  52. package/dist/modules/workflows/lib/activity-executor.js.map +2 -2
  53. package/package.json +7 -7
  54. package/src/modules/planner/commands/shared.ts +2 -11
  55. package/src/modules/resources/commands/shared.ts +2 -10
  56. package/src/modules/shipping_carriers/api/cancel/route.ts +2 -2
  57. package/src/modules/shipping_carriers/api/points/route.ts +2 -2
  58. package/src/modules/shipping_carriers/api/rates/route.ts +2 -2
  59. package/src/modules/shipping_carriers/api/shipments/route.ts +2 -2
  60. package/src/modules/shipping_carriers/api/tracking/refresh/route.ts +2 -2
  61. package/src/modules/shipping_carriers/api/tracking/route.ts +2 -2
  62. package/src/modules/shipping_carriers/i18n/de.json +1 -0
  63. package/src/modules/shipping_carriers/i18n/en.json +1 -0
  64. package/src/modules/shipping_carriers/i18n/es.json +1 -0
  65. package/src/modules/shipping_carriers/i18n/pl.json +1 -0
  66. package/src/modules/shipping_carriers/lib/upstream-error-response.ts +11 -0
  67. package/src/modules/staff/commands/activities.ts +46 -8
  68. package/src/modules/staff/commands/addresses.ts +40 -7
  69. package/src/modules/staff/commands/comments.ts +46 -8
  70. package/src/modules/staff/commands/job-histories.ts +40 -7
  71. package/src/modules/staff/commands/leave-requests.ts +36 -9
  72. package/src/modules/staff/commands/shared.ts +71 -8
  73. package/src/modules/staff/commands/tag-assignments.ts +18 -7
  74. package/src/modules/staff/commands/team-members.ts +16 -5
  75. package/src/modules/staff/commands/team-roles.ts +16 -5
  76. package/src/modules/staff/commands/teams.ts +16 -5
  77. package/src/modules/staff/commands/timesheets-entries.ts +17 -5
  78. package/src/modules/staff/commands/timesheets-projects.ts +22 -9
  79. package/src/modules/sync_excel/lib/upload-storage.ts +8 -6
  80. package/src/modules/translations/api/get/locales.ts +1 -0
  81. package/src/modules/translations/api/put/locales.ts +1 -1
  82. package/src/modules/workflows/AGENTS.md +2 -1
  83. package/src/modules/workflows/examples/sales-pipeline-definition.json +8 -8
  84. package/src/modules/workflows/lib/activity-executor.ts +49 -5
@@ -1,4 +1,4 @@
1
- [build:core] found 3455 entry points
1
+ [build:core] found 3456 entry points
2
2
  [build:core] built successfully
3
3
  [build:core:generated] found 186 entry points
4
4
  [build:core:generated] built successfully
@@ -1,12 +1,5 @@
1
- import { CrudHttpError } from "@open-mercato/shared/lib/crud/errors";
2
- import { ensureOrganizationScope } from "@open-mercato/shared/lib/commands/scope";
1
+ import { ensureOrganizationScope, ensureTenantScope } from "@open-mercato/shared/lib/commands/scope";
3
2
  import { extractUndoPayload } from "@open-mercato/shared/lib/commands/undo";
4
- function ensureTenantScope(ctx, tenantId) {
5
- const currentTenant = ctx.auth?.tenantId ?? null;
6
- if (currentTenant && currentTenant !== tenantId) {
7
- throw new CrudHttpError(403, { error: "Forbidden" });
8
- }
9
- }
10
3
  export {
11
4
  ensureOrganizationScope,
12
5
  ensureTenantScope,
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/modules/planner/commands/shared.ts"],
4
- "sourcesContent": ["import type { CommandRuntimeContext } from '@open-mercato/shared/lib/commands'\nimport { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport { ensureOrganizationScope } from '@open-mercato/shared/lib/commands/scope'\nimport { extractUndoPayload } from '@open-mercato/shared/lib/commands/undo'\n\nexport function ensureTenantScope(ctx: CommandRuntimeContext, tenantId: string): void {\n const currentTenant = ctx.auth?.tenantId ?? null\n if (currentTenant && currentTenant !== tenantId) {\n throw new CrudHttpError(403, { error: 'Forbidden' })\n }\n}\n\nexport { ensureOrganizationScope, extractUndoPayload }\n"],
5
- "mappings": "AACA,SAAS,qBAAqB;AAC9B,SAAS,+BAA+B;AACxC,SAAS,0BAA0B;AAE5B,SAAS,kBAAkB,KAA4B,UAAwB;AACpF,QAAM,gBAAgB,IAAI,MAAM,YAAY;AAC5C,MAAI,iBAAiB,kBAAkB,UAAU;AAC/C,UAAM,IAAI,cAAc,KAAK,EAAE,OAAO,YAAY,CAAC;AAAA,EACrD;AACF;",
4
+ "sourcesContent": ["import { ensureOrganizationScope, ensureTenantScope } from '@open-mercato/shared/lib/commands/scope'\nimport { extractUndoPayload } from '@open-mercato/shared/lib/commands/undo'\n\nexport { ensureOrganizationScope, ensureTenantScope, extractUndoPayload }\n"],
5
+ "mappings": "AAAA,SAAS,yBAAyB,yBAAyB;AAC3D,SAAS,0BAA0B;",
6
6
  "names": []
7
7
  }
@@ -1,13 +1,7 @@
1
1
  import { CrudHttpError } from "@open-mercato/shared/lib/crud/errors";
2
- import { ensureOrganizationScope } from "@open-mercato/shared/lib/commands/scope";
2
+ import { ensureOrganizationScope, ensureTenantScope } from "@open-mercato/shared/lib/commands/scope";
3
3
  import { extractUndoPayload } from "@open-mercato/shared/lib/commands/undo";
4
4
  import { ResourcesResource } from "../data/entities.js";
5
- function ensureTenantScope(ctx, tenantId) {
6
- const currentTenant = ctx.auth?.tenantId ?? null;
7
- if (currentTenant && currentTenant !== tenantId) {
8
- throw new CrudHttpError(403, { error: "Forbidden" });
9
- }
10
- }
11
5
  async function requireResource(em, resourceId, message = "Resource not found") {
12
6
  const resource = await em.findOne(ResourcesResource, { id: resourceId });
13
7
  if (!resource) throw new CrudHttpError(404, { error: message });
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/modules/resources/commands/shared.ts"],
4
- "sourcesContent": ["import type { CommandRuntimeContext } from '@open-mercato/shared/lib/commands'\nimport { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport { ensureOrganizationScope } from '@open-mercato/shared/lib/commands/scope'\nimport { extractUndoPayload } from '@open-mercato/shared/lib/commands/undo'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { ResourcesResource } from '../data/entities'\n\nexport function ensureTenantScope(ctx: CommandRuntimeContext, tenantId: string): void {\n const currentTenant = ctx.auth?.tenantId ?? null\n if (currentTenant && currentTenant !== tenantId) {\n throw new CrudHttpError(403, { error: 'Forbidden' })\n }\n}\n\nexport { ensureOrganizationScope, extractUndoPayload }\n\nexport async function requireResource(\n em: EntityManager,\n resourceId: string,\n message = 'Resource not found',\n): Promise<ResourcesResource> {\n const resource = await em.findOne(ResourcesResource, { id: resourceId })\n if (!resource) throw new CrudHttpError(404, { error: message })\n return resource\n}\n"],
5
- "mappings": "AACA,SAAS,qBAAqB;AAC9B,SAAS,+BAA+B;AACxC,SAAS,0BAA0B;AAEnC,SAAS,yBAAyB;AAE3B,SAAS,kBAAkB,KAA4B,UAAwB;AACpF,QAAM,gBAAgB,IAAI,MAAM,YAAY;AAC5C,MAAI,iBAAiB,kBAAkB,UAAU;AAC/C,UAAM,IAAI,cAAc,KAAK,EAAE,OAAO,YAAY,CAAC;AAAA,EACrD;AACF;AAIA,eAAsB,gBACpB,IACA,YACA,UAAU,sBACkB;AAC5B,QAAM,WAAW,MAAM,GAAG,QAAQ,mBAAmB,EAAE,IAAI,WAAW,CAAC;AACvE,MAAI,CAAC,SAAU,OAAM,IAAI,cAAc,KAAK,EAAE,OAAO,QAAQ,CAAC;AAC9D,SAAO;AACT;",
4
+ "sourcesContent": ["import { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport { ensureOrganizationScope, ensureTenantScope } from '@open-mercato/shared/lib/commands/scope'\nimport { extractUndoPayload } from '@open-mercato/shared/lib/commands/undo'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { ResourcesResource } from '../data/entities'\n\nexport { ensureOrganizationScope, ensureTenantScope, extractUndoPayload }\n\nexport async function requireResource(\n em: EntityManager,\n resourceId: string,\n message = 'Resource not found',\n): Promise<ResourcesResource> {\n const resource = await em.findOne(ResourcesResource, { id: resourceId })\n if (!resource) throw new CrudHttpError(404, { error: message })\n return resource\n}\n"],
5
+ "mappings": "AAAA,SAAS,qBAAqB;AAC9B,SAAS,yBAAyB,yBAAyB;AAC3D,SAAS,0BAA0B;AAEnC,SAAS,yBAAyB;AAIlC,eAAsB,gBACpB,IACA,YACA,UAAU,sBACkB;AAC5B,QAAM,WAAW,MAAM,GAAG,QAAQ,mBAAmB,EAAE,IAAI,WAAW,CAAC;AACvE,MAAI,CAAC,SAAU,OAAM,IAAI,cAAc,KAAK,EAAE,OAAO,QAAQ,CAAC;AAC9D,SAAO;AACT;",
6
6
  "names": []
7
7
  }
@@ -7,6 +7,7 @@ import {
7
7
  validateCrudMutationGuard
8
8
  } from "@open-mercato/shared/lib/crud/mutation-guard";
9
9
  import { isShipmentCancelNotAllowedError } from "../../lib/status-sync.js";
10
+ import { shippingCarrierUpstreamErrorResponse } from "../../lib/upstream-error-response.js";
10
11
  import { cancelShipmentSchema } from "../../data/validators.js";
11
12
  import { shippingCarriersTag } from "../openapi.js";
12
13
  function resolveGuardUserId(auth) {
@@ -70,8 +71,7 @@ async function POST(req) {
70
71
  if (isShipmentCancelNotAllowedError(error)) {
71
72
  return NextResponse.json({ error: error.message }, { status: 422 });
72
73
  }
73
- const message = error instanceof Error ? error.message : "Failed to cancel shipment";
74
- return NextResponse.json({ error: message }, { status: 502 });
74
+ return shippingCarrierUpstreamErrorResponse("cancel.post", error);
75
75
  }
76
76
  }
77
77
  const openApi = {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/modules/shipping_carriers/api/cancel/route.ts"],
4
- "sourcesContent": ["import { NextResponse } from 'next/server'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { readJsonSafe } from '@open-mercato/shared/lib/http/readJsonSafe'\nimport {\n runCrudMutationGuardAfterSuccess,\n validateCrudMutationGuard,\n} from '@open-mercato/shared/lib/crud/mutation-guard'\nimport type { ShippingCarrierService } from '../../lib/shipping-service'\nimport { isShipmentCancelNotAllowedError } from '../../lib/status-sync'\nimport { cancelShipmentSchema } from '../../data/validators'\nimport { shippingCarriersTag } from '../openapi'\n\nfunction resolveGuardUserId(auth: {\n sub?: string | null\n userId?: string | null\n keyId?: string | null\n}): string {\n if (typeof auth.sub === 'string' && auth.sub.trim().length > 0) return auth.sub\n if (typeof auth.userId === 'string' && auth.userId.trim().length > 0) return auth.userId\n if (typeof auth.keyId === 'string' && auth.keyId.trim().length > 0) return auth.keyId\n return 'system'\n}\n\nexport const metadata = {\n path: '/shipping-carriers/cancel',\n POST: { requireAuth: true, requireFeatures: ['shipping_carriers.manage'] },\n}\n\nexport async function POST(req: Request) {\n const auth = await getAuthFromRequest(req)\n if (!auth?.tenantId || !auth.orgId) {\n return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })\n }\n const payload = await readJsonSafe<unknown>(req)\n const parsed = cancelShipmentSchema.safeParse(payload)\n if (!parsed.success) {\n return NextResponse.json({ error: 'Invalid payload', details: parsed.error.flatten() }, { status: 422 })\n }\n const container = await createRequestContainer()\n const guardUserId = resolveGuardUserId(auth)\n const guardResult = await validateCrudMutationGuard(container, {\n tenantId: auth.tenantId,\n organizationId: auth.orgId,\n userId: guardUserId,\n resourceKind: 'shipping_carriers.shipment',\n resourceId: parsed.data.shipmentId,\n operation: 'custom',\n requestMethod: req.method,\n requestHeaders: req.headers,\n mutationPayload: parsed.data as Record<string, unknown>,\n })\n if (guardResult && !guardResult.ok) {\n return NextResponse.json(guardResult.body, { status: guardResult.status })\n }\n\n const service = container.resolve('shippingCarrierService') as ShippingCarrierService\n try {\n const result = await service.cancelShipment({\n ...parsed.data,\n organizationId: auth.orgId as string,\n tenantId: auth.tenantId,\n })\n\n if (guardResult?.ok && guardResult.shouldRunAfterSuccess) {\n await runCrudMutationGuardAfterSuccess(container, {\n tenantId: auth.tenantId,\n organizationId: auth.orgId,\n userId: guardUserId,\n resourceKind: 'shipping_carriers.shipment',\n resourceId: parsed.data.shipmentId,\n operation: 'custom',\n requestMethod: req.method,\n requestHeaders: req.headers,\n metadata: guardResult.metadata ?? null,\n })\n }\n\n return NextResponse.json(result)\n } catch (error: unknown) {\n if (isShipmentCancelNotAllowedError(error)) {\n return NextResponse.json({ error: error.message }, { status: 422 })\n }\n const message = error instanceof Error ? error.message : 'Failed to cancel shipment'\n return NextResponse.json({ error: message }, { status: 502 })\n }\n}\n\nexport const openApi = {\n tags: [shippingCarriersTag],\n summary: 'Cancel shipment',\n methods: {\n POST: {\n summary: 'Cancel shipment',\n tags: [shippingCarriersTag],\n responses: [\n { status: 200, description: 'Shipment cancelled' },\n { status: 422, description: 'Validation failed or shipment cannot be cancelled in its current status' },\n { status: 502, description: 'Provider upstream error' },\n ],\n },\n },\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { NextResponse } from 'next/server'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { readJsonSafe } from '@open-mercato/shared/lib/http/readJsonSafe'\nimport {\n runCrudMutationGuardAfterSuccess,\n validateCrudMutationGuard,\n} from '@open-mercato/shared/lib/crud/mutation-guard'\nimport type { ShippingCarrierService } from '../../lib/shipping-service'\nimport { isShipmentCancelNotAllowedError } from '../../lib/status-sync'\nimport { shippingCarrierUpstreamErrorResponse } from '../../lib/upstream-error-response'\nimport { cancelShipmentSchema } from '../../data/validators'\nimport { shippingCarriersTag } from '../openapi'\n\nfunction resolveGuardUserId(auth: {\n sub?: string | null\n userId?: string | null\n keyId?: string | null\n}): string {\n if (typeof auth.sub === 'string' && auth.sub.trim().length > 0) return auth.sub\n if (typeof auth.userId === 'string' && auth.userId.trim().length > 0) return auth.userId\n if (typeof auth.keyId === 'string' && auth.keyId.trim().length > 0) return auth.keyId\n return 'system'\n}\n\nexport const metadata = {\n path: '/shipping-carriers/cancel',\n POST: { requireAuth: true, requireFeatures: ['shipping_carriers.manage'] },\n}\n\nexport async function POST(req: Request) {\n const auth = await getAuthFromRequest(req)\n if (!auth?.tenantId || !auth.orgId) {\n return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })\n }\n const payload = await readJsonSafe<unknown>(req)\n const parsed = cancelShipmentSchema.safeParse(payload)\n if (!parsed.success) {\n return NextResponse.json({ error: 'Invalid payload', details: parsed.error.flatten() }, { status: 422 })\n }\n const container = await createRequestContainer()\n const guardUserId = resolveGuardUserId(auth)\n const guardResult = await validateCrudMutationGuard(container, {\n tenantId: auth.tenantId,\n organizationId: auth.orgId,\n userId: guardUserId,\n resourceKind: 'shipping_carriers.shipment',\n resourceId: parsed.data.shipmentId,\n operation: 'custom',\n requestMethod: req.method,\n requestHeaders: req.headers,\n mutationPayload: parsed.data as Record<string, unknown>,\n })\n if (guardResult && !guardResult.ok) {\n return NextResponse.json(guardResult.body, { status: guardResult.status })\n }\n\n const service = container.resolve('shippingCarrierService') as ShippingCarrierService\n try {\n const result = await service.cancelShipment({\n ...parsed.data,\n organizationId: auth.orgId as string,\n tenantId: auth.tenantId,\n })\n\n if (guardResult?.ok && guardResult.shouldRunAfterSuccess) {\n await runCrudMutationGuardAfterSuccess(container, {\n tenantId: auth.tenantId,\n organizationId: auth.orgId,\n userId: guardUserId,\n resourceKind: 'shipping_carriers.shipment',\n resourceId: parsed.data.shipmentId,\n operation: 'custom',\n requestMethod: req.method,\n requestHeaders: req.headers,\n metadata: guardResult.metadata ?? null,\n })\n }\n\n return NextResponse.json(result)\n } catch (error: unknown) {\n if (isShipmentCancelNotAllowedError(error)) {\n return NextResponse.json({ error: error.message }, { status: 422 })\n }\n return shippingCarrierUpstreamErrorResponse('cancel.post', error)\n }\n}\n\nexport const openApi = {\n tags: [shippingCarriersTag],\n summary: 'Cancel shipment',\n methods: {\n POST: {\n summary: 'Cancel shipment',\n tags: [shippingCarriersTag],\n responses: [\n { status: 200, description: 'Shipment cancelled' },\n { status: 422, description: 'Validation failed or shipment cannot be cancelled in its current status' },\n { status: 502, description: 'Provider upstream error' },\n ],\n },\n },\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,6 +1,7 @@
1
1
  import { NextResponse } from "next/server";
2
2
  import { getAuthFromRequest } from "@open-mercato/shared/lib/auth/server";
3
3
  import { createRequestContainer } from "@open-mercato/shared/lib/di/container";
4
+ import { shippingCarrierUpstreamErrorResponse } from "../../lib/upstream-error-response.js";
4
5
  import { searchDropOffPointsQuerySchema } from "../../data/validators.js";
5
6
  import { shippingCarriersTag } from "../openapi.js";
6
7
  const metadata = {
@@ -32,8 +33,7 @@ async function GET(req) {
32
33
  });
33
34
  return NextResponse.json({ points });
34
35
  } catch (error) {
35
- const message = error instanceof Error ? error.message : "Failed to search drop-off points";
36
- return NextResponse.json({ error: message }, { status: 502 });
36
+ return shippingCarrierUpstreamErrorResponse("points.search", error);
37
37
  }
38
38
  }
39
39
  const openApi = {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/modules/shipping_carriers/api/points/route.ts"],
4
- "sourcesContent": ["import { NextResponse } from 'next/server'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport type { ShippingCarrierService } from '../../lib/shipping-service'\nimport { searchDropOffPointsQuerySchema } from '../../data/validators'\nimport { shippingCarriersTag } from '../openapi'\n\nexport const metadata = {\n path: '/shipping-carriers/points',\n GET: { requireAuth: true, requireFeatures: ['shipping_carriers.view'] },\n}\n\nexport async function GET(req: Request) {\n const auth = await getAuthFromRequest(req)\n if (!auth?.tenantId || !auth.orgId) {\n return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })\n }\n const url = new URL(req.url)\n const parsed = searchDropOffPointsQuerySchema.safeParse({\n providerKey: url.searchParams.get('providerKey'),\n query: url.searchParams.get('query') ?? undefined,\n type: url.searchParams.get('type') ?? undefined,\n postCode: url.searchParams.get('postCode') ?? undefined,\n })\n if (!parsed.success) {\n return NextResponse.json({ error: 'Invalid query', details: parsed.error.flatten() }, { status: 422 })\n }\n const container = await createRequestContainer()\n const service = container.resolve('shippingCarrierService') as ShippingCarrierService\n try {\n const points = await service.searchDropOffPoints({\n ...parsed.data,\n organizationId: auth.orgId as string,\n tenantId: auth.tenantId,\n })\n return NextResponse.json({ points })\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to search drop-off points'\n return NextResponse.json({ error: message }, { status: 502 })\n }\n}\n\nexport const openApi = {\n tags: [shippingCarriersTag],\n summary: 'Search drop-off points',\n methods: {\n GET: {\n summary: 'Search carrier drop-off points (lockers, POP points)',\n tags: [shippingCarriersTag],\n responses: [\n { status: 200, description: 'Points returned' },\n { status: 422, description: 'Validation failed' },\n { status: 502, description: 'Provider upstream error or unsupported' },\n ],\n },\n },\n}\n"],
5
- "mappings": "AAAA,SAAS,oBAAoB;AAC7B,SAAS,0BAA0B;AACnC,SAAS,8BAA8B;AAEvC,SAAS,sCAAsC;AAC/C,SAAS,2BAA2B;AAE7B,MAAM,WAAW;AAAA,EACtB,MAAM;AAAA,EACN,KAAK,EAAE,aAAa,MAAM,iBAAiB,CAAC,wBAAwB,EAAE;AACxE;AAEA,eAAsB,IAAI,KAAc;AACtC,QAAM,OAAO,MAAM,mBAAmB,GAAG;AACzC,MAAI,CAAC,MAAM,YAAY,CAAC,KAAK,OAAO;AAClC,WAAO,aAAa,KAAK,EAAE,OAAO,eAAe,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EACrE;AACA,QAAM,MAAM,IAAI,IAAI,IAAI,GAAG;AAC3B,QAAM,SAAS,+BAA+B,UAAU;AAAA,IACtD,aAAa,IAAI,aAAa,IAAI,aAAa;AAAA,IAC/C,OAAO,IAAI,aAAa,IAAI,OAAO,KAAK;AAAA,IACxC,MAAM,IAAI,aAAa,IAAI,MAAM,KAAK;AAAA,IACtC,UAAU,IAAI,aAAa,IAAI,UAAU,KAAK;AAAA,EAChD,CAAC;AACD,MAAI,CAAC,OAAO,SAAS;AACnB,WAAO,aAAa,KAAK,EAAE,OAAO,iBAAiB,SAAS,OAAO,MAAM,QAAQ,EAAE,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EACvG;AACA,QAAM,YAAY,MAAM,uBAAuB;AAC/C,QAAM,UAAU,UAAU,QAAQ,wBAAwB;AAC1D,MAAI;AACF,UAAM,SAAS,MAAM,QAAQ,oBAAoB;AAAA,MAC/C,GAAG,OAAO;AAAA,MACV,gBAAgB,KAAK;AAAA,MACrB,UAAU,KAAK;AAAA,IACjB,CAAC;AACD,WAAO,aAAa,KAAK,EAAE,OAAO,CAAC;AAAA,EACrC,SAAS,OAAgB;AACvB,UAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,WAAO,aAAa,KAAK,EAAE,OAAO,QAAQ,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EAC9D;AACF;AAEO,MAAM,UAAU;AAAA,EACrB,MAAM,CAAC,mBAAmB;AAAA,EAC1B,SAAS;AAAA,EACT,SAAS;AAAA,IACP,KAAK;AAAA,MACH,SAAS;AAAA,MACT,MAAM,CAAC,mBAAmB;AAAA,MAC1B,WAAW;AAAA,QACT,EAAE,QAAQ,KAAK,aAAa,kBAAkB;AAAA,QAC9C,EAAE,QAAQ,KAAK,aAAa,oBAAoB;AAAA,QAChD,EAAE,QAAQ,KAAK,aAAa,yCAAyC;AAAA,MACvE;AAAA,IACF;AAAA,EACF;AACF;",
4
+ "sourcesContent": ["import { NextResponse } from 'next/server'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport type { ShippingCarrierService } from '../../lib/shipping-service'\nimport { shippingCarrierUpstreamErrorResponse } from '../../lib/upstream-error-response'\nimport { searchDropOffPointsQuerySchema } from '../../data/validators'\nimport { shippingCarriersTag } from '../openapi'\n\nexport const metadata = {\n path: '/shipping-carriers/points',\n GET: { requireAuth: true, requireFeatures: ['shipping_carriers.view'] },\n}\n\nexport async function GET(req: Request) {\n const auth = await getAuthFromRequest(req)\n if (!auth?.tenantId || !auth.orgId) {\n return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })\n }\n const url = new URL(req.url)\n const parsed = searchDropOffPointsQuerySchema.safeParse({\n providerKey: url.searchParams.get('providerKey'),\n query: url.searchParams.get('query') ?? undefined,\n type: url.searchParams.get('type') ?? undefined,\n postCode: url.searchParams.get('postCode') ?? undefined,\n })\n if (!parsed.success) {\n return NextResponse.json({ error: 'Invalid query', details: parsed.error.flatten() }, { status: 422 })\n }\n const container = await createRequestContainer()\n const service = container.resolve('shippingCarrierService') as ShippingCarrierService\n try {\n const points = await service.searchDropOffPoints({\n ...parsed.data,\n organizationId: auth.orgId as string,\n tenantId: auth.tenantId,\n })\n return NextResponse.json({ points })\n } catch (error: unknown) {\n return shippingCarrierUpstreamErrorResponse('points.search', error)\n }\n}\n\nexport const openApi = {\n tags: [shippingCarriersTag],\n summary: 'Search drop-off points',\n methods: {\n GET: {\n summary: 'Search carrier drop-off points (lockers, POP points)',\n tags: [shippingCarriersTag],\n responses: [\n { status: 200, description: 'Points returned' },\n { status: 422, description: 'Validation failed' },\n { status: 502, description: 'Provider upstream error or unsupported' },\n ],\n },\n },\n}\n"],
5
+ "mappings": "AAAA,SAAS,oBAAoB;AAC7B,SAAS,0BAA0B;AACnC,SAAS,8BAA8B;AAEvC,SAAS,4CAA4C;AACrD,SAAS,sCAAsC;AAC/C,SAAS,2BAA2B;AAE7B,MAAM,WAAW;AAAA,EACtB,MAAM;AAAA,EACN,KAAK,EAAE,aAAa,MAAM,iBAAiB,CAAC,wBAAwB,EAAE;AACxE;AAEA,eAAsB,IAAI,KAAc;AACtC,QAAM,OAAO,MAAM,mBAAmB,GAAG;AACzC,MAAI,CAAC,MAAM,YAAY,CAAC,KAAK,OAAO;AAClC,WAAO,aAAa,KAAK,EAAE,OAAO,eAAe,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EACrE;AACA,QAAM,MAAM,IAAI,IAAI,IAAI,GAAG;AAC3B,QAAM,SAAS,+BAA+B,UAAU;AAAA,IACtD,aAAa,IAAI,aAAa,IAAI,aAAa;AAAA,IAC/C,OAAO,IAAI,aAAa,IAAI,OAAO,KAAK;AAAA,IACxC,MAAM,IAAI,aAAa,IAAI,MAAM,KAAK;AAAA,IACtC,UAAU,IAAI,aAAa,IAAI,UAAU,KAAK;AAAA,EAChD,CAAC;AACD,MAAI,CAAC,OAAO,SAAS;AACnB,WAAO,aAAa,KAAK,EAAE,OAAO,iBAAiB,SAAS,OAAO,MAAM,QAAQ,EAAE,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EACvG;AACA,QAAM,YAAY,MAAM,uBAAuB;AAC/C,QAAM,UAAU,UAAU,QAAQ,wBAAwB;AAC1D,MAAI;AACF,UAAM,SAAS,MAAM,QAAQ,oBAAoB;AAAA,MAC/C,GAAG,OAAO;AAAA,MACV,gBAAgB,KAAK;AAAA,MACrB,UAAU,KAAK;AAAA,IACjB,CAAC;AACD,WAAO,aAAa,KAAK,EAAE,OAAO,CAAC;AAAA,EACrC,SAAS,OAAgB;AACvB,WAAO,qCAAqC,iBAAiB,KAAK;AAAA,EACpE;AACF;AAEO,MAAM,UAAU;AAAA,EACrB,MAAM,CAAC,mBAAmB;AAAA,EAC1B,SAAS;AAAA,EACT,SAAS;AAAA,IACP,KAAK;AAAA,MACH,SAAS;AAAA,MACT,MAAM,CAAC,mBAAmB;AAAA,MAC1B,WAAW;AAAA,QACT,EAAE,QAAQ,KAAK,aAAa,kBAAkB;AAAA,QAC9C,EAAE,QAAQ,KAAK,aAAa,oBAAoB;AAAA,QAChD,EAAE,QAAQ,KAAK,aAAa,yCAAyC;AAAA,MACvE;AAAA,IACF;AAAA,EACF;AACF;",
6
6
  "names": []
7
7
  }
@@ -2,6 +2,7 @@ import { NextResponse } from "next/server";
2
2
  import { getAuthFromRequest } from "@open-mercato/shared/lib/auth/server";
3
3
  import { createRequestContainer } from "@open-mercato/shared/lib/di/container";
4
4
  import { readJsonSafe } from "@open-mercato/shared/lib/http/readJsonSafe";
5
+ import { shippingCarrierUpstreamErrorResponse } from "../../lib/upstream-error-response.js";
5
6
  import { calculateRatesSchema } from "../../data/validators.js";
6
7
  import { shippingCarriersTag } from "../openapi.js";
7
8
  const metadata = {
@@ -28,8 +29,7 @@ async function POST(req) {
28
29
  });
29
30
  return NextResponse.json({ rates });
30
31
  } catch (error) {
31
- const message = error instanceof Error ? error.message : "Failed to calculate rates";
32
- return NextResponse.json({ error: message }, { status: 502 });
32
+ return shippingCarrierUpstreamErrorResponse("rates.calculate", error);
33
33
  }
34
34
  }
35
35
  const openApi = {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/modules/shipping_carriers/api/rates/route.ts"],
4
- "sourcesContent": ["import { NextResponse } from 'next/server'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { readJsonSafe } from '@open-mercato/shared/lib/http/readJsonSafe'\nimport type { ShippingCarrierService } from '../../lib/shipping-service'\nimport { calculateRatesSchema } from '../../data/validators'\nimport { shippingCarriersTag } from '../openapi'\n\nexport const metadata = {\n path: '/shipping-carriers/rates',\n POST: { requireAuth: true, requireFeatures: ['shipping_carriers.manage'] },\n}\n\nexport async function POST(req: Request) {\n const auth = await getAuthFromRequest(req)\n if (!auth?.tenantId || !auth.orgId) {\n return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })\n }\n const payload = await readJsonSafe<unknown>(req)\n const parsed = calculateRatesSchema.safeParse(payload)\n if (!parsed.success) {\n return NextResponse.json({ error: 'Invalid payload', details: parsed.error.flatten() }, { status: 422 })\n }\n const container = await createRequestContainer()\n const service = container.resolve('shippingCarrierService') as ShippingCarrierService\n try {\n const rates = await service.calculateRates({\n ...parsed.data,\n organizationId: auth.orgId as string,\n tenantId: auth.tenantId,\n })\n return NextResponse.json({ rates })\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to calculate rates'\n return NextResponse.json({ error: message }, { status: 502 })\n }\n}\n\nexport const openApi = {\n tags: [shippingCarriersTag],\n summary: 'Calculate shipping rates',\n methods: {\n POST: {\n summary: 'Calculate shipping rates',\n tags: [shippingCarriersTag],\n responses: [\n { status: 200, description: 'Rates calculated' },\n { status: 422, description: 'Validation failed' },\n { status: 502, description: 'Provider upstream error' },\n ],\n },\n },\n}\n"],
5
- "mappings": "AAAA,SAAS,oBAAoB;AAC7B,SAAS,0BAA0B;AACnC,SAAS,8BAA8B;AACvC,SAAS,oBAAoB;AAE7B,SAAS,4BAA4B;AACrC,SAAS,2BAA2B;AAE7B,MAAM,WAAW;AAAA,EACtB,MAAM;AAAA,EACN,MAAM,EAAE,aAAa,MAAM,iBAAiB,CAAC,0BAA0B,EAAE;AAC3E;AAEA,eAAsB,KAAK,KAAc;AACvC,QAAM,OAAO,MAAM,mBAAmB,GAAG;AACzC,MAAI,CAAC,MAAM,YAAY,CAAC,KAAK,OAAO;AAClC,WAAO,aAAa,KAAK,EAAE,OAAO,eAAe,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EACrE;AACA,QAAM,UAAU,MAAM,aAAsB,GAAG;AAC/C,QAAM,SAAS,qBAAqB,UAAU,OAAO;AACrD,MAAI,CAAC,OAAO,SAAS;AACnB,WAAO,aAAa,KAAK,EAAE,OAAO,mBAAmB,SAAS,OAAO,MAAM,QAAQ,EAAE,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EACzG;AACA,QAAM,YAAY,MAAM,uBAAuB;AAC/C,QAAM,UAAU,UAAU,QAAQ,wBAAwB;AAC1D,MAAI;AACF,UAAM,QAAQ,MAAM,QAAQ,eAAe;AAAA,MACzC,GAAG,OAAO;AAAA,MACV,gBAAgB,KAAK;AAAA,MACrB,UAAU,KAAK;AAAA,IACjB,CAAC;AACD,WAAO,aAAa,KAAK,EAAE,MAAM,CAAC;AAAA,EACpC,SAAS,OAAgB;AACvB,UAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,WAAO,aAAa,KAAK,EAAE,OAAO,QAAQ,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EAC9D;AACF;AAEO,MAAM,UAAU;AAAA,EACrB,MAAM,CAAC,mBAAmB;AAAA,EAC1B,SAAS;AAAA,EACT,SAAS;AAAA,IACP,MAAM;AAAA,MACJ,SAAS;AAAA,MACT,MAAM,CAAC,mBAAmB;AAAA,MAC1B,WAAW;AAAA,QACT,EAAE,QAAQ,KAAK,aAAa,mBAAmB;AAAA,QAC/C,EAAE,QAAQ,KAAK,aAAa,oBAAoB;AAAA,QAChD,EAAE,QAAQ,KAAK,aAAa,0BAA0B;AAAA,MACxD;AAAA,IACF;AAAA,EACF;AACF;",
4
+ "sourcesContent": ["import { NextResponse } from 'next/server'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { readJsonSafe } from '@open-mercato/shared/lib/http/readJsonSafe'\nimport type { ShippingCarrierService } from '../../lib/shipping-service'\nimport { shippingCarrierUpstreamErrorResponse } from '../../lib/upstream-error-response'\nimport { calculateRatesSchema } from '../../data/validators'\nimport { shippingCarriersTag } from '../openapi'\n\nexport const metadata = {\n path: '/shipping-carriers/rates',\n POST: { requireAuth: true, requireFeatures: ['shipping_carriers.manage'] },\n}\n\nexport async function POST(req: Request) {\n const auth = await getAuthFromRequest(req)\n if (!auth?.tenantId || !auth.orgId) {\n return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })\n }\n const payload = await readJsonSafe<unknown>(req)\n const parsed = calculateRatesSchema.safeParse(payload)\n if (!parsed.success) {\n return NextResponse.json({ error: 'Invalid payload', details: parsed.error.flatten() }, { status: 422 })\n }\n const container = await createRequestContainer()\n const service = container.resolve('shippingCarrierService') as ShippingCarrierService\n try {\n const rates = await service.calculateRates({\n ...parsed.data,\n organizationId: auth.orgId as string,\n tenantId: auth.tenantId,\n })\n return NextResponse.json({ rates })\n } catch (error: unknown) {\n return shippingCarrierUpstreamErrorResponse('rates.calculate', error)\n }\n}\n\nexport const openApi = {\n tags: [shippingCarriersTag],\n summary: 'Calculate shipping rates',\n methods: {\n POST: {\n summary: 'Calculate shipping rates',\n tags: [shippingCarriersTag],\n responses: [\n { status: 200, description: 'Rates calculated' },\n { status: 422, description: 'Validation failed' },\n { status: 502, description: 'Provider upstream error' },\n ],\n },\n },\n}\n"],
5
+ "mappings": "AAAA,SAAS,oBAAoB;AAC7B,SAAS,0BAA0B;AACnC,SAAS,8BAA8B;AACvC,SAAS,oBAAoB;AAE7B,SAAS,4CAA4C;AACrD,SAAS,4BAA4B;AACrC,SAAS,2BAA2B;AAE7B,MAAM,WAAW;AAAA,EACtB,MAAM;AAAA,EACN,MAAM,EAAE,aAAa,MAAM,iBAAiB,CAAC,0BAA0B,EAAE;AAC3E;AAEA,eAAsB,KAAK,KAAc;AACvC,QAAM,OAAO,MAAM,mBAAmB,GAAG;AACzC,MAAI,CAAC,MAAM,YAAY,CAAC,KAAK,OAAO;AAClC,WAAO,aAAa,KAAK,EAAE,OAAO,eAAe,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EACrE;AACA,QAAM,UAAU,MAAM,aAAsB,GAAG;AAC/C,QAAM,SAAS,qBAAqB,UAAU,OAAO;AACrD,MAAI,CAAC,OAAO,SAAS;AACnB,WAAO,aAAa,KAAK,EAAE,OAAO,mBAAmB,SAAS,OAAO,MAAM,QAAQ,EAAE,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EACzG;AACA,QAAM,YAAY,MAAM,uBAAuB;AAC/C,QAAM,UAAU,UAAU,QAAQ,wBAAwB;AAC1D,MAAI;AACF,UAAM,QAAQ,MAAM,QAAQ,eAAe;AAAA,MACzC,GAAG,OAAO;AAAA,MACV,gBAAgB,KAAK;AAAA,MACrB,UAAU,KAAK;AAAA,IACjB,CAAC;AACD,WAAO,aAAa,KAAK,EAAE,MAAM,CAAC;AAAA,EACpC,SAAS,OAAgB;AACvB,WAAO,qCAAqC,mBAAmB,KAAK;AAAA,EACtE;AACF;AAEO,MAAM,UAAU;AAAA,EACrB,MAAM,CAAC,mBAAmB;AAAA,EAC1B,SAAS;AAAA,EACT,SAAS;AAAA,IACP,MAAM;AAAA,MACJ,SAAS;AAAA,MACT,MAAM,CAAC,mBAAmB;AAAA,MAC1B,WAAW;AAAA,QACT,EAAE,QAAQ,KAAK,aAAa,mBAAmB;AAAA,QAC/C,EAAE,QAAQ,KAAK,aAAa,oBAAoB;AAAA,QAChD,EAAE,QAAQ,KAAK,aAAa,0BAA0B;AAAA,MACxD;AAAA,IACF;AAAA,EACF;AACF;",
6
6
  "names": []
7
7
  }
@@ -7,6 +7,7 @@ import {
7
7
  validateCrudMutationGuard
8
8
  } from "@open-mercato/shared/lib/crud/mutation-guard";
9
9
  import { isShipmentIdempotencyConflictError } from "../../lib/shipment-idempotency.js";
10
+ import { shippingCarrierUpstreamErrorResponse } from "../../lib/upstream-error-response.js";
10
11
  import { createShipmentSchema } from "../../data/validators.js";
11
12
  import { shippingCarriersTag } from "../openapi.js";
12
13
  function resolveGuardUserId(auth) {
@@ -79,8 +80,7 @@ async function POST(req) {
79
80
  { status: 409 }
80
81
  );
81
82
  }
82
- const message = error instanceof Error ? error.message : "Failed to create shipment";
83
- return NextResponse.json({ error: message }, { status: 502 });
83
+ return shippingCarrierUpstreamErrorResponse("shipments.create", error);
84
84
  }
85
85
  }
86
86
  const openApi = {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/modules/shipping_carriers/api/shipments/route.ts"],
4
- "sourcesContent": ["import { NextResponse } from 'next/server'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { readJsonSafe } from '@open-mercato/shared/lib/http/readJsonSafe'\nimport {\n runCrudMutationGuardAfterSuccess,\n validateCrudMutationGuard,\n} from '@open-mercato/shared/lib/crud/mutation-guard'\nimport type { ShippingCarrierService } from '../../lib/shipping-service'\nimport { isShipmentIdempotencyConflictError } from '../../lib/shipment-idempotency'\nimport { createShipmentSchema } from '../../data/validators'\nimport { shippingCarriersTag } from '../openapi'\n\nfunction resolveGuardUserId(auth: {\n sub?: string | null\n userId?: string | null\n keyId?: string | null\n}): string {\n if (typeof auth.sub === 'string' && auth.sub.trim().length > 0) return auth.sub\n if (typeof auth.userId === 'string' && auth.userId.trim().length > 0) return auth.userId\n if (typeof auth.keyId === 'string' && auth.keyId.trim().length > 0) return auth.keyId\n return 'system'\n}\n\nexport const metadata = {\n path: '/shipping-carriers/shipments',\n POST: { requireAuth: true, requireFeatures: ['shipping_carriers.manage'] },\n}\n\nexport async function POST(req: Request) {\n const auth = await getAuthFromRequest(req)\n if (!auth?.tenantId || !auth.orgId) {\n return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })\n }\n const payload = await readJsonSafe<unknown>(req)\n const parsed = createShipmentSchema.safeParse(payload)\n if (!parsed.success) {\n return NextResponse.json({ error: 'Invalid payload', details: parsed.error.flatten() }, { status: 422 })\n }\n const container = await createRequestContainer()\n const guardUserId = resolveGuardUserId(auth)\n const guardResult = await validateCrudMutationGuard(container, {\n tenantId: auth.tenantId,\n organizationId: auth.orgId,\n userId: guardUserId,\n resourceKind: 'shipping_carriers.shipment',\n resourceId: parsed.data.orderId,\n operation: 'create',\n requestMethod: req.method,\n requestHeaders: req.headers,\n mutationPayload: parsed.data as Record<string, unknown>,\n })\n if (guardResult && !guardResult.ok) {\n return NextResponse.json(guardResult.body, { status: guardResult.status })\n }\n\n const service = container.resolve('shippingCarrierService') as ShippingCarrierService\n try {\n const shipment = await service.createShipment({\n ...parsed.data,\n organizationId: auth.orgId as string,\n tenantId: auth.tenantId,\n })\n\n if (guardResult?.ok && guardResult.shouldRunAfterSuccess) {\n await runCrudMutationGuardAfterSuccess(container, {\n tenantId: auth.tenantId,\n organizationId: auth.orgId,\n userId: guardUserId,\n resourceKind: 'shipping_carriers.shipment',\n resourceId: parsed.data.orderId,\n operation: 'create',\n requestMethod: req.method,\n requestHeaders: req.headers,\n metadata: guardResult.metadata ?? null,\n })\n }\n\n return NextResponse.json({\n shipmentId: shipment.id,\n carrierShipmentId: shipment.carrierShipmentId,\n trackingNumber: shipment.trackingNumber,\n status: shipment.unifiedStatus,\n labelUrl: shipment.labelUrl,\n }, { status: 201 })\n } catch (error: unknown) {\n if (isShipmentIdempotencyConflictError(error)) {\n return NextResponse.json(\n { error: 'Shipment idempotency conflict', code: 'idempotency_conflict' },\n { status: 409 },\n )\n }\n const message = error instanceof Error ? error.message : 'Failed to create shipment'\n return NextResponse.json({ error: message }, { status: 502 })\n }\n}\n\nexport const openApi = {\n tags: [shippingCarriersTag],\n summary: 'Create shipment',\n methods: {\n POST: {\n summary: 'Create shipment',\n tags: [shippingCarriersTag],\n responses: [\n { status: 201, description: 'Shipment created' },\n { status: 409, description: 'Idempotency conflict: the idempotency key was reused with a different payload' },\n { status: 422, description: 'Validation failed' },\n { status: 502, description: 'Provider upstream error' },\n ],\n },\n },\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { NextResponse } from 'next/server'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { readJsonSafe } from '@open-mercato/shared/lib/http/readJsonSafe'\nimport {\n runCrudMutationGuardAfterSuccess,\n validateCrudMutationGuard,\n} from '@open-mercato/shared/lib/crud/mutation-guard'\nimport type { ShippingCarrierService } from '../../lib/shipping-service'\nimport { isShipmentIdempotencyConflictError } from '../../lib/shipment-idempotency'\nimport { shippingCarrierUpstreamErrorResponse } from '../../lib/upstream-error-response'\nimport { createShipmentSchema } from '../../data/validators'\nimport { shippingCarriersTag } from '../openapi'\n\nfunction resolveGuardUserId(auth: {\n sub?: string | null\n userId?: string | null\n keyId?: string | null\n}): string {\n if (typeof auth.sub === 'string' && auth.sub.trim().length > 0) return auth.sub\n if (typeof auth.userId === 'string' && auth.userId.trim().length > 0) return auth.userId\n if (typeof auth.keyId === 'string' && auth.keyId.trim().length > 0) return auth.keyId\n return 'system'\n}\n\nexport const metadata = {\n path: '/shipping-carriers/shipments',\n POST: { requireAuth: true, requireFeatures: ['shipping_carriers.manage'] },\n}\n\nexport async function POST(req: Request) {\n const auth = await getAuthFromRequest(req)\n if (!auth?.tenantId || !auth.orgId) {\n return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })\n }\n const payload = await readJsonSafe<unknown>(req)\n const parsed = createShipmentSchema.safeParse(payload)\n if (!parsed.success) {\n return NextResponse.json({ error: 'Invalid payload', details: parsed.error.flatten() }, { status: 422 })\n }\n const container = await createRequestContainer()\n const guardUserId = resolveGuardUserId(auth)\n const guardResult = await validateCrudMutationGuard(container, {\n tenantId: auth.tenantId,\n organizationId: auth.orgId,\n userId: guardUserId,\n resourceKind: 'shipping_carriers.shipment',\n resourceId: parsed.data.orderId,\n operation: 'create',\n requestMethod: req.method,\n requestHeaders: req.headers,\n mutationPayload: parsed.data as Record<string, unknown>,\n })\n if (guardResult && !guardResult.ok) {\n return NextResponse.json(guardResult.body, { status: guardResult.status })\n }\n\n const service = container.resolve('shippingCarrierService') as ShippingCarrierService\n try {\n const shipment = await service.createShipment({\n ...parsed.data,\n organizationId: auth.orgId as string,\n tenantId: auth.tenantId,\n })\n\n if (guardResult?.ok && guardResult.shouldRunAfterSuccess) {\n await runCrudMutationGuardAfterSuccess(container, {\n tenantId: auth.tenantId,\n organizationId: auth.orgId,\n userId: guardUserId,\n resourceKind: 'shipping_carriers.shipment',\n resourceId: parsed.data.orderId,\n operation: 'create',\n requestMethod: req.method,\n requestHeaders: req.headers,\n metadata: guardResult.metadata ?? null,\n })\n }\n\n return NextResponse.json({\n shipmentId: shipment.id,\n carrierShipmentId: shipment.carrierShipmentId,\n trackingNumber: shipment.trackingNumber,\n status: shipment.unifiedStatus,\n labelUrl: shipment.labelUrl,\n }, { status: 201 })\n } catch (error: unknown) {\n if (isShipmentIdempotencyConflictError(error)) {\n return NextResponse.json(\n { error: 'Shipment idempotency conflict', code: 'idempotency_conflict' },\n { status: 409 },\n )\n }\n return shippingCarrierUpstreamErrorResponse('shipments.create', error)\n }\n}\n\nexport const openApi = {\n tags: [shippingCarriersTag],\n summary: 'Create shipment',\n methods: {\n POST: {\n summary: 'Create shipment',\n tags: [shippingCarriersTag],\n responses: [\n { status: 201, description: 'Shipment created' },\n { status: 409, description: 'Idempotency conflict: the idempotency key was reused with a different payload' },\n { status: 422, description: 'Validation failed' },\n { status: 502, description: 'Provider upstream error' },\n ],\n },\n },\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -2,6 +2,7 @@ import { NextResponse } from "next/server";
2
2
  import { getAuthFromRequest } from "@open-mercato/shared/lib/auth/server";
3
3
  import { createRequestContainer } from "@open-mercato/shared/lib/di/container";
4
4
  import { readJsonSafe } from "@open-mercato/shared/lib/http/readJsonSafe";
5
+ import { shippingCarrierUpstreamErrorResponse } from "../../../lib/upstream-error-response.js";
5
6
  import { trackingRefreshSchema } from "../../../data/validators.js";
6
7
  import { shippingCarriersTag } from "../../openapi.js";
7
8
  const metadata = {
@@ -28,8 +29,7 @@ async function POST(req) {
28
29
  });
29
30
  return NextResponse.json(tracking);
30
31
  } catch (error) {
31
- const message = error instanceof Error ? error.message : "Failed to refresh tracking";
32
- return NextResponse.json({ error: message }, { status: 502 });
32
+ return shippingCarrierUpstreamErrorResponse("tracking.refresh", error);
33
33
  }
34
34
  }
35
35
  const openApi = {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../src/modules/shipping_carriers/api/tracking/refresh/route.ts"],
4
- "sourcesContent": ["import { NextResponse } from 'next/server'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { readJsonSafe } from '@open-mercato/shared/lib/http/readJsonSafe'\nimport type { ShippingCarrierService } from '../../../lib/shipping-service'\nimport { trackingRefreshSchema } from '../../../data/validators'\nimport { shippingCarriersTag } from '../../openapi'\n\nexport const metadata = {\n path: '/shipping-carriers/tracking/refresh',\n POST: { requireAuth: true, requireFeatures: ['shipping_carriers.manage'] },\n}\n\nexport async function POST(req: Request) {\n const auth = await getAuthFromRequest(req)\n if (!auth?.tenantId || !auth.orgId) {\n return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })\n }\n const payload = await readJsonSafe<unknown>(req)\n const parsed = trackingRefreshSchema.safeParse(payload)\n if (!parsed.success) {\n return NextResponse.json({ error: 'Invalid payload', details: parsed.error.flatten() }, { status: 422 })\n }\n const container = await createRequestContainer()\n const service = container.resolve('shippingCarrierService') as ShippingCarrierService\n try {\n const tracking = await service.refreshTracking({\n ...parsed.data,\n organizationId: auth.orgId as string,\n tenantId: auth.tenantId,\n })\n return NextResponse.json(tracking)\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to refresh tracking'\n return NextResponse.json({ error: message }, { status: 502 })\n }\n}\n\nexport const openApi = {\n tags: [shippingCarriersTag],\n summary: 'Refresh tracking',\n methods: {\n POST: {\n summary: 'Refresh tracking and persist the latest shipment status',\n tags: [shippingCarriersTag],\n responses: [\n { status: 200, description: 'Tracking refreshed and shipment status persisted' },\n { status: 422, description: 'Validation failed' },\n { status: 502, description: 'Provider upstream error' },\n ],\n },\n },\n}\n"],
5
- "mappings": "AAAA,SAAS,oBAAoB;AAC7B,SAAS,0BAA0B;AACnC,SAAS,8BAA8B;AACvC,SAAS,oBAAoB;AAE7B,SAAS,6BAA6B;AACtC,SAAS,2BAA2B;AAE7B,MAAM,WAAW;AAAA,EACtB,MAAM;AAAA,EACN,MAAM,EAAE,aAAa,MAAM,iBAAiB,CAAC,0BAA0B,EAAE;AAC3E;AAEA,eAAsB,KAAK,KAAc;AACvC,QAAM,OAAO,MAAM,mBAAmB,GAAG;AACzC,MAAI,CAAC,MAAM,YAAY,CAAC,KAAK,OAAO;AAClC,WAAO,aAAa,KAAK,EAAE,OAAO,eAAe,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EACrE;AACA,QAAM,UAAU,MAAM,aAAsB,GAAG;AAC/C,QAAM,SAAS,sBAAsB,UAAU,OAAO;AACtD,MAAI,CAAC,OAAO,SAAS;AACnB,WAAO,aAAa,KAAK,EAAE,OAAO,mBAAmB,SAAS,OAAO,MAAM,QAAQ,EAAE,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EACzG;AACA,QAAM,YAAY,MAAM,uBAAuB;AAC/C,QAAM,UAAU,UAAU,QAAQ,wBAAwB;AAC1D,MAAI;AACF,UAAM,WAAW,MAAM,QAAQ,gBAAgB;AAAA,MAC7C,GAAG,OAAO;AAAA,MACV,gBAAgB,KAAK;AAAA,MACrB,UAAU,KAAK;AAAA,IACjB,CAAC;AACD,WAAO,aAAa,KAAK,QAAQ;AAAA,EACnC,SAAS,OAAgB;AACvB,UAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,WAAO,aAAa,KAAK,EAAE,OAAO,QAAQ,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EAC9D;AACF;AAEO,MAAM,UAAU;AAAA,EACrB,MAAM,CAAC,mBAAmB;AAAA,EAC1B,SAAS;AAAA,EACT,SAAS;AAAA,IACP,MAAM;AAAA,MACJ,SAAS;AAAA,MACT,MAAM,CAAC,mBAAmB;AAAA,MAC1B,WAAW;AAAA,QACT,EAAE,QAAQ,KAAK,aAAa,mDAAmD;AAAA,QAC/E,EAAE,QAAQ,KAAK,aAAa,oBAAoB;AAAA,QAChD,EAAE,QAAQ,KAAK,aAAa,0BAA0B;AAAA,MACxD;AAAA,IACF;AAAA,EACF;AACF;",
4
+ "sourcesContent": ["import { NextResponse } from 'next/server'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport { readJsonSafe } from '@open-mercato/shared/lib/http/readJsonSafe'\nimport type { ShippingCarrierService } from '../../../lib/shipping-service'\nimport { shippingCarrierUpstreamErrorResponse } from '../../../lib/upstream-error-response'\nimport { trackingRefreshSchema } from '../../../data/validators'\nimport { shippingCarriersTag } from '../../openapi'\n\nexport const metadata = {\n path: '/shipping-carriers/tracking/refresh',\n POST: { requireAuth: true, requireFeatures: ['shipping_carriers.manage'] },\n}\n\nexport async function POST(req: Request) {\n const auth = await getAuthFromRequest(req)\n if (!auth?.tenantId || !auth.orgId) {\n return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })\n }\n const payload = await readJsonSafe<unknown>(req)\n const parsed = trackingRefreshSchema.safeParse(payload)\n if (!parsed.success) {\n return NextResponse.json({ error: 'Invalid payload', details: parsed.error.flatten() }, { status: 422 })\n }\n const container = await createRequestContainer()\n const service = container.resolve('shippingCarrierService') as ShippingCarrierService\n try {\n const tracking = await service.refreshTracking({\n ...parsed.data,\n organizationId: auth.orgId as string,\n tenantId: auth.tenantId,\n })\n return NextResponse.json(tracking)\n } catch (error: unknown) {\n return shippingCarrierUpstreamErrorResponse('tracking.refresh', error)\n }\n}\n\nexport const openApi = {\n tags: [shippingCarriersTag],\n summary: 'Refresh tracking',\n methods: {\n POST: {\n summary: 'Refresh tracking and persist the latest shipment status',\n tags: [shippingCarriersTag],\n responses: [\n { status: 200, description: 'Tracking refreshed and shipment status persisted' },\n { status: 422, description: 'Validation failed' },\n { status: 502, description: 'Provider upstream error' },\n ],\n },\n },\n}\n"],
5
+ "mappings": "AAAA,SAAS,oBAAoB;AAC7B,SAAS,0BAA0B;AACnC,SAAS,8BAA8B;AACvC,SAAS,oBAAoB;AAE7B,SAAS,4CAA4C;AACrD,SAAS,6BAA6B;AACtC,SAAS,2BAA2B;AAE7B,MAAM,WAAW;AAAA,EACtB,MAAM;AAAA,EACN,MAAM,EAAE,aAAa,MAAM,iBAAiB,CAAC,0BAA0B,EAAE;AAC3E;AAEA,eAAsB,KAAK,KAAc;AACvC,QAAM,OAAO,MAAM,mBAAmB,GAAG;AACzC,MAAI,CAAC,MAAM,YAAY,CAAC,KAAK,OAAO;AAClC,WAAO,aAAa,KAAK,EAAE,OAAO,eAAe,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EACrE;AACA,QAAM,UAAU,MAAM,aAAsB,GAAG;AAC/C,QAAM,SAAS,sBAAsB,UAAU,OAAO;AACtD,MAAI,CAAC,OAAO,SAAS;AACnB,WAAO,aAAa,KAAK,EAAE,OAAO,mBAAmB,SAAS,OAAO,MAAM,QAAQ,EAAE,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EACzG;AACA,QAAM,YAAY,MAAM,uBAAuB;AAC/C,QAAM,UAAU,UAAU,QAAQ,wBAAwB;AAC1D,MAAI;AACF,UAAM,WAAW,MAAM,QAAQ,gBAAgB;AAAA,MAC7C,GAAG,OAAO;AAAA,MACV,gBAAgB,KAAK;AAAA,MACrB,UAAU,KAAK;AAAA,IACjB,CAAC;AACD,WAAO,aAAa,KAAK,QAAQ;AAAA,EACnC,SAAS,OAAgB;AACvB,WAAO,qCAAqC,oBAAoB,KAAK;AAAA,EACvE;AACF;AAEO,MAAM,UAAU;AAAA,EACrB,MAAM,CAAC,mBAAmB;AAAA,EAC1B,SAAS;AAAA,EACT,SAAS;AAAA,IACP,MAAM;AAAA,MACJ,SAAS;AAAA,MACT,MAAM,CAAC,mBAAmB;AAAA,MAC1B,WAAW;AAAA,QACT,EAAE,QAAQ,KAAK,aAAa,mDAAmD;AAAA,QAC/E,EAAE,QAAQ,KAAK,aAAa,oBAAoB;AAAA,QAChD,EAAE,QAAQ,KAAK,aAAa,0BAA0B;AAAA,MACxD;AAAA,IACF;AAAA,EACF;AACF;",
6
6
  "names": []
7
7
  }
@@ -1,6 +1,7 @@
1
1
  import { NextResponse } from "next/server";
2
2
  import { getAuthFromRequest } from "@open-mercato/shared/lib/auth/server";
3
3
  import { createRequestContainer } from "@open-mercato/shared/lib/di/container";
4
+ import { shippingCarrierUpstreamErrorResponse } from "../../lib/upstream-error-response.js";
4
5
  import { trackingQuerySchema } from "../../data/validators.js";
5
6
  import { shippingCarriersTag } from "../openapi.js";
6
7
  const metadata = {
@@ -31,8 +32,7 @@ async function GET(req) {
31
32
  });
32
33
  return NextResponse.json(tracking);
33
34
  } catch (error) {
34
- const message = error instanceof Error ? error.message : "Failed to fetch tracking";
35
- return NextResponse.json({ error: message }, { status: 502 });
35
+ return shippingCarrierUpstreamErrorResponse("tracking.get", error);
36
36
  }
37
37
  }
38
38
  const openApi = {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/modules/shipping_carriers/api/tracking/route.ts"],
4
- "sourcesContent": ["import { NextResponse } from 'next/server'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport type { ShippingCarrierService } from '../../lib/shipping-service'\nimport { trackingQuerySchema } from '../../data/validators'\nimport { shippingCarriersTag } from '../openapi'\n\nexport const metadata = {\n path: '/shipping-carriers/tracking',\n GET: { requireAuth: true, requireFeatures: ['shipping_carriers.view'] },\n}\n\nexport async function GET(req: Request) {\n const auth = await getAuthFromRequest(req)\n if (!auth?.tenantId || !auth.orgId) {\n return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })\n }\n const url = new URL(req.url)\n const parsed = trackingQuerySchema.safeParse({\n providerKey: url.searchParams.get('providerKey'),\n shipmentId: url.searchParams.get('shipmentId') ?? undefined,\n trackingNumber: url.searchParams.get('trackingNumber') ?? undefined,\n })\n if (!parsed.success) {\n return NextResponse.json({ error: 'Invalid query', details: parsed.error.flatten() }, { status: 422 })\n }\n const container = await createRequestContainer()\n const service = container.resolve('shippingCarrierService') as ShippingCarrierService\n try {\n const tracking = await service.getTracking({\n ...parsed.data,\n organizationId: auth.orgId as string,\n tenantId: auth.tenantId,\n })\n return NextResponse.json(tracking)\n } catch (error: unknown) {\n const message = error instanceof Error ? error.message : 'Failed to fetch tracking'\n return NextResponse.json({ error: message }, { status: 502 })\n }\n}\n\nexport const openApi = {\n tags: [shippingCarriersTag],\n summary: 'Get tracking',\n methods: {\n GET: {\n summary: 'Get tracking',\n tags: [shippingCarriersTag],\n responses: [\n { status: 200, description: 'Tracking returned' },\n { status: 422, description: 'Validation failed' },\n { status: 502, description: 'Provider upstream error' },\n ],\n },\n },\n}\n"],
5
- "mappings": "AAAA,SAAS,oBAAoB;AAC7B,SAAS,0BAA0B;AACnC,SAAS,8BAA8B;AAEvC,SAAS,2BAA2B;AACpC,SAAS,2BAA2B;AAE7B,MAAM,WAAW;AAAA,EACtB,MAAM;AAAA,EACN,KAAK,EAAE,aAAa,MAAM,iBAAiB,CAAC,wBAAwB,EAAE;AACxE;AAEA,eAAsB,IAAI,KAAc;AACtC,QAAM,OAAO,MAAM,mBAAmB,GAAG;AACzC,MAAI,CAAC,MAAM,YAAY,CAAC,KAAK,OAAO;AAClC,WAAO,aAAa,KAAK,EAAE,OAAO,eAAe,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EACrE;AACA,QAAM,MAAM,IAAI,IAAI,IAAI,GAAG;AAC3B,QAAM,SAAS,oBAAoB,UAAU;AAAA,IAC3C,aAAa,IAAI,aAAa,IAAI,aAAa;AAAA,IAC/C,YAAY,IAAI,aAAa,IAAI,YAAY,KAAK;AAAA,IAClD,gBAAgB,IAAI,aAAa,IAAI,gBAAgB,KAAK;AAAA,EAC5D,CAAC;AACD,MAAI,CAAC,OAAO,SAAS;AACnB,WAAO,aAAa,KAAK,EAAE,OAAO,iBAAiB,SAAS,OAAO,MAAM,QAAQ,EAAE,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EACvG;AACA,QAAM,YAAY,MAAM,uBAAuB;AAC/C,QAAM,UAAU,UAAU,QAAQ,wBAAwB;AAC1D,MAAI;AACF,UAAM,WAAW,MAAM,QAAQ,YAAY;AAAA,MACzC,GAAG,OAAO;AAAA,MACV,gBAAgB,KAAK;AAAA,MACrB,UAAU,KAAK;AAAA,IACjB,CAAC;AACD,WAAO,aAAa,KAAK,QAAQ;AAAA,EACnC,SAAS,OAAgB;AACvB,UAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU;AACzD,WAAO,aAAa,KAAK,EAAE,OAAO,QAAQ,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EAC9D;AACF;AAEO,MAAM,UAAU;AAAA,EACrB,MAAM,CAAC,mBAAmB;AAAA,EAC1B,SAAS;AAAA,EACT,SAAS;AAAA,IACP,KAAK;AAAA,MACH,SAAS;AAAA,MACT,MAAM,CAAC,mBAAmB;AAAA,MAC1B,WAAW;AAAA,QACT,EAAE,QAAQ,KAAK,aAAa,oBAAoB;AAAA,QAChD,EAAE,QAAQ,KAAK,aAAa,oBAAoB;AAAA,QAChD,EAAE,QAAQ,KAAK,aAAa,0BAA0B;AAAA,MACxD;AAAA,IACF;AAAA,EACF;AACF;",
4
+ "sourcesContent": ["import { NextResponse } from 'next/server'\nimport { getAuthFromRequest } from '@open-mercato/shared/lib/auth/server'\nimport { createRequestContainer } from '@open-mercato/shared/lib/di/container'\nimport type { ShippingCarrierService } from '../../lib/shipping-service'\nimport { shippingCarrierUpstreamErrorResponse } from '../../lib/upstream-error-response'\nimport { trackingQuerySchema } from '../../data/validators'\nimport { shippingCarriersTag } from '../openapi'\n\nexport const metadata = {\n path: '/shipping-carriers/tracking',\n GET: { requireAuth: true, requireFeatures: ['shipping_carriers.view'] },\n}\n\nexport async function GET(req: Request) {\n const auth = await getAuthFromRequest(req)\n if (!auth?.tenantId || !auth.orgId) {\n return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })\n }\n const url = new URL(req.url)\n const parsed = trackingQuerySchema.safeParse({\n providerKey: url.searchParams.get('providerKey'),\n shipmentId: url.searchParams.get('shipmentId') ?? undefined,\n trackingNumber: url.searchParams.get('trackingNumber') ?? undefined,\n })\n if (!parsed.success) {\n return NextResponse.json({ error: 'Invalid query', details: parsed.error.flatten() }, { status: 422 })\n }\n const container = await createRequestContainer()\n const service = container.resolve('shippingCarrierService') as ShippingCarrierService\n try {\n const tracking = await service.getTracking({\n ...parsed.data,\n organizationId: auth.orgId as string,\n tenantId: auth.tenantId,\n })\n return NextResponse.json(tracking)\n } catch (error: unknown) {\n return shippingCarrierUpstreamErrorResponse('tracking.get', error)\n }\n}\n\nexport const openApi = {\n tags: [shippingCarriersTag],\n summary: 'Get tracking',\n methods: {\n GET: {\n summary: 'Get tracking',\n tags: [shippingCarriersTag],\n responses: [\n { status: 200, description: 'Tracking returned' },\n { status: 422, description: 'Validation failed' },\n { status: 502, description: 'Provider upstream error' },\n ],\n },\n },\n}\n"],
5
+ "mappings": "AAAA,SAAS,oBAAoB;AAC7B,SAAS,0BAA0B;AACnC,SAAS,8BAA8B;AAEvC,SAAS,4CAA4C;AACrD,SAAS,2BAA2B;AACpC,SAAS,2BAA2B;AAE7B,MAAM,WAAW;AAAA,EACtB,MAAM;AAAA,EACN,KAAK,EAAE,aAAa,MAAM,iBAAiB,CAAC,wBAAwB,EAAE;AACxE;AAEA,eAAsB,IAAI,KAAc;AACtC,QAAM,OAAO,MAAM,mBAAmB,GAAG;AACzC,MAAI,CAAC,MAAM,YAAY,CAAC,KAAK,OAAO;AAClC,WAAO,aAAa,KAAK,EAAE,OAAO,eAAe,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EACrE;AACA,QAAM,MAAM,IAAI,IAAI,IAAI,GAAG;AAC3B,QAAM,SAAS,oBAAoB,UAAU;AAAA,IAC3C,aAAa,IAAI,aAAa,IAAI,aAAa;AAAA,IAC/C,YAAY,IAAI,aAAa,IAAI,YAAY,KAAK;AAAA,IAClD,gBAAgB,IAAI,aAAa,IAAI,gBAAgB,KAAK;AAAA,EAC5D,CAAC;AACD,MAAI,CAAC,OAAO,SAAS;AACnB,WAAO,aAAa,KAAK,EAAE,OAAO,iBAAiB,SAAS,OAAO,MAAM,QAAQ,EAAE,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EACvG;AACA,QAAM,YAAY,MAAM,uBAAuB;AAC/C,QAAM,UAAU,UAAU,QAAQ,wBAAwB;AAC1D,MAAI;AACF,UAAM,WAAW,MAAM,QAAQ,YAAY;AAAA,MACzC,GAAG,OAAO;AAAA,MACV,gBAAgB,KAAK;AAAA,MACrB,UAAU,KAAK;AAAA,IACjB,CAAC;AACD,WAAO,aAAa,KAAK,QAAQ;AAAA,EACnC,SAAS,OAAgB;AACvB,WAAO,qCAAqC,gBAAgB,KAAK;AAAA,EACnE;AACF;AAEO,MAAM,UAAU;AAAA,EACrB,MAAM,CAAC,mBAAmB;AAAA,EAC1B,SAAS;AAAA,EACT,SAAS;AAAA,IACP,KAAK;AAAA,MACH,SAAS;AAAA,MACT,MAAM,CAAC,mBAAmB;AAAA,MAC1B,WAAW;AAAA,QACT,EAAE,QAAQ,KAAK,aAAa,oBAAoB;AAAA,QAChD,EAAE,QAAQ,KAAK,aAAa,oBAAoB;AAAA,QAChD,EAAE,QAAQ,KAAK,aAAa,0BAA0B;AAAA,MACxD;AAAA,IACF;AAAA,EACF;AACF;",
6
6
  "names": []
7
7
  }
@@ -0,0 +1,13 @@
1
+ import { NextResponse } from "next/server";
2
+ import { resolveTranslations } from "@open-mercato/shared/lib/i18n/server";
3
+ const upstreamFailedKey = "shipping_carriers.errors.upstreamFailed";
4
+ const upstreamFailedFallback = "Carrier provider request failed. Try again later.";
5
+ async function shippingCarrierUpstreamErrorResponse(routeId, error) {
6
+ console.error(`[shipping_carriers.${routeId}] provider upstream error`, error);
7
+ const { translate } = await resolveTranslations();
8
+ return NextResponse.json({ error: translate(upstreamFailedKey, upstreamFailedFallback) }, { status: 502 });
9
+ }
10
+ export {
11
+ shippingCarrierUpstreamErrorResponse
12
+ };
13
+ //# sourceMappingURL=upstream-error-response.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../../src/modules/shipping_carriers/lib/upstream-error-response.ts"],
4
+ "sourcesContent": ["import { NextResponse } from 'next/server'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\n\nconst upstreamFailedKey = 'shipping_carriers.errors.upstreamFailed'\nconst upstreamFailedFallback = 'Carrier provider request failed. Try again later.'\n\nexport async function shippingCarrierUpstreamErrorResponse(routeId: string, error: unknown) {\n console.error(`[shipping_carriers.${routeId}] provider upstream error`, error)\n const { translate } = await resolveTranslations()\n return NextResponse.json({ error: translate(upstreamFailedKey, upstreamFailedFallback) }, { status: 502 })\n}\n"],
5
+ "mappings": "AAAA,SAAS,oBAAoB;AAC7B,SAAS,2BAA2B;AAEpC,MAAM,oBAAoB;AAC1B,MAAM,yBAAyB;AAE/B,eAAsB,qCAAqC,SAAiB,OAAgB;AAC1F,UAAQ,MAAM,sBAAsB,OAAO,6BAA6B,KAAK;AAC7E,QAAM,EAAE,UAAU,IAAI,MAAM,oBAAoB;AAChD,SAAO,aAAa,KAAK,EAAE,OAAO,UAAU,mBAAmB,sBAAsB,EAAE,GAAG,EAAE,QAAQ,IAAI,CAAC;AAC3G;",
6
+ "names": []
7
+ }
@@ -16,7 +16,16 @@ import {
16
16
  staffTeamMemberActivityUpdateSchema
17
17
  } from "../data/validators.js";
18
18
  import { staffTeamMemberActivityCrudEvents } from "../lib/crud.js";
19
- import { ensureOrganizationScope, ensureTenantScope, extractUndoPayload, requireTeamMember } from "./shared.js";
19
+ import {
20
+ applyScopeToWhere,
21
+ commandActorScope,
22
+ commandInputScope,
23
+ ensureOrganizationScope,
24
+ ensureTenantScope,
25
+ explicitStaffCommandScope,
26
+ extractUndoPayload,
27
+ requireTeamMember
28
+ } from "./shared.js";
20
29
  import { resolveRedoSnapshot } from "@open-mercato/shared/lib/commands/redo";
21
30
  import { E } from "../../../generated/entities.ids.generated.js";
22
31
  import {
@@ -72,9 +81,15 @@ const createActivityCommand = {
72
81
  const { parsed, custom } = parseWithCustomFields(staffTeamMemberActivityCreateSchema, rawInput);
73
82
  ensureTenantScope(ctx, parsed.tenantId);
74
83
  ensureOrganizationScope(ctx, parsed.organizationId);
84
+ const scope = commandInputScope(ctx, parsed.tenantId, parsed.organizationId);
75
85
  const normalizedAuthor = normalizeAuthorUserId(parsed.authorUserId, ctx.auth);
76
86
  const em = ctx.container.resolve("em").fork();
77
- const member = await requireTeamMember(em, parsed.entityId, "Team member not found");
87
+ const member = await requireTeamMember(
88
+ em,
89
+ parsed.entityId,
90
+ scope,
91
+ "Team member not found"
92
+ );
78
93
  ensureTenantScope(ctx, member.tenantId);
79
94
  ensureOrganizationScope(ctx, member.organizationId);
80
95
  const activity = em.create(StaffTeamMemberActivity, {
@@ -148,7 +163,12 @@ const createActivityCommand = {
148
163
  throw new CrudHttpError(400, { error: "[internal] redo snapshot unavailable for activity create" });
149
164
  }
150
165
  const em = ctx.container.resolve("em").fork();
151
- const member = await requireTeamMember(em, after.activity.memberId, "Team member not found");
166
+ const member = await requireTeamMember(
167
+ em,
168
+ after.activity.memberId,
169
+ explicitStaffCommandScope(after.activity.tenantId, after.activity.organizationId),
170
+ "Team member not found"
171
+ );
152
172
  let activity = await em.findOne(StaffTeamMemberActivity, { id: after.activity.id });
153
173
  if (!activity) {
154
174
  activity = em.create(StaffTeamMemberActivity, {
@@ -206,12 +226,16 @@ const updateActivityCommand = {
206
226
  async execute(rawInput, ctx) {
207
227
  const { parsed, custom } = parseWithCustomFields(staffTeamMemberActivityUpdateSchema, rawInput);
208
228
  const em = ctx.container.resolve("em").fork();
209
- const activity = await em.findOne(StaffTeamMemberActivity, { id: parsed.id });
229
+ const scope = commandActorScope(ctx);
230
+ const activity = await em.findOne(
231
+ StaffTeamMemberActivity,
232
+ applyScopeToWhere({ id: parsed.id }, scope)
233
+ );
210
234
  if (!activity) throw new CrudHttpError(404, { error: "Activity not found" });
211
235
  ensureTenantScope(ctx, activity.tenantId);
212
236
  ensureOrganizationScope(ctx, activity.organizationId);
213
237
  if (parsed.entityId !== void 0) {
214
- const member = await requireTeamMember(em, parsed.entityId, "Team member not found");
238
+ const member = await requireTeamMember(em, parsed.entityId, scope, "Team member not found");
215
239
  ensureTenantScope(ctx, member.tenantId);
216
240
  ensureOrganizationScope(ctx, member.organizationId);
217
241
  activity.member = member;
@@ -291,7 +315,12 @@ const updateActivityCommand = {
291
315
  if (!before) return;
292
316
  const em = ctx.container.resolve("em").fork();
293
317
  let activity = await em.findOne(StaffTeamMemberActivity, { id: before.activity.id });
294
- const member = await requireTeamMember(em, before.activity.memberId, "Team member not found");
318
+ const member = await requireTeamMember(
319
+ em,
320
+ before.activity.memberId,
321
+ explicitStaffCommandScope(before.activity.tenantId, before.activity.organizationId),
322
+ "Team member not found"
323
+ );
295
324
  if (!activity) {
296
325
  activity = em.create(StaffTeamMemberActivity, {
297
326
  id: before.activity.id,
@@ -358,7 +387,11 @@ const deleteActivityCommand = {
358
387
  async execute(input, ctx) {
359
388
  const id = requireId(input, "Activity id required");
360
389
  const em = ctx.container.resolve("em").fork();
361
- const activity = await em.findOne(StaffTeamMemberActivity, { id });
390
+ const scope = commandActorScope(ctx);
391
+ const activity = await em.findOne(
392
+ StaffTeamMemberActivity,
393
+ applyScopeToWhere({ id }, scope)
394
+ );
362
395
  if (!activity) throw new CrudHttpError(404, { error: "Activity not found" });
363
396
  ensureTenantScope(ctx, activity.tenantId);
364
397
  ensureOrganizationScope(ctx, activity.organizationId);
@@ -404,7 +437,12 @@ const deleteActivityCommand = {
404
437
  const before = payload?.before;
405
438
  if (!before) return;
406
439
  const em = ctx.container.resolve("em").fork();
407
- const member = await requireTeamMember(em, before.activity.memberId, "Team member not found");
440
+ const member = await requireTeamMember(
441
+ em,
442
+ before.activity.memberId,
443
+ explicitStaffCommandScope(before.activity.tenantId, before.activity.organizationId),
444
+ "Team member not found"
445
+ );
408
446
  let activity = await em.findOne(StaffTeamMemberActivity, { id: before.activity.id });
409
447
  if (!activity) {
410
448
  activity = em.create(StaffTeamMemberActivity, {