@open-mercato/core 0.6.7-develop.6606.1.3b1ec9b1ea → 0.6.7-develop.6622.1.4d29ddaca4

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 (102) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/dist/modules/auth/api/session/refresh.js +12 -11
  3. package/dist/modules/auth/api/session/refresh.js.map +2 -2
  4. package/dist/modules/auth/lib/rateLimitCheck.js +4 -4
  5. package/dist/modules/auth/lib/rateLimitCheck.js.map +2 -2
  6. package/dist/modules/catalog/api/categories/route.js +8 -14
  7. package/dist/modules/catalog/api/categories/route.js.map +2 -2
  8. package/dist/modules/catalog/api/tags/route.js +3 -10
  9. package/dist/modules/catalog/api/tags/route.js.map +2 -2
  10. package/dist/modules/customers/api/interactions/[id]/visibility/route.js +15 -17
  11. package/dist/modules/customers/api/interactions/[id]/visibility/route.js.map +2 -2
  12. package/dist/modules/customers/api/people/[id]/email-threads/route.js +6 -4
  13. package/dist/modules/customers/api/people/[id]/email-threads/route.js.map +2 -2
  14. package/dist/modules/customers/api/people/[id]/emails/route.js +19 -17
  15. package/dist/modules/customers/api/people/[id]/emails/route.js.map +2 -2
  16. package/dist/modules/customers/components/detail/CustomFieldValuesList.js +22 -5
  17. package/dist/modules/customers/components/detail/CustomFieldValuesList.js.map +2 -2
  18. package/dist/modules/customers/components/detail/create/CreateDealForm.js +5 -2
  19. package/dist/modules/customers/components/detail/create/CreateDealForm.js.map +2 -2
  20. package/dist/modules/customers/components/detail/customFieldUtils.js +10 -3
  21. package/dist/modules/customers/components/detail/customFieldUtils.js.map +2 -2
  22. package/dist/modules/directory/backend/directory/organizations/[id]/edit/page.meta.js +4 -2
  23. package/dist/modules/directory/backend/directory/organizations/[id]/edit/page.meta.js.map +2 -2
  24. package/dist/modules/directory/backend/directory/tenants/[id]/edit/page.meta.js +4 -2
  25. package/dist/modules/directory/backend/directory/tenants/[id]/edit/page.meta.js.map +2 -2
  26. package/dist/modules/integrations/api/[id]/credentials/route.js +10 -7
  27. package/dist/modules/integrations/api/[id]/credentials/route.js.map +2 -2
  28. package/dist/modules/integrations/api/[id]/health/route.js +6 -4
  29. package/dist/modules/integrations/api/[id]/health/route.js.map +2 -2
  30. package/dist/modules/integrations/api/[id]/route.js +4 -2
  31. package/dist/modules/integrations/api/[id]/route.js.map +2 -2
  32. package/dist/modules/integrations/api/[id]/state/route.js +7 -5
  33. package/dist/modules/integrations/api/[id]/state/route.js.map +2 -2
  34. package/dist/modules/integrations/api/[id]/version/route.js +7 -5
  35. package/dist/modules/integrations/api/[id]/version/route.js.map +2 -2
  36. package/dist/modules/integrations/api/logs/route.js +4 -2
  37. package/dist/modules/integrations/api/logs/route.js.map +2 -2
  38. package/dist/modules/integrations/api/route.js +4 -2
  39. package/dist/modules/integrations/api/route.js.map +2 -2
  40. package/dist/modules/integrations/api/umes-read.js +2 -1
  41. package/dist/modules/integrations/api/umes-read.js.map +2 -2
  42. package/dist/modules/integrations/lib/organization-scope.js +12 -0
  43. package/dist/modules/integrations/lib/organization-scope.js.map +7 -0
  44. package/dist/modules/payment_gateways/lib/gateway-service.js +10 -1
  45. package/dist/modules/payment_gateways/lib/gateway-service.js.map +2 -2
  46. package/dist/modules/sales/api/document-history/route.js +6 -9
  47. package/dist/modules/sales/api/document-history/route.js.map +2 -2
  48. package/dist/modules/sales/api/quotes/accept/route.js +3 -3
  49. package/dist/modules/sales/api/quotes/accept/route.js.map +2 -2
  50. package/dist/modules/sales/api/returns/[id]/route.js +6 -9
  51. package/dist/modules/sales/api/returns/[id]/route.js.map +2 -2
  52. package/dist/modules/sales/backend/sales/documents/[id]/page.js +6 -2
  53. package/dist/modules/sales/backend/sales/documents/[id]/page.js.map +2 -2
  54. package/dist/modules/sales/components/documents/AddressesSection.js +6 -4
  55. package/dist/modules/sales/components/documents/AddressesSection.js.map +2 -2
  56. package/dist/modules/sales/workflows.js +1 -1
  57. package/dist/modules/sales/workflows.js.map +1 -1
  58. package/dist/modules/workflows/api/definitions/[id]/route.js +10 -1
  59. package/dist/modules/workflows/api/definitions/[id]/route.js.map +2 -2
  60. package/dist/modules/workflows/lib/event-trigger-service.js +44 -3
  61. package/dist/modules/workflows/lib/event-trigger-service.js.map +2 -2
  62. package/package.json +7 -7
  63. package/src/modules/auth/api/session/refresh.ts +19 -11
  64. package/src/modules/auth/lib/rateLimitCheck.ts +4 -4
  65. package/src/modules/catalog/api/categories/route.ts +14 -16
  66. package/src/modules/catalog/api/tags/route.ts +6 -10
  67. package/src/modules/catalog/i18n/pl.json +9 -9
  68. package/src/modules/customer_accounts/i18n/pl.json +129 -129
  69. package/src/modules/customers/api/interactions/[id]/visibility/route.ts +24 -20
  70. package/src/modules/customers/api/people/[id]/email-threads/route.ts +10 -6
  71. package/src/modules/customers/api/people/[id]/emails/route.ts +25 -21
  72. package/src/modules/customers/components/detail/CustomFieldValuesList.tsx +28 -4
  73. package/src/modules/customers/components/detail/create/CreateDealForm.tsx +7 -2
  74. package/src/modules/customers/components/detail/customFieldUtils.ts +15 -3
  75. package/src/modules/data_sync/i18n/pl.json +68 -68
  76. package/src/modules/directory/backend/directory/organizations/[id]/edit/page.meta.ts +4 -2
  77. package/src/modules/directory/backend/directory/tenants/[id]/edit/page.meta.ts +4 -2
  78. package/src/modules/integrations/api/[id]/credentials/route.ts +10 -7
  79. package/src/modules/integrations/api/[id]/health/route.ts +6 -4
  80. package/src/modules/integrations/api/[id]/route.ts +4 -2
  81. package/src/modules/integrations/api/[id]/state/route.ts +7 -5
  82. package/src/modules/integrations/api/[id]/version/route.ts +7 -5
  83. package/src/modules/integrations/api/logs/route.ts +4 -2
  84. package/src/modules/integrations/api/route.ts +4 -2
  85. package/src/modules/integrations/api/umes-read.ts +2 -1
  86. package/src/modules/integrations/i18n/de.json +0 -76
  87. package/src/modules/integrations/i18n/en.json +0 -76
  88. package/src/modules/integrations/i18n/es.json +0 -76
  89. package/src/modules/integrations/i18n/pl.json +0 -76
  90. package/src/modules/integrations/lib/organization-scope.ts +27 -0
  91. package/src/modules/payment_gateways/lib/gateway-service.ts +12 -1
  92. package/src/modules/sales/api/document-history/route.ts +10 -9
  93. package/src/modules/sales/api/quotes/accept/route.ts +3 -3
  94. package/src/modules/sales/api/returns/[id]/route.ts +10 -9
  95. package/src/modules/sales/backend/sales/documents/[id]/page.tsx +26 -19
  96. package/src/modules/sales/components/documents/AddressesSection.tsx +8 -4
  97. package/src/modules/sales/i18n/pl.json +24 -24
  98. package/src/modules/sales/workflows.ts +1 -1
  99. package/src/modules/staff/i18n/pl.json +178 -178
  100. package/src/modules/workflows/api/definitions/[id]/route.ts +14 -1
  101. package/src/modules/workflows/i18n/pl.json +128 -128
  102. package/src/modules/workflows/lib/event-trigger-service.ts +87 -8
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../src/modules/sales/api/returns/%5Bid%5D/route.ts"],
4
- "sourcesContent": ["import { z } from 'zod'\nimport { NextResponse } from 'next/server'\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 { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { CrudHttpError, isCrudHttpError, notFound } from '@open-mercato/shared/lib/crud/errors'\nimport { findOneWithDecryption, findWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport { SalesReturn, SalesReturnLine } from '../../../data/entities'\nimport { createLogger } from '@open-mercato/shared/lib/logger'\n\nconst logger = createLogger('sales')\n\nexport const metadata = {\n GET: { requireAuth: true, requireFeatures: ['sales.returns.view'] },\n}\n\nconst paramsSchema = z.object({ id: z.string().uuid() })\n\nconst toNumber = (value: unknown): number => {\n if (typeof value === 'number') return value\n if (typeof value === 'string') {\n const parsed = Number(value)\n if (!Number.isNaN(parsed)) return parsed\n }\n return 0\n}\n\nexport async function GET(req: Request, ctx: { params: { id: string } }) {\n try {\n const { id } = paramsSchema.parse(ctx.params ?? {})\n const container = await createRequestContainer()\n const auth = await getAuthFromRequest(req)\n const { translate } = await resolveTranslations()\n\n if (!auth || !auth.tenantId) {\n throw new CrudHttpError(401, { error: translate('sales.documents.errors.unauthorized', 'Unauthorized') })\n }\n\n const scope = await resolveOrganizationScopeForRequest({ container, auth, request: req })\n const organizationId = scope?.selectedId ?? auth.orgId ?? null\n if (!organizationId) {\n throw new CrudHttpError(400, {\n error: translate('sales.documents.errors.organization_required', 'Organization context is required'),\n })\n }\n\n const em = (container.resolve('em') as EntityManager).fork()\n const header = await findOneWithDecryption(\n em,\n SalesReturn,\n { id, deletedAt: null, tenantId: auth.tenantId, organizationId },\n { populate: ['order'] },\n { tenantId: auth.tenantId, organizationId },\n )\n if (!header || !header.order) {\n throw notFound(translate('sales.returns.notFound', 'Return not found.'))\n }\n\n const lines = await findWithDecryption(\n em,\n SalesReturnLine,\n { salesReturn: header.id, deletedAt: null },\n { populate: ['orderLine'] },\n { tenantId: auth.tenantId, organizationId },\n )\n\n const totals = lines.reduce(\n (acc, line) => {\n acc.net += toNumber(line.totalNetAmount)\n acc.gross += toNumber(line.totalGrossAmount)\n return acc\n },\n { net: 0, gross: 0 },\n )\n\n return NextResponse.json({\n return: {\n id: header.id,\n orderId: typeof header.order === 'string' ? header.order : header.order.id,\n returnNumber: header.returnNumber,\n statusEntryId: header.statusEntryId ?? null,\n status: header.status ?? null,\n reason: header.reason ?? null,\n notes: header.notes ?? null,\n returnedAt: header.returnedAt ? header.returnedAt.toISOString() : null,\n createdAt: header.createdAt ? header.createdAt.toISOString() : null,\n updatedAt: header.updatedAt ? header.updatedAt.toISOString() : null,\n totalNetAmount: totals.net,\n totalGrossAmount: totals.gross,\n },\n lines: lines.map((line) => ({\n id: line.id,\n orderLineId: typeof line.orderLine === 'string' ? line.orderLine : line.orderLine?.id ?? null,\n quantityReturned: line.quantityReturned,\n unitPriceNet: line.unitPriceNet,\n unitPriceGross: line.unitPriceGross,\n totalNetAmount: line.totalNetAmount,\n totalGrossAmount: line.totalGrossAmount,\n })),\n })\n } catch (err) {\n if (isCrudHttpError(err)) {\n return NextResponse.json(err.body, { status: err.status })\n }\n logger.error('sales.returns.get failed', { err })\n const { translate } = await resolveTranslations()\n return NextResponse.json({ error: translate('sales.returns.error', 'Failed to load return.') }, { status: 400 })\n }\n}\n\nconst returnLineSchema = z.object({\n id: z.string().uuid(),\n orderLineId: z.string().uuid().nullable(),\n quantityReturned: z.string(),\n unitPriceNet: z.string(),\n unitPriceGross: z.string(),\n totalNetAmount: z.string(),\n totalGrossAmount: z.string(),\n})\n\nexport const openApi: OpenApiRouteDoc = {\n tag: 'Sales',\n summary: 'Get a return',\n pathParams: paramsSchema,\n methods: {\n GET: {\n summary: 'Get return details',\n responses: [\n {\n status: 200,\n description: 'Return details',\n schema: z.object({\n return: z.object({\n id: z.string().uuid(),\n orderId: z.string().uuid(),\n returnNumber: z.string(),\n statusEntryId: z.string().uuid().nullable(),\n status: z.string().nullable(),\n reason: z.string().nullable(),\n notes: z.string().nullable(),\n returnedAt: z.string().nullable(),\n createdAt: z.string().nullable(),\n updatedAt: z.string().nullable(),\n totalNetAmount: z.number(),\n totalGrossAmount: z.number(),\n }),\n lines: z.array(returnLineSchema),\n }),\n },\n { status: 401, description: 'Unauthorized', schema: z.object({ error: z.string() }) },\n { status: 404, description: 'Not found', schema: z.object({ error: z.string() }) },\n ],\n },\n },\n}\n\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { z } from 'zod'\nimport { NextResponse } from 'next/server'\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 { resolveOrganizationScopeFilter } from '@open-mercato/core/modules/directory/utils/organizationScopeFilter'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { CrudHttpError, isCrudHttpError, notFound } from '@open-mercato/shared/lib/crud/errors'\nimport { findOneWithDecryption, findWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport { SalesReturn, SalesReturnLine } from '../../../data/entities'\nimport { createLogger } from '@open-mercato/shared/lib/logger'\n\nconst logger = createLogger('sales')\n\nexport const metadata = {\n GET: { requireAuth: true, requireFeatures: ['sales.returns.view'] },\n}\n\nconst paramsSchema = z.object({ id: z.string().uuid() })\n\nconst toNumber = (value: unknown): number => {\n if (typeof value === 'number') return value\n if (typeof value === 'string') {\n const parsed = Number(value)\n if (!Number.isNaN(parsed)) return parsed\n }\n return 0\n}\n\nexport async function GET(req: Request, ctx: { params: { id: string } }) {\n try {\n const { id } = paramsSchema.parse(ctx.params ?? {})\n const container = await createRequestContainer()\n const auth = await getAuthFromRequest(req)\n const { translate } = await resolveTranslations()\n\n if (!auth || !auth.tenantId) {\n throw new CrudHttpError(401, { error: translate('sales.documents.errors.unauthorized', 'Unauthorized') })\n }\n\n const scope = await resolveOrganizationScopeForRequest({ container, auth, request: req })\n // Scope by the caller's visible organizations. Under \"All organizations\"\n // (super-admin) `where` is empty and `rbacOrganizationId` is null, so the\n // return is fetched by its tenant-unique id instead of 400-ing; restricted\n // callers keep their `filterIds` `$in` guard.\n const orgFilter = resolveOrganizationScopeFilter(scope, auth)\n const decryptionOrganizationId = orgFilter.rbacOrganizationId ?? undefined\n\n const em = (container.resolve('em') as EntityManager).fork()\n const header = await findOneWithDecryption(\n em,\n SalesReturn,\n { id, deletedAt: null, tenantId: auth.tenantId, ...orgFilter.where },\n { populate: ['order'] },\n { tenantId: auth.tenantId, organizationId: decryptionOrganizationId },\n )\n if (!header || !header.order) {\n throw notFound(translate('sales.returns.notFound', 'Return not found.'))\n }\n\n const lines = await findWithDecryption(\n em,\n SalesReturnLine,\n { salesReturn: header.id, deletedAt: null },\n { populate: ['orderLine'] },\n { tenantId: auth.tenantId, organizationId: decryptionOrganizationId },\n )\n\n const totals = lines.reduce(\n (acc, line) => {\n acc.net += toNumber(line.totalNetAmount)\n acc.gross += toNumber(line.totalGrossAmount)\n return acc\n },\n { net: 0, gross: 0 },\n )\n\n return NextResponse.json({\n return: {\n id: header.id,\n orderId: typeof header.order === 'string' ? header.order : header.order.id,\n returnNumber: header.returnNumber,\n statusEntryId: header.statusEntryId ?? null,\n status: header.status ?? null,\n reason: header.reason ?? null,\n notes: header.notes ?? null,\n returnedAt: header.returnedAt ? header.returnedAt.toISOString() : null,\n createdAt: header.createdAt ? header.createdAt.toISOString() : null,\n updatedAt: header.updatedAt ? header.updatedAt.toISOString() : null,\n totalNetAmount: totals.net,\n totalGrossAmount: totals.gross,\n },\n lines: lines.map((line) => ({\n id: line.id,\n orderLineId: typeof line.orderLine === 'string' ? line.orderLine : line.orderLine?.id ?? null,\n quantityReturned: line.quantityReturned,\n unitPriceNet: line.unitPriceNet,\n unitPriceGross: line.unitPriceGross,\n totalNetAmount: line.totalNetAmount,\n totalGrossAmount: line.totalGrossAmount,\n })),\n })\n } catch (err) {\n if (isCrudHttpError(err)) {\n return NextResponse.json(err.body, { status: err.status })\n }\n logger.error('sales.returns.get failed', { err })\n const { translate } = await resolveTranslations()\n return NextResponse.json({ error: translate('sales.returns.error', 'Failed to load return.') }, { status: 400 })\n }\n}\n\nconst returnLineSchema = z.object({\n id: z.string().uuid(),\n orderLineId: z.string().uuid().nullable(),\n quantityReturned: z.string(),\n unitPriceNet: z.string(),\n unitPriceGross: z.string(),\n totalNetAmount: z.string(),\n totalGrossAmount: z.string(),\n})\n\nexport const openApi: OpenApiRouteDoc = {\n tag: 'Sales',\n summary: 'Get a return',\n pathParams: paramsSchema,\n methods: {\n GET: {\n summary: 'Get return details',\n responses: [\n {\n status: 200,\n description: 'Return details',\n schema: z.object({\n return: z.object({\n id: z.string().uuid(),\n orderId: z.string().uuid(),\n returnNumber: z.string(),\n statusEntryId: z.string().uuid().nullable(),\n status: z.string().nullable(),\n reason: z.string().nullable(),\n notes: z.string().nullable(),\n returnedAt: z.string().nullable(),\n createdAt: z.string().nullable(),\n updatedAt: z.string().nullable(),\n totalNetAmount: z.number(),\n totalGrossAmount: z.number(),\n }),\n lines: z.array(returnLineSchema),\n }),\n },\n { status: 401, description: 'Unauthorized', schema: z.object({ error: z.string() }) },\n { status: 404, description: 'Not found', schema: z.object({ error: z.string() }) },\n ],\n },\n },\n}\n\n"],
5
+ "mappings": "AAAA,SAAS,SAAS;AAClB,SAAS,oBAAoB;AAG7B,SAAS,8BAA8B;AACvC,SAAS,0BAA0B;AACnC,SAAS,0CAA0C;AACnD,SAAS,sCAAsC;AAC/C,SAAS,2BAA2B;AACpC,SAAS,eAAe,iBAAiB,gBAAgB;AACzD,SAAS,uBAAuB,0BAA0B;AAC1D,SAAS,aAAa,uBAAuB;AAC7C,SAAS,oBAAoB;AAE7B,MAAM,SAAS,aAAa,OAAO;AAE5B,MAAM,WAAW;AAAA,EACtB,KAAK,EAAE,aAAa,MAAM,iBAAiB,CAAC,oBAAoB,EAAE;AACpE;AAEA,MAAM,eAAe,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AAEvD,MAAM,WAAW,CAAC,UAA2B;AAC3C,MAAI,OAAO,UAAU,SAAU,QAAO;AACtC,MAAI,OAAO,UAAU,UAAU;AAC7B,UAAM,SAAS,OAAO,KAAK;AAC3B,QAAI,CAAC,OAAO,MAAM,MAAM,EAAG,QAAO;AAAA,EACpC;AACA,SAAO;AACT;AAEA,eAAsB,IAAI,KAAc,KAAiC;AACvE,MAAI;AACF,UAAM,EAAE,GAAG,IAAI,aAAa,MAAM,IAAI,UAAU,CAAC,CAAC;AAClD,UAAM,YAAY,MAAM,uBAAuB;AAC/C,UAAM,OAAO,MAAM,mBAAmB,GAAG;AACzC,UAAM,EAAE,UAAU,IAAI,MAAM,oBAAoB;AAEhD,QAAI,CAAC,QAAQ,CAAC,KAAK,UAAU;AAC3B,YAAM,IAAI,cAAc,KAAK,EAAE,OAAO,UAAU,uCAAuC,cAAc,EAAE,CAAC;AAAA,IAC1G;AAEA,UAAM,QAAQ,MAAM,mCAAmC,EAAE,WAAW,MAAM,SAAS,IAAI,CAAC;AAKxF,UAAM,YAAY,+BAA+B,OAAO,IAAI;AAC5D,UAAM,2BAA2B,UAAU,sBAAsB;AAEjE,UAAM,KAAM,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC3D,UAAM,SAAS,MAAM;AAAA,MACnB;AAAA,MACA;AAAA,MACA,EAAE,IAAI,WAAW,MAAM,UAAU,KAAK,UAAU,GAAG,UAAU,MAAM;AAAA,MACnE,EAAE,UAAU,CAAC,OAAO,EAAE;AAAA,MACtB,EAAE,UAAU,KAAK,UAAU,gBAAgB,yBAAyB;AAAA,IACtE;AACA,QAAI,CAAC,UAAU,CAAC,OAAO,OAAO;AAC5B,YAAM,SAAS,UAAU,0BAA0B,mBAAmB,CAAC;AAAA,IACzE;AAEA,UAAM,QAAQ,MAAM;AAAA,MAClB;AAAA,MACA;AAAA,MACA,EAAE,aAAa,OAAO,IAAI,WAAW,KAAK;AAAA,MAC1C,EAAE,UAAU,CAAC,WAAW,EAAE;AAAA,MAC1B,EAAE,UAAU,KAAK,UAAU,gBAAgB,yBAAyB;AAAA,IACtE;AAEA,UAAM,SAAS,MAAM;AAAA,MACnB,CAAC,KAAK,SAAS;AACb,YAAI,OAAO,SAAS,KAAK,cAAc;AACvC,YAAI,SAAS,SAAS,KAAK,gBAAgB;AAC3C,eAAO;AAAA,MACT;AAAA,MACA,EAAE,KAAK,GAAG,OAAO,EAAE;AAAA,IACrB;AAEA,WAAO,aAAa,KAAK;AAAA,MACvB,QAAQ;AAAA,QACN,IAAI,OAAO;AAAA,QACX,SAAS,OAAO,OAAO,UAAU,WAAW,OAAO,QAAQ,OAAO,MAAM;AAAA,QACxE,cAAc,OAAO;AAAA,QACrB,eAAe,OAAO,iBAAiB;AAAA,QACvC,QAAQ,OAAO,UAAU;AAAA,QACzB,QAAQ,OAAO,UAAU;AAAA,QACzB,OAAO,OAAO,SAAS;AAAA,QACvB,YAAY,OAAO,aAAa,OAAO,WAAW,YAAY,IAAI;AAAA,QAClE,WAAW,OAAO,YAAY,OAAO,UAAU,YAAY,IAAI;AAAA,QAC/D,WAAW,OAAO,YAAY,OAAO,UAAU,YAAY,IAAI;AAAA,QAC/D,gBAAgB,OAAO;AAAA,QACvB,kBAAkB,OAAO;AAAA,MAC3B;AAAA,MACA,OAAO,MAAM,IAAI,CAAC,UAAU;AAAA,QAC1B,IAAI,KAAK;AAAA,QACT,aAAa,OAAO,KAAK,cAAc,WAAW,KAAK,YAAY,KAAK,WAAW,MAAM;AAAA,QACzF,kBAAkB,KAAK;AAAA,QACvB,cAAc,KAAK;AAAA,QACnB,gBAAgB,KAAK;AAAA,QACrB,gBAAgB,KAAK;AAAA,QACrB,kBAAkB,KAAK;AAAA,MACzB,EAAE;AAAA,IACJ,CAAC;AAAA,EACH,SAAS,KAAK;AACZ,QAAI,gBAAgB,GAAG,GAAG;AACxB,aAAO,aAAa,KAAK,IAAI,MAAM,EAAE,QAAQ,IAAI,OAAO,CAAC;AAAA,IAC3D;AACA,WAAO,MAAM,4BAA4B,EAAE,IAAI,CAAC;AAChD,UAAM,EAAE,UAAU,IAAI,MAAM,oBAAoB;AAChD,WAAO,aAAa,KAAK,EAAE,OAAO,UAAU,uBAAuB,wBAAwB,EAAE,GAAG,EAAE,QAAQ,IAAI,CAAC;AAAA,EACjH;AACF;AAEA,MAAM,mBAAmB,EAAE,OAAO;AAAA,EAChC,IAAI,EAAE,OAAO,EAAE,KAAK;AAAA,EACpB,aAAa,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS;AAAA,EACxC,kBAAkB,EAAE,OAAO;AAAA,EAC3B,cAAc,EAAE,OAAO;AAAA,EACvB,gBAAgB,EAAE,OAAO;AAAA,EACzB,gBAAgB,EAAE,OAAO;AAAA,EACzB,kBAAkB,EAAE,OAAO;AAC7B,CAAC;AAEM,MAAM,UAA2B;AAAA,EACtC,KAAK;AAAA,EACL,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,SAAS;AAAA,IACP,KAAK;AAAA,MACH,SAAS;AAAA,MACT,WAAW;AAAA,QACT;AAAA,UACE,QAAQ;AAAA,UACR,aAAa;AAAA,UACb,QAAQ,EAAE,OAAO;AAAA,YACf,QAAQ,EAAE,OAAO;AAAA,cACf,IAAI,EAAE,OAAO,EAAE,KAAK;AAAA,cACpB,SAAS,EAAE,OAAO,EAAE,KAAK;AAAA,cACzB,cAAc,EAAE,OAAO;AAAA,cACvB,eAAe,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS;AAAA,cAC1C,QAAQ,EAAE,OAAO,EAAE,SAAS;AAAA,cAC5B,QAAQ,EAAE,OAAO,EAAE,SAAS;AAAA,cAC5B,OAAO,EAAE,OAAO,EAAE,SAAS;AAAA,cAC3B,YAAY,EAAE,OAAO,EAAE,SAAS;AAAA,cAChC,WAAW,EAAE,OAAO,EAAE,SAAS;AAAA,cAC/B,WAAW,EAAE,OAAO,EAAE,SAAS;AAAA,cAC/B,gBAAgB,EAAE,OAAO;AAAA,cACzB,kBAAkB,EAAE,OAAO;AAAA,YAC7B,CAAC;AAAA,YACD,OAAO,EAAE,MAAM,gBAAgB;AAAA,UACjC,CAAC;AAAA,QACH;AAAA,QACA,EAAE,QAAQ,KAAK,aAAa,gBAAgB,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE;AAAA,QACpF,EAAE,QAAQ,KAAK,aAAa,aAAa,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,EAAE;AAAA,MACnF;AAAA,IACF;AAAA,EACF;AACF;",
6
6
  "names": []
7
7
  }
@@ -24,6 +24,8 @@ import { ArrowRightLeft, Building2, CreditCard, Mail, Pencil, Plus, Send, Store,
24
24
  import { FormHeader } from "@open-mercato/ui/backend/forms";
25
25
  import { VersionHistoryAction } from "@open-mercato/ui/backend/version-history";
26
26
  import { SendObjectMessageDialog } from "@open-mercato/ui/backend/messages";
27
+ import { useBackendChrome } from "@open-mercato/ui/backend/BackendChromeProvider";
28
+ import { hasFeature } from "@open-mercato/shared/security/features";
27
29
  import Link from "next/link";
28
30
  import { flash } from "@open-mercato/ui/backend/FlashMessages";
29
31
  import { apiCall, apiCallOrThrow, readApiResultOrThrow, withScopedApiRequestHeaders } from "@open-mercato/ui/backend/utils/apiCall";
@@ -3256,6 +3258,8 @@ function SalesDocumentDetailPage({
3256
3258
  ({ value, emptyLabel }) => /* @__PURE__ */ jsx(ContactEmailDisplay, { value, emptyLabel }),
3257
3259
  []
3258
3260
  );
3261
+ const { payload: backendChromePayload, isReady: backendChromeReady } = useBackendChrome();
3262
+ const canComposeMessages = backendChromeReady && hasFeature(backendChromePayload?.grantedFeatures, "messages.compose");
3259
3263
  const tabInjectionSpotId = React.useMemo(() => `sales.document.detail.${kind}:tabs`, [kind]);
3260
3264
  const { widgets: injectedTabWidgets } = useInjectionWidgets(tabInjectionSpotId, {
3261
3265
  context: detailInjectionContext,
@@ -3783,7 +3787,7 @@ function SalesDocumentDetailPage({
3783
3787
  backHref: kind === "order" ? "/backend/sales/orders" : "/backend/sales/quotes",
3784
3788
  backLabel: t("sales.documents.detail.back", "Back to documents"),
3785
3789
  utilityActions: record ? /* @__PURE__ */ jsxs(Fragment, { children: [
3786
- /* @__PURE__ */ jsx(
3790
+ canComposeMessages ? /* @__PURE__ */ jsx(
3787
3791
  SendObjectMessageDialog,
3788
3792
  {
3789
3793
  object: {
@@ -3804,7 +3808,7 @@ function SalesDocumentDetailPage({
3804
3808
  sourceEntityId: record.id
3805
3809
  }
3806
3810
  }
3807
- ),
3811
+ ) : null,
3808
3812
  /* @__PURE__ */ jsx(
3809
3813
  VersionHistoryAction,
3810
3814
  {