@open-mercato/core 0.6.7-develop.6553.1.2ec7246e04 → 0.6.7-develop.6566.1.15385fa179

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 (143) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/dist/modules/attachments/api/partitions/route.js.map +1 -1
  3. package/dist/modules/attachments/lib/reconcileOrganization.js +9 -7
  4. package/dist/modules/attachments/lib/reconcileOrganization.js.map +2 -2
  5. package/dist/modules/catalog/api/products/route.js.map +1 -1
  6. package/dist/modules/customers/api/companies/[id]/people/route.js +2 -2
  7. package/dist/modules/customers/api/companies/[id]/people/route.js.map +2 -2
  8. package/dist/modules/customers/api/deals/[id]/companies/route.js +2 -2
  9. package/dist/modules/customers/api/deals/[id]/companies/route.js.map +2 -2
  10. package/dist/modules/customers/api/deals/[id]/people/route.js +2 -2
  11. package/dist/modules/customers/api/deals/[id]/people/route.js.map +2 -2
  12. package/dist/modules/customers/api/dictionaries/[kind]/[id]/route.js +4 -4
  13. package/dist/modules/customers/api/dictionaries/[kind]/[id]/route.js.map +2 -2
  14. package/dist/modules/customers/api/entity-roles-factory.js +3 -3
  15. package/dist/modules/customers/api/entity-roles-factory.js.map +2 -2
  16. package/dist/modules/customers/api/labels/assign/route.js +2 -2
  17. package/dist/modules/customers/api/labels/assign/route.js.map +2 -2
  18. package/dist/modules/customers/api/labels/unassign/route.js +2 -2
  19. package/dist/modules/customers/api/labels/unassign/route.js.map +2 -2
  20. package/dist/modules/customers/api/people/[id]/companies/[linkId]/route.js +3 -7
  21. package/dist/modules/customers/api/people/[id]/companies/[linkId]/route.js.map +2 -2
  22. package/dist/modules/customers/api/people/[id]/companies/context.js +3 -3
  23. package/dist/modules/customers/api/people/[id]/companies/context.js.map +2 -2
  24. package/dist/modules/customers/api/people/[id]/companies/enriched/route.js +2 -2
  25. package/dist/modules/customers/api/people/[id]/companies/enriched/route.js.map +2 -2
  26. package/dist/modules/customers/api/todos/route.js +2 -2
  27. package/dist/modules/customers/api/todos/route.js.map +2 -2
  28. package/dist/modules/customers/commands/addresses.js +3 -3
  29. package/dist/modules/customers/commands/addresses.js.map +2 -2
  30. package/dist/modules/customers/commands/comments.js +3 -3
  31. package/dist/modules/customers/commands/comments.js.map +2 -2
  32. package/dist/modules/customers/commands/companies.js +2 -2
  33. package/dist/modules/customers/commands/companies.js.map +2 -2
  34. package/dist/modules/customers/commands/deals.js +3 -3
  35. package/dist/modules/customers/commands/deals.js.map +2 -2
  36. package/dist/modules/customers/commands/dictionaries.js +3 -3
  37. package/dist/modules/customers/commands/dictionaries.js.map +2 -2
  38. package/dist/modules/customers/commands/entity-roles.js +3 -3
  39. package/dist/modules/customers/commands/entity-roles.js.map +2 -2
  40. package/dist/modules/customers/commands/interactions.js +6 -6
  41. package/dist/modules/customers/commands/interactions.js.map +2 -2
  42. package/dist/modules/customers/commands/labels.js +7 -7
  43. package/dist/modules/customers/commands/labels.js.map +2 -2
  44. package/dist/modules/customers/commands/people.js +3 -3
  45. package/dist/modules/customers/commands/people.js.map +2 -2
  46. package/dist/modules/customers/commands/personCompanyLinks.js +6 -6
  47. package/dist/modules/customers/commands/personCompanyLinks.js.map +2 -2
  48. package/dist/modules/customers/commands/pipeline-stages.js +3 -3
  49. package/dist/modules/customers/commands/pipeline-stages.js.map +2 -2
  50. package/dist/modules/customers/commands/pipelines.js +3 -3
  51. package/dist/modules/customers/commands/pipelines.js.map +2 -2
  52. package/dist/modules/customers/commands/shared.js +3 -3
  53. package/dist/modules/customers/commands/shared.js.map +2 -2
  54. package/dist/modules/customers/commands/tags.js +7 -7
  55. package/dist/modules/customers/commands/tags.js.map +2 -2
  56. package/dist/modules/customers/commands/todos.js +3 -3
  57. package/dist/modules/customers/commands/todos.js.map +2 -2
  58. package/dist/modules/customers/lib/personCompanies.js +4 -4
  59. package/dist/modules/customers/lib/personCompanies.js.map +2 -2
  60. package/dist/modules/perspectives/data/validators.js +4 -0
  61. package/dist/modules/perspectives/data/validators.js.map +2 -2
  62. package/dist/modules/sales/api/notes/route.js +2 -4
  63. package/dist/modules/sales/api/notes/route.js.map +2 -2
  64. package/dist/modules/sales/api/quotes/accept/route.js +2 -2
  65. package/dist/modules/sales/api/quotes/accept/route.js.map +2 -2
  66. package/dist/modules/sales/api/quotes/public/[token]/route.js +3 -7
  67. package/dist/modules/sales/api/quotes/public/[token]/route.js.map +2 -2
  68. package/dist/modules/sales/api/quotes/send/route.js +2 -2
  69. package/dist/modules/sales/api/quotes/send/route.js.map +2 -2
  70. package/dist/modules/sales/api/returns/[id]/route.js +2 -2
  71. package/dist/modules/sales/api/returns/[id]/route.js.map +2 -2
  72. package/dist/modules/sales/commands/configuration.js +11 -11
  73. package/dist/modules/sales/commands/configuration.js.map +2 -2
  74. package/dist/modules/sales/commands/documentAddresses.js +3 -3
  75. package/dist/modules/sales/commands/documentAddresses.js.map +2 -2
  76. package/dist/modules/sales/commands/documents.js +31 -39
  77. package/dist/modules/sales/commands/documents.js.map +2 -2
  78. package/dist/modules/sales/commands/notes.js +7 -7
  79. package/dist/modules/sales/commands/notes.js.map +2 -2
  80. package/dist/modules/sales/commands/payments.js +2 -2
  81. package/dist/modules/sales/commands/payments.js.map +2 -2
  82. package/dist/modules/sales/commands/returns.js +8 -8
  83. package/dist/modules/sales/commands/returns.js.map +2 -2
  84. package/dist/modules/sales/commands/shared.js +2 -2
  85. package/dist/modules/sales/commands/shared.js.map +2 -2
  86. package/dist/modules/sales/commands/shipments.js +5 -5
  87. package/dist/modules/sales/commands/shipments.js.map +2 -2
  88. package/dist/modules/sales/commands/statuses.js +2 -2
  89. package/dist/modules/sales/commands/statuses.js.map +2 -2
  90. package/dist/modules/sales/commands/tags.js +3 -3
  91. package/dist/modules/sales/commands/tags.js.map +2 -2
  92. package/package.json +8 -8
  93. package/src/modules/attachments/api/partitions/route.ts +1 -1
  94. package/src/modules/attachments/lib/reconcileOrganization.ts +16 -7
  95. package/src/modules/catalog/api/products/route.ts +1 -1
  96. package/src/modules/customer_accounts/i18n/de.json +12 -0
  97. package/src/modules/customer_accounts/i18n/en.json +12 -0
  98. package/src/modules/customer_accounts/i18n/es.json +34 -22
  99. package/src/modules/customer_accounts/i18n/pl.json +32 -20
  100. package/src/modules/customers/api/companies/[id]/people/route.ts +2 -2
  101. package/src/modules/customers/api/deals/[id]/companies/route.ts +2 -2
  102. package/src/modules/customers/api/deals/[id]/people/route.ts +2 -2
  103. package/src/modules/customers/api/dictionaries/[kind]/[id]/route.ts +4 -4
  104. package/src/modules/customers/api/entity-roles-factory.ts +3 -3
  105. package/src/modules/customers/api/labels/assign/route.ts +2 -2
  106. package/src/modules/customers/api/labels/unassign/route.ts +2 -2
  107. package/src/modules/customers/api/people/[id]/companies/[linkId]/route.ts +3 -7
  108. package/src/modules/customers/api/people/[id]/companies/context.ts +3 -3
  109. package/src/modules/customers/api/people/[id]/companies/enriched/route.ts +2 -2
  110. package/src/modules/customers/api/todos/route.ts +2 -2
  111. package/src/modules/customers/commands/addresses.ts +3 -3
  112. package/src/modules/customers/commands/comments.ts +3 -3
  113. package/src/modules/customers/commands/companies.ts +2 -2
  114. package/src/modules/customers/commands/deals.ts +3 -3
  115. package/src/modules/customers/commands/dictionaries.ts +3 -3
  116. package/src/modules/customers/commands/entity-roles.ts +3 -3
  117. package/src/modules/customers/commands/interactions.ts +6 -6
  118. package/src/modules/customers/commands/labels.ts +7 -7
  119. package/src/modules/customers/commands/people.ts +3 -3
  120. package/src/modules/customers/commands/personCompanyLinks.ts +6 -6
  121. package/src/modules/customers/commands/pipeline-stages.ts +3 -3
  122. package/src/modules/customers/commands/pipelines.ts +3 -3
  123. package/src/modules/customers/commands/shared.ts +3 -3
  124. package/src/modules/customers/commands/tags.ts +7 -7
  125. package/src/modules/customers/commands/todos.ts +3 -3
  126. package/src/modules/customers/lib/personCompanies.ts +4 -4
  127. package/src/modules/perspectives/data/validators.ts +4 -0
  128. package/src/modules/sales/api/notes/route.ts +2 -4
  129. package/src/modules/sales/api/quotes/accept/route.ts +2 -2
  130. package/src/modules/sales/api/quotes/public/[token]/route.ts +3 -7
  131. package/src/modules/sales/api/quotes/send/route.ts +2 -2
  132. package/src/modules/sales/api/returns/[id]/route.ts +2 -2
  133. package/src/modules/sales/commands/configuration.ts +11 -11
  134. package/src/modules/sales/commands/documentAddresses.ts +3 -3
  135. package/src/modules/sales/commands/documents.ts +23 -31
  136. package/src/modules/sales/commands/notes.ts +7 -7
  137. package/src/modules/sales/commands/payments.ts +2 -2
  138. package/src/modules/sales/commands/returns.ts +8 -8
  139. package/src/modules/sales/commands/shared.ts +2 -2
  140. package/src/modules/sales/commands/shipments.ts +5 -5
  141. package/src/modules/sales/commands/statuses.ts +2 -2
  142. package/src/modules/sales/commands/tags.ts +3 -3
  143. package/tsconfig.json +0 -2
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../src/modules/customers/api/todos/route.ts"],
4
- "sourcesContent": ["/**\n * @deprecated Use /api/customers/interactions instead. This route is maintained\n * as a compatibility bridge per SPEC-046b. Will be removed in a future release.\n */\nimport { NextResponse } from 'next/server'\nimport { z } from 'zod'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'\nimport type { CommandBus } from '@open-mercato/shared/lib/commands'\nimport { CrudHttpError, isCrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport { parseBooleanToken } from '@open-mercato/shared/lib/boolean'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport {\n runCrudMutationGuardAfterSuccess,\n validateCrudMutationGuard,\n} from '@open-mercato/shared/lib/crud/mutation-guard'\nimport { readJsonSafe } from '@open-mercato/shared/lib/http/readJsonSafe'\nimport type { QueryEngine } from '@open-mercato/shared/lib/query/types'\nimport { createCustomersCrudOpenApi, createPagedListResponseSchema, defaultOkResponseSchema } from '../openapi'\nimport { CustomerInteraction, CustomerTodoLink } from '../../data/entities'\nimport { todoLinkWithTodoCreateSchema } from '../../data/validators'\nimport { withOperationMetadata } from '../../lib/operationMetadata'\nimport { resolveCustomerInteractionFeatureFlags } from '../../lib/interactionFeatureFlags'\nimport { resolveCustomersRequestContext } from '../../lib/interactionRequestContext'\nimport {\n EXAMPLE_TODO_SOURCE,\n CUSTOMER_INTERACTION_TODO_ADAPTER_SOURCE,\n} from '../../lib/interactionCompatibility'\nimport {\n filterTodoRows,\n listCanonicalTodoRows,\n listLegacyTodoRows,\n normalizeTodoSearch,\n paginateTodoRows,\n sortTodoRows,\n resolveLegacyTodoDetails,\n} from '../../lib/todoCompatibility'\nimport { createLogger } from '@open-mercato/shared/lib/logger'\n\nconst logger = createLogger('customers')\n\nconst querySchema = z.object({\n page: z.coerce.number().min(1).default(1),\n pageSize: z.coerce.number().min(1).max(100).default(50),\n search: z.string().optional(),\n all: z.string().optional(),\n entityId: z.string().uuid().optional(),\n})\n\nconst todoCreateBodySchema = todoLinkWithTodoCreateSchema.omit({\n tenantId: true,\n organizationId: true,\n}).passthrough()\n\nconst todoUpdateBodySchema = z\n .object({\n id: z.string().uuid(),\n linkId: z.string().uuid().optional(),\n title: z.string().trim().min(1).max(200).optional(),\n isDone: z.boolean().optional(),\n is_done: z.boolean().optional(),\n customFields: z.record(z.string(), z.unknown()).optional(),\n customValues: z.record(z.string(), z.unknown()).optional(),\n })\n .passthrough()\n\nconst todoDeleteBodySchema = z.object({\n id: z.string().uuid(),\n todoId: z.string().uuid().optional(),\n})\n\nexport const metadata = {\n GET: { requireAuth: true, requireFeatures: ['customers.view'] },\n POST: { requireAuth: true, requireFeatures: ['customers.interactions.manage'] },\n PUT: { requireAuth: true, requireFeatures: ['customers.interactions.manage'] },\n DELETE: { requireAuth: true, requireFeatures: ['customers.interactions.manage'] },\n}\n\nconst DEPRECATION_HEADERS = {\n Deprecation: 'true',\n Sunset: 'Tue, 30 Jun 2026 00:00:00 GMT',\n Link: '</api/customers/interactions>; rel=\"successor-version\"',\n}\n\n// Caps the per-source fetch window used by the deprecated merged (legacy +\n// canonical bridge) read path. Keeps memory bounded on tenants with large\n// todo history; deep-pagination beyond this window is not supported here \u2014\n// use /api/customers/interactions instead.\nconst MERGED_TODO_FETCH_CAP = 2000\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\nfunction withAdapterHeaders(response: Response): Response {\n const headers = new Headers(response.headers)\n Object.entries(DEPRECATION_HEADERS).forEach(([key, value]) => headers.set(key, value))\n return new Response(response.body, {\n status: response.status,\n statusText: response.statusText,\n headers,\n })\n}\n\nasync function legacyAdaptersDisabledResponse(): Promise<Response> {\n const { translate } = await resolveTranslations()\n return withAdapterHeaders(NextResponse.json(\n {\n error: translate(\n 'customers.interactions.legacyAdapters.disabled',\n 'This legacy adapter has been disabled. Use /api/customers/interactions instead.',\n ),\n },\n { status: 410 },\n ))\n}\n\nfunction normalizeTodoStatusInput(body: z.infer<typeof todoUpdateBodySchema>): boolean | undefined {\n if (typeof body.isDone === 'boolean') return body.isDone\n if (typeof body.is_done === 'boolean') return body.is_done\n return undefined\n}\n\nfunction collectTodoCustomValues(\n body: Record<string, unknown>,\n): Record<string, unknown> | undefined {\n const direct =\n body.customValues && typeof body.customValues === 'object'\n ? { ...(body.customValues as Record<string, unknown>) }\n : {}\n if (body.todoCustom && typeof body.todoCustom === 'object') {\n Object.assign(direct, body.todoCustom as Record<string, unknown>)\n }\n if (body.customFields && typeof body.customFields === 'object') {\n Object.assign(direct, body.customFields as Record<string, unknown>)\n }\n return Object.keys(direct).length > 0 ? direct : undefined\n}\n\nasync function findLegacyTodoLink(\n em: EntityManager,\n target: { linkId?: string; todoId?: string },\n tenantId: string,\n): Promise<CustomerTodoLink | null> {\n if (target.linkId) {\n const byLinkId = await em.findOne(CustomerTodoLink, { id: target.linkId, tenantId }, { populate: ['entity'] })\n if (byLinkId) return byLinkId\n }\n if (target.todoId) {\n return await em.findOne(CustomerTodoLink, { todoId: target.todoId, tenantId }, { populate: ['entity'] })\n }\n return null\n}\n\nasync function ensureCanonicalTodoBridge(\n em: EntityManager,\n queryEngine: QueryEngine,\n commandBus: CommandBus,\n commandContext: Parameters<CommandBus['execute']>[1]['ctx'],\n link: CustomerTodoLink,\n): Promise<string> {\n const existing = await em.findOne(CustomerInteraction, { id: link.todoId, tenantId: link.tenantId })\n if (existing) return existing.id\n\n const detailMap = await resolveLegacyTodoDetails(\n queryEngine,\n [link],\n link.tenantId,\n [link.organizationId],\n )\n const source =\n typeof link.todoSource === 'string' && link.todoSource.trim().length > 0\n ? link.todoSource\n : EXAMPLE_TODO_SOURCE\n const detail = detailMap.get(`${source}:${link.todoId}`) ?? null\n const entityId = typeof link.entity === 'string' ? link.entity : link.entity.id\n\n await commandBus.execute('customers.interactions.create', {\n input: {\n id: link.todoId,\n tenantId: link.tenantId,\n organizationId: link.organizationId,\n entityId,\n interactionType: 'task',\n title: detail?.title ?? null,\n body: detail?.description ?? null,\n status: detail?.isDone ? 'done' : 'planned',\n scheduledAt: detail?.dueAt ?? null,\n priority: detail?.priority ?? null,\n source: CUSTOMER_INTERACTION_TODO_ADAPTER_SOURCE,\n ...(detail?.customValues ? { customValues: detail.customValues } : {}),\n },\n ctx: commandContext,\n })\n\n return link.todoId\n}\n\nasync function resolveCanonicalTodoTargetId(\n em: EntityManager,\n queryEngine: QueryEngine,\n commandBus: CommandBus,\n commandContext: Parameters<CommandBus['execute']>[1]['ctx'],\n target: { todoId?: string; linkId?: string },\n tenantId: string,\n): Promise<string> {\n if (target.todoId) {\n const interaction = await em.findOne(CustomerInteraction, { id: target.todoId, tenantId })\n if (interaction) return interaction.id\n }\n\n const legacyLink = await findLegacyTodoLink(em, target, tenantId)\n if (!legacyLink) {\n if (!target.todoId) throw new CrudHttpError(404, { error: 'Todo not found' })\n return target.todoId\n }\n\n return ensureCanonicalTodoBridge(\n em,\n queryEngine,\n commandBus,\n commandContext,\n legacyLink,\n )\n}\n\nexport async function GET(request: Request): Promise<Response> {\n try {\n const { auth, em, organizationIds, container, selectedOrganizationId } =\n await resolveCustomersRequestContext(request)\n const query = querySchema.parse(Object.fromEntries(new URL(request.url).searchParams))\n const flags = await resolveCustomerInteractionFeatureFlags(container, auth.tenantId)\n if (!flags.legacyAdapters) {\n return await legacyAdaptersDisabledResponse()\n }\n const queryEngine = container.resolve('queryEngine') as QueryEngine\n const exportAll = parseBooleanToken(query.all) === true\n const search = normalizeTodoSearch(query.search)\n\n if (flags.unified) {\n const canonical = await listCanonicalTodoRows(\n em,\n container,\n auth,\n selectedOrganizationId,\n organizationIds,\n {\n entityId: query.entityId,\n pagination: exportAll ? null : { page: query.page, pageSize: query.pageSize },\n searchText: search,\n },\n )\n const total = canonical.total\n return withAdapterHeaders(\n NextResponse.json({\n items: canonical.items,\n total,\n page: exportAll ? 1 : query.page,\n pageSize: exportAll ? canonical.items.length : query.pageSize,\n totalPages: exportAll ? 1 : Math.max(1, Math.ceil(total / query.pageSize)),\n }),\n )\n }\n\n const legacyWindow = exportAll\n ? null\n : Math.min(MERGED_TODO_FETCH_CAP, Math.max(query.pageSize, query.page * query.pageSize + query.pageSize))\n const [legacyRows, canonicalRows] = await Promise.all([\n listLegacyTodoRows(em, queryEngine, auth.tenantId, organizationIds, query.entityId, {\n limit: legacyWindow,\n }),\n listCanonicalTodoRows(\n em,\n container,\n auth,\n selectedOrganizationId,\n organizationIds,\n {\n entityId: query.entityId,\n includeDeleted: true,\n source: CUSTOMER_INTERACTION_TODO_ADAPTER_SOURCE,\n limit: legacyWindow,\n },\n ),\n ])\n const mergedRows = [\n ...legacyRows.filter((row) => !canonicalRows.bridgeIds.has(row.todoId)),\n ...canonicalRows.items,\n ]\n const filteredRows = filterTodoRows(sortTodoRows(mergedRows), search)\n const paged = paginateTodoRows(filteredRows, query.page, query.pageSize, exportAll)\n\n return withAdapterHeaders(\n NextResponse.json({\n items: paged.items,\n total: paged.total,\n page: paged.page,\n pageSize: paged.pageSize,\n totalPages: paged.totalPages,\n }),\n )\n } catch (err) {\n if (isCrudHttpError(err)) {\n return withAdapterHeaders(NextResponse.json(err.body, { status: err.status }))\n }\n if (err instanceof z.ZodError) {\n return withAdapterHeaders(\n NextResponse.json({ error: 'Validation failed', details: err.issues }, { status: 400 }),\n )\n }\n logger.error('customers.todos.get failed', { err })\n return withAdapterHeaders(\n NextResponse.json({ error: 'Internal server error' }, { status: 500 }),\n )\n }\n}\n\nexport async function POST(request: Request): Promise<Response> {\n try {\n const { commandContext, container, auth, selectedOrganizationId } = await resolveCustomersRequestContext(request)\n const flags = await resolveCustomerInteractionFeatureFlags(container, auth.tenantId)\n if (!flags.legacyAdapters) {\n return await legacyAdaptersDisabledResponse()\n }\n const commandBus = container.resolve('commandBus') as CommandBus\n const body = todoCreateBodySchema.parse(await readJsonSafe<Record<string, unknown>>(request, {}))\n const guardUserId = resolveGuardUserId(auth)\n const guardResult = await validateCrudMutationGuard(container, {\n tenantId: auth.tenantId,\n organizationId: selectedOrganizationId,\n userId: guardUserId,\n resourceKind: 'customers.todoLink',\n resourceId: body.entityId,\n operation: 'create',\n requestMethod: request.method,\n requestHeaders: request.headers,\n mutationPayload: body,\n })\n if (guardResult && !guardResult.ok) {\n return withAdapterHeaders(NextResponse.json(guardResult.body, { status: guardResult.status }))\n }\n const customValues = collectTodoCustomValues(body as Record<string, unknown>)\n\n const { result, logEntry } = await commandBus.execute('customers.interactions.create', {\n input: {\n tenantId: auth.tenantId,\n organizationId: selectedOrganizationId ?? auth.orgId,\n entityId: body.entityId,\n interactionType: 'task',\n title: body.title,\n status: body.is_done === true || body.isDone === true ? 'done' : 'planned',\n source: CUSTOMER_INTERACTION_TODO_ADAPTER_SOURCE,\n ...(customValues ? {\n customValues,\n priority: typeof customValues.priority === 'number' ? customValues.priority : null,\n body: typeof customValues.description === 'string' ? customValues.description : null,\n scheduledAt:\n typeof customValues.due_at === 'string'\n ? customValues.due_at\n : typeof customValues.dueAt === 'string'\n ? customValues.dueAt\n : null,\n } : {}),\n },\n ctx: commandContext,\n })\n if (guardResult?.ok && guardResult.shouldRunAfterSuccess) {\n await runCrudMutationGuardAfterSuccess(container, {\n tenantId: auth.tenantId,\n organizationId: selectedOrganizationId,\n userId: guardUserId,\n resourceKind: 'customers.todoLink',\n resourceId: body.entityId,\n operation: 'create',\n requestMethod: request.method,\n requestHeaders: request.headers,\n metadata: guardResult.metadata ?? null,\n })\n }\n\n const interactionId =\n result &&\n typeof result === 'object' &&\n 'interactionId' in result &&\n typeof result.interactionId === 'string'\n ? result.interactionId\n : result &&\n typeof result === 'object' &&\n 'id' in result &&\n typeof result.id === 'string'\n ? result.id\n : null\n return withAdapterHeaders(\n withOperationMetadata(\n NextResponse.json(\n {\n linkId: interactionId,\n todoId: interactionId,\n },\n { status: 201 },\n ),\n logEntry,\n { resourceKind: 'customers.todoLink', resourceId: interactionId },\n ),\n )\n } catch (err) {\n if (isCrudHttpError(err)) {\n return withAdapterHeaders(NextResponse.json(err.body, { status: err.status }))\n }\n if (err instanceof z.ZodError) {\n return withAdapterHeaders(\n NextResponse.json({ error: 'Validation failed', details: err.issues }, { status: 400 }),\n )\n }\n logger.error('customers.todos.post failed', { err })\n return withAdapterHeaders(\n NextResponse.json({ error: 'Internal server error' }, { status: 500 }),\n )\n }\n}\n\nexport async function PUT(request: Request): Promise<Response> {\n try {\n const { commandContext, container, em, auth, selectedOrganizationId } = await resolveCustomersRequestContext(request)\n const flags = await resolveCustomerInteractionFeatureFlags(container, auth.tenantId)\n if (!flags.legacyAdapters) {\n return await legacyAdaptersDisabledResponse()\n }\n const commandBus = container.resolve('commandBus') as CommandBus\n const queryEngine = container.resolve('queryEngine') as QueryEngine\n const body = todoUpdateBodySchema.parse(await readJsonSafe<Record<string, unknown>>(request, {}))\n const guardUserId = resolveGuardUserId(auth)\n const guardResult = await validateCrudMutationGuard(container, {\n tenantId: auth.tenantId,\n organizationId: selectedOrganizationId,\n userId: guardUserId,\n resourceKind: 'customers.todoLink',\n resourceId: body.linkId ?? body.id,\n operation: 'update',\n requestMethod: request.method,\n requestHeaders: request.headers,\n mutationPayload: body,\n })\n if (guardResult && !guardResult.ok) {\n return withAdapterHeaders(NextResponse.json(guardResult.body, { status: guardResult.status }))\n }\n const interactionId = flags.unified\n ? body.id\n : await resolveCanonicalTodoTargetId(\n em,\n queryEngine,\n commandBus,\n commandContext,\n {\n todoId: body.id,\n linkId: body.linkId,\n },\n auth.tenantId,\n )\n const customValues = collectTodoCustomValues(body as Record<string, unknown>)\n const nextDone = normalizeTodoStatusInput(body)\n\n const { logEntry } = await commandBus.execute('customers.interactions.update', {\n input: {\n id: interactionId,\n ...(body.title !== undefined ? { title: body.title } : {}),\n ...(nextDone !== undefined ? { status: nextDone ? 'done' : 'planned' } : {}),\n ...(customValues ? {\n customValues,\n priority: typeof customValues.priority === 'number' ? customValues.priority : null,\n body: typeof customValues.description === 'string' ? customValues.description : null,\n scheduledAt:\n typeof customValues.due_at === 'string'\n ? customValues.due_at\n : typeof customValues.dueAt === 'string'\n ? customValues.dueAt\n : null,\n } : {}),\n },\n ctx: commandContext,\n })\n if (guardResult?.ok && guardResult.shouldRunAfterSuccess) {\n await runCrudMutationGuardAfterSuccess(container, {\n tenantId: auth.tenantId,\n organizationId: selectedOrganizationId,\n userId: guardUserId,\n resourceKind: 'customers.todoLink',\n resourceId: body.linkId ?? body.id,\n operation: 'update',\n requestMethod: request.method,\n requestHeaders: request.headers,\n metadata: guardResult.metadata ?? null,\n })\n }\n\n return withAdapterHeaders(\n withOperationMetadata(\n NextResponse.json({ ok: true }),\n logEntry,\n { resourceKind: 'customers.todoLink', resourceId: body.linkId ?? body.id },\n ),\n )\n } catch (err) {\n if (isCrudHttpError(err)) {\n return withAdapterHeaders(NextResponse.json(err.body, { status: err.status }))\n }\n if (err instanceof z.ZodError) {\n return withAdapterHeaders(\n NextResponse.json({ error: 'Validation failed', details: err.issues }, { status: 400 }),\n )\n }\n logger.error('customers.todos.put failed', { err })\n return withAdapterHeaders(\n NextResponse.json({ error: 'Internal server error' }, { status: 500 }),\n )\n }\n}\n\nexport async function DELETE(request: Request): Promise<Response> {\n try {\n const { commandContext, container, em, auth, selectedOrganizationId } = await resolveCustomersRequestContext(request)\n const flags = await resolveCustomerInteractionFeatureFlags(container, auth.tenantId)\n if (!flags.legacyAdapters) {\n return await legacyAdaptersDisabledResponse()\n }\n const commandBus = container.resolve('commandBus') as CommandBus\n const queryEngine = container.resolve('queryEngine') as QueryEngine\n const body = todoDeleteBodySchema.parse(await readJsonSafe<Record<string, unknown>>(request, {}))\n const guardUserId = resolveGuardUserId(auth)\n const guardResult = await validateCrudMutationGuard(container, {\n tenantId: auth.tenantId,\n organizationId: selectedOrganizationId,\n userId: guardUserId,\n resourceKind: 'customers.todoLink',\n resourceId: body.id,\n operation: 'delete',\n requestMethod: request.method,\n requestHeaders: request.headers,\n mutationPayload: body,\n })\n if (guardResult && !guardResult.ok) {\n return withAdapterHeaders(NextResponse.json(guardResult.body, { status: guardResult.status }))\n }\n const interactionId = flags.unified\n ? body.todoId ?? body.id\n : await resolveCanonicalTodoTargetId(\n em,\n queryEngine,\n commandBus,\n commandContext,\n {\n linkId: body.id,\n todoId: body.todoId ?? body.id,\n },\n auth.tenantId,\n )\n\n const { logEntry } = await commandBus.execute('customers.interactions.delete', {\n input: { id: interactionId },\n ctx: commandContext,\n })\n if (guardResult?.ok && guardResult.shouldRunAfterSuccess) {\n await runCrudMutationGuardAfterSuccess(container, {\n tenantId: auth.tenantId,\n organizationId: selectedOrganizationId,\n userId: guardUserId,\n resourceKind: 'customers.todoLink',\n resourceId: body.id,\n operation: 'delete',\n requestMethod: request.method,\n requestHeaders: request.headers,\n metadata: guardResult.metadata ?? null,\n })\n }\n\n return withAdapterHeaders(\n withOperationMetadata(\n NextResponse.json({ ok: true }),\n logEntry,\n { resourceKind: 'customers.todoLink', resourceId: body.id },\n ),\n )\n } catch (err) {\n if (isCrudHttpError(err)) {\n return withAdapterHeaders(NextResponse.json(err.body, { status: err.status }))\n }\n if (err instanceof z.ZodError) {\n return withAdapterHeaders(\n NextResponse.json({ error: 'Validation failed', details: err.issues }, { status: 400 }),\n )\n }\n logger.error('customers.todos.delete failed', { err })\n return withAdapterHeaders(\n NextResponse.json({ error: 'Internal server error' }, { status: 500 }),\n )\n }\n}\n\nconst todoItemSchema = z.object({\n id: z.string(),\n todoId: z.string(),\n todoSource: z.string(),\n todoTitle: z.string().nullable(),\n todoIsDone: z.boolean().nullable(),\n todoPriority: z.number().nullable().optional(),\n todoSeverity: z.string().nullable().optional(),\n todoDescription: z.string().nullable().optional(),\n todoDueAt: z.string().nullable().optional(),\n todoCustomValues: z.record(z.string(), z.unknown()).nullable().optional(),\n todoOrganizationId: z.string().nullable(),\n todoUpdatedAt: z.string().nullable().optional(),\n organizationId: z.string(),\n tenantId: z.string(),\n createdAt: z.string(),\n externalHref: z.string().nullable().optional(),\n _integrations: z.record(z.string(), z.unknown()).optional(),\n customer: z.object({\n id: z.string().nullable(),\n displayName: z.string().nullable(),\n kind: z.string().nullable(),\n }),\n})\n\nconst todoCreateResponseSchema = z.object({\n linkId: z.string().uuid().nullable(),\n todoId: z.string().uuid().nullable(),\n})\n\nexport const openApi: OpenApiRouteDoc = createCustomersCrudOpenApi({\n resourceName: 'CustomerTodo',\n querySchema,\n listResponseSchema: createPagedListResponseSchema(todoItemSchema),\n create: {\n schema: todoCreateBodySchema,\n responseSchema: todoCreateResponseSchema,\n description: 'DEPRECATED (sunset 2026-06-30): Creates a customer task. Use POST /api/customers/interactions instead.',\n },\n update: {\n schema: todoUpdateBodySchema,\n responseSchema: defaultOkResponseSchema,\n description: 'DEPRECATED (sunset 2026-06-30): Updates a customer task. Use PUT /api/customers/interactions instead.',\n },\n del: {\n schema: todoDeleteBodySchema,\n responseSchema: defaultOkResponseSchema,\n description: 'DEPRECATED (sunset 2026-06-30): Deletes a customer task. Use DELETE /api/customers/interactions instead.',\n },\n})\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["/**\n * @deprecated Use /api/customers/interactions instead. This route is maintained\n * as a compatibility bridge per SPEC-046b. Will be removed in a future release.\n */\nimport { NextResponse } from 'next/server'\nimport { z } from 'zod'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport type { OpenApiRouteDoc } from '@open-mercato/shared/lib/openapi'\nimport type { CommandBus } from '@open-mercato/shared/lib/commands'\nimport { isCrudHttpError, notFound } from '@open-mercato/shared/lib/crud/errors'\nimport { parseBooleanToken } from '@open-mercato/shared/lib/boolean'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport {\n runCrudMutationGuardAfterSuccess,\n validateCrudMutationGuard,\n} from '@open-mercato/shared/lib/crud/mutation-guard'\nimport { readJsonSafe } from '@open-mercato/shared/lib/http/readJsonSafe'\nimport type { QueryEngine } from '@open-mercato/shared/lib/query/types'\nimport { createCustomersCrudOpenApi, createPagedListResponseSchema, defaultOkResponseSchema } from '../openapi'\nimport { CustomerInteraction, CustomerTodoLink } from '../../data/entities'\nimport { todoLinkWithTodoCreateSchema } from '../../data/validators'\nimport { withOperationMetadata } from '../../lib/operationMetadata'\nimport { resolveCustomerInteractionFeatureFlags } from '../../lib/interactionFeatureFlags'\nimport { resolveCustomersRequestContext } from '../../lib/interactionRequestContext'\nimport {\n EXAMPLE_TODO_SOURCE,\n CUSTOMER_INTERACTION_TODO_ADAPTER_SOURCE,\n} from '../../lib/interactionCompatibility'\nimport {\n filterTodoRows,\n listCanonicalTodoRows,\n listLegacyTodoRows,\n normalizeTodoSearch,\n paginateTodoRows,\n sortTodoRows,\n resolveLegacyTodoDetails,\n} from '../../lib/todoCompatibility'\nimport { createLogger } from '@open-mercato/shared/lib/logger'\n\nconst logger = createLogger('customers')\n\nconst querySchema = z.object({\n page: z.coerce.number().min(1).default(1),\n pageSize: z.coerce.number().min(1).max(100).default(50),\n search: z.string().optional(),\n all: z.string().optional(),\n entityId: z.string().uuid().optional(),\n})\n\nconst todoCreateBodySchema = todoLinkWithTodoCreateSchema.omit({\n tenantId: true,\n organizationId: true,\n}).passthrough()\n\nconst todoUpdateBodySchema = z\n .object({\n id: z.string().uuid(),\n linkId: z.string().uuid().optional(),\n title: z.string().trim().min(1).max(200).optional(),\n isDone: z.boolean().optional(),\n is_done: z.boolean().optional(),\n customFields: z.record(z.string(), z.unknown()).optional(),\n customValues: z.record(z.string(), z.unknown()).optional(),\n })\n .passthrough()\n\nconst todoDeleteBodySchema = z.object({\n id: z.string().uuid(),\n todoId: z.string().uuid().optional(),\n})\n\nexport const metadata = {\n GET: { requireAuth: true, requireFeatures: ['customers.view'] },\n POST: { requireAuth: true, requireFeatures: ['customers.interactions.manage'] },\n PUT: { requireAuth: true, requireFeatures: ['customers.interactions.manage'] },\n DELETE: { requireAuth: true, requireFeatures: ['customers.interactions.manage'] },\n}\n\nconst DEPRECATION_HEADERS = {\n Deprecation: 'true',\n Sunset: 'Tue, 30 Jun 2026 00:00:00 GMT',\n Link: '</api/customers/interactions>; rel=\"successor-version\"',\n}\n\n// Caps the per-source fetch window used by the deprecated merged (legacy +\n// canonical bridge) read path. Keeps memory bounded on tenants with large\n// todo history; deep-pagination beyond this window is not supported here \u2014\n// use /api/customers/interactions instead.\nconst MERGED_TODO_FETCH_CAP = 2000\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\nfunction withAdapterHeaders(response: Response): Response {\n const headers = new Headers(response.headers)\n Object.entries(DEPRECATION_HEADERS).forEach(([key, value]) => headers.set(key, value))\n return new Response(response.body, {\n status: response.status,\n statusText: response.statusText,\n headers,\n })\n}\n\nasync function legacyAdaptersDisabledResponse(): Promise<Response> {\n const { translate } = await resolveTranslations()\n return withAdapterHeaders(NextResponse.json(\n {\n error: translate(\n 'customers.interactions.legacyAdapters.disabled',\n 'This legacy adapter has been disabled. Use /api/customers/interactions instead.',\n ),\n },\n { status: 410 },\n ))\n}\n\nfunction normalizeTodoStatusInput(body: z.infer<typeof todoUpdateBodySchema>): boolean | undefined {\n if (typeof body.isDone === 'boolean') return body.isDone\n if (typeof body.is_done === 'boolean') return body.is_done\n return undefined\n}\n\nfunction collectTodoCustomValues(\n body: Record<string, unknown>,\n): Record<string, unknown> | undefined {\n const direct =\n body.customValues && typeof body.customValues === 'object'\n ? { ...(body.customValues as Record<string, unknown>) }\n : {}\n if (body.todoCustom && typeof body.todoCustom === 'object') {\n Object.assign(direct, body.todoCustom as Record<string, unknown>)\n }\n if (body.customFields && typeof body.customFields === 'object') {\n Object.assign(direct, body.customFields as Record<string, unknown>)\n }\n return Object.keys(direct).length > 0 ? direct : undefined\n}\n\nasync function findLegacyTodoLink(\n em: EntityManager,\n target: { linkId?: string; todoId?: string },\n tenantId: string,\n): Promise<CustomerTodoLink | null> {\n if (target.linkId) {\n const byLinkId = await em.findOne(CustomerTodoLink, { id: target.linkId, tenantId }, { populate: ['entity'] })\n if (byLinkId) return byLinkId\n }\n if (target.todoId) {\n return await em.findOne(CustomerTodoLink, { todoId: target.todoId, tenantId }, { populate: ['entity'] })\n }\n return null\n}\n\nasync function ensureCanonicalTodoBridge(\n em: EntityManager,\n queryEngine: QueryEngine,\n commandBus: CommandBus,\n commandContext: Parameters<CommandBus['execute']>[1]['ctx'],\n link: CustomerTodoLink,\n): Promise<string> {\n const existing = await em.findOne(CustomerInteraction, { id: link.todoId, tenantId: link.tenantId })\n if (existing) return existing.id\n\n const detailMap = await resolveLegacyTodoDetails(\n queryEngine,\n [link],\n link.tenantId,\n [link.organizationId],\n )\n const source =\n typeof link.todoSource === 'string' && link.todoSource.trim().length > 0\n ? link.todoSource\n : EXAMPLE_TODO_SOURCE\n const detail = detailMap.get(`${source}:${link.todoId}`) ?? null\n const entityId = typeof link.entity === 'string' ? link.entity : link.entity.id\n\n await commandBus.execute('customers.interactions.create', {\n input: {\n id: link.todoId,\n tenantId: link.tenantId,\n organizationId: link.organizationId,\n entityId,\n interactionType: 'task',\n title: detail?.title ?? null,\n body: detail?.description ?? null,\n status: detail?.isDone ? 'done' : 'planned',\n scheduledAt: detail?.dueAt ?? null,\n priority: detail?.priority ?? null,\n source: CUSTOMER_INTERACTION_TODO_ADAPTER_SOURCE,\n ...(detail?.customValues ? { customValues: detail.customValues } : {}),\n },\n ctx: commandContext,\n })\n\n return link.todoId\n}\n\nasync function resolveCanonicalTodoTargetId(\n em: EntityManager,\n queryEngine: QueryEngine,\n commandBus: CommandBus,\n commandContext: Parameters<CommandBus['execute']>[1]['ctx'],\n target: { todoId?: string; linkId?: string },\n tenantId: string,\n): Promise<string> {\n if (target.todoId) {\n const interaction = await em.findOne(CustomerInteraction, { id: target.todoId, tenantId })\n if (interaction) return interaction.id\n }\n\n const legacyLink = await findLegacyTodoLink(em, target, tenantId)\n if (!legacyLink) {\n if (!target.todoId) throw notFound('Todo not found')\n return target.todoId\n }\n\n return ensureCanonicalTodoBridge(\n em,\n queryEngine,\n commandBus,\n commandContext,\n legacyLink,\n )\n}\n\nexport async function GET(request: Request): Promise<Response> {\n try {\n const { auth, em, organizationIds, container, selectedOrganizationId } =\n await resolveCustomersRequestContext(request)\n const query = querySchema.parse(Object.fromEntries(new URL(request.url).searchParams))\n const flags = await resolveCustomerInteractionFeatureFlags(container, auth.tenantId)\n if (!flags.legacyAdapters) {\n return await legacyAdaptersDisabledResponse()\n }\n const queryEngine = container.resolve('queryEngine') as QueryEngine\n const exportAll = parseBooleanToken(query.all) === true\n const search = normalizeTodoSearch(query.search)\n\n if (flags.unified) {\n const canonical = await listCanonicalTodoRows(\n em,\n container,\n auth,\n selectedOrganizationId,\n organizationIds,\n {\n entityId: query.entityId,\n pagination: exportAll ? null : { page: query.page, pageSize: query.pageSize },\n searchText: search,\n },\n )\n const total = canonical.total\n return withAdapterHeaders(\n NextResponse.json({\n items: canonical.items,\n total,\n page: exportAll ? 1 : query.page,\n pageSize: exportAll ? canonical.items.length : query.pageSize,\n totalPages: exportAll ? 1 : Math.max(1, Math.ceil(total / query.pageSize)),\n }),\n )\n }\n\n const legacyWindow = exportAll\n ? null\n : Math.min(MERGED_TODO_FETCH_CAP, Math.max(query.pageSize, query.page * query.pageSize + query.pageSize))\n const [legacyRows, canonicalRows] = await Promise.all([\n listLegacyTodoRows(em, queryEngine, auth.tenantId, organizationIds, query.entityId, {\n limit: legacyWindow,\n }),\n listCanonicalTodoRows(\n em,\n container,\n auth,\n selectedOrganizationId,\n organizationIds,\n {\n entityId: query.entityId,\n includeDeleted: true,\n source: CUSTOMER_INTERACTION_TODO_ADAPTER_SOURCE,\n limit: legacyWindow,\n },\n ),\n ])\n const mergedRows = [\n ...legacyRows.filter((row) => !canonicalRows.bridgeIds.has(row.todoId)),\n ...canonicalRows.items,\n ]\n const filteredRows = filterTodoRows(sortTodoRows(mergedRows), search)\n const paged = paginateTodoRows(filteredRows, query.page, query.pageSize, exportAll)\n\n return withAdapterHeaders(\n NextResponse.json({\n items: paged.items,\n total: paged.total,\n page: paged.page,\n pageSize: paged.pageSize,\n totalPages: paged.totalPages,\n }),\n )\n } catch (err) {\n if (isCrudHttpError(err)) {\n return withAdapterHeaders(NextResponse.json(err.body, { status: err.status }))\n }\n if (err instanceof z.ZodError) {\n return withAdapterHeaders(\n NextResponse.json({ error: 'Validation failed', details: err.issues }, { status: 400 }),\n )\n }\n logger.error('customers.todos.get failed', { err })\n return withAdapterHeaders(\n NextResponse.json({ error: 'Internal server error' }, { status: 500 }),\n )\n }\n}\n\nexport async function POST(request: Request): Promise<Response> {\n try {\n const { commandContext, container, auth, selectedOrganizationId } = await resolveCustomersRequestContext(request)\n const flags = await resolveCustomerInteractionFeatureFlags(container, auth.tenantId)\n if (!flags.legacyAdapters) {\n return await legacyAdaptersDisabledResponse()\n }\n const commandBus = container.resolve('commandBus') as CommandBus\n const body = todoCreateBodySchema.parse(await readJsonSafe<Record<string, unknown>>(request, {}))\n const guardUserId = resolveGuardUserId(auth)\n const guardResult = await validateCrudMutationGuard(container, {\n tenantId: auth.tenantId,\n organizationId: selectedOrganizationId,\n userId: guardUserId,\n resourceKind: 'customers.todoLink',\n resourceId: body.entityId,\n operation: 'create',\n requestMethod: request.method,\n requestHeaders: request.headers,\n mutationPayload: body,\n })\n if (guardResult && !guardResult.ok) {\n return withAdapterHeaders(NextResponse.json(guardResult.body, { status: guardResult.status }))\n }\n const customValues = collectTodoCustomValues(body as Record<string, unknown>)\n\n const { result, logEntry } = await commandBus.execute('customers.interactions.create', {\n input: {\n tenantId: auth.tenantId,\n organizationId: selectedOrganizationId ?? auth.orgId,\n entityId: body.entityId,\n interactionType: 'task',\n title: body.title,\n status: body.is_done === true || body.isDone === true ? 'done' : 'planned',\n source: CUSTOMER_INTERACTION_TODO_ADAPTER_SOURCE,\n ...(customValues ? {\n customValues,\n priority: typeof customValues.priority === 'number' ? customValues.priority : null,\n body: typeof customValues.description === 'string' ? customValues.description : null,\n scheduledAt:\n typeof customValues.due_at === 'string'\n ? customValues.due_at\n : typeof customValues.dueAt === 'string'\n ? customValues.dueAt\n : null,\n } : {}),\n },\n ctx: commandContext,\n })\n if (guardResult?.ok && guardResult.shouldRunAfterSuccess) {\n await runCrudMutationGuardAfterSuccess(container, {\n tenantId: auth.tenantId,\n organizationId: selectedOrganizationId,\n userId: guardUserId,\n resourceKind: 'customers.todoLink',\n resourceId: body.entityId,\n operation: 'create',\n requestMethod: request.method,\n requestHeaders: request.headers,\n metadata: guardResult.metadata ?? null,\n })\n }\n\n const interactionId =\n result &&\n typeof result === 'object' &&\n 'interactionId' in result &&\n typeof result.interactionId === 'string'\n ? result.interactionId\n : result &&\n typeof result === 'object' &&\n 'id' in result &&\n typeof result.id === 'string'\n ? result.id\n : null\n return withAdapterHeaders(\n withOperationMetadata(\n NextResponse.json(\n {\n linkId: interactionId,\n todoId: interactionId,\n },\n { status: 201 },\n ),\n logEntry,\n { resourceKind: 'customers.todoLink', resourceId: interactionId },\n ),\n )\n } catch (err) {\n if (isCrudHttpError(err)) {\n return withAdapterHeaders(NextResponse.json(err.body, { status: err.status }))\n }\n if (err instanceof z.ZodError) {\n return withAdapterHeaders(\n NextResponse.json({ error: 'Validation failed', details: err.issues }, { status: 400 }),\n )\n }\n logger.error('customers.todos.post failed', { err })\n return withAdapterHeaders(\n NextResponse.json({ error: 'Internal server error' }, { status: 500 }),\n )\n }\n}\n\nexport async function PUT(request: Request): Promise<Response> {\n try {\n const { commandContext, container, em, auth, selectedOrganizationId } = await resolveCustomersRequestContext(request)\n const flags = await resolveCustomerInteractionFeatureFlags(container, auth.tenantId)\n if (!flags.legacyAdapters) {\n return await legacyAdaptersDisabledResponse()\n }\n const commandBus = container.resolve('commandBus') as CommandBus\n const queryEngine = container.resolve('queryEngine') as QueryEngine\n const body = todoUpdateBodySchema.parse(await readJsonSafe<Record<string, unknown>>(request, {}))\n const guardUserId = resolveGuardUserId(auth)\n const guardResult = await validateCrudMutationGuard(container, {\n tenantId: auth.tenantId,\n organizationId: selectedOrganizationId,\n userId: guardUserId,\n resourceKind: 'customers.todoLink',\n resourceId: body.linkId ?? body.id,\n operation: 'update',\n requestMethod: request.method,\n requestHeaders: request.headers,\n mutationPayload: body,\n })\n if (guardResult && !guardResult.ok) {\n return withAdapterHeaders(NextResponse.json(guardResult.body, { status: guardResult.status }))\n }\n const interactionId = flags.unified\n ? body.id\n : await resolveCanonicalTodoTargetId(\n em,\n queryEngine,\n commandBus,\n commandContext,\n {\n todoId: body.id,\n linkId: body.linkId,\n },\n auth.tenantId,\n )\n const customValues = collectTodoCustomValues(body as Record<string, unknown>)\n const nextDone = normalizeTodoStatusInput(body)\n\n const { logEntry } = await commandBus.execute('customers.interactions.update', {\n input: {\n id: interactionId,\n ...(body.title !== undefined ? { title: body.title } : {}),\n ...(nextDone !== undefined ? { status: nextDone ? 'done' : 'planned' } : {}),\n ...(customValues ? {\n customValues,\n priority: typeof customValues.priority === 'number' ? customValues.priority : null,\n body: typeof customValues.description === 'string' ? customValues.description : null,\n scheduledAt:\n typeof customValues.due_at === 'string'\n ? customValues.due_at\n : typeof customValues.dueAt === 'string'\n ? customValues.dueAt\n : null,\n } : {}),\n },\n ctx: commandContext,\n })\n if (guardResult?.ok && guardResult.shouldRunAfterSuccess) {\n await runCrudMutationGuardAfterSuccess(container, {\n tenantId: auth.tenantId,\n organizationId: selectedOrganizationId,\n userId: guardUserId,\n resourceKind: 'customers.todoLink',\n resourceId: body.linkId ?? body.id,\n operation: 'update',\n requestMethod: request.method,\n requestHeaders: request.headers,\n metadata: guardResult.metadata ?? null,\n })\n }\n\n return withAdapterHeaders(\n withOperationMetadata(\n NextResponse.json({ ok: true }),\n logEntry,\n { resourceKind: 'customers.todoLink', resourceId: body.linkId ?? body.id },\n ),\n )\n } catch (err) {\n if (isCrudHttpError(err)) {\n return withAdapterHeaders(NextResponse.json(err.body, { status: err.status }))\n }\n if (err instanceof z.ZodError) {\n return withAdapterHeaders(\n NextResponse.json({ error: 'Validation failed', details: err.issues }, { status: 400 }),\n )\n }\n logger.error('customers.todos.put failed', { err })\n return withAdapterHeaders(\n NextResponse.json({ error: 'Internal server error' }, { status: 500 }),\n )\n }\n}\n\nexport async function DELETE(request: Request): Promise<Response> {\n try {\n const { commandContext, container, em, auth, selectedOrganizationId } = await resolveCustomersRequestContext(request)\n const flags = await resolveCustomerInteractionFeatureFlags(container, auth.tenantId)\n if (!flags.legacyAdapters) {\n return await legacyAdaptersDisabledResponse()\n }\n const commandBus = container.resolve('commandBus') as CommandBus\n const queryEngine = container.resolve('queryEngine') as QueryEngine\n const body = todoDeleteBodySchema.parse(await readJsonSafe<Record<string, unknown>>(request, {}))\n const guardUserId = resolveGuardUserId(auth)\n const guardResult = await validateCrudMutationGuard(container, {\n tenantId: auth.tenantId,\n organizationId: selectedOrganizationId,\n userId: guardUserId,\n resourceKind: 'customers.todoLink',\n resourceId: body.id,\n operation: 'delete',\n requestMethod: request.method,\n requestHeaders: request.headers,\n mutationPayload: body,\n })\n if (guardResult && !guardResult.ok) {\n return withAdapterHeaders(NextResponse.json(guardResult.body, { status: guardResult.status }))\n }\n const interactionId = flags.unified\n ? body.todoId ?? body.id\n : await resolveCanonicalTodoTargetId(\n em,\n queryEngine,\n commandBus,\n commandContext,\n {\n linkId: body.id,\n todoId: body.todoId ?? body.id,\n },\n auth.tenantId,\n )\n\n const { logEntry } = await commandBus.execute('customers.interactions.delete', {\n input: { id: interactionId },\n ctx: commandContext,\n })\n if (guardResult?.ok && guardResult.shouldRunAfterSuccess) {\n await runCrudMutationGuardAfterSuccess(container, {\n tenantId: auth.tenantId,\n organizationId: selectedOrganizationId,\n userId: guardUserId,\n resourceKind: 'customers.todoLink',\n resourceId: body.id,\n operation: 'delete',\n requestMethod: request.method,\n requestHeaders: request.headers,\n metadata: guardResult.metadata ?? null,\n })\n }\n\n return withAdapterHeaders(\n withOperationMetadata(\n NextResponse.json({ ok: true }),\n logEntry,\n { resourceKind: 'customers.todoLink', resourceId: body.id },\n ),\n )\n } catch (err) {\n if (isCrudHttpError(err)) {\n return withAdapterHeaders(NextResponse.json(err.body, { status: err.status }))\n }\n if (err instanceof z.ZodError) {\n return withAdapterHeaders(\n NextResponse.json({ error: 'Validation failed', details: err.issues }, { status: 400 }),\n )\n }\n logger.error('customers.todos.delete failed', { err })\n return withAdapterHeaders(\n NextResponse.json({ error: 'Internal server error' }, { status: 500 }),\n )\n }\n}\n\nconst todoItemSchema = z.object({\n id: z.string(),\n todoId: z.string(),\n todoSource: z.string(),\n todoTitle: z.string().nullable(),\n todoIsDone: z.boolean().nullable(),\n todoPriority: z.number().nullable().optional(),\n todoSeverity: z.string().nullable().optional(),\n todoDescription: z.string().nullable().optional(),\n todoDueAt: z.string().nullable().optional(),\n todoCustomValues: z.record(z.string(), z.unknown()).nullable().optional(),\n todoOrganizationId: z.string().nullable(),\n todoUpdatedAt: z.string().nullable().optional(),\n organizationId: z.string(),\n tenantId: z.string(),\n createdAt: z.string(),\n externalHref: z.string().nullable().optional(),\n _integrations: z.record(z.string(), z.unknown()).optional(),\n customer: z.object({\n id: z.string().nullable(),\n displayName: z.string().nullable(),\n kind: z.string().nullable(),\n }),\n})\n\nconst todoCreateResponseSchema = z.object({\n linkId: z.string().uuid().nullable(),\n todoId: z.string().uuid().nullable(),\n})\n\nexport const openApi: OpenApiRouteDoc = createCustomersCrudOpenApi({\n resourceName: 'CustomerTodo',\n querySchema,\n listResponseSchema: createPagedListResponseSchema(todoItemSchema),\n create: {\n schema: todoCreateBodySchema,\n responseSchema: todoCreateResponseSchema,\n description: 'DEPRECATED (sunset 2026-06-30): Creates a customer task. Use POST /api/customers/interactions instead.',\n },\n update: {\n schema: todoUpdateBodySchema,\n responseSchema: defaultOkResponseSchema,\n description: 'DEPRECATED (sunset 2026-06-30): Updates a customer task. Use PUT /api/customers/interactions instead.',\n },\n del: {\n schema: todoDeleteBodySchema,\n responseSchema: defaultOkResponseSchema,\n description: 'DEPRECATED (sunset 2026-06-30): Deletes a customer task. Use DELETE /api/customers/interactions instead.',\n },\n})\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -11,7 +11,7 @@ import {
11
11
  resolveParentResourceKind
12
12
  } from "./shared.js";
13
13
  import { resolveTranslations } from "@open-mercato/shared/lib/i18n/server";
14
- import { CrudHttpError } from "@open-mercato/shared/lib/crud/errors";
14
+ import { CrudHttpError, notFound } from "@open-mercato/shared/lib/crud/errors";
15
15
  import { E } from "../../../generated/entities.ids.generated.js";
16
16
  import { withAtomicFlush } from "@open-mercato/shared/lib/commands/flush";
17
17
  import { resolveRedoSnapshot } from "@open-mercato/shared/lib/commands/redo";
@@ -243,7 +243,7 @@ const updateAddressCommand = {
243
243
  const parsed = addressUpdateSchema.parse(rawInput);
244
244
  const em = ctx.container.resolve("em").fork();
245
245
  const address = await em.findOne(CustomerAddress, { id: parsed.id });
246
- if (!address) throw new CrudHttpError(404, { error: "Address not found" });
246
+ if (!address) throw notFound("Address not found");
247
247
  ensureTenantScope(ctx, address.tenantId);
248
248
  ensureOrganizationScope(ctx, address.organizationId);
249
249
  if (parsed.entityId !== void 0) {
@@ -422,7 +422,7 @@ const deleteAddressCommand = {
422
422
  const id = requireId(input, "Address id required");
423
423
  const em = ctx.container.resolve("em").fork();
424
424
  const address = await em.findOne(CustomerAddress, { id });
425
- if (!address) throw new CrudHttpError(404, { error: "Address not found" });
425
+ if (!address) throw notFound("Address not found");
426
426
  ensureTenantScope(ctx, address.tenantId);
427
427
  ensureOrganizationScope(ctx, address.organizationId);
428
428
  em.remove(address);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/modules/customers/commands/addresses.ts"],
4
- "sourcesContent": ["import { registerCommand } from '@open-mercato/shared/lib/commands'\nimport type { CommandHandler } from '@open-mercato/shared/lib/commands'\nimport { emitCrudSideEffects, emitCrudUndoSideEffects, buildChanges, requireId } from '@open-mercato/shared/lib/commands/helpers'\nimport type { DataEngine } from '@open-mercato/shared/lib/data/engine'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { CustomerAddress } from '../data/entities'\nimport { addressCreateSchema, addressUpdateSchema, type AddressCreateInput, type AddressUpdateInput } from '../data/validators'\nimport {\n ensureOrganizationScope,\n ensureTenantScope,\n requireCustomerEntity,\n ensureSameScope,\n extractUndoPayload,\n resolveParentResourceKind,\n} from './shared'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport type { CrudIndexerConfig, CrudEventsConfig } from '@open-mercato/shared/lib/crud/types'\nimport { E } from '#generated/entities.ids.generated'\nimport { withAtomicFlush } from '@open-mercato/shared/lib/commands/flush'\nimport { resolveRedoSnapshot } from '@open-mercato/shared/lib/commands/redo'\nimport { findOneWithDecryption } from '@open-mercato/shared/lib/encryption/find'\n\nconst addressCrudIndexer: CrudIndexerConfig<CustomerAddress> = {\n entityType: E.customers.customer_address,\n}\n\nconst addressCrudEvents: CrudEventsConfig = {\n module: 'customers',\n entity: 'address',\n persistent: true,\n buildPayload: (ctx) => ({\n id: ctx.identifiers.id,\n organizationId: ctx.identifiers.organizationId,\n tenantId: ctx.identifiers.tenantId,\n }),\n}\n\ntype AddressSnapshot = {\n id: string\n organizationId: string\n tenantId: string\n entityId: string\n entityKind: string | null\n name: string | null\n purpose: string | null\n companyName: string | null\n addressLine1: string\n addressLine2: string | null\n buildingNumber: string | null\n flatNumber: string | null\n city: string | null\n region: string | null\n postalCode: string | null\n country: string | null\n latitude: number | null\n longitude: number | null\n isPrimary: boolean\n}\n\ntype AddressUndoPayload = {\n before?: AddressSnapshot | null\n after?: AddressSnapshot | null\n}\n\nasync function loadAddressSnapshot(em: EntityManager, id: string): Promise<AddressSnapshot | null> {\n const address = await em.findOne(CustomerAddress, { id }, { populate: ['entity'] })\n if (!address) return null\n const entityRef = address.entity\n const entityKind = (typeof entityRef === 'object' && entityRef !== null && 'kind' in entityRef)\n ? (entityRef as { kind: string }).kind\n : null\n return {\n id: address.id,\n organizationId: address.organizationId,\n tenantId: address.tenantId,\n entityId: typeof entityRef === 'string' ? entityRef : entityRef.id,\n entityKind,\n name: address.name ?? null,\n purpose: address.purpose ?? null,\n companyName: address.companyName ?? null,\n addressLine1: address.addressLine1,\n addressLine2: address.addressLine2 ?? null,\n buildingNumber: address.buildingNumber ?? null,\n flatNumber: address.flatNumber ?? null,\n city: address.city ?? null,\n region: address.region ?? null,\n postalCode: address.postalCode ?? null,\n country: address.country ?? null,\n latitude: address.latitude ?? null,\n longitude: address.longitude ?? null,\n isPrimary: address.isPrimary,\n }\n}\n\nasync function enforcePrimaryAddress(em: EntityManager, entityId: string, addressId: string): Promise<void> {\n await em.nativeUpdate(\n CustomerAddress,\n { entity: entityId, id: { $ne: addressId }, isPrimary: true },\n { isPrimary: false }\n )\n}\n\nconst createAddressCommand: CommandHandler<AddressCreateInput, { addressId: string }> = {\n id: 'customers.addresses.create',\n async execute(rawInput, ctx) {\n const parsed = addressCreateSchema.parse(rawInput)\n ensureTenantScope(ctx, parsed.tenantId)\n ensureOrganizationScope(ctx, parsed.organizationId)\n\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const entity = await requireCustomerEntity(em, parsed.entityId, { tenantId: parsed.tenantId, organizationId: parsed.organizationId }, undefined, 'Customer not found')\n ensureSameScope(entity, parsed.organizationId, parsed.tenantId)\n\n const address = em.create(CustomerAddress, {\n organizationId: parsed.organizationId,\n tenantId: parsed.tenantId,\n entity,\n name: parsed.name ?? null,\n purpose: parsed.purpose ?? null,\n companyName: parsed.companyName ?? null,\n addressLine1: parsed.addressLine1,\n addressLine2: parsed.addressLine2 ?? null,\n buildingNumber: parsed.buildingNumber ?? null,\n flatNumber: parsed.flatNumber ?? null,\n city: parsed.city ?? null,\n region: parsed.region ?? null,\n postalCode: parsed.postalCode ?? null,\n country: parsed.country ?? null,\n latitude: parsed.latitude ?? null,\n longitude: parsed.longitude ?? null,\n isPrimary: parsed.isPrimary ?? false,\n createdAt: new Date(),\n updatedAt: new Date(),\n })\n await withAtomicFlush(em, [\n async () => {\n em.persist(address)\n await em.flush()\n if (address.isPrimary) {\n await enforcePrimaryAddress(em, entity.id, address.id)\n }\n },\n ], { transaction: true })\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n await emitCrudSideEffects({\n dataEngine: de,\n action: 'created',\n entity: address,\n identifiers: {\n id: address.id,\n organizationId: address.organizationId,\n tenantId: address.tenantId,\n },\n indexer: addressCrudIndexer,\n events: addressCrudEvents,\n })\n\n return { addressId: address.id }\n },\n captureAfter: async (_input, result, ctx) => {\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return await loadAddressSnapshot(em, result.addressId)\n },\n buildLog: async ({ result, snapshots }) => {\n const { translate } = await resolveTranslations()\n const snapshot = snapshots.after as AddressSnapshot | undefined\n return {\n actionLabel: translate('customers.audit.addresses.create', 'Create address'),\n resourceKind: 'customers.address',\n resourceId: result.addressId,\n parentResourceKind: resolveParentResourceKind(snapshot?.entityKind),\n parentResourceId: snapshot?.entityId ?? null,\n tenantId: snapshot?.tenantId ?? null,\n organizationId: snapshot?.organizationId ?? null,\n snapshotAfter: snapshot ?? null,\n payload: {\n undo: {\n after: snapshot ?? null,\n } satisfies AddressUndoPayload,\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const addressId = logEntry?.resourceId ?? null\n if (!addressId) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const address = await em.findOne(CustomerAddress, { id: addressId })\n if (address) {\n em.remove(address)\n await em.flush()\n }\n },\n redo: async ({ logEntry, ctx }) => {\n const after = resolveRedoSnapshot<AddressSnapshot>(logEntry)\n if (!after) {\n throw new CrudHttpError(400, { error: '[internal] redo snapshot unavailable for address create' })\n }\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const entity = await requireCustomerEntity(em, after.entityId, { tenantId: after.tenantId, organizationId: after.organizationId }, undefined, 'Customer not found')\n let address = await findOneWithDecryption(\n em,\n CustomerAddress,\n { id: after.id },\n undefined,\n { tenantId: after.tenantId, organizationId: after.organizationId },\n )\n if (!address) {\n address = em.create(CustomerAddress, {\n id: after.id,\n organizationId: after.organizationId,\n tenantId: after.tenantId,\n entity,\n name: after.name,\n purpose: after.purpose,\n companyName: after.companyName,\n addressLine1: after.addressLine1,\n addressLine2: after.addressLine2,\n buildingNumber: after.buildingNumber,\n flatNumber: after.flatNumber,\n city: after.city,\n region: after.region,\n postalCode: after.postalCode,\n country: after.country,\n latitude: after.latitude,\n longitude: after.longitude,\n isPrimary: after.isPrimary,\n createdAt: new Date(),\n updatedAt: new Date(),\n })\n em.persist(address)\n } else {\n address.entity = entity\n address.name = after.name\n address.purpose = after.purpose\n address.companyName = after.companyName\n address.addressLine1 = after.addressLine1\n address.addressLine2 = after.addressLine2\n address.buildingNumber = after.buildingNumber\n address.flatNumber = after.flatNumber\n address.city = after.city\n address.region = after.region\n address.postalCode = after.postalCode\n address.country = after.country\n address.latitude = after.latitude\n address.longitude = after.longitude\n address.isPrimary = after.isPrimary\n }\n const restoredAddress = address\n await withAtomicFlush(em, [\n async () => {\n em.persist(restoredAddress)\n await em.flush()\n if (after.isPrimary) {\n await enforcePrimaryAddress(em, after.entityId, after.id)\n }\n },\n ], { transaction: true })\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n await emitCrudSideEffects({\n dataEngine: de,\n action: 'created',\n entity: restoredAddress,\n identifiers: {\n id: restoredAddress.id,\n organizationId: restoredAddress.organizationId,\n tenantId: restoredAddress.tenantId,\n },\n indexer: addressCrudIndexer,\n events: addressCrudEvents,\n })\n\n return { addressId: restoredAddress.id }\n },\n}\n\nconst updateAddressCommand: CommandHandler<AddressUpdateInput, { addressId: string }> = {\n id: 'customers.addresses.update',\n async prepare(rawInput, ctx) {\n const parsed = addressUpdateSchema.parse(rawInput)\n const em = (ctx.container.resolve('em') as EntityManager)\n const snapshot = await loadAddressSnapshot(em, parsed.id)\n return snapshot ? { before: snapshot } : {}\n },\n async execute(rawInput, ctx) {\n const parsed = addressUpdateSchema.parse(rawInput)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const address = await em.findOne(CustomerAddress, { id: parsed.id })\n if (!address) throw new CrudHttpError(404, { error: 'Address not found' })\n ensureTenantScope(ctx, address.tenantId)\n ensureOrganizationScope(ctx, address.organizationId)\n\n if (parsed.entityId !== undefined) {\n const entity = await requireCustomerEntity(em, parsed.entityId, { tenantId: address.tenantId, organizationId: address.organizationId }, undefined, 'Customer not found')\n ensureSameScope(entity, address.organizationId, address.tenantId)\n address.entity = entity\n }\n\n await withAtomicFlush(em, [\n () => {\n if (parsed.name !== undefined) address.name = parsed.name ?? null\n if (parsed.purpose !== undefined) address.purpose = parsed.purpose ?? null\n if (parsed.companyName !== undefined) address.companyName = parsed.companyName ?? null\n if (parsed.addressLine1 !== undefined) address.addressLine1 = parsed.addressLine1\n if (parsed.addressLine2 !== undefined) address.addressLine2 = parsed.addressLine2 ?? null\n if (parsed.buildingNumber !== undefined) address.buildingNumber = parsed.buildingNumber ?? null\n if (parsed.flatNumber !== undefined) address.flatNumber = parsed.flatNumber ?? null\n if (parsed.city !== undefined) address.city = parsed.city ?? null\n if (parsed.region !== undefined) address.region = parsed.region ?? null\n if (parsed.postalCode !== undefined) address.postalCode = parsed.postalCode ?? null\n if (parsed.country !== undefined) address.country = parsed.country ?? null\n if (parsed.latitude !== undefined) address.latitude = parsed.latitude ?? null\n if (parsed.longitude !== undefined) address.longitude = parsed.longitude ?? null\n if (parsed.isPrimary !== undefined) address.isPrimary = parsed.isPrimary\n },\n async () => {\n if (address.isPrimary) {\n await enforcePrimaryAddress(em, typeof address.entity === 'string' ? address.entity : address.entity.id, address.id)\n }\n },\n ], { transaction: true })\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n await emitCrudSideEffects({\n dataEngine: de,\n action: 'updated',\n entity: address,\n identifiers: {\n id: address.id,\n organizationId: address.organizationId,\n tenantId: address.tenantId,\n },\n indexer: addressCrudIndexer,\n events: addressCrudEvents,\n })\n\n return { addressId: address.id }\n },\n captureAfter: async (_input, result, ctx) => {\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return await loadAddressSnapshot(em, result.addressId)\n },\n buildLog: async ({ snapshots }) => {\n const { translate } = await resolveTranslations()\n const before = snapshots.before as AddressSnapshot | undefined\n if (!before) return null\n const afterSnapshot = snapshots.after as AddressSnapshot | undefined\n const changes =\n afterSnapshot && before\n ? buildChanges(\n before as unknown as Record<string, unknown>,\n afterSnapshot as unknown as Record<string, unknown>,\n [\n 'entityId',\n 'name',\n 'purpose',\n 'companyName',\n 'addressLine1',\n 'addressLine2',\n 'buildingNumber',\n 'flatNumber',\n 'city',\n 'region',\n 'postalCode',\n 'country',\n 'latitude',\n 'longitude',\n 'isPrimary',\n ]\n )\n : {}\n return {\n actionLabel: translate('customers.audit.addresses.update', 'Update address'),\n resourceKind: 'customers.address',\n resourceId: before.id,\n parentResourceKind: resolveParentResourceKind(before.entityKind),\n parentResourceId: before.entityId ?? null,\n tenantId: before.tenantId,\n organizationId: before.organizationId,\n snapshotBefore: before,\n snapshotAfter: afterSnapshot ?? null,\n changes,\n payload: {\n undo: {\n before,\n after: afterSnapshot ?? null,\n } satisfies AddressUndoPayload,\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<AddressUndoPayload>(logEntry)\n const before = payload?.before\n if (!before) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n let address = await em.findOne(CustomerAddress, { id: before.id })\n const entity = await requireCustomerEntity(em, before.entityId, { tenantId: before.tenantId, organizationId: before.organizationId }, undefined, 'Customer not found')\n if (!address) {\n address = em.create(CustomerAddress, {\n id: before.id,\n organizationId: before.organizationId,\n tenantId: before.tenantId,\n entity,\n name: before.name,\n purpose: before.purpose,\n companyName: before.companyName,\n addressLine1: before.addressLine1,\n addressLine2: before.addressLine2,\n buildingNumber: before.buildingNumber,\n flatNumber: before.flatNumber,\n city: before.city,\n region: before.region,\n postalCode: before.postalCode,\n country: before.country,\n latitude: before.latitude,\n longitude: before.longitude,\n isPrimary: before.isPrimary,\n createdAt: new Date(),\n updatedAt: new Date(),\n })\n em.persist(address)\n } else {\n address.entity = entity\n address.name = before.name\n address.purpose = before.purpose\n address.companyName = before.companyName\n address.addressLine1 = before.addressLine1\n address.addressLine2 = before.addressLine2\n address.buildingNumber = before.buildingNumber\n address.flatNumber = before.flatNumber\n address.city = before.city\n address.region = before.region\n address.postalCode = before.postalCode\n address.country = before.country\n address.latitude = before.latitude\n address.longitude = before.longitude\n address.isPrimary = before.isPrimary\n }\n await withAtomicFlush(em, [\n async () => {\n em.persist(address)\n await em.flush()\n if (before.isPrimary) {\n await enforcePrimaryAddress(em, before.entityId, before.id)\n }\n },\n ], { transaction: true })\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n await emitCrudUndoSideEffects({\n dataEngine: de,\n action: 'updated',\n entity: address,\n identifiers: {\n id: address.id,\n organizationId: address.organizationId,\n tenantId: address.tenantId,\n },\n indexer: addressCrudIndexer,\n events: addressCrudEvents,\n })\n },\n}\n\nconst deleteAddressCommand: CommandHandler<{ body?: Record<string, unknown>; query?: Record<string, unknown> }, { addressId: string }> =\n {\n id: 'customers.addresses.delete',\n async prepare(input, ctx) {\n const id = requireId(input, 'Address id required')\n const em = (ctx.container.resolve('em') as EntityManager)\n const snapshot = await loadAddressSnapshot(em, id)\n return snapshot ? { before: snapshot } : {}\n },\n async execute(input, ctx) {\n const id = requireId(input, 'Address id required')\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const address = await em.findOne(CustomerAddress, { id })\n if (!address) throw new CrudHttpError(404, { error: 'Address not found' })\n ensureTenantScope(ctx, address.tenantId)\n ensureOrganizationScope(ctx, address.organizationId)\n em.remove(address)\n await em.flush()\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n await emitCrudSideEffects({\n dataEngine: de,\n action: 'deleted',\n entity: address,\n identifiers: {\n id: address.id,\n organizationId: address.organizationId,\n tenantId: address.tenantId,\n },\n indexer: addressCrudIndexer,\n events: addressCrudEvents,\n })\n return { addressId: address.id }\n },\n buildLog: async ({ snapshots }) => {\n const before = snapshots.before as AddressSnapshot | undefined\n if (!before) return null\n const { translate } = await resolveTranslations()\n return {\n actionLabel: translate('customers.audit.addresses.delete', 'Delete address'),\n resourceKind: 'customers.address',\n resourceId: before.id,\n parentResourceKind: resolveParentResourceKind(before.entityKind),\n parentResourceId: before.entityId ?? null,\n tenantId: before.tenantId,\n organizationId: before.organizationId,\n snapshotBefore: before,\n payload: {\n undo: {\n before,\n } satisfies AddressUndoPayload,\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<AddressUndoPayload>(logEntry)\n const before = payload?.before\n if (!before) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const entity = await requireCustomerEntity(em, before.entityId, { tenantId: before.tenantId, organizationId: before.organizationId }, undefined, 'Customer not found')\n let address = await em.findOne(CustomerAddress, { id: before.id })\n if (!address) {\n address = em.create(CustomerAddress, {\n id: before.id,\n organizationId: before.organizationId,\n tenantId: before.tenantId,\n entity,\n name: before.name,\n purpose: before.purpose,\n companyName: before.companyName,\n addressLine1: before.addressLine1,\n addressLine2: before.addressLine2,\n buildingNumber: before.buildingNumber,\n flatNumber: before.flatNumber,\n city: before.city,\n region: before.region,\n postalCode: before.postalCode,\n country: before.country,\n latitude: before.latitude,\n longitude: before.longitude,\n isPrimary: before.isPrimary,\n createdAt: new Date(),\n updatedAt: new Date(),\n })\n em.persist(address)\n } else {\n address.entity = entity\n address.name = before.name\n address.purpose = before.purpose\n address.addressLine1 = before.addressLine1\n address.addressLine2 = before.addressLine2\n address.buildingNumber = before.buildingNumber\n address.flatNumber = before.flatNumber\n address.city = before.city\n address.region = before.region\n address.postalCode = before.postalCode\n address.country = before.country\n address.latitude = before.latitude\n address.longitude = before.longitude\n address.isPrimary = before.isPrimary\n }\n await withAtomicFlush(em, [\n async () => {\n em.persist(address)\n await em.flush()\n if (before.isPrimary) {\n await enforcePrimaryAddress(em, before.entityId, before.id)\n }\n },\n ], { transaction: true })\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n await emitCrudUndoSideEffects({\n dataEngine: de,\n action: 'created',\n entity: address,\n identifiers: {\n id: address.id,\n organizationId: address.organizationId,\n tenantId: address.tenantId,\n },\n indexer: addressCrudIndexer,\n events: addressCrudEvents,\n })\n },\n }\n\nregisterCommand(createAddressCommand)\nregisterCommand(updateAddressCommand)\nregisterCommand(deleteAddressCommand)\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { registerCommand } from '@open-mercato/shared/lib/commands'\nimport type { CommandHandler } from '@open-mercato/shared/lib/commands'\nimport { emitCrudSideEffects, emitCrudUndoSideEffects, buildChanges, requireId } from '@open-mercato/shared/lib/commands/helpers'\nimport type { DataEngine } from '@open-mercato/shared/lib/data/engine'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { CustomerAddress } from '../data/entities'\nimport { addressCreateSchema, addressUpdateSchema, type AddressCreateInput, type AddressUpdateInput } from '../data/validators'\nimport {\n ensureOrganizationScope,\n ensureTenantScope,\n requireCustomerEntity,\n ensureSameScope,\n extractUndoPayload,\n resolveParentResourceKind,\n} from './shared'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { CrudHttpError, notFound } from '@open-mercato/shared/lib/crud/errors'\nimport type { CrudIndexerConfig, CrudEventsConfig } from '@open-mercato/shared/lib/crud/types'\nimport { E } from '#generated/entities.ids.generated'\nimport { withAtomicFlush } from '@open-mercato/shared/lib/commands/flush'\nimport { resolveRedoSnapshot } from '@open-mercato/shared/lib/commands/redo'\nimport { findOneWithDecryption } from '@open-mercato/shared/lib/encryption/find'\n\nconst addressCrudIndexer: CrudIndexerConfig<CustomerAddress> = {\n entityType: E.customers.customer_address,\n}\n\nconst addressCrudEvents: CrudEventsConfig = {\n module: 'customers',\n entity: 'address',\n persistent: true,\n buildPayload: (ctx) => ({\n id: ctx.identifiers.id,\n organizationId: ctx.identifiers.organizationId,\n tenantId: ctx.identifiers.tenantId,\n }),\n}\n\ntype AddressSnapshot = {\n id: string\n organizationId: string\n tenantId: string\n entityId: string\n entityKind: string | null\n name: string | null\n purpose: string | null\n companyName: string | null\n addressLine1: string\n addressLine2: string | null\n buildingNumber: string | null\n flatNumber: string | null\n city: string | null\n region: string | null\n postalCode: string | null\n country: string | null\n latitude: number | null\n longitude: number | null\n isPrimary: boolean\n}\n\ntype AddressUndoPayload = {\n before?: AddressSnapshot | null\n after?: AddressSnapshot | null\n}\n\nasync function loadAddressSnapshot(em: EntityManager, id: string): Promise<AddressSnapshot | null> {\n const address = await em.findOne(CustomerAddress, { id }, { populate: ['entity'] })\n if (!address) return null\n const entityRef = address.entity\n const entityKind = (typeof entityRef === 'object' && entityRef !== null && 'kind' in entityRef)\n ? (entityRef as { kind: string }).kind\n : null\n return {\n id: address.id,\n organizationId: address.organizationId,\n tenantId: address.tenantId,\n entityId: typeof entityRef === 'string' ? entityRef : entityRef.id,\n entityKind,\n name: address.name ?? null,\n purpose: address.purpose ?? null,\n companyName: address.companyName ?? null,\n addressLine1: address.addressLine1,\n addressLine2: address.addressLine2 ?? null,\n buildingNumber: address.buildingNumber ?? null,\n flatNumber: address.flatNumber ?? null,\n city: address.city ?? null,\n region: address.region ?? null,\n postalCode: address.postalCode ?? null,\n country: address.country ?? null,\n latitude: address.latitude ?? null,\n longitude: address.longitude ?? null,\n isPrimary: address.isPrimary,\n }\n}\n\nasync function enforcePrimaryAddress(em: EntityManager, entityId: string, addressId: string): Promise<void> {\n await em.nativeUpdate(\n CustomerAddress,\n { entity: entityId, id: { $ne: addressId }, isPrimary: true },\n { isPrimary: false }\n )\n}\n\nconst createAddressCommand: CommandHandler<AddressCreateInput, { addressId: string }> = {\n id: 'customers.addresses.create',\n async execute(rawInput, ctx) {\n const parsed = addressCreateSchema.parse(rawInput)\n ensureTenantScope(ctx, parsed.tenantId)\n ensureOrganizationScope(ctx, parsed.organizationId)\n\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const entity = await requireCustomerEntity(em, parsed.entityId, { tenantId: parsed.tenantId, organizationId: parsed.organizationId }, undefined, 'Customer not found')\n ensureSameScope(entity, parsed.organizationId, parsed.tenantId)\n\n const address = em.create(CustomerAddress, {\n organizationId: parsed.organizationId,\n tenantId: parsed.tenantId,\n entity,\n name: parsed.name ?? null,\n purpose: parsed.purpose ?? null,\n companyName: parsed.companyName ?? null,\n addressLine1: parsed.addressLine1,\n addressLine2: parsed.addressLine2 ?? null,\n buildingNumber: parsed.buildingNumber ?? null,\n flatNumber: parsed.flatNumber ?? null,\n city: parsed.city ?? null,\n region: parsed.region ?? null,\n postalCode: parsed.postalCode ?? null,\n country: parsed.country ?? null,\n latitude: parsed.latitude ?? null,\n longitude: parsed.longitude ?? null,\n isPrimary: parsed.isPrimary ?? false,\n createdAt: new Date(),\n updatedAt: new Date(),\n })\n await withAtomicFlush(em, [\n async () => {\n em.persist(address)\n await em.flush()\n if (address.isPrimary) {\n await enforcePrimaryAddress(em, entity.id, address.id)\n }\n },\n ], { transaction: true })\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n await emitCrudSideEffects({\n dataEngine: de,\n action: 'created',\n entity: address,\n identifiers: {\n id: address.id,\n organizationId: address.organizationId,\n tenantId: address.tenantId,\n },\n indexer: addressCrudIndexer,\n events: addressCrudEvents,\n })\n\n return { addressId: address.id }\n },\n captureAfter: async (_input, result, ctx) => {\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return await loadAddressSnapshot(em, result.addressId)\n },\n buildLog: async ({ result, snapshots }) => {\n const { translate } = await resolveTranslations()\n const snapshot = snapshots.after as AddressSnapshot | undefined\n return {\n actionLabel: translate('customers.audit.addresses.create', 'Create address'),\n resourceKind: 'customers.address',\n resourceId: result.addressId,\n parentResourceKind: resolveParentResourceKind(snapshot?.entityKind),\n parentResourceId: snapshot?.entityId ?? null,\n tenantId: snapshot?.tenantId ?? null,\n organizationId: snapshot?.organizationId ?? null,\n snapshotAfter: snapshot ?? null,\n payload: {\n undo: {\n after: snapshot ?? null,\n } satisfies AddressUndoPayload,\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const addressId = logEntry?.resourceId ?? null\n if (!addressId) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const address = await em.findOne(CustomerAddress, { id: addressId })\n if (address) {\n em.remove(address)\n await em.flush()\n }\n },\n redo: async ({ logEntry, ctx }) => {\n const after = resolveRedoSnapshot<AddressSnapshot>(logEntry)\n if (!after) {\n throw new CrudHttpError(400, { error: '[internal] redo snapshot unavailable for address create' })\n }\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const entity = await requireCustomerEntity(em, after.entityId, { tenantId: after.tenantId, organizationId: after.organizationId }, undefined, 'Customer not found')\n let address = await findOneWithDecryption(\n em,\n CustomerAddress,\n { id: after.id },\n undefined,\n { tenantId: after.tenantId, organizationId: after.organizationId },\n )\n if (!address) {\n address = em.create(CustomerAddress, {\n id: after.id,\n organizationId: after.organizationId,\n tenantId: after.tenantId,\n entity,\n name: after.name,\n purpose: after.purpose,\n companyName: after.companyName,\n addressLine1: after.addressLine1,\n addressLine2: after.addressLine2,\n buildingNumber: after.buildingNumber,\n flatNumber: after.flatNumber,\n city: after.city,\n region: after.region,\n postalCode: after.postalCode,\n country: after.country,\n latitude: after.latitude,\n longitude: after.longitude,\n isPrimary: after.isPrimary,\n createdAt: new Date(),\n updatedAt: new Date(),\n })\n em.persist(address)\n } else {\n address.entity = entity\n address.name = after.name\n address.purpose = after.purpose\n address.companyName = after.companyName\n address.addressLine1 = after.addressLine1\n address.addressLine2 = after.addressLine2\n address.buildingNumber = after.buildingNumber\n address.flatNumber = after.flatNumber\n address.city = after.city\n address.region = after.region\n address.postalCode = after.postalCode\n address.country = after.country\n address.latitude = after.latitude\n address.longitude = after.longitude\n address.isPrimary = after.isPrimary\n }\n const restoredAddress = address\n await withAtomicFlush(em, [\n async () => {\n em.persist(restoredAddress)\n await em.flush()\n if (after.isPrimary) {\n await enforcePrimaryAddress(em, after.entityId, after.id)\n }\n },\n ], { transaction: true })\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n await emitCrudSideEffects({\n dataEngine: de,\n action: 'created',\n entity: restoredAddress,\n identifiers: {\n id: restoredAddress.id,\n organizationId: restoredAddress.organizationId,\n tenantId: restoredAddress.tenantId,\n },\n indexer: addressCrudIndexer,\n events: addressCrudEvents,\n })\n\n return { addressId: restoredAddress.id }\n },\n}\n\nconst updateAddressCommand: CommandHandler<AddressUpdateInput, { addressId: string }> = {\n id: 'customers.addresses.update',\n async prepare(rawInput, ctx) {\n const parsed = addressUpdateSchema.parse(rawInput)\n const em = (ctx.container.resolve('em') as EntityManager)\n const snapshot = await loadAddressSnapshot(em, parsed.id)\n return snapshot ? { before: snapshot } : {}\n },\n async execute(rawInput, ctx) {\n const parsed = addressUpdateSchema.parse(rawInput)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const address = await em.findOne(CustomerAddress, { id: parsed.id })\n if (!address) throw notFound('Address not found')\n ensureTenantScope(ctx, address.tenantId)\n ensureOrganizationScope(ctx, address.organizationId)\n\n if (parsed.entityId !== undefined) {\n const entity = await requireCustomerEntity(em, parsed.entityId, { tenantId: address.tenantId, organizationId: address.organizationId }, undefined, 'Customer not found')\n ensureSameScope(entity, address.organizationId, address.tenantId)\n address.entity = entity\n }\n\n await withAtomicFlush(em, [\n () => {\n if (parsed.name !== undefined) address.name = parsed.name ?? null\n if (parsed.purpose !== undefined) address.purpose = parsed.purpose ?? null\n if (parsed.companyName !== undefined) address.companyName = parsed.companyName ?? null\n if (parsed.addressLine1 !== undefined) address.addressLine1 = parsed.addressLine1\n if (parsed.addressLine2 !== undefined) address.addressLine2 = parsed.addressLine2 ?? null\n if (parsed.buildingNumber !== undefined) address.buildingNumber = parsed.buildingNumber ?? null\n if (parsed.flatNumber !== undefined) address.flatNumber = parsed.flatNumber ?? null\n if (parsed.city !== undefined) address.city = parsed.city ?? null\n if (parsed.region !== undefined) address.region = parsed.region ?? null\n if (parsed.postalCode !== undefined) address.postalCode = parsed.postalCode ?? null\n if (parsed.country !== undefined) address.country = parsed.country ?? null\n if (parsed.latitude !== undefined) address.latitude = parsed.latitude ?? null\n if (parsed.longitude !== undefined) address.longitude = parsed.longitude ?? null\n if (parsed.isPrimary !== undefined) address.isPrimary = parsed.isPrimary\n },\n async () => {\n if (address.isPrimary) {\n await enforcePrimaryAddress(em, typeof address.entity === 'string' ? address.entity : address.entity.id, address.id)\n }\n },\n ], { transaction: true })\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n await emitCrudSideEffects({\n dataEngine: de,\n action: 'updated',\n entity: address,\n identifiers: {\n id: address.id,\n organizationId: address.organizationId,\n tenantId: address.tenantId,\n },\n indexer: addressCrudIndexer,\n events: addressCrudEvents,\n })\n\n return { addressId: address.id }\n },\n captureAfter: async (_input, result, ctx) => {\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return await loadAddressSnapshot(em, result.addressId)\n },\n buildLog: async ({ snapshots }) => {\n const { translate } = await resolveTranslations()\n const before = snapshots.before as AddressSnapshot | undefined\n if (!before) return null\n const afterSnapshot = snapshots.after as AddressSnapshot | undefined\n const changes =\n afterSnapshot && before\n ? buildChanges(\n before as unknown as Record<string, unknown>,\n afterSnapshot as unknown as Record<string, unknown>,\n [\n 'entityId',\n 'name',\n 'purpose',\n 'companyName',\n 'addressLine1',\n 'addressLine2',\n 'buildingNumber',\n 'flatNumber',\n 'city',\n 'region',\n 'postalCode',\n 'country',\n 'latitude',\n 'longitude',\n 'isPrimary',\n ]\n )\n : {}\n return {\n actionLabel: translate('customers.audit.addresses.update', 'Update address'),\n resourceKind: 'customers.address',\n resourceId: before.id,\n parentResourceKind: resolveParentResourceKind(before.entityKind),\n parentResourceId: before.entityId ?? null,\n tenantId: before.tenantId,\n organizationId: before.organizationId,\n snapshotBefore: before,\n snapshotAfter: afterSnapshot ?? null,\n changes,\n payload: {\n undo: {\n before,\n after: afterSnapshot ?? null,\n } satisfies AddressUndoPayload,\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<AddressUndoPayload>(logEntry)\n const before = payload?.before\n if (!before) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n let address = await em.findOne(CustomerAddress, { id: before.id })\n const entity = await requireCustomerEntity(em, before.entityId, { tenantId: before.tenantId, organizationId: before.organizationId }, undefined, 'Customer not found')\n if (!address) {\n address = em.create(CustomerAddress, {\n id: before.id,\n organizationId: before.organizationId,\n tenantId: before.tenantId,\n entity,\n name: before.name,\n purpose: before.purpose,\n companyName: before.companyName,\n addressLine1: before.addressLine1,\n addressLine2: before.addressLine2,\n buildingNumber: before.buildingNumber,\n flatNumber: before.flatNumber,\n city: before.city,\n region: before.region,\n postalCode: before.postalCode,\n country: before.country,\n latitude: before.latitude,\n longitude: before.longitude,\n isPrimary: before.isPrimary,\n createdAt: new Date(),\n updatedAt: new Date(),\n })\n em.persist(address)\n } else {\n address.entity = entity\n address.name = before.name\n address.purpose = before.purpose\n address.companyName = before.companyName\n address.addressLine1 = before.addressLine1\n address.addressLine2 = before.addressLine2\n address.buildingNumber = before.buildingNumber\n address.flatNumber = before.flatNumber\n address.city = before.city\n address.region = before.region\n address.postalCode = before.postalCode\n address.country = before.country\n address.latitude = before.latitude\n address.longitude = before.longitude\n address.isPrimary = before.isPrimary\n }\n await withAtomicFlush(em, [\n async () => {\n em.persist(address)\n await em.flush()\n if (before.isPrimary) {\n await enforcePrimaryAddress(em, before.entityId, before.id)\n }\n },\n ], { transaction: true })\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n await emitCrudUndoSideEffects({\n dataEngine: de,\n action: 'updated',\n entity: address,\n identifiers: {\n id: address.id,\n organizationId: address.organizationId,\n tenantId: address.tenantId,\n },\n indexer: addressCrudIndexer,\n events: addressCrudEvents,\n })\n },\n}\n\nconst deleteAddressCommand: CommandHandler<{ body?: Record<string, unknown>; query?: Record<string, unknown> }, { addressId: string }> =\n {\n id: 'customers.addresses.delete',\n async prepare(input, ctx) {\n const id = requireId(input, 'Address id required')\n const em = (ctx.container.resolve('em') as EntityManager)\n const snapshot = await loadAddressSnapshot(em, id)\n return snapshot ? { before: snapshot } : {}\n },\n async execute(input, ctx) {\n const id = requireId(input, 'Address id required')\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const address = await em.findOne(CustomerAddress, { id })\n if (!address) throw notFound('Address not found')\n ensureTenantScope(ctx, address.tenantId)\n ensureOrganizationScope(ctx, address.organizationId)\n em.remove(address)\n await em.flush()\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n await emitCrudSideEffects({\n dataEngine: de,\n action: 'deleted',\n entity: address,\n identifiers: {\n id: address.id,\n organizationId: address.organizationId,\n tenantId: address.tenantId,\n },\n indexer: addressCrudIndexer,\n events: addressCrudEvents,\n })\n return { addressId: address.id }\n },\n buildLog: async ({ snapshots }) => {\n const before = snapshots.before as AddressSnapshot | undefined\n if (!before) return null\n const { translate } = await resolveTranslations()\n return {\n actionLabel: translate('customers.audit.addresses.delete', 'Delete address'),\n resourceKind: 'customers.address',\n resourceId: before.id,\n parentResourceKind: resolveParentResourceKind(before.entityKind),\n parentResourceId: before.entityId ?? null,\n tenantId: before.tenantId,\n organizationId: before.organizationId,\n snapshotBefore: before,\n payload: {\n undo: {\n before,\n } satisfies AddressUndoPayload,\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<AddressUndoPayload>(logEntry)\n const before = payload?.before\n if (!before) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const entity = await requireCustomerEntity(em, before.entityId, { tenantId: before.tenantId, organizationId: before.organizationId }, undefined, 'Customer not found')\n let address = await em.findOne(CustomerAddress, { id: before.id })\n if (!address) {\n address = em.create(CustomerAddress, {\n id: before.id,\n organizationId: before.organizationId,\n tenantId: before.tenantId,\n entity,\n name: before.name,\n purpose: before.purpose,\n companyName: before.companyName,\n addressLine1: before.addressLine1,\n addressLine2: before.addressLine2,\n buildingNumber: before.buildingNumber,\n flatNumber: before.flatNumber,\n city: before.city,\n region: before.region,\n postalCode: before.postalCode,\n country: before.country,\n latitude: before.latitude,\n longitude: before.longitude,\n isPrimary: before.isPrimary,\n createdAt: new Date(),\n updatedAt: new Date(),\n })\n em.persist(address)\n } else {\n address.entity = entity\n address.name = before.name\n address.purpose = before.purpose\n address.addressLine1 = before.addressLine1\n address.addressLine2 = before.addressLine2\n address.buildingNumber = before.buildingNumber\n address.flatNumber = before.flatNumber\n address.city = before.city\n address.region = before.region\n address.postalCode = before.postalCode\n address.country = before.country\n address.latitude = before.latitude\n address.longitude = before.longitude\n address.isPrimary = before.isPrimary\n }\n await withAtomicFlush(em, [\n async () => {\n em.persist(address)\n await em.flush()\n if (before.isPrimary) {\n await enforcePrimaryAddress(em, before.entityId, before.id)\n }\n },\n ], { transaction: true })\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n await emitCrudUndoSideEffects({\n dataEngine: de,\n action: 'created',\n entity: address,\n identifiers: {\n id: address.id,\n organizationId: address.organizationId,\n tenantId: address.tenantId,\n },\n indexer: addressCrudIndexer,\n events: addressCrudEvents,\n })\n },\n }\n\nregisterCommand(createAddressCommand)\nregisterCommand(updateAddressCommand)\nregisterCommand(deleteAddressCommand)\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -12,7 +12,7 @@ import {
12
12
  resolveParentResourceKind
13
13
  } from "./shared.js";
14
14
  import { resolveTranslations } from "@open-mercato/shared/lib/i18n/server";
15
- import { CrudHttpError } from "@open-mercato/shared/lib/crud/errors";
15
+ import { notFound } from "@open-mercato/shared/lib/crud/errors";
16
16
  import { E } from "../../../generated/entities.ids.generated.js";
17
17
  import { makeCreateRedo } from "@open-mercato/shared/lib/commands/redo";
18
18
  import { findOneWithDecryption } from "@open-mercato/shared/lib/encryption/find";
@@ -162,7 +162,7 @@ const updateCommentCommand = {
162
162
  const parsed = commentUpdateSchema.parse(rawInput);
163
163
  const em = ctx.container.resolve("em").fork();
164
164
  const comment = await em.findOne(CustomerComment, { id: parsed.id });
165
- if (!comment) throw new CrudHttpError(404, { error: "Comment not found" });
165
+ if (!comment) throw notFound("Comment not found");
166
166
  ensureTenantScope(ctx, comment.tenantId);
167
167
  ensureOrganizationScope(ctx, comment.organizationId);
168
168
  if (parsed.entityId !== void 0) {
@@ -287,7 +287,7 @@ const deleteCommentCommand = {
287
287
  const id = requireId(input, "Comment id required");
288
288
  const em = ctx.container.resolve("em").fork();
289
289
  const comment = await em.findOne(CustomerComment, { id });
290
- if (!comment) throw new CrudHttpError(404, { error: "Comment not found" });
290
+ if (!comment) throw notFound("Comment not found");
291
291
  ensureTenantScope(ctx, comment.tenantId);
292
292
  ensureOrganizationScope(ctx, comment.organizationId);
293
293
  em.remove(comment);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/modules/customers/commands/comments.ts"],
4
- "sourcesContent": ["import { registerCommand } from '@open-mercato/shared/lib/commands'\nimport type { CommandHandler } from '@open-mercato/shared/lib/commands'\nimport { emitCrudSideEffects, emitCrudUndoSideEffects, buildChanges, requireId, normalizeAuthorUserId } from '@open-mercato/shared/lib/commands/helpers'\nimport type { DataEngine } from '@open-mercato/shared/lib/data/engine'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { CustomerComment } from '../data/entities'\nimport { commentCreateSchema, commentUpdateSchema, type CommentCreateInput, type CommentUpdateInput } from '../data/validators'\nimport {\n ensureOrganizationScope,\n ensureTenantScope,\n requireTimelineParentEntity,\n ensureSameScope,\n extractUndoPayload,\n requireDealInScope,\n resolveParentResourceKind,\n} from './shared'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport type { CrudIndexerConfig, CrudEventsConfig } from '@open-mercato/shared/lib/crud/types'\nimport { E } from '#generated/entities.ids.generated'\nimport { makeCreateRedo } from '@open-mercato/shared/lib/commands/redo'\nimport { findOneWithDecryption } from '@open-mercato/shared/lib/encryption/find'\n\nconst commentCrudIndexer: CrudIndexerConfig<CustomerComment> = {\n entityType: E.customers.customer_comment,\n}\n\nconst commentCrudEvents: CrudEventsConfig = {\n module: 'customers',\n entity: 'comment',\n persistent: true,\n buildPayload: (ctx) => ({\n id: ctx.identifiers.id,\n organizationId: ctx.identifiers.organizationId,\n tenantId: ctx.identifiers.tenantId,\n }),\n}\n\ntype CommentSnapshot = {\n id: string\n organizationId: string\n tenantId: string\n entityId: string\n entityKind: string | null\n dealId: string | null\n body: string\n authorUserId: string | null\n appearanceIcon: string | null\n appearanceColor: string | null\n}\n\ntype CommentUndoPayload = {\n before?: CommentSnapshot | null\n after?: CommentSnapshot | null\n}\n\nasync function loadCommentSnapshot(em: EntityManager, id: string): Promise<CommentSnapshot | null> {\n const comment = await em.findOne(CustomerComment, { id }, { populate: ['entity'] })\n if (!comment) return null\n const entityRef = comment.entity\n const entityKind = (typeof entityRef === 'object' && entityRef !== null && 'kind' in entityRef)\n ? (entityRef as { kind: string }).kind\n : null\n return {\n id: comment.id,\n organizationId: comment.organizationId,\n tenantId: comment.tenantId,\n entityId: typeof entityRef === 'string' ? entityRef : entityRef.id,\n entityKind,\n dealId: comment.deal ? (typeof comment.deal === 'string' ? comment.deal : comment.deal.id) : null,\n body: comment.body,\n authorUserId: comment.authorUserId ?? null,\n appearanceIcon: comment.appearanceIcon ?? null,\n appearanceColor: comment.appearanceColor ?? null,\n }\n}\n\nconst createCommentCommand: CommandHandler<CommentCreateInput, { commentId: string; authorUserId: string | null }> = {\n id: 'customers.comments.create',\n async execute(rawInput, ctx) {\n const parsed = commentCreateSchema.parse(rawInput)\n ensureTenantScope(ctx, parsed.tenantId)\n ensureOrganizationScope(ctx, parsed.organizationId)\n const normalizedAuthor = normalizeAuthorUserId(parsed.authorUserId, ctx.auth)\n\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const entity = await requireTimelineParentEntity(em, parsed.entityId, { tenantId: parsed.tenantId, organizationId: parsed.organizationId })\n ensureSameScope(entity, parsed.organizationId, parsed.tenantId)\n const deal = await requireDealInScope(em, parsed.dealId, parsed.tenantId, parsed.organizationId)\n\n const comment = em.create(CustomerComment, {\n organizationId: parsed.organizationId,\n tenantId: parsed.tenantId,\n entity,\n deal,\n body: parsed.body,\n authorUserId: normalizedAuthor,\n appearanceIcon: parsed.appearanceIcon ?? null,\n appearanceColor: parsed.appearanceColor ?? null,\n createdAt: new Date(),\n updatedAt: new Date(),\n })\n em.persist(comment)\n await em.flush()\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n await emitCrudSideEffects({\n dataEngine: de,\n action: 'created',\n entity: comment,\n identifiers: {\n id: comment.id,\n organizationId: comment.organizationId,\n tenantId: comment.tenantId,\n },\n indexer: commentCrudIndexer,\n events: commentCrudEvents,\n })\n\n return { commentId: comment.id, authorUserId: comment.authorUserId ?? null }\n },\n captureAfter: async (_input, result, ctx) => {\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return await loadCommentSnapshot(em, result.commentId)\n },\n buildLog: async ({ result, snapshots }) => {\n const { translate } = await resolveTranslations()\n const snapshot = snapshots.after as CommentSnapshot | undefined\n return {\n actionLabel: translate('customers.audit.comments.create', 'Create note'),\n resourceKind: 'customers.comment',\n resourceId: result.commentId,\n parentResourceKind: snapshot?.entityId ? resolveParentResourceKind(snapshot.entityKind) : (snapshot?.dealId ? 'customers.deal' : null),\n parentResourceId: snapshot?.entityId ?? snapshot?.dealId ?? null,\n tenantId: snapshot?.tenantId ?? null,\n organizationId: snapshot?.organizationId ?? null,\n snapshotAfter: snapshot ?? null,\n relatedResourceKind: snapshot?.dealId ? 'customers.deal' : null,\n relatedResourceId: snapshot?.dealId ?? null,\n payload: {\n undo: {\n after: snapshot ?? null,\n } satisfies CommentUndoPayload,\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const commentId = logEntry?.resourceId ?? null\n if (!commentId) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const existing = await em.findOne(CustomerComment, { id: commentId })\n if (existing) {\n em.remove(existing)\n await em.flush()\n }\n },\n redo: makeCreateRedo<CustomerComment, CommentSnapshot, CommentCreateInput, { commentId: string; authorUserId: string | null }>({\n entityClass: CustomerComment,\n indexer: commentCrudIndexer,\n events: commentCrudEvents,\n findRow: ({ em, id, snapshot }) =>\n findOneWithDecryption(\n em,\n CustomerComment,\n { id },\n undefined,\n { tenantId: snapshot.tenantId, organizationId: snapshot.organizationId },\n ),\n seedFromSnapshot: (snapshot) => ({\n id: snapshot.id,\n organizationId: snapshot.organizationId,\n tenantId: snapshot.tenantId,\n body: snapshot.body,\n authorUserId: snapshot.authorUserId,\n appearanceIcon: snapshot.appearanceIcon,\n appearanceColor: snapshot.appearanceColor,\n }),\n beforeRestore: async ({ em, snapshot }) => {\n const entity = await requireTimelineParentEntity(em, snapshot.entityId, { tenantId: snapshot.tenantId, organizationId: snapshot.organizationId })\n const deal = await requireDealInScope(em, snapshot.dealId, snapshot.tenantId, snapshot.organizationId)\n return { entity, deal }\n },\n buildResult: (entity) => ({ commentId: entity.id, authorUserId: entity.authorUserId ?? null }),\n }),\n}\n\nconst updateCommentCommand: CommandHandler<CommentUpdateInput, { commentId: string }> = {\n id: 'customers.comments.update',\n async prepare(rawInput, ctx) {\n const parsed = commentUpdateSchema.parse(rawInput)\n const em = (ctx.container.resolve('em') as EntityManager)\n const snapshot = await loadCommentSnapshot(em, parsed.id)\n return snapshot ? { before: snapshot } : {}\n },\n async execute(rawInput, ctx) {\n const parsed = commentUpdateSchema.parse(rawInput)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const comment = await em.findOne(CustomerComment, { id: parsed.id })\n if (!comment) throw new CrudHttpError(404, { error: 'Comment not found' })\n ensureTenantScope(ctx, comment.tenantId)\n ensureOrganizationScope(ctx, comment.organizationId)\n\n if (parsed.entityId !== undefined) {\n const entity = await requireTimelineParentEntity(em, parsed.entityId, { tenantId: comment.tenantId, organizationId: comment.organizationId })\n ensureSameScope(entity, comment.organizationId, comment.tenantId)\n comment.entity = entity\n }\n if (parsed.dealId !== undefined) {\n comment.deal = await requireDealInScope(em, parsed.dealId, comment.tenantId, comment.organizationId)\n }\n if (parsed.body !== undefined) comment.body = parsed.body\n if (parsed.authorUserId !== undefined) comment.authorUserId = parsed.authorUserId ?? null\n if (parsed.appearanceIcon !== undefined) comment.appearanceIcon = parsed.appearanceIcon ?? null\n if (parsed.appearanceColor !== undefined) comment.appearanceColor = parsed.appearanceColor ?? null\n\n await em.flush()\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n await emitCrudSideEffects({\n dataEngine: de,\n action: 'updated',\n entity: comment,\n identifiers: {\n id: comment.id,\n organizationId: comment.organizationId,\n tenantId: comment.tenantId,\n },\n indexer: commentCrudIndexer,\n events: commentCrudEvents,\n })\n\n return { commentId: comment.id }\n },\n captureAfter: async (_input, result, ctx) => {\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return await loadCommentSnapshot(em, result.commentId)\n },\n buildLog: async ({ snapshots }) => {\n const { translate } = await resolveTranslations()\n const before = snapshots.before as CommentSnapshot | undefined\n if (!before) return null\n const afterSnapshot = snapshots.after as CommentSnapshot | undefined\n const changes =\n afterSnapshot && before\n ? buildChanges(\n before as unknown as Record<string, unknown>,\n afterSnapshot as unknown as Record<string, unknown>,\n ['entityId', 'dealId', 'body', 'authorUserId', 'appearanceIcon', 'appearanceColor']\n )\n : {}\n return {\n actionLabel: translate('customers.audit.comments.update', 'Update note'),\n resourceKind: 'customers.comment',\n resourceId: before.id,\n parentResourceKind: before.entityId ? resolveParentResourceKind(before.entityKind) : (before.dealId ? 'customers.deal' : null),\n parentResourceId: before.entityId ?? before.dealId ?? null,\n tenantId: before.tenantId,\n organizationId: before.organizationId,\n snapshotBefore: before,\n snapshotAfter: afterSnapshot ?? null,\n relatedResourceKind: (afterSnapshot?.dealId ?? before.dealId) ? 'customers.deal' : null,\n relatedResourceId: afterSnapshot?.dealId ?? before.dealId ?? null,\n changes,\n payload: {\n undo: {\n before,\n after: afterSnapshot ?? null,\n } satisfies CommentUndoPayload,\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<CommentUndoPayload>(logEntry)\n const before = payload?.before\n if (!before) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n let comment = await em.findOne(CustomerComment, { id: before.id })\n const entity = await requireTimelineParentEntity(em, before.entityId, { tenantId: before.tenantId, organizationId: before.organizationId })\n const deal = await requireDealInScope(em, before.dealId, before.tenantId, before.organizationId)\n\n if (!comment) {\n comment = em.create(CustomerComment, {\n id: before.id,\n organizationId: before.organizationId,\n tenantId: before.tenantId,\n entity,\n deal,\n body: before.body,\n authorUserId: before.authorUserId,\n appearanceIcon: before.appearanceIcon,\n appearanceColor: before.appearanceColor,\n createdAt: new Date(),\n updatedAt: new Date(),\n })\n em.persist(comment)\n } else {\n comment.entity = entity\n comment.deal = deal\n comment.body = before.body\n comment.authorUserId = before.authorUserId\n comment.appearanceIcon = before.appearanceIcon\n comment.appearanceColor = before.appearanceColor\n }\n await em.flush()\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n await emitCrudUndoSideEffects({\n dataEngine: de,\n action: 'updated',\n entity: comment,\n identifiers: {\n id: comment.id,\n organizationId: comment.organizationId,\n tenantId: comment.tenantId,\n },\n indexer: commentCrudIndexer,\n events: commentCrudEvents,\n })\n },\n}\n\nconst deleteCommentCommand: CommandHandler<{ body?: Record<string, unknown>; query?: Record<string, unknown> }, { commentId: string }> =\n {\n id: 'customers.comments.delete',\n async prepare(input, ctx) {\n const id = requireId(input, 'Comment id required')\n const em = (ctx.container.resolve('em') as EntityManager)\n const snapshot = await loadCommentSnapshot(em, id)\n return snapshot ? { before: snapshot } : {}\n },\n async execute(input, ctx) {\n const id = requireId(input, 'Comment id required')\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const comment = await em.findOne(CustomerComment, { id })\n if (!comment) throw new CrudHttpError(404, { error: 'Comment not found' })\n ensureTenantScope(ctx, comment.tenantId)\n ensureOrganizationScope(ctx, comment.organizationId)\n em.remove(comment)\n await em.flush()\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n await emitCrudSideEffects({\n dataEngine: de,\n action: 'deleted',\n entity: comment,\n identifiers: {\n id: comment.id,\n organizationId: comment.organizationId,\n tenantId: comment.tenantId,\n },\n indexer: commentCrudIndexer,\n events: commentCrudEvents,\n })\n return { commentId: comment.id }\n },\n buildLog: async ({ snapshots }) => {\n const before = snapshots.before as CommentSnapshot | undefined\n if (!before) return null\n const { translate } = await resolveTranslations()\n return {\n actionLabel: translate('customers.audit.comments.delete', 'Delete note'),\n resourceKind: 'customers.comment',\n resourceId: before.id,\n parentResourceKind: before.entityId ? resolveParentResourceKind(before.entityKind) : (before.dealId ? 'customers.deal' : null),\n parentResourceId: before.entityId ?? before.dealId ?? null,\n tenantId: before.tenantId,\n organizationId: before.organizationId,\n snapshotBefore: before,\n relatedResourceKind: before.dealId ? 'customers.deal' : null,\n relatedResourceId: before.dealId ?? null,\n payload: {\n undo: {\n before,\n } satisfies CommentUndoPayload,\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<CommentUndoPayload>(logEntry)\n const before = payload?.before\n if (!before) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const entity = await requireTimelineParentEntity(em, before.entityId, { tenantId: before.tenantId, organizationId: before.organizationId })\n const deal = await requireDealInScope(em, before.dealId, before.tenantId, before.organizationId)\n let comment = await em.findOne(CustomerComment, { id: before.id })\n if (!comment) {\n comment = em.create(CustomerComment, {\n id: before.id,\n organizationId: before.organizationId,\n tenantId: before.tenantId,\n entity,\n deal,\n body: before.body,\n authorUserId: before.authorUserId,\n appearanceIcon: before.appearanceIcon,\n appearanceColor: before.appearanceColor,\n createdAt: new Date(),\n updatedAt: new Date(),\n })\n em.persist(comment)\n } else {\n comment.entity = entity\n comment.deal = deal\n comment.body = before.body\n comment.authorUserId = before.authorUserId\n comment.appearanceIcon = before.appearanceIcon\n comment.appearanceColor = before.appearanceColor\n }\n await em.flush()\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n await emitCrudUndoSideEffects({\n dataEngine: de,\n action: 'created',\n entity: comment,\n identifiers: {\n id: comment.id,\n organizationId: comment.organizationId,\n tenantId: comment.tenantId,\n },\n indexer: commentCrudIndexer,\n events: commentCrudEvents,\n })\n },\n }\n\nregisterCommand(createCommentCommand)\nregisterCommand(updateCommentCommand)\nregisterCommand(deleteCommentCommand)\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { registerCommand } from '@open-mercato/shared/lib/commands'\nimport type { CommandHandler } from '@open-mercato/shared/lib/commands'\nimport { emitCrudSideEffects, emitCrudUndoSideEffects, buildChanges, requireId, normalizeAuthorUserId } from '@open-mercato/shared/lib/commands/helpers'\nimport type { DataEngine } from '@open-mercato/shared/lib/data/engine'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport { CustomerComment } from '../data/entities'\nimport { commentCreateSchema, commentUpdateSchema, type CommentCreateInput, type CommentUpdateInput } from '../data/validators'\nimport {\n ensureOrganizationScope,\n ensureTenantScope,\n requireTimelineParentEntity,\n ensureSameScope,\n extractUndoPayload,\n requireDealInScope,\n resolveParentResourceKind,\n} from './shared'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { notFound } from '@open-mercato/shared/lib/crud/errors'\nimport type { CrudIndexerConfig, CrudEventsConfig } from '@open-mercato/shared/lib/crud/types'\nimport { E } from '#generated/entities.ids.generated'\nimport { makeCreateRedo } from '@open-mercato/shared/lib/commands/redo'\nimport { findOneWithDecryption } from '@open-mercato/shared/lib/encryption/find'\n\nconst commentCrudIndexer: CrudIndexerConfig<CustomerComment> = {\n entityType: E.customers.customer_comment,\n}\n\nconst commentCrudEvents: CrudEventsConfig = {\n module: 'customers',\n entity: 'comment',\n persistent: true,\n buildPayload: (ctx) => ({\n id: ctx.identifiers.id,\n organizationId: ctx.identifiers.organizationId,\n tenantId: ctx.identifiers.tenantId,\n }),\n}\n\ntype CommentSnapshot = {\n id: string\n organizationId: string\n tenantId: string\n entityId: string\n entityKind: string | null\n dealId: string | null\n body: string\n authorUserId: string | null\n appearanceIcon: string | null\n appearanceColor: string | null\n}\n\ntype CommentUndoPayload = {\n before?: CommentSnapshot | null\n after?: CommentSnapshot | null\n}\n\nasync function loadCommentSnapshot(em: EntityManager, id: string): Promise<CommentSnapshot | null> {\n const comment = await em.findOne(CustomerComment, { id }, { populate: ['entity'] })\n if (!comment) return null\n const entityRef = comment.entity\n const entityKind = (typeof entityRef === 'object' && entityRef !== null && 'kind' in entityRef)\n ? (entityRef as { kind: string }).kind\n : null\n return {\n id: comment.id,\n organizationId: comment.organizationId,\n tenantId: comment.tenantId,\n entityId: typeof entityRef === 'string' ? entityRef : entityRef.id,\n entityKind,\n dealId: comment.deal ? (typeof comment.deal === 'string' ? comment.deal : comment.deal.id) : null,\n body: comment.body,\n authorUserId: comment.authorUserId ?? null,\n appearanceIcon: comment.appearanceIcon ?? null,\n appearanceColor: comment.appearanceColor ?? null,\n }\n}\n\nconst createCommentCommand: CommandHandler<CommentCreateInput, { commentId: string; authorUserId: string | null }> = {\n id: 'customers.comments.create',\n async execute(rawInput, ctx) {\n const parsed = commentCreateSchema.parse(rawInput)\n ensureTenantScope(ctx, parsed.tenantId)\n ensureOrganizationScope(ctx, parsed.organizationId)\n const normalizedAuthor = normalizeAuthorUserId(parsed.authorUserId, ctx.auth)\n\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const entity = await requireTimelineParentEntity(em, parsed.entityId, { tenantId: parsed.tenantId, organizationId: parsed.organizationId })\n ensureSameScope(entity, parsed.organizationId, parsed.tenantId)\n const deal = await requireDealInScope(em, parsed.dealId, parsed.tenantId, parsed.organizationId)\n\n const comment = em.create(CustomerComment, {\n organizationId: parsed.organizationId,\n tenantId: parsed.tenantId,\n entity,\n deal,\n body: parsed.body,\n authorUserId: normalizedAuthor,\n appearanceIcon: parsed.appearanceIcon ?? null,\n appearanceColor: parsed.appearanceColor ?? null,\n createdAt: new Date(),\n updatedAt: new Date(),\n })\n em.persist(comment)\n await em.flush()\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n await emitCrudSideEffects({\n dataEngine: de,\n action: 'created',\n entity: comment,\n identifiers: {\n id: comment.id,\n organizationId: comment.organizationId,\n tenantId: comment.tenantId,\n },\n indexer: commentCrudIndexer,\n events: commentCrudEvents,\n })\n\n return { commentId: comment.id, authorUserId: comment.authorUserId ?? null }\n },\n captureAfter: async (_input, result, ctx) => {\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return await loadCommentSnapshot(em, result.commentId)\n },\n buildLog: async ({ result, snapshots }) => {\n const { translate } = await resolveTranslations()\n const snapshot = snapshots.after as CommentSnapshot | undefined\n return {\n actionLabel: translate('customers.audit.comments.create', 'Create note'),\n resourceKind: 'customers.comment',\n resourceId: result.commentId,\n parentResourceKind: snapshot?.entityId ? resolveParentResourceKind(snapshot.entityKind) : (snapshot?.dealId ? 'customers.deal' : null),\n parentResourceId: snapshot?.entityId ?? snapshot?.dealId ?? null,\n tenantId: snapshot?.tenantId ?? null,\n organizationId: snapshot?.organizationId ?? null,\n snapshotAfter: snapshot ?? null,\n relatedResourceKind: snapshot?.dealId ? 'customers.deal' : null,\n relatedResourceId: snapshot?.dealId ?? null,\n payload: {\n undo: {\n after: snapshot ?? null,\n } satisfies CommentUndoPayload,\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const commentId = logEntry?.resourceId ?? null\n if (!commentId) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const existing = await em.findOne(CustomerComment, { id: commentId })\n if (existing) {\n em.remove(existing)\n await em.flush()\n }\n },\n redo: makeCreateRedo<CustomerComment, CommentSnapshot, CommentCreateInput, { commentId: string; authorUserId: string | null }>({\n entityClass: CustomerComment,\n indexer: commentCrudIndexer,\n events: commentCrudEvents,\n findRow: ({ em, id, snapshot }) =>\n findOneWithDecryption(\n em,\n CustomerComment,\n { id },\n undefined,\n { tenantId: snapshot.tenantId, organizationId: snapshot.organizationId },\n ),\n seedFromSnapshot: (snapshot) => ({\n id: snapshot.id,\n organizationId: snapshot.organizationId,\n tenantId: snapshot.tenantId,\n body: snapshot.body,\n authorUserId: snapshot.authorUserId,\n appearanceIcon: snapshot.appearanceIcon,\n appearanceColor: snapshot.appearanceColor,\n }),\n beforeRestore: async ({ em, snapshot }) => {\n const entity = await requireTimelineParentEntity(em, snapshot.entityId, { tenantId: snapshot.tenantId, organizationId: snapshot.organizationId })\n const deal = await requireDealInScope(em, snapshot.dealId, snapshot.tenantId, snapshot.organizationId)\n return { entity, deal }\n },\n buildResult: (entity) => ({ commentId: entity.id, authorUserId: entity.authorUserId ?? null }),\n }),\n}\n\nconst updateCommentCommand: CommandHandler<CommentUpdateInput, { commentId: string }> = {\n id: 'customers.comments.update',\n async prepare(rawInput, ctx) {\n const parsed = commentUpdateSchema.parse(rawInput)\n const em = (ctx.container.resolve('em') as EntityManager)\n const snapshot = await loadCommentSnapshot(em, parsed.id)\n return snapshot ? { before: snapshot } : {}\n },\n async execute(rawInput, ctx) {\n const parsed = commentUpdateSchema.parse(rawInput)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const comment = await em.findOne(CustomerComment, { id: parsed.id })\n if (!comment) throw notFound('Comment not found')\n ensureTenantScope(ctx, comment.tenantId)\n ensureOrganizationScope(ctx, comment.organizationId)\n\n if (parsed.entityId !== undefined) {\n const entity = await requireTimelineParentEntity(em, parsed.entityId, { tenantId: comment.tenantId, organizationId: comment.organizationId })\n ensureSameScope(entity, comment.organizationId, comment.tenantId)\n comment.entity = entity\n }\n if (parsed.dealId !== undefined) {\n comment.deal = await requireDealInScope(em, parsed.dealId, comment.tenantId, comment.organizationId)\n }\n if (parsed.body !== undefined) comment.body = parsed.body\n if (parsed.authorUserId !== undefined) comment.authorUserId = parsed.authorUserId ?? null\n if (parsed.appearanceIcon !== undefined) comment.appearanceIcon = parsed.appearanceIcon ?? null\n if (parsed.appearanceColor !== undefined) comment.appearanceColor = parsed.appearanceColor ?? null\n\n await em.flush()\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n await emitCrudSideEffects({\n dataEngine: de,\n action: 'updated',\n entity: comment,\n identifiers: {\n id: comment.id,\n organizationId: comment.organizationId,\n tenantId: comment.tenantId,\n },\n indexer: commentCrudIndexer,\n events: commentCrudEvents,\n })\n\n return { commentId: comment.id }\n },\n captureAfter: async (_input, result, ctx) => {\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n return await loadCommentSnapshot(em, result.commentId)\n },\n buildLog: async ({ snapshots }) => {\n const { translate } = await resolveTranslations()\n const before = snapshots.before as CommentSnapshot | undefined\n if (!before) return null\n const afterSnapshot = snapshots.after as CommentSnapshot | undefined\n const changes =\n afterSnapshot && before\n ? buildChanges(\n before as unknown as Record<string, unknown>,\n afterSnapshot as unknown as Record<string, unknown>,\n ['entityId', 'dealId', 'body', 'authorUserId', 'appearanceIcon', 'appearanceColor']\n )\n : {}\n return {\n actionLabel: translate('customers.audit.comments.update', 'Update note'),\n resourceKind: 'customers.comment',\n resourceId: before.id,\n parentResourceKind: before.entityId ? resolveParentResourceKind(before.entityKind) : (before.dealId ? 'customers.deal' : null),\n parentResourceId: before.entityId ?? before.dealId ?? null,\n tenantId: before.tenantId,\n organizationId: before.organizationId,\n snapshotBefore: before,\n snapshotAfter: afterSnapshot ?? null,\n relatedResourceKind: (afterSnapshot?.dealId ?? before.dealId) ? 'customers.deal' : null,\n relatedResourceId: afterSnapshot?.dealId ?? before.dealId ?? null,\n changes,\n payload: {\n undo: {\n before,\n after: afterSnapshot ?? null,\n } satisfies CommentUndoPayload,\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<CommentUndoPayload>(logEntry)\n const before = payload?.before\n if (!before) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n let comment = await em.findOne(CustomerComment, { id: before.id })\n const entity = await requireTimelineParentEntity(em, before.entityId, { tenantId: before.tenantId, organizationId: before.organizationId })\n const deal = await requireDealInScope(em, before.dealId, before.tenantId, before.organizationId)\n\n if (!comment) {\n comment = em.create(CustomerComment, {\n id: before.id,\n organizationId: before.organizationId,\n tenantId: before.tenantId,\n entity,\n deal,\n body: before.body,\n authorUserId: before.authorUserId,\n appearanceIcon: before.appearanceIcon,\n appearanceColor: before.appearanceColor,\n createdAt: new Date(),\n updatedAt: new Date(),\n })\n em.persist(comment)\n } else {\n comment.entity = entity\n comment.deal = deal\n comment.body = before.body\n comment.authorUserId = before.authorUserId\n comment.appearanceIcon = before.appearanceIcon\n comment.appearanceColor = before.appearanceColor\n }\n await em.flush()\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n await emitCrudUndoSideEffects({\n dataEngine: de,\n action: 'updated',\n entity: comment,\n identifiers: {\n id: comment.id,\n organizationId: comment.organizationId,\n tenantId: comment.tenantId,\n },\n indexer: commentCrudIndexer,\n events: commentCrudEvents,\n })\n },\n}\n\nconst deleteCommentCommand: CommandHandler<{ body?: Record<string, unknown>; query?: Record<string, unknown> }, { commentId: string }> =\n {\n id: 'customers.comments.delete',\n async prepare(input, ctx) {\n const id = requireId(input, 'Comment id required')\n const em = (ctx.container.resolve('em') as EntityManager)\n const snapshot = await loadCommentSnapshot(em, id)\n return snapshot ? { before: snapshot } : {}\n },\n async execute(input, ctx) {\n const id = requireId(input, 'Comment id required')\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const comment = await em.findOne(CustomerComment, { id })\n if (!comment) throw notFound('Comment not found')\n ensureTenantScope(ctx, comment.tenantId)\n ensureOrganizationScope(ctx, comment.organizationId)\n em.remove(comment)\n await em.flush()\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n await emitCrudSideEffects({\n dataEngine: de,\n action: 'deleted',\n entity: comment,\n identifiers: {\n id: comment.id,\n organizationId: comment.organizationId,\n tenantId: comment.tenantId,\n },\n indexer: commentCrudIndexer,\n events: commentCrudEvents,\n })\n return { commentId: comment.id }\n },\n buildLog: async ({ snapshots }) => {\n const before = snapshots.before as CommentSnapshot | undefined\n if (!before) return null\n const { translate } = await resolveTranslations()\n return {\n actionLabel: translate('customers.audit.comments.delete', 'Delete note'),\n resourceKind: 'customers.comment',\n resourceId: before.id,\n parentResourceKind: before.entityId ? resolveParentResourceKind(before.entityKind) : (before.dealId ? 'customers.deal' : null),\n parentResourceId: before.entityId ?? before.dealId ?? null,\n tenantId: before.tenantId,\n organizationId: before.organizationId,\n snapshotBefore: before,\n relatedResourceKind: before.dealId ? 'customers.deal' : null,\n relatedResourceId: before.dealId ?? null,\n payload: {\n undo: {\n before,\n } satisfies CommentUndoPayload,\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<CommentUndoPayload>(logEntry)\n const before = payload?.before\n if (!before) return\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const entity = await requireTimelineParentEntity(em, before.entityId, { tenantId: before.tenantId, organizationId: before.organizationId })\n const deal = await requireDealInScope(em, before.dealId, before.tenantId, before.organizationId)\n let comment = await em.findOne(CustomerComment, { id: before.id })\n if (!comment) {\n comment = em.create(CustomerComment, {\n id: before.id,\n organizationId: before.organizationId,\n tenantId: before.tenantId,\n entity,\n deal,\n body: before.body,\n authorUserId: before.authorUserId,\n appearanceIcon: before.appearanceIcon,\n appearanceColor: before.appearanceColor,\n createdAt: new Date(),\n updatedAt: new Date(),\n })\n em.persist(comment)\n } else {\n comment.entity = entity\n comment.deal = deal\n comment.body = before.body\n comment.authorUserId = before.authorUserId\n comment.appearanceIcon = before.appearanceIcon\n comment.appearanceColor = before.appearanceColor\n }\n await em.flush()\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n await emitCrudUndoSideEffects({\n dataEngine: de,\n action: 'created',\n entity: comment,\n identifiers: {\n id: comment.id,\n organizationId: comment.organizationId,\n tenantId: comment.tenantId,\n },\n indexer: commentCrudIndexer,\n events: commentCrudEvents,\n })\n },\n }\n\nregisterCommand(createCommentCommand)\nregisterCommand(updateCommentCommand)\nregisterCommand(deleteCommentCommand)\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -7,7 +7,7 @@ import {
7
7
  requireId,
8
8
  snapshotsEqual
9
9
  } from "@open-mercato/shared/lib/commands/helpers";
10
- import { CrudHttpError } from "@open-mercato/shared/lib/crud/errors";
10
+ import { CrudHttpError, notFound } from "@open-mercato/shared/lib/crud/errors";
11
11
  import {
12
12
  CustomerAddress,
13
13
  CustomerComment,
@@ -550,7 +550,7 @@ const updateCompanyCommand = {
550
550
  ensureTenantScope(ctx, record.tenantId);
551
551
  ensureOrganizationScope(ctx, record.organizationId);
552
552
  const profile = await em.findOne(CustomerCompanyProfile, { entity: record });
553
- if (!profile) throw new CrudHttpError(404, { error: "Company profile not found" });
553
+ if (!profile) throw notFound("Company profile not found");
554
554
  await withAtomicFlush(em, [
555
555
  () => {
556
556
  if (parsed.displayName !== void 0) record.displayName = parsed.displayName;