@open-mercato/core 0.6.5-develop.4490.1.d8e873f3cf → 0.6.5-develop.4498.1.55dc06a57c

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.
@@ -1,4 +1,4 @@
1
- [build:core] found 2941 entry points
1
+ [build:core] found 2943 entry points
2
2
  [build:core] built successfully
3
3
  [build:core:generated] found 184 entry points
4
4
  [build:core:generated] built successfully
@@ -230,33 +230,37 @@ const createPersonCompanyLinkCommand = {
230
230
  { tenantId: after.tenantId, organizationId: after.organizationId }
231
231
  );
232
232
  if (!link) return;
233
+ let person = null;
234
+ let profile = null;
235
+ let remainingLinks = [];
233
236
  await withAtomicFlush(em, [
234
237
  async () => {
235
- link.isPrimary = false;
236
- link.deletedAt = /* @__PURE__ */ new Date();
237
- const person = await findOneWithDecryption(
238
+ person = await findOneWithDecryption(
238
239
  em,
239
240
  CustomerEntity,
240
241
  { id: after.personEntityId, kind: "person", tenantId: after.tenantId, organizationId: after.organizationId, deletedAt: null },
241
242
  void 0,
242
243
  { tenantId: after.tenantId, organizationId: after.organizationId }
243
244
  );
244
- if (person) {
245
- const profile = await findOneWithDecryption(
246
- em,
247
- CustomerPersonProfile,
248
- { entity: person },
249
- { populate: ["company"] },
250
- { tenantId: person.tenantId, organizationId: person.organizationId }
251
- );
252
- if (profile) {
253
- const remainingLinks = await loadPersonCompanyLinks(em, person);
254
- if (after.isPrimary) {
255
- await promoteFallbackPrimaryLink(em, person, profile, remainingLinks, after.companyEntityId);
256
- } else if (profile.company && typeof profile.company !== "string" && profile.company.id === after.companyEntityId) {
257
- profile.company = null;
258
- }
259
- }
245
+ if (!person) return;
246
+ profile = await findOneWithDecryption(
247
+ em,
248
+ CustomerPersonProfile,
249
+ { entity: person },
250
+ { populate: ["company"] },
251
+ { tenantId: person.tenantId, organizationId: person.organizationId }
252
+ );
253
+ if (!profile) return;
254
+ remainingLinks = (await loadPersonCompanyLinks(em, person)).filter((entry) => entry.id !== link.id);
255
+ },
256
+ async () => {
257
+ link.isPrimary = false;
258
+ link.deletedAt = /* @__PURE__ */ new Date();
259
+ if (!person || !profile) return;
260
+ if (after.isPrimary) {
261
+ await promoteFallbackPrimaryLink(em, person, profile, remainingLinks, after.companyEntityId);
262
+ } else if (profile.company && typeof profile.company !== "string" && profile.company.id === after.companyEntityId) {
263
+ profile.company = null;
260
264
  }
261
265
  }
262
266
  ], { transaction: true });
@@ -380,39 +384,43 @@ const updatePersonCompanyLinkCommand = {
380
384
  { tenantId: before.tenantId, organizationId: before.organizationId }
381
385
  );
382
386
  if (!link) return;
387
+ let person = null;
388
+ let profile = null;
389
+ let company = null;
383
390
  await withAtomicFlush(em, [
384
391
  async () => {
385
- const person = await findOneWithDecryption(
392
+ person = await findOneWithDecryption(
386
393
  em,
387
394
  CustomerEntity,
388
395
  { id: before.personEntityId, kind: "person", tenantId: before.tenantId, organizationId: before.organizationId, deletedAt: null },
389
396
  void 0,
390
397
  { tenantId: before.tenantId, organizationId: before.organizationId }
391
398
  );
392
- if (person) {
393
- const profile = await findOneWithDecryption(
394
- em,
395
- CustomerPersonProfile,
396
- { entity: person },
397
- { populate: ["company"] },
398
- { tenantId: person.tenantId, organizationId: person.organizationId }
399
- );
400
- if (profile) {
401
- if (before.isPrimary) {
402
- await clearPrimaryFlagsForPerson(em, person);
403
- link.isPrimary = true;
404
- const company = await findOneWithDecryption(
405
- em,
406
- CustomerEntity,
407
- { id: before.companyEntityId, kind: "company", tenantId: before.tenantId, organizationId: before.organizationId, deletedAt: null },
408
- void 0,
409
- { tenantId: before.tenantId, organizationId: before.organizationId }
410
- );
411
- if (company) profile.company = company;
412
- } else {
413
- link.isPrimary = false;
414
- }
415
- }
399
+ if (!person) return;
400
+ profile = await findOneWithDecryption(
401
+ em,
402
+ CustomerPersonProfile,
403
+ { entity: person },
404
+ { populate: ["company"] },
405
+ { tenantId: person.tenantId, organizationId: person.organizationId }
406
+ );
407
+ if (!profile || !before.isPrimary) return;
408
+ company = await findOneWithDecryption(
409
+ em,
410
+ CustomerEntity,
411
+ { id: before.companyEntityId, kind: "company", tenantId: before.tenantId, organizationId: before.organizationId, deletedAt: null },
412
+ void 0,
413
+ { tenantId: before.tenantId, organizationId: before.organizationId }
414
+ );
415
+ },
416
+ async () => {
417
+ if (!person || !profile) return;
418
+ if (before.isPrimary) {
419
+ await clearPrimaryFlagsForPerson(em, person);
420
+ link.isPrimary = true;
421
+ if (company) profile.company = company;
422
+ } else {
423
+ link.isPrimary = false;
416
424
  }
417
425
  }
418
426
  ], { transaction: true });
@@ -527,37 +535,42 @@ const deletePersonCompanyLinkCommand = {
527
535
  { tenantId: before.tenantId, organizationId: before.organizationId }
528
536
  );
529
537
  if (!link) return;
538
+ let person = null;
539
+ let profile = null;
540
+ let company = null;
530
541
  await withAtomicFlush(em, [
531
542
  async () => {
532
- link.deletedAt = null;
533
- link.isPrimary = before.isPrimary;
534
- const person = await findOneWithDecryption(
543
+ person = await findOneWithDecryption(
535
544
  em,
536
545
  CustomerEntity,
537
546
  { id: before.personEntityId, kind: "person", tenantId: before.tenantId, organizationId: before.organizationId, deletedAt: null },
538
547
  void 0,
539
548
  { tenantId: before.tenantId, organizationId: before.organizationId }
540
549
  );
550
+ if (!person || !before.isPrimary) return;
551
+ profile = await findOneWithDecryption(
552
+ em,
553
+ CustomerPersonProfile,
554
+ { entity: person },
555
+ { populate: ["company"] },
556
+ { tenantId: person.tenantId, organizationId: person.organizationId }
557
+ );
558
+ if (!profile) return;
559
+ company = await findOneWithDecryption(
560
+ em,
561
+ CustomerEntity,
562
+ { id: before.companyEntityId, kind: "company", tenantId: before.tenantId, organizationId: before.organizationId, deletedAt: null },
563
+ void 0,
564
+ { tenantId: before.tenantId, organizationId: before.organizationId }
565
+ );
566
+ },
567
+ async () => {
568
+ link.deletedAt = null;
569
+ link.isPrimary = before.isPrimary;
541
570
  if (person && before.isPrimary) {
542
571
  await clearPrimaryFlagsForPerson(em, person);
543
572
  link.isPrimary = true;
544
- const profile = await findOneWithDecryption(
545
- em,
546
- CustomerPersonProfile,
547
- { entity: person },
548
- { populate: ["company"] },
549
- { tenantId: person.tenantId, organizationId: person.organizationId }
550
- );
551
- if (profile) {
552
- const company = await findOneWithDecryption(
553
- em,
554
- CustomerEntity,
555
- { id: before.companyEntityId, kind: "company", tenantId: before.tenantId, organizationId: before.organizationId, deletedAt: null },
556
- void 0,
557
- { tenantId: before.tenantId, organizationId: before.organizationId }
558
- );
559
- if (company) profile.company = company;
560
- }
573
+ if (profile && company) profile.company = company;
561
574
  }
562
575
  }
563
576
  ], { transaction: true });
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/modules/customers/commands/personCompanyLinks.ts"],
4
- "sourcesContent": ["import { registerCommand } from '@open-mercato/shared/lib/commands'\nimport type { CommandHandler } from '@open-mercato/shared/lib/commands'\nimport type { CrudEventsConfig } from '@open-mercato/shared/lib/crud/types'\nimport { emitCrudSideEffects, emitCrudUndoSideEffects } from '@open-mercato/shared/lib/commands/helpers'\nimport { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { findOneWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport type { DataEngine } from '@open-mercato/shared/lib/data/engine'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport {\n CustomerEntity,\n CustomerPersonCompanyLink,\n CustomerPersonProfile,\n} from '../data/entities'\nimport {\n personCompanyLinkCreateSchema,\n personCompanyLinkDeleteSchema,\n personCompanyLinkUpdateSchema,\n type PersonCompanyLinkCreateInput,\n type PersonCompanyLinkDeleteInput,\n type PersonCompanyLinkUpdateInput,\n} from '../data/validators'\nimport {\n findDeletedPersonCompanyLink,\n loadPersonCompanyLinks,\n promoteFallbackPrimaryLink,\n} from '../lib/personCompanies'\nimport {\n ensureOrganizationScope,\n ensureTenantScope,\n extractUndoPayload,\n} from './shared'\nimport { withAtomicFlush } from '@open-mercato/shared/lib/commands/flush'\n\ntype PersonCompanyLinkSnapshot = {\n id: string\n personEntityId: string\n companyEntityId: string\n isPrimary: boolean\n tenantId: string\n organizationId: string\n deletedAt: string | null\n}\n\ntype PersonCompanyLinkUndoPayload = {\n before?: PersonCompanyLinkSnapshot | null\n after?: PersonCompanyLinkSnapshot | null\n}\n\nconst personCompanyLinkCrudEvents: CrudEventsConfig = {\n module: 'customers',\n entity: 'person_company_link',\n persistent: true,\n buildPayload: (ctx) => ({\n id: ctx.identifiers.id,\n organizationId: ctx.identifiers.organizationId,\n tenantId: ctx.identifiers.tenantId,\n ...(ctx.entity && typeof ctx.entity === 'object' && 'person' in (ctx.entity as Record<string, unknown>)\n ? {\n personEntityId:\n typeof (ctx.entity as CustomerPersonCompanyLink).person === 'string'\n ? (ctx.entity as any).person\n : (ctx.entity as CustomerPersonCompanyLink).person?.id ?? null,\n companyEntityId:\n typeof (ctx.entity as CustomerPersonCompanyLink).company === 'string'\n ? (ctx.entity as any).company\n : (ctx.entity as CustomerPersonCompanyLink).company?.id ?? null,\n }\n : {}),\n ...(ctx.syncOrigin ? { syncOrigin: ctx.syncOrigin } : {}),\n }),\n}\n\nfunction getLinkIdentifiers(link: CustomerPersonCompanyLink) {\n return {\n id: link.id,\n organizationId: link.organizationId,\n tenantId: link.tenantId,\n }\n}\n\nasync function loadPersonCompanyLinkSnapshot(\n em: EntityManager,\n id: string,\n scope?: { tenantId?: string | null; organizationId?: string | null },\n): Promise<PersonCompanyLinkSnapshot | null> {\n const filter: Record<string, unknown> = { id }\n if (scope?.tenantId) filter.tenantId = scope.tenantId\n if (scope?.organizationId) filter.organizationId = scope.organizationId\n const link = await findOneWithDecryption(\n em,\n CustomerPersonCompanyLink,\n filter,\n undefined,\n {\n tenantId: scope?.tenantId ?? null,\n organizationId: scope?.organizationId ?? null,\n },\n )\n if (!link) return null\n const personId = typeof link.person === 'string' ? link.person : link.person.id\n const companyId = typeof link.company === 'string' ? link.company : link.company.id\n return {\n id: link.id,\n personEntityId: personId,\n companyEntityId: companyId,\n isPrimary: Boolean(link.isPrimary),\n tenantId: link.tenantId,\n organizationId: link.organizationId,\n deletedAt: link.deletedAt ? link.deletedAt.toISOString() : null,\n }\n}\n\nasync function requirePersonEntity(\n em: EntityManager,\n entityId: string,\n tenantId: string,\n organizationId: string,\n): Promise<CustomerEntity> {\n const person = await findOneWithDecryption(\n em,\n CustomerEntity,\n { id: entityId, kind: 'person', tenantId, organizationId, deletedAt: null },\n undefined,\n { tenantId, organizationId },\n )\n if (!person) {\n throw new CrudHttpError(404, { error: 'Person not found' })\n }\n return person\n}\n\nasync function requireCompanyEntity(\n em: EntityManager,\n entityId: string,\n tenantId: string,\n organizationId: string,\n): Promise<CustomerEntity> {\n const company = await findOneWithDecryption(\n em,\n CustomerEntity,\n { id: entityId, kind: 'company', tenantId, organizationId, deletedAt: null },\n undefined,\n { tenantId, organizationId },\n )\n if (!company) {\n throw new CrudHttpError(404, { error: 'Company not found' })\n }\n return company\n}\n\nasync function requirePersonProfile(\n em: EntityManager,\n person: CustomerEntity,\n): Promise<CustomerPersonProfile> {\n const profile = await findOneWithDecryption(\n em,\n CustomerPersonProfile,\n { entity: person },\n { populate: ['company'] },\n { tenantId: person.tenantId, organizationId: person.organizationId },\n )\n if (!profile) {\n throw new CrudHttpError(404, { error: 'Person profile not found' })\n }\n return profile\n}\n\nasync function clearPrimaryFlagsForPerson(em: EntityManager, person: CustomerEntity): Promise<void> {\n await em.nativeUpdate(\n CustomerPersonCompanyLink,\n { person, organizationId: person.organizationId, tenantId: person.tenantId, isPrimary: true },\n { isPrimary: false },\n )\n}\n\nconst createPersonCompanyLinkCommand: CommandHandler<PersonCompanyLinkCreateInput, { linkId: string; created: boolean; undeleted: boolean }> = {\n id: 'customers.personCompanyLinks.create',\n async execute(rawInput, ctx) {\n const parsed = personCompanyLinkCreateSchema.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 person = await requirePersonEntity(em, parsed.personEntityId, parsed.tenantId, parsed.organizationId)\n const company = await requireCompanyEntity(em, parsed.companyEntityId, parsed.tenantId, parsed.organizationId)\n const profile = await requirePersonProfile(em, person)\n\n const existingLinks = await loadPersonCompanyLinks(em, person)\n const makePrimary = Boolean(parsed.isPrimary) || existingLinks.length === 0\n const existingLive =\n existingLinks.find((link) => (typeof link.company === 'string' ? link.company : link.company.id) === company.id) ?? null\n\n if (existingLive) {\n if (makePrimary && !existingLive.isPrimary) {\n await withAtomicFlush(em, [\n () => clearPrimaryFlagsForPerson(em, person),\n () => {\n existingLive.isPrimary = true\n profile.company = company\n },\n ], { transaction: true })\n }\n return { linkId: existingLive.id, created: false, undeleted: false }\n }\n\n let link!: CustomerPersonCompanyLink\n let undeleted = false\n await withAtomicFlush(em, [\n async () => {\n const deletedLink = await findDeletedPersonCompanyLink(em, person, company)\n if (makePrimary) {\n await clearPrimaryFlagsForPerson(em, person)\n }\n if (deletedLink) {\n deletedLink.deletedAt = null\n deletedLink.isPrimary = makePrimary\n em.persist(deletedLink)\n link = deletedLink\n undeleted = true\n } else {\n link = em.create(CustomerPersonCompanyLink, {\n organizationId: parsed.organizationId,\n tenantId: parsed.tenantId,\n person,\n company,\n isPrimary: makePrimary,\n })\n em.persist(link)\n }\n },\n () => {\n if (makePrimary) {\n profile.company = company\n } else if (!profile.company && existingLinks.length === 0) {\n profile.company = company\n link.isPrimary = true\n }\n },\n ], { transaction: true })\n\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n await emitCrudSideEffects({\n dataEngine,\n action: undeleted ? 'updated' : 'created',\n entity: link,\n identifiers: getLinkIdentifiers(link),\n syncOrigin: ctx.syncOrigin,\n events: personCompanyLinkCrudEvents,\n indexer: { entityType: 'customers:customer_person_company_link' },\n })\n\n return { linkId: link.id, created: !undeleted, undeleted }\n },\n captureAfter: async (_input, result, ctx) => {\n const em = ctx.container.resolve('em') as EntityManager\n return loadPersonCompanyLinkSnapshot(em, result.linkId, {\n tenantId: ctx.auth?.tenantId ?? null,\n organizationId: ctx.selectedOrganizationId ?? ctx.auth?.orgId ?? null,\n })\n },\n buildLog: async ({ result, snapshots }) => {\n const { translate } = await resolveTranslations()\n const after = snapshots.after as PersonCompanyLinkSnapshot | undefined\n return {\n actionLabel: translate('customers.audit.personCompanyLinks.create', 'Link company to person'),\n resourceKind: 'customers.personCompanyLink',\n resourceId: result.linkId,\n parentResourceKind: 'customers.person',\n parentResourceId: after?.personEntityId ?? null,\n tenantId: after?.tenantId ?? null,\n organizationId: after?.organizationId ?? null,\n snapshotAfter: after ?? null,\n payload: {\n undo: {\n after: after ?? null,\n ...(result.undeleted ? { before: null } : {}),\n } satisfies PersonCompanyLinkUndoPayload,\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<PersonCompanyLinkUndoPayload>(logEntry)\n const after = payload?.after\n if (!after) return\n\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const link = await findOneWithDecryption(\n em,\n CustomerPersonCompanyLink,\n { id: after.id },\n undefined,\n { tenantId: after.tenantId, organizationId: after.organizationId },\n )\n if (!link) return\n\n await withAtomicFlush(em, [\n async () => {\n link.isPrimary = false\n link.deletedAt = new Date()\n const person = await findOneWithDecryption(\n em,\n CustomerEntity,\n { id: after.personEntityId, kind: 'person', tenantId: after.tenantId, organizationId: after.organizationId, deletedAt: null },\n undefined,\n { tenantId: after.tenantId, organizationId: after.organizationId },\n )\n if (person) {\n const profile = await findOneWithDecryption(\n em,\n CustomerPersonProfile,\n { entity: person },\n { populate: ['company'] },\n { tenantId: person.tenantId, organizationId: person.organizationId },\n )\n if (profile) {\n const remainingLinks = await loadPersonCompanyLinks(em, person)\n if (after.isPrimary) {\n await promoteFallbackPrimaryLink(em, person, profile, remainingLinks, after.companyEntityId)\n } else if (profile.company && typeof profile.company !== 'string' && profile.company.id === after.companyEntityId) {\n profile.company = null\n }\n }\n }\n },\n ], { transaction: true })\n\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n await emitCrudUndoSideEffects({\n dataEngine,\n action: 'deleted',\n entity: link,\n identifiers: getLinkIdentifiers(link),\n syncOrigin: ctx.syncOrigin,\n events: personCompanyLinkCrudEvents,\n indexer: { entityType: 'customers:customer_person_company_link' },\n })\n },\n}\n\nconst updatePersonCompanyLinkCommand: CommandHandler<PersonCompanyLinkUpdateInput, { linkId: string }> = {\n id: 'customers.personCompanyLinks.update',\n async prepare(rawInput, ctx) {\n const parsed = personCompanyLinkUpdateSchema.parse(rawInput)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const snapshot = await loadPersonCompanyLinkSnapshot(em, parsed.linkId, {\n tenantId: ctx.auth?.tenantId ?? null,\n organizationId: ctx.selectedOrganizationId ?? ctx.auth?.orgId ?? null,\n })\n return snapshot ? { before: snapshot } : {}\n },\n async execute(rawInput, ctx) {\n const parsed = personCompanyLinkUpdateSchema.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 link = await findOneWithDecryption(\n em,\n CustomerPersonCompanyLink,\n {\n id: parsed.linkId,\n tenantId: parsed.tenantId,\n organizationId: parsed.organizationId,\n deletedAt: null,\n },\n undefined,\n { tenantId: parsed.tenantId, organizationId: parsed.organizationId },\n )\n if (!link) {\n throw new CrudHttpError(404, { error: 'Company link not found' })\n }\n\n const personId = typeof link.person === 'string' ? link.person : link.person.id\n const companyId = typeof link.company === 'string' ? link.company : link.company.id\n const person = await requirePersonEntity(em, personId, parsed.tenantId, parsed.organizationId)\n const profile = await requirePersonProfile(em, person)\n const linkedCompany = await requireCompanyEntity(em, companyId, parsed.tenantId, parsed.organizationId)\n\n await withAtomicFlush(em, [\n async () => {\n if (parsed.isPrimary) {\n await clearPrimaryFlagsForPerson(em, person)\n link.isPrimary = true\n profile.company = linkedCompany\n } else if (!parsed.isPrimary) {\n const linkWasPrimary = link.isPrimary\n link.isPrimary = false\n if (linkWasPrimary) {\n const remainingLinks = (await loadPersonCompanyLinks(em, person)).filter((entry) => entry.id !== link.id)\n await promoteFallbackPrimaryLink(em, person, profile, remainingLinks, companyId)\n } else if (profile.company && typeof profile.company !== 'string' && profile.company.id === companyId) {\n profile.company = null\n }\n }\n },\n ], { transaction: true })\n\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n await emitCrudSideEffects({\n dataEngine,\n action: 'updated',\n entity: link,\n identifiers: getLinkIdentifiers(link),\n syncOrigin: ctx.syncOrigin,\n events: personCompanyLinkCrudEvents,\n indexer: { entityType: 'customers:customer_person_company_link' },\n })\n\n return { linkId: link.id }\n },\n captureAfter: async (_input, result, ctx) => {\n const em = ctx.container.resolve('em') as EntityManager\n return loadPersonCompanyLinkSnapshot(em, result.linkId, {\n tenantId: ctx.auth?.tenantId ?? null,\n organizationId: ctx.selectedOrganizationId ?? ctx.auth?.orgId ?? null,\n })\n },\n buildLog: async ({ result, snapshots }) => {\n const { translate } = await resolveTranslations()\n const before = snapshots.before as PersonCompanyLinkSnapshot | undefined\n const after = snapshots.after as PersonCompanyLinkSnapshot | undefined\n return {\n actionLabel: translate('customers.audit.personCompanyLinks.update', 'Update company link'),\n resourceKind: 'customers.personCompanyLink',\n resourceId: result.linkId,\n parentResourceKind: 'customers.person',\n parentResourceId: after?.personEntityId ?? before?.personEntityId ?? null,\n tenantId: after?.tenantId ?? before?.tenantId ?? null,\n organizationId: after?.organizationId ?? before?.organizationId ?? null,\n snapshotBefore: before ?? null,\n snapshotAfter: after ?? null,\n payload: {\n undo: {\n before: before ?? null,\n after: after ?? null,\n } satisfies PersonCompanyLinkUndoPayload,\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<PersonCompanyLinkUndoPayload>(logEntry)\n const before = payload?.before\n if (!before) return\n\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const link = await findOneWithDecryption(\n em,\n CustomerPersonCompanyLink,\n { id: before.id },\n undefined,\n { tenantId: before.tenantId, organizationId: before.organizationId },\n )\n if (!link) return\n\n await withAtomicFlush(em, [\n async () => {\n const person = await findOneWithDecryption(\n em,\n CustomerEntity,\n { id: before.personEntityId, kind: 'person', tenantId: before.tenantId, organizationId: before.organizationId, deletedAt: null },\n undefined,\n { tenantId: before.tenantId, organizationId: before.organizationId },\n )\n if (person) {\n const profile = await findOneWithDecryption(\n em,\n CustomerPersonProfile,\n { entity: person },\n { populate: ['company'] },\n { tenantId: person.tenantId, organizationId: person.organizationId },\n )\n if (profile) {\n if (before.isPrimary) {\n await clearPrimaryFlagsForPerson(em, person)\n link.isPrimary = true\n const company = await findOneWithDecryption(\n em,\n CustomerEntity,\n { id: before.companyEntityId, kind: 'company', tenantId: before.tenantId, organizationId: before.organizationId, deletedAt: null },\n undefined,\n { tenantId: before.tenantId, organizationId: before.organizationId },\n )\n if (company) profile.company = company\n } else {\n link.isPrimary = false\n }\n }\n }\n },\n ], { transaction: true })\n\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n await emitCrudUndoSideEffects({\n dataEngine,\n action: 'updated',\n entity: link,\n identifiers: getLinkIdentifiers(link),\n syncOrigin: ctx.syncOrigin,\n events: personCompanyLinkCrudEvents,\n indexer: { entityType: 'customers:customer_person_company_link' },\n })\n },\n}\n\nconst deletePersonCompanyLinkCommand: CommandHandler<PersonCompanyLinkDeleteInput, { linkId: string }> = {\n id: 'customers.personCompanyLinks.delete',\n async prepare(rawInput, ctx) {\n const parsed = personCompanyLinkDeleteSchema.parse(rawInput)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const snapshot = await loadPersonCompanyLinkSnapshot(em, parsed.linkId, {\n tenantId: ctx.auth?.tenantId ?? null,\n organizationId: ctx.selectedOrganizationId ?? ctx.auth?.orgId ?? null,\n })\n return snapshot ? { before: snapshot } : {}\n },\n async execute(rawInput, ctx) {\n const parsed = personCompanyLinkDeleteSchema.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 link = await findOneWithDecryption(\n em,\n CustomerPersonCompanyLink,\n {\n id: parsed.linkId,\n tenantId: parsed.tenantId,\n organizationId: parsed.organizationId,\n deletedAt: null,\n },\n undefined,\n { tenantId: parsed.tenantId, organizationId: parsed.organizationId },\n )\n if (!link) {\n throw new CrudHttpError(404, { error: 'Company link not found' })\n }\n\n const personId = typeof link.person === 'string' ? link.person : link.person.id\n const companyId = typeof link.company === 'string' ? link.company : link.company.id\n const person = await requirePersonEntity(em, personId, parsed.tenantId, parsed.organizationId)\n const profile = await requirePersonProfile(em, person)\n const linkWasPrimary = link.isPrimary\n\n const existingLinks = await loadPersonCompanyLinks(em, person)\n const remainingLinks = existingLinks.filter((entry) => entry.id !== link.id)\n\n await withAtomicFlush(em, [\n () => {\n link.isPrimary = false\n link.deletedAt = new Date()\n },\n async () => {\n if (linkWasPrimary) {\n await promoteFallbackPrimaryLink(em, person, profile, remainingLinks, companyId)\n } else if (profile.company && typeof profile.company !== 'string' && profile.company.id === companyId) {\n const primary = remainingLinks.find((entry) => entry.isPrimary) ?? null\n const primaryCompany = primary && typeof primary.company !== 'string' ? primary.company : null\n if (primaryCompany) {\n profile.company = primaryCompany\n }\n }\n },\n ], { transaction: true })\n\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n await emitCrudSideEffects({\n dataEngine,\n action: 'deleted',\n entity: link,\n identifiers: getLinkIdentifiers(link),\n syncOrigin: ctx.syncOrigin,\n events: personCompanyLinkCrudEvents,\n indexer: { entityType: 'customers:customer_person_company_link' },\n })\n\n return { linkId: link.id }\n },\n buildLog: async ({ result, snapshots }) => {\n const { translate } = await resolveTranslations()\n const before = snapshots.before as PersonCompanyLinkSnapshot | undefined\n return {\n actionLabel: translate('customers.audit.personCompanyLinks.delete', 'Remove company link'),\n resourceKind: 'customers.personCompanyLink',\n resourceId: result.linkId,\n parentResourceKind: 'customers.person',\n parentResourceId: before?.personEntityId ?? null,\n tenantId: before?.tenantId ?? null,\n organizationId: before?.organizationId ?? null,\n snapshotBefore: before ?? null,\n payload: {\n undo: {\n before: before ?? null,\n } satisfies PersonCompanyLinkUndoPayload,\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<PersonCompanyLinkUndoPayload>(logEntry)\n const before = payload?.before\n if (!before) return\n\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const link = await findOneWithDecryption(\n em,\n CustomerPersonCompanyLink,\n { id: before.id },\n undefined,\n { tenantId: before.tenantId, organizationId: before.organizationId },\n )\n if (!link) return\n\n await withAtomicFlush(em, [\n async () => {\n link.deletedAt = null\n link.isPrimary = before.isPrimary\n\n const person = await findOneWithDecryption(\n em,\n CustomerEntity,\n { id: before.personEntityId, kind: 'person', tenantId: before.tenantId, organizationId: before.organizationId, deletedAt: null },\n undefined,\n { tenantId: before.tenantId, organizationId: before.organizationId },\n )\n if (person && before.isPrimary) {\n await clearPrimaryFlagsForPerson(em, person)\n link.isPrimary = true\n const profile = await findOneWithDecryption(\n em,\n CustomerPersonProfile,\n { entity: person },\n { populate: ['company'] },\n { tenantId: person.tenantId, organizationId: person.organizationId },\n )\n if (profile) {\n const company = await findOneWithDecryption(\n em,\n CustomerEntity,\n { id: before.companyEntityId, kind: 'company', tenantId: before.tenantId, organizationId: before.organizationId, deletedAt: null },\n undefined,\n { tenantId: before.tenantId, organizationId: before.organizationId },\n )\n if (company) profile.company = company\n }\n }\n },\n ], { transaction: true })\n\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n await emitCrudUndoSideEffects({\n dataEngine,\n action: 'created',\n entity: link,\n identifiers: getLinkIdentifiers(link),\n syncOrigin: ctx.syncOrigin,\n events: personCompanyLinkCrudEvents,\n indexer: { entityType: 'customers:customer_person_company_link' },\n })\n },\n}\n\nregisterCommand(createPersonCompanyLinkCommand)\nregisterCommand(updatePersonCompanyLinkCommand)\nregisterCommand(deletePersonCompanyLinkCommand)\n"],
5
- "mappings": "AAAA,SAAS,uBAAuB;AAGhC,SAAS,qBAAqB,+BAA+B;AAC7D,SAAS,qBAAqB;AAC9B,SAAS,2BAA2B;AACpC,SAAS,6BAA6B;AAGtC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAIK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,uBAAuB;AAiBhC,MAAM,8BAAgD;AAAA,EACpD,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,cAAc,CAAC,SAAS;AAAA,IACtB,IAAI,IAAI,YAAY;AAAA,IACpB,gBAAgB,IAAI,YAAY;AAAA,IAChC,UAAU,IAAI,YAAY;AAAA,IAC1B,GAAI,IAAI,UAAU,OAAO,IAAI,WAAW,YAAY,YAAa,IAAI,SACjE;AAAA,MACE,gBACE,OAAQ,IAAI,OAAqC,WAAW,WACvD,IAAI,OAAe,SACnB,IAAI,OAAqC,QAAQ,MAAM;AAAA,MAC9D,iBACE,OAAQ,IAAI,OAAqC,YAAY,WACxD,IAAI,OAAe,UACnB,IAAI,OAAqC,SAAS,MAAM;AAAA,IACjE,IACA,CAAC;AAAA,IACL,GAAI,IAAI,aAAa,EAAE,YAAY,IAAI,WAAW,IAAI,CAAC;AAAA,EACzD;AACF;AAEA,SAAS,mBAAmB,MAAiC;AAC3D,SAAO;AAAA,IACL,IAAI,KAAK;AAAA,IACT,gBAAgB,KAAK;AAAA,IACrB,UAAU,KAAK;AAAA,EACjB;AACF;AAEA,eAAe,8BACb,IACA,IACA,OAC2C;AAC3C,QAAM,SAAkC,EAAE,GAAG;AAC7C,MAAI,OAAO,SAAU,QAAO,WAAW,MAAM;AAC7C,MAAI,OAAO,eAAgB,QAAO,iBAAiB,MAAM;AACzD,QAAM,OAAO,MAAM;AAAA,IACjB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,MACE,UAAU,OAAO,YAAY;AAAA,MAC7B,gBAAgB,OAAO,kBAAkB;AAAA,IAC3C;AAAA,EACF;AACA,MAAI,CAAC,KAAM,QAAO;AAClB,QAAM,WAAW,OAAO,KAAK,WAAW,WAAW,KAAK,SAAS,KAAK,OAAO;AAC7E,QAAM,YAAY,OAAO,KAAK,YAAY,WAAW,KAAK,UAAU,KAAK,QAAQ;AACjF,SAAO;AAAA,IACL,IAAI,KAAK;AAAA,IACT,gBAAgB;AAAA,IAChB,iBAAiB;AAAA,IACjB,WAAW,QAAQ,KAAK,SAAS;AAAA,IACjC,UAAU,KAAK;AAAA,IACf,gBAAgB,KAAK;AAAA,IACrB,WAAW,KAAK,YAAY,KAAK,UAAU,YAAY,IAAI;AAAA,EAC7D;AACF;AAEA,eAAe,oBACb,IACA,UACA,UACA,gBACyB;AACzB,QAAM,SAAS,MAAM;AAAA,IACnB;AAAA,IACA;AAAA,IACA,EAAE,IAAI,UAAU,MAAM,UAAU,UAAU,gBAAgB,WAAW,KAAK;AAAA,IAC1E;AAAA,IACA,EAAE,UAAU,eAAe;AAAA,EAC7B;AACA,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,cAAc,KAAK,EAAE,OAAO,mBAAmB,CAAC;AAAA,EAC5D;AACA,SAAO;AACT;AAEA,eAAe,qBACb,IACA,UACA,UACA,gBACyB;AACzB,QAAM,UAAU,MAAM;AAAA,IACpB;AAAA,IACA;AAAA,IACA,EAAE,IAAI,UAAU,MAAM,WAAW,UAAU,gBAAgB,WAAW,KAAK;AAAA,IAC3E;AAAA,IACA,EAAE,UAAU,eAAe;AAAA,EAC7B;AACA,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,cAAc,KAAK,EAAE,OAAO,oBAAoB,CAAC;AAAA,EAC7D;AACA,SAAO;AACT;AAEA,eAAe,qBACb,IACA,QACgC;AAChC,QAAM,UAAU,MAAM;AAAA,IACpB;AAAA,IACA;AAAA,IACA,EAAE,QAAQ,OAAO;AAAA,IACjB,EAAE,UAAU,CAAC,SAAS,EAAE;AAAA,IACxB,EAAE,UAAU,OAAO,UAAU,gBAAgB,OAAO,eAAe;AAAA,EACrE;AACA,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,cAAc,KAAK,EAAE,OAAO,2BAA2B,CAAC;AAAA,EACpE;AACA,SAAO;AACT;AAEA,eAAe,2BAA2B,IAAmB,QAAuC;AAClG,QAAM,GAAG;AAAA,IACP;AAAA,IACA,EAAE,QAAQ,gBAAgB,OAAO,gBAAgB,UAAU,OAAO,UAAU,WAAW,KAAK;AAAA,IAC5F,EAAE,WAAW,MAAM;AAAA,EACrB;AACF;AAEA,MAAM,iCAAyI;AAAA,EAC7I,IAAI;AAAA,EACJ,MAAM,QAAQ,UAAU,KAAK;AAC3B,UAAM,SAAS,8BAA8B,MAAM,QAAQ;AAC3D,sBAAkB,KAAK,OAAO,QAAQ;AACtC,4BAAwB,KAAK,OAAO,cAAc;AAElD,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,UAAM,SAAS,MAAM,oBAAoB,IAAI,OAAO,gBAAgB,OAAO,UAAU,OAAO,cAAc;AAC1G,UAAM,UAAU,MAAM,qBAAqB,IAAI,OAAO,iBAAiB,OAAO,UAAU,OAAO,cAAc;AAC7G,UAAM,UAAU,MAAM,qBAAqB,IAAI,MAAM;AAErD,UAAM,gBAAgB,MAAM,uBAAuB,IAAI,MAAM;AAC7D,UAAM,cAAc,QAAQ,OAAO,SAAS,KAAK,cAAc,WAAW;AAC1E,UAAM,eACJ,cAAc,KAAK,CAACA,WAAU,OAAOA,MAAK,YAAY,WAAWA,MAAK,UAAUA,MAAK,QAAQ,QAAQ,QAAQ,EAAE,KAAK;AAEtH,QAAI,cAAc;AAChB,UAAI,eAAe,CAAC,aAAa,WAAW;AAC1C,cAAM,gBAAgB,IAAI;AAAA,UACxB,MAAM,2BAA2B,IAAI,MAAM;AAAA,UAC3C,MAAM;AACJ,yBAAa,YAAY;AACzB,oBAAQ,UAAU;AAAA,UACpB;AAAA,QACF,GAAG,EAAE,aAAa,KAAK,CAAC;AAAA,MAC1B;AACA,aAAO,EAAE,QAAQ,aAAa,IAAI,SAAS,OAAO,WAAW,MAAM;AAAA,IACrE;AAEA,QAAI;AACJ,QAAI,YAAY;AAChB,UAAM,gBAAgB,IAAI;AAAA,MACxB,YAAY;AACV,cAAM,cAAc,MAAM,6BAA6B,IAAI,QAAQ,OAAO;AAC1E,YAAI,aAAa;AACf,gBAAM,2BAA2B,IAAI,MAAM;AAAA,QAC7C;AACA,YAAI,aAAa;AACf,sBAAY,YAAY;AACxB,sBAAY,YAAY;AACxB,aAAG,QAAQ,WAAW;AACtB,iBAAO;AACP,sBAAY;AAAA,QACd,OAAO;AACL,iBAAO,GAAG,OAAO,2BAA2B;AAAA,YAC1C,gBAAgB,OAAO;AAAA,YACvB,UAAU,OAAO;AAAA,YACjB;AAAA,YACA;AAAA,YACA,WAAW;AAAA,UACb,CAAC;AACD,aAAG,QAAQ,IAAI;AAAA,QACjB;AAAA,MACF;AAAA,MACA,MAAM;AACJ,YAAI,aAAa;AACf,kBAAQ,UAAU;AAAA,QACpB,WAAW,CAAC,QAAQ,WAAW,cAAc,WAAW,GAAG;AACzD,kBAAQ,UAAU;AAClB,eAAK,YAAY;AAAA,QACnB;AAAA,MACF;AAAA,IACF,GAAG,EAAE,aAAa,KAAK,CAAC;AAExB,UAAM,aAAa,IAAI,UAAU,QAAQ,YAAY;AACrD,UAAM,oBAAoB;AAAA,MACxB;AAAA,MACA,QAAQ,YAAY,YAAY;AAAA,MAChC,QAAQ;AAAA,MACR,aAAa,mBAAmB,IAAI;AAAA,MACpC,YAAY,IAAI;AAAA,MAChB,QAAQ;AAAA,MACR,SAAS,EAAE,YAAY,yCAAyC;AAAA,IAClE,CAAC;AAED,WAAO,EAAE,QAAQ,KAAK,IAAI,SAAS,CAAC,WAAW,UAAU;AAAA,EAC3D;AAAA,EACA,cAAc,OAAO,QAAQ,QAAQ,QAAQ;AAC3C,UAAM,KAAK,IAAI,UAAU,QAAQ,IAAI;AACrC,WAAO,8BAA8B,IAAI,OAAO,QAAQ;AAAA,MACtD,UAAU,IAAI,MAAM,YAAY;AAAA,MAChC,gBAAgB,IAAI,0BAA0B,IAAI,MAAM,SAAS;AAAA,IACnE,CAAC;AAAA,EACH;AAAA,EACA,UAAU,OAAO,EAAE,QAAQ,UAAU,MAAM;AACzC,UAAM,EAAE,UAAU,IAAI,MAAM,oBAAoB;AAChD,UAAM,QAAQ,UAAU;AACxB,WAAO;AAAA,MACL,aAAa,UAAU,6CAA6C,wBAAwB;AAAA,MAC5F,cAAc;AAAA,MACd,YAAY,OAAO;AAAA,MACnB,oBAAoB;AAAA,MACpB,kBAAkB,OAAO,kBAAkB;AAAA,MAC3C,UAAU,OAAO,YAAY;AAAA,MAC7B,gBAAgB,OAAO,kBAAkB;AAAA,MACzC,eAAe,SAAS;AAAA,MACxB,SAAS;AAAA,QACP,MAAM;AAAA,UACJ,OAAO,SAAS;AAAA,UAChB,GAAI,OAAO,YAAY,EAAE,QAAQ,KAAK,IAAI,CAAC;AAAA,QAC7C;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA,MAAM,OAAO,EAAE,UAAU,IAAI,MAAM;AACjC,UAAM,UAAU,mBAAiD,QAAQ;AACzE,UAAM,QAAQ,SAAS;AACvB,QAAI,CAAC,MAAO;AAEZ,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,UAAM,OAAO,MAAM;AAAA,MACjB;AAAA,MACA;AAAA,MACA,EAAE,IAAI,MAAM,GAAG;AAAA,MACf;AAAA,MACA,EAAE,UAAU,MAAM,UAAU,gBAAgB,MAAM,eAAe;AAAA,IACnE;AACA,QAAI,CAAC,KAAM;AAEX,UAAM,gBAAgB,IAAI;AAAA,MACxB,YAAY;AACV,aAAK,YAAY;AACjB,aAAK,YAAY,oBAAI,KAAK;AAC1B,cAAM,SAAS,MAAM;AAAA,UACnB;AAAA,UACA;AAAA,UACA,EAAE,IAAI,MAAM,gBAAgB,MAAM,UAAU,UAAU,MAAM,UAAU,gBAAgB,MAAM,gBAAgB,WAAW,KAAK;AAAA,UAC5H;AAAA,UACA,EAAE,UAAU,MAAM,UAAU,gBAAgB,MAAM,eAAe;AAAA,QACnE;AACA,YAAI,QAAQ;AACV,gBAAM,UAAU,MAAM;AAAA,YACpB;AAAA,YACA;AAAA,YACA,EAAE,QAAQ,OAAO;AAAA,YACjB,EAAE,UAAU,CAAC,SAAS,EAAE;AAAA,YACxB,EAAE,UAAU,OAAO,UAAU,gBAAgB,OAAO,eAAe;AAAA,UACrE;AACA,cAAI,SAAS;AACX,kBAAM,iBAAiB,MAAM,uBAAuB,IAAI,MAAM;AAC9D,gBAAI,MAAM,WAAW;AACnB,oBAAM,2BAA2B,IAAI,QAAQ,SAAS,gBAAgB,MAAM,eAAe;AAAA,YAC7F,WAAW,QAAQ,WAAW,OAAO,QAAQ,YAAY,YAAY,QAAQ,QAAQ,OAAO,MAAM,iBAAiB;AACjH,sBAAQ,UAAU;AAAA,YACpB;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF,GAAG,EAAE,aAAa,KAAK,CAAC;AAExB,UAAM,aAAa,IAAI,UAAU,QAAQ,YAAY;AACrD,UAAM,wBAAwB;AAAA,MAC5B;AAAA,MACA,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,aAAa,mBAAmB,IAAI;AAAA,MACpC,YAAY,IAAI;AAAA,MAChB,QAAQ;AAAA,MACR,SAAS,EAAE,YAAY,yCAAyC;AAAA,IAClE,CAAC;AAAA,EACH;AACF;AAEA,MAAM,iCAAmG;AAAA,EACvG,IAAI;AAAA,EACJ,MAAM,QAAQ,UAAU,KAAK;AAC3B,UAAM,SAAS,8BAA8B,MAAM,QAAQ;AAC3D,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,UAAM,WAAW,MAAM,8BAA8B,IAAI,OAAO,QAAQ;AAAA,MACtE,UAAU,IAAI,MAAM,YAAY;AAAA,MAChC,gBAAgB,IAAI,0BAA0B,IAAI,MAAM,SAAS;AAAA,IACnE,CAAC;AACD,WAAO,WAAW,EAAE,QAAQ,SAAS,IAAI,CAAC;AAAA,EAC5C;AAAA,EACA,MAAM,QAAQ,UAAU,KAAK;AAC3B,UAAM,SAAS,8BAA8B,MAAM,QAAQ;AAC3D,sBAAkB,KAAK,OAAO,QAAQ;AACtC,4BAAwB,KAAK,OAAO,cAAc;AAElD,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,UAAM,OAAO,MAAM;AAAA,MACjB;AAAA,MACA;AAAA,MACA;AAAA,QACE,IAAI,OAAO;AAAA,QACX,UAAU,OAAO;AAAA,QACjB,gBAAgB,OAAO;AAAA,QACvB,WAAW;AAAA,MACb;AAAA,MACA;AAAA,MACA,EAAE,UAAU,OAAO,UAAU,gBAAgB,OAAO,eAAe;AAAA,IACrE;AACA,QAAI,CAAC,MAAM;AACT,YAAM,IAAI,cAAc,KAAK,EAAE,OAAO,yBAAyB,CAAC;AAAA,IAClE;AAEA,UAAM,WAAW,OAAO,KAAK,WAAW,WAAW,KAAK,SAAS,KAAK,OAAO;AAC7E,UAAM,YAAY,OAAO,KAAK,YAAY,WAAW,KAAK,UAAU,KAAK,QAAQ;AACjF,UAAM,SAAS,MAAM,oBAAoB,IAAI,UAAU,OAAO,UAAU,OAAO,cAAc;AAC7F,UAAM,UAAU,MAAM,qBAAqB,IAAI,MAAM;AACrD,UAAM,gBAAgB,MAAM,qBAAqB,IAAI,WAAW,OAAO,UAAU,OAAO,cAAc;AAEtG,UAAM,gBAAgB,IAAI;AAAA,MACxB,YAAY;AACV,YAAI,OAAO,WAAW;AACpB,gBAAM,2BAA2B,IAAI,MAAM;AAC3C,eAAK,YAAY;AACjB,kBAAQ,UAAU;AAAA,QACpB,WAAW,CAAC,OAAO,WAAW;AAC5B,gBAAM,iBAAiB,KAAK;AAC5B,eAAK,YAAY;AACjB,cAAI,gBAAgB;AAClB,kBAAM,kBAAkB,MAAM,uBAAuB,IAAI,MAAM,GAAG,OAAO,CAAC,UAAU,MAAM,OAAO,KAAK,EAAE;AACxG,kBAAM,2BAA2B,IAAI,QAAQ,SAAS,gBAAgB,SAAS;AAAA,UACjF,WAAW,QAAQ,WAAW,OAAO,QAAQ,YAAY,YAAY,QAAQ,QAAQ,OAAO,WAAW;AACrG,oBAAQ,UAAU;AAAA,UACpB;AAAA,QACF;AAAA,MACF;AAAA,IACF,GAAG,EAAE,aAAa,KAAK,CAAC;AAExB,UAAM,aAAa,IAAI,UAAU,QAAQ,YAAY;AACrD,UAAM,oBAAoB;AAAA,MACxB;AAAA,MACA,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,aAAa,mBAAmB,IAAI;AAAA,MACpC,YAAY,IAAI;AAAA,MAChB,QAAQ;AAAA,MACR,SAAS,EAAE,YAAY,yCAAyC;AAAA,IAClE,CAAC;AAED,WAAO,EAAE,QAAQ,KAAK,GAAG;AAAA,EAC3B;AAAA,EACA,cAAc,OAAO,QAAQ,QAAQ,QAAQ;AAC3C,UAAM,KAAK,IAAI,UAAU,QAAQ,IAAI;AACrC,WAAO,8BAA8B,IAAI,OAAO,QAAQ;AAAA,MACtD,UAAU,IAAI,MAAM,YAAY;AAAA,MAChC,gBAAgB,IAAI,0BAA0B,IAAI,MAAM,SAAS;AAAA,IACnE,CAAC;AAAA,EACH;AAAA,EACA,UAAU,OAAO,EAAE,QAAQ,UAAU,MAAM;AACzC,UAAM,EAAE,UAAU,IAAI,MAAM,oBAAoB;AAChD,UAAM,SAAS,UAAU;AACzB,UAAM,QAAQ,UAAU;AACxB,WAAO;AAAA,MACL,aAAa,UAAU,6CAA6C,qBAAqB;AAAA,MACzF,cAAc;AAAA,MACd,YAAY,OAAO;AAAA,MACnB,oBAAoB;AAAA,MACpB,kBAAkB,OAAO,kBAAkB,QAAQ,kBAAkB;AAAA,MACrE,UAAU,OAAO,YAAY,QAAQ,YAAY;AAAA,MACjD,gBAAgB,OAAO,kBAAkB,QAAQ,kBAAkB;AAAA,MACnE,gBAAgB,UAAU;AAAA,MAC1B,eAAe,SAAS;AAAA,MACxB,SAAS;AAAA,QACP,MAAM;AAAA,UACJ,QAAQ,UAAU;AAAA,UAClB,OAAO,SAAS;AAAA,QAClB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA,MAAM,OAAO,EAAE,UAAU,IAAI,MAAM;AACjC,UAAM,UAAU,mBAAiD,QAAQ;AACzE,UAAM,SAAS,SAAS;AACxB,QAAI,CAAC,OAAQ;AAEb,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,UAAM,OAAO,MAAM;AAAA,MACjB;AAAA,MACA;AAAA,MACA,EAAE,IAAI,OAAO,GAAG;AAAA,MAChB;AAAA,MACA,EAAE,UAAU,OAAO,UAAU,gBAAgB,OAAO,eAAe;AAAA,IACrE;AACA,QAAI,CAAC,KAAM;AAEX,UAAM,gBAAgB,IAAI;AAAA,MACxB,YAAY;AACV,cAAM,SAAS,MAAM;AAAA,UACnB;AAAA,UACA;AAAA,UACA,EAAE,IAAI,OAAO,gBAAgB,MAAM,UAAU,UAAU,OAAO,UAAU,gBAAgB,OAAO,gBAAgB,WAAW,KAAK;AAAA,UAC/H;AAAA,UACA,EAAE,UAAU,OAAO,UAAU,gBAAgB,OAAO,eAAe;AAAA,QACrE;AACA,YAAI,QAAQ;AACV,gBAAM,UAAU,MAAM;AAAA,YACpB;AAAA,YACA;AAAA,YACA,EAAE,QAAQ,OAAO;AAAA,YACjB,EAAE,UAAU,CAAC,SAAS,EAAE;AAAA,YACxB,EAAE,UAAU,OAAO,UAAU,gBAAgB,OAAO,eAAe;AAAA,UACrE;AACA,cAAI,SAAS;AACX,gBAAI,OAAO,WAAW;AACpB,oBAAM,2BAA2B,IAAI,MAAM;AAC3C,mBAAK,YAAY;AACjB,oBAAM,UAAU,MAAM;AAAA,gBACpB;AAAA,gBACA;AAAA,gBACA,EAAE,IAAI,OAAO,iBAAiB,MAAM,WAAW,UAAU,OAAO,UAAU,gBAAgB,OAAO,gBAAgB,WAAW,KAAK;AAAA,gBACjI;AAAA,gBACA,EAAE,UAAU,OAAO,UAAU,gBAAgB,OAAO,eAAe;AAAA,cACrE;AACA,kBAAI,QAAS,SAAQ,UAAU;AAAA,YACjC,OAAO;AACL,mBAAK,YAAY;AAAA,YACnB;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,IACF,GAAG,EAAE,aAAa,KAAK,CAAC;AAExB,UAAM,aAAa,IAAI,UAAU,QAAQ,YAAY;AACrD,UAAM,wBAAwB;AAAA,MAC5B;AAAA,MACA,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,aAAa,mBAAmB,IAAI;AAAA,MACpC,YAAY,IAAI;AAAA,MAChB,QAAQ;AAAA,MACR,SAAS,EAAE,YAAY,yCAAyC;AAAA,IAClE,CAAC;AAAA,EACH;AACF;AAEA,MAAM,iCAAmG;AAAA,EACvG,IAAI;AAAA,EACJ,MAAM,QAAQ,UAAU,KAAK;AAC3B,UAAM,SAAS,8BAA8B,MAAM,QAAQ;AAC3D,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,UAAM,WAAW,MAAM,8BAA8B,IAAI,OAAO,QAAQ;AAAA,MACtE,UAAU,IAAI,MAAM,YAAY;AAAA,MAChC,gBAAgB,IAAI,0BAA0B,IAAI,MAAM,SAAS;AAAA,IACnE,CAAC;AACD,WAAO,WAAW,EAAE,QAAQ,SAAS,IAAI,CAAC;AAAA,EAC5C;AAAA,EACA,MAAM,QAAQ,UAAU,KAAK;AAC3B,UAAM,SAAS,8BAA8B,MAAM,QAAQ;AAC3D,sBAAkB,KAAK,OAAO,QAAQ;AACtC,4BAAwB,KAAK,OAAO,cAAc;AAElD,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,UAAM,OAAO,MAAM;AAAA,MACjB;AAAA,MACA;AAAA,MACA;AAAA,QACE,IAAI,OAAO;AAAA,QACX,UAAU,OAAO;AAAA,QACjB,gBAAgB,OAAO;AAAA,QACvB,WAAW;AAAA,MACb;AAAA,MACA;AAAA,MACA,EAAE,UAAU,OAAO,UAAU,gBAAgB,OAAO,eAAe;AAAA,IACrE;AACA,QAAI,CAAC,MAAM;AACT,YAAM,IAAI,cAAc,KAAK,EAAE,OAAO,yBAAyB,CAAC;AAAA,IAClE;AAEA,UAAM,WAAW,OAAO,KAAK,WAAW,WAAW,KAAK,SAAS,KAAK,OAAO;AAC7E,UAAM,YAAY,OAAO,KAAK,YAAY,WAAW,KAAK,UAAU,KAAK,QAAQ;AACjF,UAAM,SAAS,MAAM,oBAAoB,IAAI,UAAU,OAAO,UAAU,OAAO,cAAc;AAC7F,UAAM,UAAU,MAAM,qBAAqB,IAAI,MAAM;AACrD,UAAM,iBAAiB,KAAK;AAE5B,UAAM,gBAAgB,MAAM,uBAAuB,IAAI,MAAM;AAC7D,UAAM,iBAAiB,cAAc,OAAO,CAAC,UAAU,MAAM,OAAO,KAAK,EAAE;AAE3E,UAAM,gBAAgB,IAAI;AAAA,MACxB,MAAM;AACJ,aAAK,YAAY;AACjB,aAAK,YAAY,oBAAI,KAAK;AAAA,MAC5B;AAAA,MACA,YAAY;AACV,YAAI,gBAAgB;AAClB,gBAAM,2BAA2B,IAAI,QAAQ,SAAS,gBAAgB,SAAS;AAAA,QACjF,WAAW,QAAQ,WAAW,OAAO,QAAQ,YAAY,YAAY,QAAQ,QAAQ,OAAO,WAAW;AACrG,gBAAM,UAAU,eAAe,KAAK,CAAC,UAAU,MAAM,SAAS,KAAK;AACnE,gBAAM,iBAAiB,WAAW,OAAO,QAAQ,YAAY,WAAW,QAAQ,UAAU;AAC1F,cAAI,gBAAgB;AAClB,oBAAQ,UAAU;AAAA,UACpB;AAAA,QACF;AAAA,MACF;AAAA,IACF,GAAG,EAAE,aAAa,KAAK,CAAC;AAExB,UAAM,aAAa,IAAI,UAAU,QAAQ,YAAY;AACrD,UAAM,oBAAoB;AAAA,MACxB;AAAA,MACA,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,aAAa,mBAAmB,IAAI;AAAA,MACpC,YAAY,IAAI;AAAA,MAChB,QAAQ;AAAA,MACR,SAAS,EAAE,YAAY,yCAAyC;AAAA,IAClE,CAAC;AAED,WAAO,EAAE,QAAQ,KAAK,GAAG;AAAA,EAC3B;AAAA,EACA,UAAU,OAAO,EAAE,QAAQ,UAAU,MAAM;AACzC,UAAM,EAAE,UAAU,IAAI,MAAM,oBAAoB;AAChD,UAAM,SAAS,UAAU;AACzB,WAAO;AAAA,MACL,aAAa,UAAU,6CAA6C,qBAAqB;AAAA,MACzF,cAAc;AAAA,MACd,YAAY,OAAO;AAAA,MACnB,oBAAoB;AAAA,MACpB,kBAAkB,QAAQ,kBAAkB;AAAA,MAC5C,UAAU,QAAQ,YAAY;AAAA,MAC9B,gBAAgB,QAAQ,kBAAkB;AAAA,MAC1C,gBAAgB,UAAU;AAAA,MAC1B,SAAS;AAAA,QACP,MAAM;AAAA,UACJ,QAAQ,UAAU;AAAA,QACpB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA,MAAM,OAAO,EAAE,UAAU,IAAI,MAAM;AACjC,UAAM,UAAU,mBAAiD,QAAQ;AACzE,UAAM,SAAS,SAAS;AACxB,QAAI,CAAC,OAAQ;AAEb,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,UAAM,OAAO,MAAM;AAAA,MACjB;AAAA,MACA;AAAA,MACA,EAAE,IAAI,OAAO,GAAG;AAAA,MAChB;AAAA,MACA,EAAE,UAAU,OAAO,UAAU,gBAAgB,OAAO,eAAe;AAAA,IACrE;AACA,QAAI,CAAC,KAAM;AAEX,UAAM,gBAAgB,IAAI;AAAA,MACxB,YAAY;AACV,aAAK,YAAY;AACjB,aAAK,YAAY,OAAO;AAExB,cAAM,SAAS,MAAM;AAAA,UACnB;AAAA,UACA;AAAA,UACA,EAAE,IAAI,OAAO,gBAAgB,MAAM,UAAU,UAAU,OAAO,UAAU,gBAAgB,OAAO,gBAAgB,WAAW,KAAK;AAAA,UAC/H;AAAA,UACA,EAAE,UAAU,OAAO,UAAU,gBAAgB,OAAO,eAAe;AAAA,QACrE;AACA,YAAI,UAAU,OAAO,WAAW;AAC9B,gBAAM,2BAA2B,IAAI,MAAM;AAC3C,eAAK,YAAY;AACjB,gBAAM,UAAU,MAAM;AAAA,YACpB;AAAA,YACA;AAAA,YACA,EAAE,QAAQ,OAAO;AAAA,YACjB,EAAE,UAAU,CAAC,SAAS,EAAE;AAAA,YACxB,EAAE,UAAU,OAAO,UAAU,gBAAgB,OAAO,eAAe;AAAA,UACrE;AACA,cAAI,SAAS;AACX,kBAAM,UAAU,MAAM;AAAA,cACpB;AAAA,cACA;AAAA,cACA,EAAE,IAAI,OAAO,iBAAiB,MAAM,WAAW,UAAU,OAAO,UAAU,gBAAgB,OAAO,gBAAgB,WAAW,KAAK;AAAA,cACjI;AAAA,cACA,EAAE,UAAU,OAAO,UAAU,gBAAgB,OAAO,eAAe;AAAA,YACrE;AACA,gBAAI,QAAS,SAAQ,UAAU;AAAA,UACjC;AAAA,QACF;AAAA,MACF;AAAA,IACF,GAAG,EAAE,aAAa,KAAK,CAAC;AAExB,UAAM,aAAa,IAAI,UAAU,QAAQ,YAAY;AACrD,UAAM,wBAAwB;AAAA,MAC5B;AAAA,MACA,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,aAAa,mBAAmB,IAAI;AAAA,MACpC,YAAY,IAAI;AAAA,MAChB,QAAQ;AAAA,MACR,SAAS,EAAE,YAAY,yCAAyC;AAAA,IAClE,CAAC;AAAA,EACH;AACF;AAEA,gBAAgB,8BAA8B;AAC9C,gBAAgB,8BAA8B;AAC9C,gBAAgB,8BAA8B;",
4
+ "sourcesContent": ["import { registerCommand } from '@open-mercato/shared/lib/commands'\nimport type { CommandHandler } from '@open-mercato/shared/lib/commands'\nimport type { CrudEventsConfig } from '@open-mercato/shared/lib/crud/types'\nimport { emitCrudSideEffects, emitCrudUndoSideEffects } from '@open-mercato/shared/lib/commands/helpers'\nimport { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { findOneWithDecryption } from '@open-mercato/shared/lib/encryption/find'\nimport type { DataEngine } from '@open-mercato/shared/lib/data/engine'\nimport type { EntityManager } from '@mikro-orm/postgresql'\nimport {\n CustomerEntity,\n CustomerPersonCompanyLink,\n CustomerPersonProfile,\n} from '../data/entities'\nimport {\n personCompanyLinkCreateSchema,\n personCompanyLinkDeleteSchema,\n personCompanyLinkUpdateSchema,\n type PersonCompanyLinkCreateInput,\n type PersonCompanyLinkDeleteInput,\n type PersonCompanyLinkUpdateInput,\n} from '../data/validators'\nimport {\n findDeletedPersonCompanyLink,\n loadPersonCompanyLinks,\n promoteFallbackPrimaryLink,\n} from '../lib/personCompanies'\nimport {\n ensureOrganizationScope,\n ensureTenantScope,\n extractUndoPayload,\n} from './shared'\nimport { withAtomicFlush } from '@open-mercato/shared/lib/commands/flush'\n\ntype PersonCompanyLinkSnapshot = {\n id: string\n personEntityId: string\n companyEntityId: string\n isPrimary: boolean\n tenantId: string\n organizationId: string\n deletedAt: string | null\n}\n\ntype PersonCompanyLinkUndoPayload = {\n before?: PersonCompanyLinkSnapshot | null\n after?: PersonCompanyLinkSnapshot | null\n}\n\nconst personCompanyLinkCrudEvents: CrudEventsConfig = {\n module: 'customers',\n entity: 'person_company_link',\n persistent: true,\n buildPayload: (ctx) => ({\n id: ctx.identifiers.id,\n organizationId: ctx.identifiers.organizationId,\n tenantId: ctx.identifiers.tenantId,\n ...(ctx.entity && typeof ctx.entity === 'object' && 'person' in (ctx.entity as Record<string, unknown>)\n ? {\n personEntityId:\n typeof (ctx.entity as CustomerPersonCompanyLink).person === 'string'\n ? (ctx.entity as any).person\n : (ctx.entity as CustomerPersonCompanyLink).person?.id ?? null,\n companyEntityId:\n typeof (ctx.entity as CustomerPersonCompanyLink).company === 'string'\n ? (ctx.entity as any).company\n : (ctx.entity as CustomerPersonCompanyLink).company?.id ?? null,\n }\n : {}),\n ...(ctx.syncOrigin ? { syncOrigin: ctx.syncOrigin } : {}),\n }),\n}\n\nfunction getLinkIdentifiers(link: CustomerPersonCompanyLink) {\n return {\n id: link.id,\n organizationId: link.organizationId,\n tenantId: link.tenantId,\n }\n}\n\nasync function loadPersonCompanyLinkSnapshot(\n em: EntityManager,\n id: string,\n scope?: { tenantId?: string | null; organizationId?: string | null },\n): Promise<PersonCompanyLinkSnapshot | null> {\n const filter: Record<string, unknown> = { id }\n if (scope?.tenantId) filter.tenantId = scope.tenantId\n if (scope?.organizationId) filter.organizationId = scope.organizationId\n const link = await findOneWithDecryption(\n em,\n CustomerPersonCompanyLink,\n filter,\n undefined,\n {\n tenantId: scope?.tenantId ?? null,\n organizationId: scope?.organizationId ?? null,\n },\n )\n if (!link) return null\n const personId = typeof link.person === 'string' ? link.person : link.person.id\n const companyId = typeof link.company === 'string' ? link.company : link.company.id\n return {\n id: link.id,\n personEntityId: personId,\n companyEntityId: companyId,\n isPrimary: Boolean(link.isPrimary),\n tenantId: link.tenantId,\n organizationId: link.organizationId,\n deletedAt: link.deletedAt ? link.deletedAt.toISOString() : null,\n }\n}\n\nasync function requirePersonEntity(\n em: EntityManager,\n entityId: string,\n tenantId: string,\n organizationId: string,\n): Promise<CustomerEntity> {\n const person = await findOneWithDecryption(\n em,\n CustomerEntity,\n { id: entityId, kind: 'person', tenantId, organizationId, deletedAt: null },\n undefined,\n { tenantId, organizationId },\n )\n if (!person) {\n throw new CrudHttpError(404, { error: 'Person not found' })\n }\n return person\n}\n\nasync function requireCompanyEntity(\n em: EntityManager,\n entityId: string,\n tenantId: string,\n organizationId: string,\n): Promise<CustomerEntity> {\n const company = await findOneWithDecryption(\n em,\n CustomerEntity,\n { id: entityId, kind: 'company', tenantId, organizationId, deletedAt: null },\n undefined,\n { tenantId, organizationId },\n )\n if (!company) {\n throw new CrudHttpError(404, { error: 'Company not found' })\n }\n return company\n}\n\nasync function requirePersonProfile(\n em: EntityManager,\n person: CustomerEntity,\n): Promise<CustomerPersonProfile> {\n const profile = await findOneWithDecryption(\n em,\n CustomerPersonProfile,\n { entity: person },\n { populate: ['company'] },\n { tenantId: person.tenantId, organizationId: person.organizationId },\n )\n if (!profile) {\n throw new CrudHttpError(404, { error: 'Person profile not found' })\n }\n return profile\n}\n\nasync function clearPrimaryFlagsForPerson(em: EntityManager, person: CustomerEntity): Promise<void> {\n await em.nativeUpdate(\n CustomerPersonCompanyLink,\n { person, organizationId: person.organizationId, tenantId: person.tenantId, isPrimary: true },\n { isPrimary: false },\n )\n}\n\nconst createPersonCompanyLinkCommand: CommandHandler<PersonCompanyLinkCreateInput, { linkId: string; created: boolean; undeleted: boolean }> = {\n id: 'customers.personCompanyLinks.create',\n async execute(rawInput, ctx) {\n const parsed = personCompanyLinkCreateSchema.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 person = await requirePersonEntity(em, parsed.personEntityId, parsed.tenantId, parsed.organizationId)\n const company = await requireCompanyEntity(em, parsed.companyEntityId, parsed.tenantId, parsed.organizationId)\n const profile = await requirePersonProfile(em, person)\n\n const existingLinks = await loadPersonCompanyLinks(em, person)\n const makePrimary = Boolean(parsed.isPrimary) || existingLinks.length === 0\n const existingLive =\n existingLinks.find((link) => (typeof link.company === 'string' ? link.company : link.company.id) === company.id) ?? null\n\n if (existingLive) {\n if (makePrimary && !existingLive.isPrimary) {\n await withAtomicFlush(em, [\n () => clearPrimaryFlagsForPerson(em, person),\n () => {\n existingLive.isPrimary = true\n profile.company = company\n },\n ], { transaction: true })\n }\n return { linkId: existingLive.id, created: false, undeleted: false }\n }\n\n let link!: CustomerPersonCompanyLink\n let undeleted = false\n await withAtomicFlush(em, [\n async () => {\n const deletedLink = await findDeletedPersonCompanyLink(em, person, company)\n if (makePrimary) {\n await clearPrimaryFlagsForPerson(em, person)\n }\n if (deletedLink) {\n deletedLink.deletedAt = null\n deletedLink.isPrimary = makePrimary\n em.persist(deletedLink)\n link = deletedLink\n undeleted = true\n } else {\n link = em.create(CustomerPersonCompanyLink, {\n organizationId: parsed.organizationId,\n tenantId: parsed.tenantId,\n person,\n company,\n isPrimary: makePrimary,\n })\n em.persist(link)\n }\n },\n () => {\n if (makePrimary) {\n profile.company = company\n } else if (!profile.company && existingLinks.length === 0) {\n profile.company = company\n link.isPrimary = true\n }\n },\n ], { transaction: true })\n\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n await emitCrudSideEffects({\n dataEngine,\n action: undeleted ? 'updated' : 'created',\n entity: link,\n identifiers: getLinkIdentifiers(link),\n syncOrigin: ctx.syncOrigin,\n events: personCompanyLinkCrudEvents,\n indexer: { entityType: 'customers:customer_person_company_link' },\n })\n\n return { linkId: link.id, created: !undeleted, undeleted }\n },\n captureAfter: async (_input, result, ctx) => {\n const em = ctx.container.resolve('em') as EntityManager\n return loadPersonCompanyLinkSnapshot(em, result.linkId, {\n tenantId: ctx.auth?.tenantId ?? null,\n organizationId: ctx.selectedOrganizationId ?? ctx.auth?.orgId ?? null,\n })\n },\n buildLog: async ({ result, snapshots }) => {\n const { translate } = await resolveTranslations()\n const after = snapshots.after as PersonCompanyLinkSnapshot | undefined\n return {\n actionLabel: translate('customers.audit.personCompanyLinks.create', 'Link company to person'),\n resourceKind: 'customers.personCompanyLink',\n resourceId: result.linkId,\n parentResourceKind: 'customers.person',\n parentResourceId: after?.personEntityId ?? null,\n tenantId: after?.tenantId ?? null,\n organizationId: after?.organizationId ?? null,\n snapshotAfter: after ?? null,\n payload: {\n undo: {\n after: after ?? null,\n ...(result.undeleted ? { before: null } : {}),\n } satisfies PersonCompanyLinkUndoPayload,\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<PersonCompanyLinkUndoPayload>(logEntry)\n const after = payload?.after\n if (!after) return\n\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const link = await findOneWithDecryption(\n em,\n CustomerPersonCompanyLink,\n { id: after.id },\n undefined,\n { tenantId: after.tenantId, organizationId: after.organizationId },\n )\n if (!link) return\n\n let person: CustomerEntity | null = null\n let profile: CustomerPersonProfile | null = null\n let remainingLinks: CustomerPersonCompanyLink[] = []\n\n await withAtomicFlush(em, [\n async () => {\n person = await findOneWithDecryption(\n em,\n CustomerEntity,\n { id: after.personEntityId, kind: 'person', tenantId: after.tenantId, organizationId: after.organizationId, deletedAt: null },\n undefined,\n { tenantId: after.tenantId, organizationId: after.organizationId },\n )\n if (!person) return\n profile = await findOneWithDecryption(\n em,\n CustomerPersonProfile,\n { entity: person },\n { populate: ['company'] },\n { tenantId: person.tenantId, organizationId: person.organizationId },\n )\n if (!profile) return\n remainingLinks = (await loadPersonCompanyLinks(em, person)).filter((entry) => entry.id !== link.id)\n },\n async () => {\n link.isPrimary = false\n link.deletedAt = new Date()\n if (!person || !profile) return\n if (after.isPrimary) {\n await promoteFallbackPrimaryLink(em, person, profile, remainingLinks, after.companyEntityId)\n } else if (profile.company && typeof profile.company !== 'string' && profile.company.id === after.companyEntityId) {\n profile.company = null\n }\n },\n ], { transaction: true })\n\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n await emitCrudUndoSideEffects({\n dataEngine,\n action: 'deleted',\n entity: link,\n identifiers: getLinkIdentifiers(link),\n syncOrigin: ctx.syncOrigin,\n events: personCompanyLinkCrudEvents,\n indexer: { entityType: 'customers:customer_person_company_link' },\n })\n },\n}\n\nconst updatePersonCompanyLinkCommand: CommandHandler<PersonCompanyLinkUpdateInput, { linkId: string }> = {\n id: 'customers.personCompanyLinks.update',\n async prepare(rawInput, ctx) {\n const parsed = personCompanyLinkUpdateSchema.parse(rawInput)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const snapshot = await loadPersonCompanyLinkSnapshot(em, parsed.linkId, {\n tenantId: ctx.auth?.tenantId ?? null,\n organizationId: ctx.selectedOrganizationId ?? ctx.auth?.orgId ?? null,\n })\n return snapshot ? { before: snapshot } : {}\n },\n async execute(rawInput, ctx) {\n const parsed = personCompanyLinkUpdateSchema.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 link = await findOneWithDecryption(\n em,\n CustomerPersonCompanyLink,\n {\n id: parsed.linkId,\n tenantId: parsed.tenantId,\n organizationId: parsed.organizationId,\n deletedAt: null,\n },\n undefined,\n { tenantId: parsed.tenantId, organizationId: parsed.organizationId },\n )\n if (!link) {\n throw new CrudHttpError(404, { error: 'Company link not found' })\n }\n\n const personId = typeof link.person === 'string' ? link.person : link.person.id\n const companyId = typeof link.company === 'string' ? link.company : link.company.id\n const person = await requirePersonEntity(em, personId, parsed.tenantId, parsed.organizationId)\n const profile = await requirePersonProfile(em, person)\n const linkedCompany = await requireCompanyEntity(em, companyId, parsed.tenantId, parsed.organizationId)\n\n await withAtomicFlush(em, [\n async () => {\n if (parsed.isPrimary) {\n await clearPrimaryFlagsForPerson(em, person)\n link.isPrimary = true\n profile.company = linkedCompany\n } else if (!parsed.isPrimary) {\n const linkWasPrimary = link.isPrimary\n link.isPrimary = false\n if (linkWasPrimary) {\n const remainingLinks = (await loadPersonCompanyLinks(em, person)).filter((entry) => entry.id !== link.id)\n await promoteFallbackPrimaryLink(em, person, profile, remainingLinks, companyId)\n } else if (profile.company && typeof profile.company !== 'string' && profile.company.id === companyId) {\n profile.company = null\n }\n }\n },\n ], { transaction: true })\n\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n await emitCrudSideEffects({\n dataEngine,\n action: 'updated',\n entity: link,\n identifiers: getLinkIdentifiers(link),\n syncOrigin: ctx.syncOrigin,\n events: personCompanyLinkCrudEvents,\n indexer: { entityType: 'customers:customer_person_company_link' },\n })\n\n return { linkId: link.id }\n },\n captureAfter: async (_input, result, ctx) => {\n const em = ctx.container.resolve('em') as EntityManager\n return loadPersonCompanyLinkSnapshot(em, result.linkId, {\n tenantId: ctx.auth?.tenantId ?? null,\n organizationId: ctx.selectedOrganizationId ?? ctx.auth?.orgId ?? null,\n })\n },\n buildLog: async ({ result, snapshots }) => {\n const { translate } = await resolveTranslations()\n const before = snapshots.before as PersonCompanyLinkSnapshot | undefined\n const after = snapshots.after as PersonCompanyLinkSnapshot | undefined\n return {\n actionLabel: translate('customers.audit.personCompanyLinks.update', 'Update company link'),\n resourceKind: 'customers.personCompanyLink',\n resourceId: result.linkId,\n parentResourceKind: 'customers.person',\n parentResourceId: after?.personEntityId ?? before?.personEntityId ?? null,\n tenantId: after?.tenantId ?? before?.tenantId ?? null,\n organizationId: after?.organizationId ?? before?.organizationId ?? null,\n snapshotBefore: before ?? null,\n snapshotAfter: after ?? null,\n payload: {\n undo: {\n before: before ?? null,\n after: after ?? null,\n } satisfies PersonCompanyLinkUndoPayload,\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<PersonCompanyLinkUndoPayload>(logEntry)\n const before = payload?.before\n if (!before) return\n\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const link = await findOneWithDecryption(\n em,\n CustomerPersonCompanyLink,\n { id: before.id },\n undefined,\n { tenantId: before.tenantId, organizationId: before.organizationId },\n )\n if (!link) return\n\n let person: CustomerEntity | null = null\n let profile: CustomerPersonProfile | null = null\n let company: CustomerEntity | null = null\n\n await withAtomicFlush(em, [\n async () => {\n person = await findOneWithDecryption(\n em,\n CustomerEntity,\n { id: before.personEntityId, kind: 'person', tenantId: before.tenantId, organizationId: before.organizationId, deletedAt: null },\n undefined,\n { tenantId: before.tenantId, organizationId: before.organizationId },\n )\n if (!person) return\n profile = await findOneWithDecryption(\n em,\n CustomerPersonProfile,\n { entity: person },\n { populate: ['company'] },\n { tenantId: person.tenantId, organizationId: person.organizationId },\n )\n if (!profile || !before.isPrimary) return\n company = await findOneWithDecryption(\n em,\n CustomerEntity,\n { id: before.companyEntityId, kind: 'company', tenantId: before.tenantId, organizationId: before.organizationId, deletedAt: null },\n undefined,\n { tenantId: before.tenantId, organizationId: before.organizationId },\n )\n },\n async () => {\n if (!person || !profile) return\n if (before.isPrimary) {\n await clearPrimaryFlagsForPerson(em, person)\n link.isPrimary = true\n if (company) profile.company = company\n } else {\n link.isPrimary = false\n }\n },\n ], { transaction: true })\n\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n await emitCrudUndoSideEffects({\n dataEngine,\n action: 'updated',\n entity: link,\n identifiers: getLinkIdentifiers(link),\n syncOrigin: ctx.syncOrigin,\n events: personCompanyLinkCrudEvents,\n indexer: { entityType: 'customers:customer_person_company_link' },\n })\n },\n}\n\nconst deletePersonCompanyLinkCommand: CommandHandler<PersonCompanyLinkDeleteInput, { linkId: string }> = {\n id: 'customers.personCompanyLinks.delete',\n async prepare(rawInput, ctx) {\n const parsed = personCompanyLinkDeleteSchema.parse(rawInput)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const snapshot = await loadPersonCompanyLinkSnapshot(em, parsed.linkId, {\n tenantId: ctx.auth?.tenantId ?? null,\n organizationId: ctx.selectedOrganizationId ?? ctx.auth?.orgId ?? null,\n })\n return snapshot ? { before: snapshot } : {}\n },\n async execute(rawInput, ctx) {\n const parsed = personCompanyLinkDeleteSchema.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 link = await findOneWithDecryption(\n em,\n CustomerPersonCompanyLink,\n {\n id: parsed.linkId,\n tenantId: parsed.tenantId,\n organizationId: parsed.organizationId,\n deletedAt: null,\n },\n undefined,\n { tenantId: parsed.tenantId, organizationId: parsed.organizationId },\n )\n if (!link) {\n throw new CrudHttpError(404, { error: 'Company link not found' })\n }\n\n const personId = typeof link.person === 'string' ? link.person : link.person.id\n const companyId = typeof link.company === 'string' ? link.company : link.company.id\n const person = await requirePersonEntity(em, personId, parsed.tenantId, parsed.organizationId)\n const profile = await requirePersonProfile(em, person)\n const linkWasPrimary = link.isPrimary\n\n const existingLinks = await loadPersonCompanyLinks(em, person)\n const remainingLinks = existingLinks.filter((entry) => entry.id !== link.id)\n\n await withAtomicFlush(em, [\n () => {\n link.isPrimary = false\n link.deletedAt = new Date()\n },\n async () => {\n if (linkWasPrimary) {\n await promoteFallbackPrimaryLink(em, person, profile, remainingLinks, companyId)\n } else if (profile.company && typeof profile.company !== 'string' && profile.company.id === companyId) {\n const primary = remainingLinks.find((entry) => entry.isPrimary) ?? null\n const primaryCompany = primary && typeof primary.company !== 'string' ? primary.company : null\n if (primaryCompany) {\n profile.company = primaryCompany\n }\n }\n },\n ], { transaction: true })\n\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n await emitCrudSideEffects({\n dataEngine,\n action: 'deleted',\n entity: link,\n identifiers: getLinkIdentifiers(link),\n syncOrigin: ctx.syncOrigin,\n events: personCompanyLinkCrudEvents,\n indexer: { entityType: 'customers:customer_person_company_link' },\n })\n\n return { linkId: link.id }\n },\n buildLog: async ({ result, snapshots }) => {\n const { translate } = await resolveTranslations()\n const before = snapshots.before as PersonCompanyLinkSnapshot | undefined\n return {\n actionLabel: translate('customers.audit.personCompanyLinks.delete', 'Remove company link'),\n resourceKind: 'customers.personCompanyLink',\n resourceId: result.linkId,\n parentResourceKind: 'customers.person',\n parentResourceId: before?.personEntityId ?? null,\n tenantId: before?.tenantId ?? null,\n organizationId: before?.organizationId ?? null,\n snapshotBefore: before ?? null,\n payload: {\n undo: {\n before: before ?? null,\n } satisfies PersonCompanyLinkUndoPayload,\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<PersonCompanyLinkUndoPayload>(logEntry)\n const before = payload?.before\n if (!before) return\n\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const link = await findOneWithDecryption(\n em,\n CustomerPersonCompanyLink,\n { id: before.id },\n undefined,\n { tenantId: before.tenantId, organizationId: before.organizationId },\n )\n if (!link) return\n\n let person: CustomerEntity | null = null\n let profile: CustomerPersonProfile | null = null\n let company: CustomerEntity | null = null\n\n await withAtomicFlush(em, [\n async () => {\n person = await findOneWithDecryption(\n em,\n CustomerEntity,\n { id: before.personEntityId, kind: 'person', tenantId: before.tenantId, organizationId: before.organizationId, deletedAt: null },\n undefined,\n { tenantId: before.tenantId, organizationId: before.organizationId },\n )\n if (!person || !before.isPrimary) return\n profile = await findOneWithDecryption(\n em,\n CustomerPersonProfile,\n { entity: person },\n { populate: ['company'] },\n { tenantId: person.tenantId, organizationId: person.organizationId },\n )\n if (!profile) return\n company = await findOneWithDecryption(\n em,\n CustomerEntity,\n { id: before.companyEntityId, kind: 'company', tenantId: before.tenantId, organizationId: before.organizationId, deletedAt: null },\n undefined,\n { tenantId: before.tenantId, organizationId: before.organizationId },\n )\n },\n async () => {\n link.deletedAt = null\n link.isPrimary = before.isPrimary\n if (person && before.isPrimary) {\n await clearPrimaryFlagsForPerson(em, person)\n link.isPrimary = true\n if (profile && company) profile.company = company\n }\n },\n ], { transaction: true })\n\n const dataEngine = ctx.container.resolve('dataEngine') as DataEngine\n await emitCrudUndoSideEffects({\n dataEngine,\n action: 'created',\n entity: link,\n identifiers: getLinkIdentifiers(link),\n syncOrigin: ctx.syncOrigin,\n events: personCompanyLinkCrudEvents,\n indexer: { entityType: 'customers:customer_person_company_link' },\n })\n },\n}\n\nregisterCommand(createPersonCompanyLinkCommand)\nregisterCommand(updatePersonCompanyLinkCommand)\nregisterCommand(deletePersonCompanyLinkCommand)\n"],
5
+ "mappings": "AAAA,SAAS,uBAAuB;AAGhC,SAAS,qBAAqB,+BAA+B;AAC7D,SAAS,qBAAqB;AAC9B,SAAS,2BAA2B;AACpC,SAAS,6BAA6B;AAGtC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAIK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,uBAAuB;AAiBhC,MAAM,8BAAgD;AAAA,EACpD,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,cAAc,CAAC,SAAS;AAAA,IACtB,IAAI,IAAI,YAAY;AAAA,IACpB,gBAAgB,IAAI,YAAY;AAAA,IAChC,UAAU,IAAI,YAAY;AAAA,IAC1B,GAAI,IAAI,UAAU,OAAO,IAAI,WAAW,YAAY,YAAa,IAAI,SACjE;AAAA,MACE,gBACE,OAAQ,IAAI,OAAqC,WAAW,WACvD,IAAI,OAAe,SACnB,IAAI,OAAqC,QAAQ,MAAM;AAAA,MAC9D,iBACE,OAAQ,IAAI,OAAqC,YAAY,WACxD,IAAI,OAAe,UACnB,IAAI,OAAqC,SAAS,MAAM;AAAA,IACjE,IACA,CAAC;AAAA,IACL,GAAI,IAAI,aAAa,EAAE,YAAY,IAAI,WAAW,IAAI,CAAC;AAAA,EACzD;AACF;AAEA,SAAS,mBAAmB,MAAiC;AAC3D,SAAO;AAAA,IACL,IAAI,KAAK;AAAA,IACT,gBAAgB,KAAK;AAAA,IACrB,UAAU,KAAK;AAAA,EACjB;AACF;AAEA,eAAe,8BACb,IACA,IACA,OAC2C;AAC3C,QAAM,SAAkC,EAAE,GAAG;AAC7C,MAAI,OAAO,SAAU,QAAO,WAAW,MAAM;AAC7C,MAAI,OAAO,eAAgB,QAAO,iBAAiB,MAAM;AACzD,QAAM,OAAO,MAAM;AAAA,IACjB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,MACE,UAAU,OAAO,YAAY;AAAA,MAC7B,gBAAgB,OAAO,kBAAkB;AAAA,IAC3C;AAAA,EACF;AACA,MAAI,CAAC,KAAM,QAAO;AAClB,QAAM,WAAW,OAAO,KAAK,WAAW,WAAW,KAAK,SAAS,KAAK,OAAO;AAC7E,QAAM,YAAY,OAAO,KAAK,YAAY,WAAW,KAAK,UAAU,KAAK,QAAQ;AACjF,SAAO;AAAA,IACL,IAAI,KAAK;AAAA,IACT,gBAAgB;AAAA,IAChB,iBAAiB;AAAA,IACjB,WAAW,QAAQ,KAAK,SAAS;AAAA,IACjC,UAAU,KAAK;AAAA,IACf,gBAAgB,KAAK;AAAA,IACrB,WAAW,KAAK,YAAY,KAAK,UAAU,YAAY,IAAI;AAAA,EAC7D;AACF;AAEA,eAAe,oBACb,IACA,UACA,UACA,gBACyB;AACzB,QAAM,SAAS,MAAM;AAAA,IACnB;AAAA,IACA;AAAA,IACA,EAAE,IAAI,UAAU,MAAM,UAAU,UAAU,gBAAgB,WAAW,KAAK;AAAA,IAC1E;AAAA,IACA,EAAE,UAAU,eAAe;AAAA,EAC7B;AACA,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,cAAc,KAAK,EAAE,OAAO,mBAAmB,CAAC;AAAA,EAC5D;AACA,SAAO;AACT;AAEA,eAAe,qBACb,IACA,UACA,UACA,gBACyB;AACzB,QAAM,UAAU,MAAM;AAAA,IACpB;AAAA,IACA;AAAA,IACA,EAAE,IAAI,UAAU,MAAM,WAAW,UAAU,gBAAgB,WAAW,KAAK;AAAA,IAC3E;AAAA,IACA,EAAE,UAAU,eAAe;AAAA,EAC7B;AACA,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,cAAc,KAAK,EAAE,OAAO,oBAAoB,CAAC;AAAA,EAC7D;AACA,SAAO;AACT;AAEA,eAAe,qBACb,IACA,QACgC;AAChC,QAAM,UAAU,MAAM;AAAA,IACpB;AAAA,IACA;AAAA,IACA,EAAE,QAAQ,OAAO;AAAA,IACjB,EAAE,UAAU,CAAC,SAAS,EAAE;AAAA,IACxB,EAAE,UAAU,OAAO,UAAU,gBAAgB,OAAO,eAAe;AAAA,EACrE;AACA,MAAI,CAAC,SAAS;AACZ,UAAM,IAAI,cAAc,KAAK,EAAE,OAAO,2BAA2B,CAAC;AAAA,EACpE;AACA,SAAO;AACT;AAEA,eAAe,2BAA2B,IAAmB,QAAuC;AAClG,QAAM,GAAG;AAAA,IACP;AAAA,IACA,EAAE,QAAQ,gBAAgB,OAAO,gBAAgB,UAAU,OAAO,UAAU,WAAW,KAAK;AAAA,IAC5F,EAAE,WAAW,MAAM;AAAA,EACrB;AACF;AAEA,MAAM,iCAAyI;AAAA,EAC7I,IAAI;AAAA,EACJ,MAAM,QAAQ,UAAU,KAAK;AAC3B,UAAM,SAAS,8BAA8B,MAAM,QAAQ;AAC3D,sBAAkB,KAAK,OAAO,QAAQ;AACtC,4BAAwB,KAAK,OAAO,cAAc;AAElD,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,UAAM,SAAS,MAAM,oBAAoB,IAAI,OAAO,gBAAgB,OAAO,UAAU,OAAO,cAAc;AAC1G,UAAM,UAAU,MAAM,qBAAqB,IAAI,OAAO,iBAAiB,OAAO,UAAU,OAAO,cAAc;AAC7G,UAAM,UAAU,MAAM,qBAAqB,IAAI,MAAM;AAErD,UAAM,gBAAgB,MAAM,uBAAuB,IAAI,MAAM;AAC7D,UAAM,cAAc,QAAQ,OAAO,SAAS,KAAK,cAAc,WAAW;AAC1E,UAAM,eACJ,cAAc,KAAK,CAACA,WAAU,OAAOA,MAAK,YAAY,WAAWA,MAAK,UAAUA,MAAK,QAAQ,QAAQ,QAAQ,EAAE,KAAK;AAEtH,QAAI,cAAc;AAChB,UAAI,eAAe,CAAC,aAAa,WAAW;AAC1C,cAAM,gBAAgB,IAAI;AAAA,UACxB,MAAM,2BAA2B,IAAI,MAAM;AAAA,UAC3C,MAAM;AACJ,yBAAa,YAAY;AACzB,oBAAQ,UAAU;AAAA,UACpB;AAAA,QACF,GAAG,EAAE,aAAa,KAAK,CAAC;AAAA,MAC1B;AACA,aAAO,EAAE,QAAQ,aAAa,IAAI,SAAS,OAAO,WAAW,MAAM;AAAA,IACrE;AAEA,QAAI;AACJ,QAAI,YAAY;AAChB,UAAM,gBAAgB,IAAI;AAAA,MACxB,YAAY;AACV,cAAM,cAAc,MAAM,6BAA6B,IAAI,QAAQ,OAAO;AAC1E,YAAI,aAAa;AACf,gBAAM,2BAA2B,IAAI,MAAM;AAAA,QAC7C;AACA,YAAI,aAAa;AACf,sBAAY,YAAY;AACxB,sBAAY,YAAY;AACxB,aAAG,QAAQ,WAAW;AACtB,iBAAO;AACP,sBAAY;AAAA,QACd,OAAO;AACL,iBAAO,GAAG,OAAO,2BAA2B;AAAA,YAC1C,gBAAgB,OAAO;AAAA,YACvB,UAAU,OAAO;AAAA,YACjB;AAAA,YACA;AAAA,YACA,WAAW;AAAA,UACb,CAAC;AACD,aAAG,QAAQ,IAAI;AAAA,QACjB;AAAA,MACF;AAAA,MACA,MAAM;AACJ,YAAI,aAAa;AACf,kBAAQ,UAAU;AAAA,QACpB,WAAW,CAAC,QAAQ,WAAW,cAAc,WAAW,GAAG;AACzD,kBAAQ,UAAU;AAClB,eAAK,YAAY;AAAA,QACnB;AAAA,MACF;AAAA,IACF,GAAG,EAAE,aAAa,KAAK,CAAC;AAExB,UAAM,aAAa,IAAI,UAAU,QAAQ,YAAY;AACrD,UAAM,oBAAoB;AAAA,MACxB;AAAA,MACA,QAAQ,YAAY,YAAY;AAAA,MAChC,QAAQ;AAAA,MACR,aAAa,mBAAmB,IAAI;AAAA,MACpC,YAAY,IAAI;AAAA,MAChB,QAAQ;AAAA,MACR,SAAS,EAAE,YAAY,yCAAyC;AAAA,IAClE,CAAC;AAED,WAAO,EAAE,QAAQ,KAAK,IAAI,SAAS,CAAC,WAAW,UAAU;AAAA,EAC3D;AAAA,EACA,cAAc,OAAO,QAAQ,QAAQ,QAAQ;AAC3C,UAAM,KAAK,IAAI,UAAU,QAAQ,IAAI;AACrC,WAAO,8BAA8B,IAAI,OAAO,QAAQ;AAAA,MACtD,UAAU,IAAI,MAAM,YAAY;AAAA,MAChC,gBAAgB,IAAI,0BAA0B,IAAI,MAAM,SAAS;AAAA,IACnE,CAAC;AAAA,EACH;AAAA,EACA,UAAU,OAAO,EAAE,QAAQ,UAAU,MAAM;AACzC,UAAM,EAAE,UAAU,IAAI,MAAM,oBAAoB;AAChD,UAAM,QAAQ,UAAU;AACxB,WAAO;AAAA,MACL,aAAa,UAAU,6CAA6C,wBAAwB;AAAA,MAC5F,cAAc;AAAA,MACd,YAAY,OAAO;AAAA,MACnB,oBAAoB;AAAA,MACpB,kBAAkB,OAAO,kBAAkB;AAAA,MAC3C,UAAU,OAAO,YAAY;AAAA,MAC7B,gBAAgB,OAAO,kBAAkB;AAAA,MACzC,eAAe,SAAS;AAAA,MACxB,SAAS;AAAA,QACP,MAAM;AAAA,UACJ,OAAO,SAAS;AAAA,UAChB,GAAI,OAAO,YAAY,EAAE,QAAQ,KAAK,IAAI,CAAC;AAAA,QAC7C;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA,MAAM,OAAO,EAAE,UAAU,IAAI,MAAM;AACjC,UAAM,UAAU,mBAAiD,QAAQ;AACzE,UAAM,QAAQ,SAAS;AACvB,QAAI,CAAC,MAAO;AAEZ,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,UAAM,OAAO,MAAM;AAAA,MACjB;AAAA,MACA;AAAA,MACA,EAAE,IAAI,MAAM,GAAG;AAAA,MACf;AAAA,MACA,EAAE,UAAU,MAAM,UAAU,gBAAgB,MAAM,eAAe;AAAA,IACnE;AACA,QAAI,CAAC,KAAM;AAEX,QAAI,SAAgC;AACpC,QAAI,UAAwC;AAC5C,QAAI,iBAA8C,CAAC;AAEnD,UAAM,gBAAgB,IAAI;AAAA,MACxB,YAAY;AACV,iBAAS,MAAM;AAAA,UACb;AAAA,UACA;AAAA,UACA,EAAE,IAAI,MAAM,gBAAgB,MAAM,UAAU,UAAU,MAAM,UAAU,gBAAgB,MAAM,gBAAgB,WAAW,KAAK;AAAA,UAC5H;AAAA,UACA,EAAE,UAAU,MAAM,UAAU,gBAAgB,MAAM,eAAe;AAAA,QACnE;AACA,YAAI,CAAC,OAAQ;AACb,kBAAU,MAAM;AAAA,UACd;AAAA,UACA;AAAA,UACA,EAAE,QAAQ,OAAO;AAAA,UACjB,EAAE,UAAU,CAAC,SAAS,EAAE;AAAA,UACxB,EAAE,UAAU,OAAO,UAAU,gBAAgB,OAAO,eAAe;AAAA,QACrE;AACA,YAAI,CAAC,QAAS;AACd,0BAAkB,MAAM,uBAAuB,IAAI,MAAM,GAAG,OAAO,CAAC,UAAU,MAAM,OAAO,KAAK,EAAE;AAAA,MACpG;AAAA,MACA,YAAY;AACV,aAAK,YAAY;AACjB,aAAK,YAAY,oBAAI,KAAK;AAC1B,YAAI,CAAC,UAAU,CAAC,QAAS;AACzB,YAAI,MAAM,WAAW;AACnB,gBAAM,2BAA2B,IAAI,QAAQ,SAAS,gBAAgB,MAAM,eAAe;AAAA,QAC7F,WAAW,QAAQ,WAAW,OAAO,QAAQ,YAAY,YAAY,QAAQ,QAAQ,OAAO,MAAM,iBAAiB;AACjH,kBAAQ,UAAU;AAAA,QACpB;AAAA,MACF;AAAA,IACF,GAAG,EAAE,aAAa,KAAK,CAAC;AAExB,UAAM,aAAa,IAAI,UAAU,QAAQ,YAAY;AACrD,UAAM,wBAAwB;AAAA,MAC5B;AAAA,MACA,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,aAAa,mBAAmB,IAAI;AAAA,MACpC,YAAY,IAAI;AAAA,MAChB,QAAQ;AAAA,MACR,SAAS,EAAE,YAAY,yCAAyC;AAAA,IAClE,CAAC;AAAA,EACH;AACF;AAEA,MAAM,iCAAmG;AAAA,EACvG,IAAI;AAAA,EACJ,MAAM,QAAQ,UAAU,KAAK;AAC3B,UAAM,SAAS,8BAA8B,MAAM,QAAQ;AAC3D,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,UAAM,WAAW,MAAM,8BAA8B,IAAI,OAAO,QAAQ;AAAA,MACtE,UAAU,IAAI,MAAM,YAAY;AAAA,MAChC,gBAAgB,IAAI,0BAA0B,IAAI,MAAM,SAAS;AAAA,IACnE,CAAC;AACD,WAAO,WAAW,EAAE,QAAQ,SAAS,IAAI,CAAC;AAAA,EAC5C;AAAA,EACA,MAAM,QAAQ,UAAU,KAAK;AAC3B,UAAM,SAAS,8BAA8B,MAAM,QAAQ;AAC3D,sBAAkB,KAAK,OAAO,QAAQ;AACtC,4BAAwB,KAAK,OAAO,cAAc;AAElD,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,UAAM,OAAO,MAAM;AAAA,MACjB;AAAA,MACA;AAAA,MACA;AAAA,QACE,IAAI,OAAO;AAAA,QACX,UAAU,OAAO;AAAA,QACjB,gBAAgB,OAAO;AAAA,QACvB,WAAW;AAAA,MACb;AAAA,MACA;AAAA,MACA,EAAE,UAAU,OAAO,UAAU,gBAAgB,OAAO,eAAe;AAAA,IACrE;AACA,QAAI,CAAC,MAAM;AACT,YAAM,IAAI,cAAc,KAAK,EAAE,OAAO,yBAAyB,CAAC;AAAA,IAClE;AAEA,UAAM,WAAW,OAAO,KAAK,WAAW,WAAW,KAAK,SAAS,KAAK,OAAO;AAC7E,UAAM,YAAY,OAAO,KAAK,YAAY,WAAW,KAAK,UAAU,KAAK,QAAQ;AACjF,UAAM,SAAS,MAAM,oBAAoB,IAAI,UAAU,OAAO,UAAU,OAAO,cAAc;AAC7F,UAAM,UAAU,MAAM,qBAAqB,IAAI,MAAM;AACrD,UAAM,gBAAgB,MAAM,qBAAqB,IAAI,WAAW,OAAO,UAAU,OAAO,cAAc;AAEtG,UAAM,gBAAgB,IAAI;AAAA,MACxB,YAAY;AACV,YAAI,OAAO,WAAW;AACpB,gBAAM,2BAA2B,IAAI,MAAM;AAC3C,eAAK,YAAY;AACjB,kBAAQ,UAAU;AAAA,QACpB,WAAW,CAAC,OAAO,WAAW;AAC5B,gBAAM,iBAAiB,KAAK;AAC5B,eAAK,YAAY;AACjB,cAAI,gBAAgB;AAClB,kBAAM,kBAAkB,MAAM,uBAAuB,IAAI,MAAM,GAAG,OAAO,CAAC,UAAU,MAAM,OAAO,KAAK,EAAE;AACxG,kBAAM,2BAA2B,IAAI,QAAQ,SAAS,gBAAgB,SAAS;AAAA,UACjF,WAAW,QAAQ,WAAW,OAAO,QAAQ,YAAY,YAAY,QAAQ,QAAQ,OAAO,WAAW;AACrG,oBAAQ,UAAU;AAAA,UACpB;AAAA,QACF;AAAA,MACF;AAAA,IACF,GAAG,EAAE,aAAa,KAAK,CAAC;AAExB,UAAM,aAAa,IAAI,UAAU,QAAQ,YAAY;AACrD,UAAM,oBAAoB;AAAA,MACxB;AAAA,MACA,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,aAAa,mBAAmB,IAAI;AAAA,MACpC,YAAY,IAAI;AAAA,MAChB,QAAQ;AAAA,MACR,SAAS,EAAE,YAAY,yCAAyC;AAAA,IAClE,CAAC;AAED,WAAO,EAAE,QAAQ,KAAK,GAAG;AAAA,EAC3B;AAAA,EACA,cAAc,OAAO,QAAQ,QAAQ,QAAQ;AAC3C,UAAM,KAAK,IAAI,UAAU,QAAQ,IAAI;AACrC,WAAO,8BAA8B,IAAI,OAAO,QAAQ;AAAA,MACtD,UAAU,IAAI,MAAM,YAAY;AAAA,MAChC,gBAAgB,IAAI,0BAA0B,IAAI,MAAM,SAAS;AAAA,IACnE,CAAC;AAAA,EACH;AAAA,EACA,UAAU,OAAO,EAAE,QAAQ,UAAU,MAAM;AACzC,UAAM,EAAE,UAAU,IAAI,MAAM,oBAAoB;AAChD,UAAM,SAAS,UAAU;AACzB,UAAM,QAAQ,UAAU;AACxB,WAAO;AAAA,MACL,aAAa,UAAU,6CAA6C,qBAAqB;AAAA,MACzF,cAAc;AAAA,MACd,YAAY,OAAO;AAAA,MACnB,oBAAoB;AAAA,MACpB,kBAAkB,OAAO,kBAAkB,QAAQ,kBAAkB;AAAA,MACrE,UAAU,OAAO,YAAY,QAAQ,YAAY;AAAA,MACjD,gBAAgB,OAAO,kBAAkB,QAAQ,kBAAkB;AAAA,MACnE,gBAAgB,UAAU;AAAA,MAC1B,eAAe,SAAS;AAAA,MACxB,SAAS;AAAA,QACP,MAAM;AAAA,UACJ,QAAQ,UAAU;AAAA,UAClB,OAAO,SAAS;AAAA,QAClB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA,MAAM,OAAO,EAAE,UAAU,IAAI,MAAM;AACjC,UAAM,UAAU,mBAAiD,QAAQ;AACzE,UAAM,SAAS,SAAS;AACxB,QAAI,CAAC,OAAQ;AAEb,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,UAAM,OAAO,MAAM;AAAA,MACjB;AAAA,MACA;AAAA,MACA,EAAE,IAAI,OAAO,GAAG;AAAA,MAChB;AAAA,MACA,EAAE,UAAU,OAAO,UAAU,gBAAgB,OAAO,eAAe;AAAA,IACrE;AACA,QAAI,CAAC,KAAM;AAEX,QAAI,SAAgC;AACpC,QAAI,UAAwC;AAC5C,QAAI,UAAiC;AAErC,UAAM,gBAAgB,IAAI;AAAA,MACxB,YAAY;AACV,iBAAS,MAAM;AAAA,UACb;AAAA,UACA;AAAA,UACA,EAAE,IAAI,OAAO,gBAAgB,MAAM,UAAU,UAAU,OAAO,UAAU,gBAAgB,OAAO,gBAAgB,WAAW,KAAK;AAAA,UAC/H;AAAA,UACA,EAAE,UAAU,OAAO,UAAU,gBAAgB,OAAO,eAAe;AAAA,QACrE;AACA,YAAI,CAAC,OAAQ;AACb,kBAAU,MAAM;AAAA,UACd;AAAA,UACA;AAAA,UACA,EAAE,QAAQ,OAAO;AAAA,UACjB,EAAE,UAAU,CAAC,SAAS,EAAE;AAAA,UACxB,EAAE,UAAU,OAAO,UAAU,gBAAgB,OAAO,eAAe;AAAA,QACrE;AACA,YAAI,CAAC,WAAW,CAAC,OAAO,UAAW;AACnC,kBAAU,MAAM;AAAA,UACd;AAAA,UACA;AAAA,UACA,EAAE,IAAI,OAAO,iBAAiB,MAAM,WAAW,UAAU,OAAO,UAAU,gBAAgB,OAAO,gBAAgB,WAAW,KAAK;AAAA,UACjI;AAAA,UACA,EAAE,UAAU,OAAO,UAAU,gBAAgB,OAAO,eAAe;AAAA,QACrE;AAAA,MACF;AAAA,MACA,YAAY;AACV,YAAI,CAAC,UAAU,CAAC,QAAS;AACzB,YAAI,OAAO,WAAW;AACpB,gBAAM,2BAA2B,IAAI,MAAM;AAC3C,eAAK,YAAY;AACjB,cAAI,QAAS,SAAQ,UAAU;AAAA,QACjC,OAAO;AACL,eAAK,YAAY;AAAA,QACnB;AAAA,MACF;AAAA,IACF,GAAG,EAAE,aAAa,KAAK,CAAC;AAExB,UAAM,aAAa,IAAI,UAAU,QAAQ,YAAY;AACrD,UAAM,wBAAwB;AAAA,MAC5B;AAAA,MACA,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,aAAa,mBAAmB,IAAI;AAAA,MACpC,YAAY,IAAI;AAAA,MAChB,QAAQ;AAAA,MACR,SAAS,EAAE,YAAY,yCAAyC;AAAA,IAClE,CAAC;AAAA,EACH;AACF;AAEA,MAAM,iCAAmG;AAAA,EACvG,IAAI;AAAA,EACJ,MAAM,QAAQ,UAAU,KAAK;AAC3B,UAAM,SAAS,8BAA8B,MAAM,QAAQ;AAC3D,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,UAAM,WAAW,MAAM,8BAA8B,IAAI,OAAO,QAAQ;AAAA,MACtE,UAAU,IAAI,MAAM,YAAY;AAAA,MAChC,gBAAgB,IAAI,0BAA0B,IAAI,MAAM,SAAS;AAAA,IACnE,CAAC;AACD,WAAO,WAAW,EAAE,QAAQ,SAAS,IAAI,CAAC;AAAA,EAC5C;AAAA,EACA,MAAM,QAAQ,UAAU,KAAK;AAC3B,UAAM,SAAS,8BAA8B,MAAM,QAAQ;AAC3D,sBAAkB,KAAK,OAAO,QAAQ;AACtC,4BAAwB,KAAK,OAAO,cAAc;AAElD,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,UAAM,OAAO,MAAM;AAAA,MACjB;AAAA,MACA;AAAA,MACA;AAAA,QACE,IAAI,OAAO;AAAA,QACX,UAAU,OAAO;AAAA,QACjB,gBAAgB,OAAO;AAAA,QACvB,WAAW;AAAA,MACb;AAAA,MACA;AAAA,MACA,EAAE,UAAU,OAAO,UAAU,gBAAgB,OAAO,eAAe;AAAA,IACrE;AACA,QAAI,CAAC,MAAM;AACT,YAAM,IAAI,cAAc,KAAK,EAAE,OAAO,yBAAyB,CAAC;AAAA,IAClE;AAEA,UAAM,WAAW,OAAO,KAAK,WAAW,WAAW,KAAK,SAAS,KAAK,OAAO;AAC7E,UAAM,YAAY,OAAO,KAAK,YAAY,WAAW,KAAK,UAAU,KAAK,QAAQ;AACjF,UAAM,SAAS,MAAM,oBAAoB,IAAI,UAAU,OAAO,UAAU,OAAO,cAAc;AAC7F,UAAM,UAAU,MAAM,qBAAqB,IAAI,MAAM;AACrD,UAAM,iBAAiB,KAAK;AAE5B,UAAM,gBAAgB,MAAM,uBAAuB,IAAI,MAAM;AAC7D,UAAM,iBAAiB,cAAc,OAAO,CAAC,UAAU,MAAM,OAAO,KAAK,EAAE;AAE3E,UAAM,gBAAgB,IAAI;AAAA,MACxB,MAAM;AACJ,aAAK,YAAY;AACjB,aAAK,YAAY,oBAAI,KAAK;AAAA,MAC5B;AAAA,MACA,YAAY;AACV,YAAI,gBAAgB;AAClB,gBAAM,2BAA2B,IAAI,QAAQ,SAAS,gBAAgB,SAAS;AAAA,QACjF,WAAW,QAAQ,WAAW,OAAO,QAAQ,YAAY,YAAY,QAAQ,QAAQ,OAAO,WAAW;AACrG,gBAAM,UAAU,eAAe,KAAK,CAAC,UAAU,MAAM,SAAS,KAAK;AACnE,gBAAM,iBAAiB,WAAW,OAAO,QAAQ,YAAY,WAAW,QAAQ,UAAU;AAC1F,cAAI,gBAAgB;AAClB,oBAAQ,UAAU;AAAA,UACpB;AAAA,QACF;AAAA,MACF;AAAA,IACF,GAAG,EAAE,aAAa,KAAK,CAAC;AAExB,UAAM,aAAa,IAAI,UAAU,QAAQ,YAAY;AACrD,UAAM,oBAAoB;AAAA,MACxB;AAAA,MACA,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,aAAa,mBAAmB,IAAI;AAAA,MACpC,YAAY,IAAI;AAAA,MAChB,QAAQ;AAAA,MACR,SAAS,EAAE,YAAY,yCAAyC;AAAA,IAClE,CAAC;AAED,WAAO,EAAE,QAAQ,KAAK,GAAG;AAAA,EAC3B;AAAA,EACA,UAAU,OAAO,EAAE,QAAQ,UAAU,MAAM;AACzC,UAAM,EAAE,UAAU,IAAI,MAAM,oBAAoB;AAChD,UAAM,SAAS,UAAU;AACzB,WAAO;AAAA,MACL,aAAa,UAAU,6CAA6C,qBAAqB;AAAA,MACzF,cAAc;AAAA,MACd,YAAY,OAAO;AAAA,MACnB,oBAAoB;AAAA,MACpB,kBAAkB,QAAQ,kBAAkB;AAAA,MAC5C,UAAU,QAAQ,YAAY;AAAA,MAC9B,gBAAgB,QAAQ,kBAAkB;AAAA,MAC1C,gBAAgB,UAAU;AAAA,MAC1B,SAAS;AAAA,QACP,MAAM;AAAA,UACJ,QAAQ,UAAU;AAAA,QACpB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA,MAAM,OAAO,EAAE,UAAU,IAAI,MAAM;AACjC,UAAM,UAAU,mBAAiD,QAAQ;AACzE,UAAM,SAAS,SAAS;AACxB,QAAI,CAAC,OAAQ;AAEb,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,UAAM,OAAO,MAAM;AAAA,MACjB;AAAA,MACA;AAAA,MACA,EAAE,IAAI,OAAO,GAAG;AAAA,MAChB;AAAA,MACA,EAAE,UAAU,OAAO,UAAU,gBAAgB,OAAO,eAAe;AAAA,IACrE;AACA,QAAI,CAAC,KAAM;AAEX,QAAI,SAAgC;AACpC,QAAI,UAAwC;AAC5C,QAAI,UAAiC;AAErC,UAAM,gBAAgB,IAAI;AAAA,MACxB,YAAY;AACV,iBAAS,MAAM;AAAA,UACb;AAAA,UACA;AAAA,UACA,EAAE,IAAI,OAAO,gBAAgB,MAAM,UAAU,UAAU,OAAO,UAAU,gBAAgB,OAAO,gBAAgB,WAAW,KAAK;AAAA,UAC/H;AAAA,UACA,EAAE,UAAU,OAAO,UAAU,gBAAgB,OAAO,eAAe;AAAA,QACrE;AACA,YAAI,CAAC,UAAU,CAAC,OAAO,UAAW;AAClC,kBAAU,MAAM;AAAA,UACd;AAAA,UACA;AAAA,UACA,EAAE,QAAQ,OAAO;AAAA,UACjB,EAAE,UAAU,CAAC,SAAS,EAAE;AAAA,UACxB,EAAE,UAAU,OAAO,UAAU,gBAAgB,OAAO,eAAe;AAAA,QACrE;AACA,YAAI,CAAC,QAAS;AACd,kBAAU,MAAM;AAAA,UACd;AAAA,UACA;AAAA,UACA,EAAE,IAAI,OAAO,iBAAiB,MAAM,WAAW,UAAU,OAAO,UAAU,gBAAgB,OAAO,gBAAgB,WAAW,KAAK;AAAA,UACjI;AAAA,UACA,EAAE,UAAU,OAAO,UAAU,gBAAgB,OAAO,eAAe;AAAA,QACrE;AAAA,MACF;AAAA,MACA,YAAY;AACV,aAAK,YAAY;AACjB,aAAK,YAAY,OAAO;AACxB,YAAI,UAAU,OAAO,WAAW;AAC9B,gBAAM,2BAA2B,IAAI,MAAM;AAC3C,eAAK,YAAY;AACjB,cAAI,WAAW,QAAS,SAAQ,UAAU;AAAA,QAC5C;AAAA,MACF;AAAA,IACF,GAAG,EAAE,aAAa,KAAK,CAAC;AAExB,UAAM,aAAa,IAAI,UAAU,QAAQ,YAAY;AACrD,UAAM,wBAAwB;AAAA,MAC5B;AAAA,MACA,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,aAAa,mBAAmB,IAAI;AAAA,MACpC,YAAY,IAAI;AAAA,MAChB,QAAQ;AAAA,MACR,SAAS,EAAE,YAAY,yCAAyC;AAAA,IAClE,CAAC;AAAA,EACH;AACF;AAEA,gBAAgB,8BAA8B;AAC9C,gBAAgB,8BAA8B;AAC9C,gBAAgB,8BAA8B;",
6
6
  "names": ["link"]
7
7
  }
@@ -610,6 +610,7 @@ const updatePaymentCommand = {
610
610
  });
611
611
  }
612
612
  payment.updatedAt = /* @__PURE__ */ new Date();
613
+ await tx.flush();
613
614
  if (input.allocations !== void 0) {
614
615
  const existingAllocations = await findWithDecryption(tx, SalesPaymentAllocation, { payment }, {}, { tenantId: payment.tenantId, organizationId: payment.organizationId });
615
616
  existingAllocations.forEach((allocation) => tx.remove(allocation));
@@ -668,6 +669,20 @@ const updatePaymentCommand = {
668
669
  });
669
670
  tx.persist(entity);
670
671
  }
672
+ } else if (input.amount !== void 0 || input.currencyCode !== void 0) {
673
+ const existingAllocations = await findWithDecryption(tx, SalesPaymentAllocation, { payment }, {}, { tenantId: payment.tenantId, organizationId: payment.organizationId });
674
+ const paymentOrderId = (typeof payment.order === "string" ? payment.order : payment.order?.id) ?? null;
675
+ const isDefaultAllocation = (allocation) => {
676
+ const allocationOrderId = typeof allocation.order === "string" ? allocation.order : allocation.order?.id ?? null;
677
+ const allocationInvoiceId = typeof allocation.invoice === "string" ? allocation.invoice : allocation.invoice?.id ?? null;
678
+ return allocationInvoiceId === null && allocationOrderId === paymentOrderId;
679
+ };
680
+ if (existingAllocations.length === 1 && isDefaultAllocation(existingAllocations[0])) {
681
+ const [allocation] = existingAllocations;
682
+ allocation.amount = toNumericString(toNumber(payment.amount)) ?? "0";
683
+ allocation.currencyCode = payment.currencyCode;
684
+ tx.persist(allocation);
685
+ }
671
686
  }
672
687
  });
673
688
  const nextOrderId = payment.order?.id ?? (typeof payment.order === "string" ? payment.order : null);