@open-mercato/core 0.10.1-develop.7715.1.9483283afa → 0.10.1-develop.7717.1.2befe9c634
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.
|
@@ -17,7 +17,7 @@ import {
|
|
|
17
17
|
buildCustomFieldResetMap,
|
|
18
18
|
diffCustomFieldChanges
|
|
19
19
|
} from "@open-mercato/shared/lib/commands/customFieldSnapshots";
|
|
20
|
-
import { extractUndoPayload } from "@open-mercato/shared/lib/commands/undo";
|
|
20
|
+
import { extractUndoPayload, reviveSnapshotDates } from "@open-mercato/shared/lib/commands/undo";
|
|
21
21
|
import { resolveRedoSnapshot } from "@open-mercato/shared/lib/commands/redo";
|
|
22
22
|
import { withAtomicFlush } from "@open-mercato/shared/lib/commands/flush";
|
|
23
23
|
import {
|
|
@@ -150,6 +150,7 @@ function captureOrganizationSnapshots(entity, childParents, custom) {
|
|
|
150
150
|
undo: {
|
|
151
151
|
id: String(entity.id),
|
|
152
152
|
tenantId,
|
|
153
|
+
createdAt: entity.createdAt ? entity.createdAt.toISOString() : null,
|
|
153
154
|
name: entity.name,
|
|
154
155
|
slug: entity.slug ?? null,
|
|
155
156
|
logoUrl: entity.logoUrl ?? null,
|
|
@@ -251,8 +252,7 @@ async function resolveUniqueSlug(em, tenantId, baseSlug, excludeId) {
|
|
|
251
252
|
while (suffix < maxAttempts) {
|
|
252
253
|
const filter = {
|
|
253
254
|
tenant: tenantId,
|
|
254
|
-
slug: candidate
|
|
255
|
-
deletedAt: null
|
|
255
|
+
slug: candidate
|
|
256
256
|
};
|
|
257
257
|
const existing = await em.findOne(Organization, filter);
|
|
258
258
|
if (!existing || excludeId && String(existing.id) === excludeId) return candidate;
|
|
@@ -373,6 +373,7 @@ const createOrganizationCommand = {
|
|
|
373
373
|
await assertOrganizationUndoTenantAccess(ctx, tenantId);
|
|
374
374
|
const em = ctx.container.resolve("em");
|
|
375
375
|
const de = ctx.container.resolve("dataEngine");
|
|
376
|
+
let organization = null;
|
|
376
377
|
await withAtomicFlush(em, [
|
|
377
378
|
async () => {
|
|
378
379
|
await lockOrganizationHierarchyForTenant(em, tenantId);
|
|
@@ -391,14 +392,28 @@ const createOrganizationCommand = {
|
|
|
391
392
|
});
|
|
392
393
|
}
|
|
393
394
|
}
|
|
394
|
-
await de.deleteOrmEntity({
|
|
395
|
+
organization = await de.deleteOrmEntity({
|
|
395
396
|
entity: Organization,
|
|
396
397
|
where: buildOrganizationMutationFilter(after.id, tenantId),
|
|
397
|
-
soft:
|
|
398
|
+
soft: true,
|
|
399
|
+
softDeleteField: "deletedAt"
|
|
398
400
|
});
|
|
401
|
+
if (organization) {
|
|
402
|
+
organization.isActive = false;
|
|
403
|
+
organization.parentId = null;
|
|
404
|
+
await em.flush();
|
|
405
|
+
}
|
|
399
406
|
await rebuildHierarchyForTenant(em, tenantId);
|
|
400
407
|
}
|
|
401
408
|
], { transaction: true });
|
|
409
|
+
await emitCrudUndoSideEffects({
|
|
410
|
+
dataEngine: de,
|
|
411
|
+
action: "deleted",
|
|
412
|
+
entity: organization,
|
|
413
|
+
identifiers: { id: after.id, tenantId, organizationId: after.id },
|
|
414
|
+
events: organizationCrudEvents,
|
|
415
|
+
indexer: organizationCrudIndexer
|
|
416
|
+
});
|
|
402
417
|
},
|
|
403
418
|
redo: async ({ logEntry, ctx }) => {
|
|
404
419
|
const after = resolveRedoSnapshot(logEntry);
|
|
@@ -424,10 +439,14 @@ const createOrganizationCommand = {
|
|
|
424
439
|
await em.flush();
|
|
425
440
|
organization = existing;
|
|
426
441
|
} else {
|
|
442
|
+
const snapshotAfter = logEntry.snapshotAfter;
|
|
443
|
+
const createdAt = after.createdAt ?? (snapshotAfter && typeof snapshotAfter === "object" && "createdAt" in snapshotAfter ? snapshotAfter.createdAt : void 0);
|
|
444
|
+
const creationTime = typeof createdAt === "string" || createdAt instanceof Date ? reviveSnapshotDates({ createdAt }, ["createdAt"]) : {};
|
|
427
445
|
organization = await de.createOrmEntity({
|
|
428
446
|
entity: Organization,
|
|
429
447
|
data: {
|
|
430
448
|
id: after.id,
|
|
449
|
+
...creationTime,
|
|
431
450
|
name: after.name,
|
|
432
451
|
slug: after.slug ?? null,
|
|
433
452
|
logoUrl: after.logoUrl ?? null,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/modules/directory/commands/organizations.ts"],
|
|
4
|
-
"sourcesContent": ["import type { CommandHandler, CommandRuntimeContext } from '@open-mercato/shared/lib/commands'\nimport { registerCommand } from '@open-mercato/shared/lib/commands'\nimport { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport type { EntityManager, FilterQuery } from '@mikro-orm/postgresql'\nimport type { DataEngine } from '@open-mercato/shared/lib/data/engine'\nimport { Organization, Tenant } from '@open-mercato/core/modules/directory/data/entities'\nimport { organizationCreateSchema, organizationUpdateSchema } from '@open-mercato/core/modules/directory/data/validators'\nimport {\n lockOrganizationHierarchyForTenant,\n rebuildHierarchyForTenant,\n} from '@open-mercato/core/modules/directory/lib/hierarchy'\nimport {\n enforceTenantSelection,\n normalizeTenantId,\n resolveIsSuperAdmin,\n} from '@open-mercato/core/modules/auth/lib/tenantAccess'\nimport { E } from '#generated/entities.ids.generated'\nimport type { CrudEmitContext, CrudEventsConfig, CrudIndexerConfig } from '@open-mercato/shared/lib/crud/types'\nimport {\n loadCustomFieldSnapshot,\n buildCustomFieldResetMap,\n diffCustomFieldChanges,\n} from '@open-mercato/shared/lib/commands/customFieldSnapshots'\nimport { extractUndoPayload } from '@open-mercato/shared/lib/commands/undo'\nimport { resolveRedoSnapshot } from '@open-mercato/shared/lib/commands/redo'\nimport { withAtomicFlush } from '@open-mercato/shared/lib/commands/flush'\nimport {\n parseWithCustomFields,\n setCustomFieldsIfAny,\n emitCrudSideEffects,\n emitCrudUndoSideEffects,\n requireId,\n buildChanges,\n} from '@open-mercato/shared/lib/commands/helpers'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { toOptionalString } from '@open-mercato/shared/lib/string/coerce'\nimport { slugify } from '@open-mercato/shared/lib/slugify'\n\nexport const organizationCrudEvents: CrudEventsConfig = {\n module: 'directory',\n entity: 'organization',\n persistent: true,\n buildPayload: (ctx) => {\n const orgCtx = ctx as CrudEmitContext<Organization>\n return {\n id: orgCtx.identifiers.id,\n tenantId: tenantIdFromContext(orgCtx),\n organizationId: orgCtx.identifiers.id,\n }\n },\n}\n\nexport const organizationCrudIndexer: CrudIndexerConfig = {\n entityType: E.directory.organization,\n buildUpsertPayload: (ctx) => {\n const orgCtx = ctx as CrudEmitContext<Organization>\n return {\n entityType: E.directory.organization,\n recordId: orgCtx.identifiers.id,\n organizationId: orgCtx.identifiers.id,\n tenantId: tenantIdFromContext(orgCtx),\n }\n },\n buildDeletePayload: (ctx) => {\n const orgCtx = ctx as CrudEmitContext<Organization>\n return {\n entityType: E.directory.organization,\n recordId: orgCtx.identifiers.id,\n organizationId: orgCtx.identifiers.id,\n tenantId: tenantIdFromContext(orgCtx),\n }\n },\n}\n\ntype OrganizationTenantShape = {\n __tenantId?: unknown\n tenant?: string | { id?: unknown; getEntity?: () => { id?: unknown } }\n tenantId?: unknown\n tenant_id?: unknown\n}\n\ntype SerializedOrganization = ReturnType<typeof serializeOrganization>\n\ntype ChildParentSnapshot = {\n childId: string\n parentId: string | null\n}\n\ntype OrganizationUndoSnapshot = {\n id: string\n tenantId: string | null\n name: string\n slug?: string | null\n logoUrl?: string | null\n logoPreserveAspectRatio?: boolean\n isActive: boolean\n parentId: string | null\n childParents: ChildParentSnapshot[]\n custom?: Record<string, unknown>\n}\n\ntype OrganizationSnapshots = {\n view: SerializedOrganization\n undo: OrganizationUndoSnapshot\n}\n\ntype OrganizationActorScope = {\n isUnrestricted: boolean\n tenantId: string | null\n}\n\ntype AuthorizedOrganizationTarget = {\n organization: Organization\n tenantId: string\n}\n\nexport function resolveTenantIdFromEntity(entity: Organization): string | null {\n const shape = entity as unknown as OrganizationTenantShape\n const cached = toOptionalString(shape.__tenantId)\n if (cached) return cached\n const tenantRef = shape.tenant\n if (typeof tenantRef === 'string') return tenantRef\n if (tenantRef && typeof tenantRef === 'object') {\n const direct = toOptionalString(tenantRef.id)\n if (direct) return direct\n if (typeof tenantRef.getEntity === 'function') {\n const nested = tenantRef.getEntity()\n const nestedId = nested ? toOptionalString(nested.id) : null\n if (nestedId) return nestedId\n }\n }\n const fallback = toOptionalString(shape.tenantId) || toOptionalString(shape.tenant_id)\n return fallback\n}\n\nasync function resolveOrganizationActorScope(ctx: CommandRuntimeContext): Promise<OrganizationActorScope> {\n if (ctx.systemActor === true) return { isUnrestricted: true, tenantId: null }\n const tenantId = normalizeTenantId(ctx.auth?.tenantId ?? null) ?? null\n const isSuperAdmin = await resolveIsSuperAdmin(ctx)\n return { isUnrestricted: isSuperAdmin, tenantId }\n}\n\nfunction buildOrganizationTargetFilter(\n id: string,\n scope: OrganizationActorScope,\n): FilterQuery<Organization> | null {\n if (!scope.isUnrestricted && !scope.tenantId) return null\n return {\n id,\n deletedAt: null,\n ...(scope.isUnrestricted ? {} : { tenant: scope.tenantId }),\n } as FilterQuery<Organization>\n}\n\nasync function loadAuthorizedOrganizationTarget(\n em: EntityManager,\n id: string,\n ctx: CommandRuntimeContext,\n): Promise<AuthorizedOrganizationTarget> {\n const scope = await resolveOrganizationActorScope(ctx)\n const filter = buildOrganizationTargetFilter(id, scope)\n if (!filter) throw new CrudHttpError(404, { error: 'Not found' })\n const organization = await em.findOne(Organization, filter)\n if (!organization) throw new CrudHttpError(404, { error: 'Not found' })\n const tenantId = resolveTenantIdFromEntity(organization)\n if (!tenantId || (!scope.isUnrestricted && tenantId !== scope.tenantId)) {\n throw new CrudHttpError(404, { error: 'Not found' })\n }\n return { organization, tenantId }\n}\n\nfunction buildOrganizationMutationFilter(\n id: string,\n tenantId: string,\n): FilterQuery<Organization> {\n return {\n id,\n deletedAt: null,\n tenant: tenantId,\n } as FilterQuery<Organization>\n}\n\nasync function assertOrganizationUndoTenantAccess(\n ctx: CommandRuntimeContext,\n targetTenantId: string,\n): Promise<void> {\n const scope = await resolveOrganizationActorScope(ctx)\n if (!scope.isUnrestricted && scope.tenantId !== targetTenantId) {\n throw new CrudHttpError(404, { error: 'Not found' })\n }\n}\n\nfunction buildOrganizationUndoTargetFilter(\n id: string,\n tenantId: string,\n): FilterQuery<Organization> {\n return { id, tenant: tenantId } as FilterQuery<Organization>\n}\n\nfunction serializeOrganization(entity: Organization, custom?: Record<string, unknown> | null) {\n return {\n id: String(entity.id),\n tenantId: resolveTenantIdFromEntity(entity),\n name: entity.name,\n slug: entity.slug ?? null,\n logoUrl: entity.logoUrl ?? null,\n logoPreserveAspectRatio: !!entity.logoPreserveAspectRatio,\n isActive: !!entity.isActive,\n parentId: entity.parentId ?? null,\n ancestorIds: Array.isArray(entity.ancestorIds) ? [...entity.ancestorIds] : [],\n childIds: Array.isArray(entity.childIds) ? [...entity.childIds] : [],\n descendantIds: Array.isArray(entity.descendantIds) ? [...entity.descendantIds] : [],\n createdAt: entity.createdAt ? entity.createdAt.toISOString() : null,\n updatedAt: entity.updatedAt ? entity.updatedAt.toISOString() : null,\n ...(custom && Object.keys(custom).length ? { custom } : {}),\n }\n}\n\nfunction captureOrganizationSnapshots(\n entity: Organization,\n childParents: ChildParentSnapshot[],\n custom?: Record<string, unknown> | null\n): OrganizationSnapshots {\n const tenantId = resolveTenantIdFromEntity(entity)\n return {\n view: serializeOrganization(entity, custom),\n undo: {\n id: String(entity.id),\n tenantId,\n name: entity.name,\n slug: entity.slug ?? null,\n logoUrl: entity.logoUrl ?? null,\n logoPreserveAspectRatio: !!entity.logoPreserveAspectRatio,\n isActive: !!entity.isActive,\n parentId: entity.parentId ?? null,\n childParents: (childParents ?? []).map((entry) => ({\n childId: String(entry.childId),\n parentId: entry.parentId,\n })),\n ...(custom && Object.keys(custom).length ? { custom } : {}),\n },\n }\n}\n\nasync function loadChildParentSnapshots(\n em: EntityManager,\n tenantId: string | null,\n childIds: Iterable<string>\n): Promise<ChildParentSnapshot[]> {\n if (!tenantId) return []\n const ids = Array.from(new Set(Array.from(childIds ?? []).map((id) => String(id)).filter(Boolean)))\n if (!ids.length) return []\n const filter: FilterQuery<Organization> = {\n tenant: tenantId,\n deletedAt: null,\n id: { $in: ids },\n } as unknown as FilterQuery<Organization>\n const children = await em.find(Organization, filter)\n if (!children.length) return []\n const map = new Map(children.map((child) => [String(child.id), child.parentId ? String(child.parentId) : null]))\n return ids\n .filter((id) => map.has(id))\n .map((id) => ({\n childId: id,\n parentId: map.get(id) ?? null,\n }))\n}\n\nasync function restoreChildParents(em: EntityManager, tenantId: string, snapshots: ChildParentSnapshot[]) {\n if (!snapshots?.length) return\n const ids = Array.from(new Set(snapshots.map((entry) => entry.childId).filter(Boolean)))\n if (!ids.length) return\n const filter: FilterQuery<Organization> = {\n tenant: tenantId,\n deletedAt: null,\n id: { $in: ids },\n } as unknown as FilterQuery<Organization>\n const children = await em.find(Organization, filter)\n if (!children.length) return\n const desired = new Map(snapshots.map((entry) => [entry.childId, entry.parentId ?? null]))\n const toPersist: Organization[] = []\n for (const child of children) {\n const id = String(child.id)\n if (!desired.has(id)) continue\n const nextParent = desired.get(id) ?? null\n if (child.parentId !== nextParent) {\n child.parentId = nextParent\n toPersist.push(child)\n }\n }\n if (toPersist.length) await em.persist(toPersist).flush()\n}\n\nfunction normalizeChildIds(ids: readonly string[], exclude: string[]): string[] {\n const excludeSet = new Set(exclude)\n return Array.from(new Set(ids)).filter((id) => !excludeSet.has(id))\n}\n\nasync function ensureParentExists(em: EntityManager, tenantId: string, parentId: string | null): Promise<void> {\n if (!parentId) return\n const parentFilter: FilterQuery<Organization> = { id: parentId, tenant: tenantId, deletedAt: null }\n const parent = await em.findOne(Organization, parentFilter)\n if (!parent) throw new CrudHttpError(400, { error: 'Parent not found' })\n}\n\nasync function ensureChildrenValid(em: EntityManager, tenantId: string, childIds: string[]): Promise<void> {\n if (!childIds.length) return\n const childFilter: FilterQuery<Organization> = { id: { $in: childIds }, tenant: tenantId, deletedAt: null }\n const children = await em.find(Organization, childFilter)\n if (children.length !== childIds.length) throw new CrudHttpError(400, { error: 'Invalid child assignment' })\n}\n\nasync function assignChildren(\n em: EntityManager,\n tenantId: string,\n recordId: string,\n desiredChildIds: Iterable<string>\n): Promise<void> {\n const targetIds = Array.from(new Set(desiredChildIds)).filter((id) => id !== recordId)\n if (!targetIds.length) return\n const filter: FilterQuery<Organization> = { tenant: tenantId, deletedAt: null, id: { $in: targetIds } }\n const children = await em.find(Organization, filter)\n const toPersist: Organization[] = []\n for (const child of children) {\n if (String(child.id) === recordId) continue\n if (child.parentId !== recordId) {\n child.parentId = recordId\n toPersist.push(child)\n }\n }\n if (toPersist.length) await em.persist(toPersist).flush()\n}\n\nasync function clearRemovedChildren(em: EntityManager, tenantId: string, recordId: string, desiredChildIds: Set<string>): Promise<void> {\n const currentFilter: FilterQuery<Organization> = { tenant: tenantId, parentId: recordId, deletedAt: null }\n const current = await em.find(Organization, currentFilter)\n const toPersist = current.filter((child) => !desiredChildIds.has(String(child.id)))\n if (!toPersist.length) return\n for (const child of toPersist) child.parentId = null\n await em.persist(toPersist).flush()\n}\n\nasync function resolveUniqueSlug(em: EntityManager, tenantId: string, baseSlug: string, excludeId?: string): Promise<string> {\n let candidate = baseSlug\n let suffix = 0\n const maxAttempts = 50\n while (suffix < maxAttempts) {\n const filter: FilterQuery<Organization> = {\n tenant: tenantId,\n slug: candidate,\n deletedAt: null,\n } as unknown as FilterQuery<Organization>\n const existing = await em.findOne(Organization, filter)\n if (!existing || (excludeId && String(existing.id) === excludeId)) return candidate\n suffix += 1\n candidate = `${baseSlug}-${suffix}`\n }\n return `${baseSlug}-${Date.now()}`\n}\n\nconst createOrganizationCommand: CommandHandler<Record<string, unknown>, Organization> = {\n id: 'directory.organizations.create',\n async execute(rawInput, ctx) {\n const { parsed, custom } = parseWithCustomFields(organizationCreateSchema, rawInput)\n const em = (ctx.container.resolve('em') as EntityManager)\n const tenantId = await enforceTenantSelection(ctx, parsed.tenantId)\n if (!tenantId) throw new CrudHttpError(400, { error: 'Tenant scope required' })\n\n const parentId = parsed.parentId ?? null\n const childIds = normalizeChildIds(parsed.childIds ?? [], parentId ? [parentId] : [])\n if (parentId && childIds.includes(parentId)) throw new CrudHttpError(400, { error: 'Child cannot equal parent' })\n\n const tenantRef = em.getReference(Tenant, tenantId)\n const baseSlug = parsed.slug ? parsed.slug : slugify(parsed.name)\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n\n let organization!: Organization\n await withAtomicFlush(em, [\n async () => {\n await lockOrganizationHierarchyForTenant(em, tenantId)\n if (parentId) {\n await ensureParentExists(em, tenantId, parentId)\n }\n await ensureChildrenValid(em, tenantId, childIds)\n const childParentsBefore = await loadChildParentSnapshots(em, tenantId, childIds)\n const slug = baseSlug ? await resolveUniqueSlug(em, tenantId, baseSlug) : null\n organization = await de.createOrmEntity({\n entity: Organization,\n data: {\n tenant: tenantRef,\n name: parsed.name,\n slug,\n logoUrl: parsed.logoUrl ?? null,\n logoPreserveAspectRatio: parsed.logoPreserveAspectRatio ?? false,\n isActive: parsed.isActive ?? true,\n parentId,\n },\n })\n setInternalTenantId(organization, tenantId)\n const recordId = String(organization.id)\n\n if (childIds.length) {\n await assignChildren(em, tenantId, recordId, childIds)\n }\n const childParentsAfter = await loadChildParentSnapshots(em, tenantId, childIds)\n setUndoMeta(organization, { childParentsBefore, childParentsAfter })\n\n await setCustomFieldsIfAny({\n dataEngine: de,\n entityId: E.directory.organization,\n recordId,\n tenantId,\n organizationId: recordId,\n values: custom,\n })\n\n await rebuildHierarchyForTenant(em, tenantId)\n },\n ], { transaction: true })\n\n const recordId = String(organization.id)\n const identifiers = { id: recordId, organizationId: recordId, tenantId }\n await emitCrudSideEffects({\n dataEngine: de,\n action: 'created',\n entity: organization,\n identifiers,\n events: organizationCrudEvents,\n indexer: organizationCrudIndexer,\n })\n\n return organization\n },\n captureAfter: async (_input, result, ctx) => {\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const tenantId = resolveTenantIdFromEntity(result)\n const custom = await loadCustomFieldSnapshot(em, {\n entityId: E.directory.organization,\n recordId: String(result.id),\n tenantId,\n organizationId: String(result.id),\n })\n return serializeOrganization(result, custom)\n },\n buildLog: async ({ result, ctx }) => {\n const { translate } = await resolveTranslations()\n const meta = getUndoMeta(result)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const tenantId = resolveTenantIdFromEntity(result)\n const custom = await loadCustomFieldSnapshot(em, {\n entityId: E.directory.organization,\n recordId: String(result.id),\n tenantId,\n organizationId: String(result.id),\n })\n const afterSnapshots = captureOrganizationSnapshots(result, meta.childParentsAfter ?? [], custom)\n return {\n actionLabel: translate('directory.audit.organizations.create', 'Create organization'),\n resourceKind: 'directory.organization',\n resourceId: String(result.id),\n tenantId,\n snapshotAfter: afterSnapshots.view,\n payload: {\n undo: {\n after: afterSnapshots.undo,\n childrenBefore: meta.childParentsBefore ?? [],\n },\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<OrganizationUndoPayload>(logEntry)\n const after = payload?.after\n const childrenBefore = payload?.childrenBefore ?? []\n if (!after) return\n const tenantId = after.tenantId\n if (!tenantId) return\n await assertOrganizationUndoTenantAccess(ctx, tenantId)\n const em = (ctx.container.resolve('em') as EntityManager)\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n await withAtomicFlush(em, [\n async () => {\n await lockOrganizationHierarchyForTenant(em, tenantId)\n await restoreChildParents(em, tenantId, childrenBefore)\n if (after.custom && Object.keys(after.custom).length) {\n const reset = buildCustomFieldResetMap(undefined, after.custom)\n if (Object.keys(reset).length) {\n const resetValues = reset as Parameters<DataEngine['setCustomFields']>[0]['values']\n await de.setCustomFields({\n entityId: E.directory.organization,\n recordId: after.id,\n tenantId,\n organizationId: after.id,\n values: resetValues,\n notify: false,\n })\n }\n }\n await de.deleteOrmEntity({\n entity: Organization,\n where: buildOrganizationMutationFilter(after.id, tenantId),\n soft: false,\n })\n await rebuildHierarchyForTenant(em, tenantId)\n },\n ], { transaction: true })\n },\n redo: async ({ logEntry, ctx }) => {\n const after = resolveRedoSnapshot<OrganizationUndoSnapshot>(logEntry)\n if (!after) throw new CrudHttpError(400, { error: '[internal] redo snapshot unavailable for organization create' })\n const tenantId = after.tenantId\n if (!tenantId) throw new CrudHttpError(400, { error: '[internal] redo snapshot missing tenant for organization create' })\n await assertOrganizationUndoTenantAccess(ctx, tenantId)\n const em = (ctx.container.resolve('em') as EntityManager)\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n let organization!: Organization\n await withAtomicFlush(em, [\n async () => {\n await lockOrganizationHierarchyForTenant(em, tenantId)\n const existing = await em.findOne(Organization, buildOrganizationUndoTargetFilter(after.id, tenantId))\n if (existing) {\n existing.deletedAt = null\n existing.name = after.name\n if (after.slug !== undefined) existing.slug = after.slug ?? null\n if (after.logoUrl !== undefined) existing.logoUrl = after.logoUrl ?? null\n if (after.logoPreserveAspectRatio !== undefined) existing.logoPreserveAspectRatio = !!after.logoPreserveAspectRatio\n existing.isActive = after.isActive\n existing.parentId = after.parentId\n await em.flush()\n organization = existing\n } else {\n organization = await de.createOrmEntity({\n entity: Organization,\n data: {\n id: after.id,\n name: after.name,\n slug: after.slug ?? null,\n logoUrl: after.logoUrl ?? null,\n logoPreserveAspectRatio: after.logoPreserveAspectRatio ?? false,\n tenant: em.getReference(Tenant, tenantId),\n isActive: after.isActive,\n parentId: after.parentId,\n },\n })\n }\n setInternalTenantId(organization, tenantId)\n\n if (after.custom && Object.keys(after.custom).length) {\n const reset = buildCustomFieldResetMap(after.custom, undefined)\n if (Object.keys(reset).length) {\n const resetValues = reset as Parameters<DataEngine['setCustomFields']>[0]['values']\n await de.setCustomFields({\n entityId: E.directory.organization,\n recordId: after.id,\n tenantId,\n organizationId: after.id,\n values: resetValues,\n notify: false,\n })\n }\n }\n\n await assignChildren(em, tenantId, after.id, after.childParents.map((entry) => entry.childId))\n await rebuildHierarchyForTenant(em, tenantId)\n },\n ], { transaction: true })\n\n const identifiers = { id: after.id, organizationId: after.id, tenantId }\n await emitCrudSideEffects({\n dataEngine: de,\n action: 'created',\n entity: organization,\n identifiers,\n events: organizationCrudEvents,\n indexer: organizationCrudIndexer,\n })\n\n return organization\n },\n}\n\nconst updateOrganizationCommand: CommandHandler<Record<string, unknown>, Organization> = {\n id: 'directory.organizations.update',\n async prepare(rawInput, ctx) {\n const { parsed } = parseWithCustomFields(organizationUpdateSchema, rawInput)\n const em = (ctx.container.resolve('em') as EntityManager)\n const { organization: current, tenantId } = await loadAuthorizedOrganizationTarget(em, parsed.id, ctx)\n const currentChildIds = Array.isArray(current.childIds) ? current.childIds : []\n const requestedChildIds = Array.isArray(parsed.childIds) ? parsed.childIds : []\n const combinedChildIds = new Set<string>([...currentChildIds.map(String), ...requestedChildIds.map(String)])\n const childParentsBefore = tenantId\n ? await loadChildParentSnapshots(em, tenantId, combinedChildIds)\n : []\n const custom = await loadCustomFieldSnapshot(em, {\n entityId: E.directory.organization,\n recordId: String(current.id),\n tenantId,\n organizationId: String(current.id),\n })\n return { before: captureOrganizationSnapshots(current, childParentsBefore, custom) }\n },\n async execute(rawInput, ctx) {\n const { parsed, custom } = parseWithCustomFields(organizationUpdateSchema, rawInput)\n const em = (ctx.container.resolve('em') as EntityManager)\n const { tenantId } = await loadAuthorizedOrganizationTarget(em, parsed.id, ctx)\n\n const parentProvided = parsed.parentId !== undefined\n const childrenProvided = parsed.childIds !== undefined\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n\n let resolvedOrganization!: Organization\n await withAtomicFlush(em, [\n async () => {\n await lockOrganizationHierarchyForTenant(em, tenantId)\n const existing = await em.findOne(\n Organization,\n buildOrganizationMutationFilter(parsed.id, tenantId),\n { refresh: true },\n )\n if (!existing) throw new CrudHttpError(404, { error: 'Not found' })\n\n const parentId = parentProvided ? parsed.parentId ?? null : existing.parentId ?? null\n if (parentProvided && parentId) {\n if (parentId === parsed.id) throw new CrudHttpError(400, { error: 'Organization cannot be its own parent' })\n if (Array.isArray(existing.descendantIds) && existing.descendantIds.includes(parentId)) {\n throw new CrudHttpError(400, { error: 'Cannot assign descendant as parent' })\n }\n await ensureParentExists(em, tenantId, parentId)\n }\n\n const normalizedChildIds = normalizeChildIds(parsed.childIds ?? [], [parsed.id, parentProvided ? parentId ?? '' : ''])\n if (normalizedChildIds.some((id) => id === parentId)) throw new CrudHttpError(400, { error: 'Child cannot equal parent' })\n if (Array.isArray(existing.ancestorIds) && normalizedChildIds.some((id) => existing.ancestorIds.includes(id))) {\n throw new CrudHttpError(400, { error: 'Cannot assign ancestor as child' })\n }\n\n if (normalizedChildIds.length) {\n await ensureChildrenValid(em, tenantId, normalizedChildIds)\n const childFilter = {\n tenant: tenantId,\n deletedAt: null,\n id: { $in: normalizedChildIds },\n } as unknown as FilterQuery<Organization>\n const children = await em.find(Organization, childFilter)\n for (const child of children) {\n if (Array.isArray(child.descendantIds) && child.descendantIds.includes(parsed.id)) {\n throw new CrudHttpError(400, { error: 'Cannot assign descendant cycle' })\n }\n }\n }\n\n const combinedChildIds = new Set<string>([\n ...normalizedChildIds.map(String),\n ...(Array.isArray(existing.childIds) ? existing.childIds.map(String) : []),\n ])\n const childParentsBefore = await loadChildParentSnapshots(em, tenantId, combinedChildIds)\n\n let resolvedSlug: string | null | undefined\n if (parsed.slug !== undefined) {\n resolvedSlug = parsed.slug ? await resolveUniqueSlug(em, tenantId, parsed.slug, parsed.id) : parsed.slug\n }\n\n const organization = await de.updateOrmEntity({\n entity: Organization,\n where: buildOrganizationMutationFilter(parsed.id, tenantId),\n apply: (entity) => {\n if (parsed.name !== undefined) entity.name = parsed.name\n if (resolvedSlug !== undefined) entity.slug = resolvedSlug\n if (parsed.logoUrl !== undefined) entity.logoUrl = parsed.logoUrl ?? null\n if (parsed.logoPreserveAspectRatio !== undefined) entity.logoPreserveAspectRatio = parsed.logoPreserveAspectRatio\n if (parsed.isActive !== undefined) entity.isActive = parsed.isActive\n if (parentProvided) entity.parentId = parentId\n },\n })\n if (!organization) throw new CrudHttpError(404, { error: 'Not found' })\n setInternalTenantId(organization, tenantId)\n\n const recordId = String(organization.id)\n const desiredChildIds = new Set(normalizedChildIds.filter((id) => id !== recordId))\n if (childrenProvided) {\n await clearRemovedChildren(em, tenantId, recordId, desiredChildIds)\n await assignChildren(em, tenantId, recordId, desiredChildIds)\n }\n const childParentsAfter = await loadChildParentSnapshots(em, tenantId, combinedChildIds)\n setUndoMeta(organization, { childParentsBefore, childParentsAfter })\n\n await setCustomFieldsIfAny({\n dataEngine: de,\n entityId: E.directory.organization,\n recordId,\n tenantId,\n organizationId: recordId,\n values: custom,\n })\n\n await rebuildHierarchyForTenant(em, tenantId)\n resolvedOrganization = organization\n },\n ], { transaction: true })\n\n const recordId = String(resolvedOrganization.id)\n const identifiers = { id: recordId, organizationId: recordId, tenantId }\n await emitCrudSideEffects({\n dataEngine: de,\n action: 'updated',\n entity: resolvedOrganization,\n identifiers,\n events: organizationCrudEvents,\n indexer: organizationCrudIndexer,\n })\n\n return resolvedOrganization\n },\n captureAfter: async (_input, result, ctx) => {\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const tenantId = resolveTenantIdFromEntity(result)\n const custom = await loadCustomFieldSnapshot(em, {\n entityId: E.directory.organization,\n recordId: String(result.id),\n tenantId,\n organizationId: String(result.id),\n })\n return serializeOrganization(result, custom)\n },\n buildLog: async ({ snapshots, result, ctx }) => {\n const { translate } = await resolveTranslations()\n const meta = getUndoMeta(result)\n const beforeSnapshots = snapshots.before as OrganizationSnapshots | undefined\n const beforeRecord = beforeSnapshots?.view ?? null\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const tenantId = resolveTenantIdFromEntity(result)\n const custom = await loadCustomFieldSnapshot(em, {\n entityId: E.directory.organization,\n recordId: String(result.id),\n tenantId,\n organizationId: String(result.id),\n })\n const after = serializeOrganization(result, custom)\n const changes = buildChanges(beforeRecord, after as Record<string, unknown>, ['name', 'slug', 'logoUrl', 'logoPreserveAspectRatio', 'isActive', 'parentId'])\n const customDiff = diffCustomFieldChanges(beforeRecord?.custom, custom)\n for (const [key, diff] of Object.entries(customDiff)) {\n changes[`cf_${key}`] = diff\n }\n return {\n actionLabel: translate('directory.audit.organizations.update', 'Update organization'),\n resourceKind: 'directory.organization',\n resourceId: String(result.id),\n changes,\n tenantId: after.tenantId,\n payload: {\n undo: {\n before: beforeSnapshots?.undo ?? null,\n after: captureOrganizationSnapshots(result, meta.childParentsAfter ?? [], custom).undo,\n },\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<OrganizationUndoPayload>(logEntry)\n const before = payload?.before\n const after = payload?.after\n if (!before) return\n const tenantId = before.tenantId\n if (!tenantId) return\n await assertOrganizationUndoTenantAccess(ctx, tenantId)\n const em = (ctx.container.resolve('em') as EntityManager)\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n let updated: Organization | null = null\n await withAtomicFlush(em, [\n async () => {\n await lockOrganizationHierarchyForTenant(em, tenantId)\n updated = await de.updateOrmEntity({\n entity: Organization,\n where: buildOrganizationUndoTargetFilter(before.id, tenantId),\n apply: (entity) => {\n entity.name = before.name\n if (before.slug !== undefined) entity.slug = before.slug\n if (before.logoUrl !== undefined) entity.logoUrl = before.logoUrl ?? null\n if (before.logoPreserveAspectRatio !== undefined) entity.logoPreserveAspectRatio = !!before.logoPreserveAspectRatio\n entity.isActive = before.isActive\n entity.parentId = before.parentId\n },\n })\n if (!updated) throw new CrudHttpError(404, { error: 'Not found' })\n setInternalTenantId(updated, tenantId)\n const reset = buildCustomFieldResetMap(before.custom, after?.custom)\n if (Object.keys(reset).length) {\n const resetValues = reset as Parameters<DataEngine['setCustomFields']>[0]['values']\n await de.setCustomFields({\n entityId: E.directory.organization,\n recordId: before.id,\n tenantId,\n organizationId: before.id,\n values: resetValues,\n notify: false,\n })\n }\n const childSnapshots = before.childParents\n await restoreChildParents(em, tenantId, childSnapshots)\n await rebuildHierarchyForTenant(em, tenantId)\n },\n ], { transaction: true })\n await emitCrudUndoSideEffects({\n dataEngine: de,\n action: 'updated',\n entity: updated,\n identifiers: {\n id: before.id,\n tenantId,\n organizationId: before.id,\n },\n events: organizationCrudEvents,\n indexer: organizationCrudIndexer,\n })\n },\n}\n\nconst deleteOrganizationCommand: CommandHandler<{ body: any; query: Record<string, string> }, Organization> = {\n id: 'directory.organizations.delete',\n async prepare(input, ctx) {\n const id = requireId(input, 'Organization id required')\n const em = (ctx.container.resolve('em') as EntityManager)\n const { organization: existing, tenantId } = await loadAuthorizedOrganizationTarget(em, id, ctx)\n const childParentsBefore = tenantId\n ? await loadChildParentSnapshots(em, tenantId, Array.isArray(existing.childIds) ? existing.childIds : [])\n : []\n const custom = await loadCustomFieldSnapshot(em, {\n entityId: E.directory.organization,\n recordId: String(existing.id),\n tenantId,\n organizationId: String(existing.id),\n })\n return { before: captureOrganizationSnapshots(existing, childParentsBefore, custom) }\n },\n async execute(input, ctx) {\n const id = requireId(input, 'Organization id required')\n const em = (ctx.container.resolve('em') as EntityManager)\n const { organization: existing, tenantId } = await loadAuthorizedOrganizationTarget(em, id, ctx)\n\n const parentId = existing.parentId ?? null\n const childSnapshotsBefore = await loadChildParentSnapshots(\n em,\n tenantId,\n Array.isArray(existing.childIds) ? existing.childIds : [],\n )\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n\n let resolvedDeleted!: Organization\n await withAtomicFlush(em, [\n async () => {\n await lockOrganizationHierarchyForTenant(em, tenantId)\n const deleted = await de.deleteOrmEntity({\n entity: Organization,\n where: buildOrganizationMutationFilter(id, tenantId),\n soft: true,\n softDeleteField: 'deletedAt',\n })\n if (!deleted) throw new CrudHttpError(404, { error: 'Not found' })\n setInternalTenantId(deleted, tenantId)\n deleted.isActive = false\n deleted.parentId = null\n resolvedDeleted = deleted\n },\n async () => {\n const deleted = resolvedDeleted\n const childrenFilter: FilterQuery<Organization> = { tenant: tenantId, parentId: id, deletedAt: null }\n const children = await em.find(Organization, childrenFilter)\n const toPersist: Organization[] = []\n for (const child of children) {\n child.parentId = parentId\n toPersist.push(child)\n }\n toPersist.push(deleted)\n if (toPersist.length) em.persist(toPersist)\n setUndoMeta(deleted, { childParentsBefore: childSnapshotsBefore })\n },\n async () => {\n await rebuildHierarchyForTenant(em, tenantId)\n },\n ], { transaction: true })\n\n const identifiers = { id, organizationId: id, tenantId }\n await emitCrudSideEffects({\n dataEngine: de,\n action: 'deleted',\n entity: resolvedDeleted,\n identifiers,\n events: organizationCrudEvents,\n indexer: organizationCrudIndexer,\n })\n\n return resolvedDeleted\n },\n buildLog: async ({ snapshots, input }) => {\n const { translate } = await resolveTranslations()\n const beforeSnapshots = snapshots.before as OrganizationSnapshots | undefined\n const beforeSnapshot = beforeSnapshots?.view ?? null\n const beforeUndo = beforeSnapshots?.undo ?? null\n const id = String(input?.body?.id ?? input?.query?.id ?? '')\n const fallbackId = beforeSnapshot?.id ?? null\n const fallbackTenant = beforeSnapshot?.tenantId ?? null\n return {\n actionLabel: translate('directory.audit.organizations.delete', 'Delete organization'),\n resourceKind: 'directory.organization',\n resourceId: id || fallbackId || null,\n snapshotBefore: beforeSnapshot ?? null,\n tenantId: beforeUndo?.tenantId ?? fallbackTenant,\n payload: {\n undo: {\n before: beforeUndo,\n },\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<OrganizationUndoPayload>(logEntry)\n const before = payload?.before\n if (!before) return\n const tenantId = before.tenantId\n if (!tenantId) return\n await assertOrganizationUndoTenantAccess(ctx, tenantId)\n const em = (ctx.container.resolve('em') as EntityManager)\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n let organization: Organization | null = null\n await withAtomicFlush(em, [\n async () => {\n await lockOrganizationHierarchyForTenant(em, tenantId)\n organization = await em.findOne(\n Organization,\n buildOrganizationUndoTargetFilter(before.id, tenantId),\n )\n if (organization) {\n organization.deletedAt = null\n organization.isActive = before.isActive\n organization.name = before.name\n if (before.slug !== undefined) organization.slug = before.slug\n organization.parentId = before.parentId\n await em.flush()\n if (tenantId) setInternalTenantId(organization, tenantId)\n } else {\n organization = await de.createOrmEntity({\n entity: Organization,\n data: {\n id: before.id,\n name: before.name,\n slug: before.slug ?? null,\n tenant: tenantId ? em.getReference(Tenant, tenantId) : undefined,\n isActive: before.isActive,\n parentId: before.parentId,\n },\n })\n if (tenantId) setInternalTenantId(organization, tenantId)\n }\n if (tenantId) {\n const customValues = buildCustomFieldResetMap(before.custom, undefined)\n if (Object.keys(customValues).length) {\n const resetValues = customValues as Parameters<DataEngine['setCustomFields']>[0]['values']\n await de.setCustomFields({\n entityId: E.directory.organization,\n recordId: before.id,\n tenantId,\n organizationId: before.id,\n values: resetValues,\n notify: false,\n })\n }\n }\n await restoreChildParents(em, tenantId, before.childParents)\n await rebuildHierarchyForTenant(em, tenantId)\n },\n ], { transaction: true })\n await emitCrudUndoSideEffects({\n dataEngine: de,\n action: 'updated',\n entity: organization,\n identifiers: {\n id: before.id,\n tenantId,\n organizationId: before.id,\n },\n events: organizationCrudEvents,\n indexer: organizationCrudIndexer,\n })\n },\n}\n\ntype OrganizationUndoPayload = {\n before?: OrganizationUndoSnapshot | null\n after?: OrganizationUndoSnapshot | null\n childrenBefore?: ChildParentSnapshot[] | null\n}\n\ntype OrganizationUndoMeta = {\n childParentsBefore?: ChildParentSnapshot[]\n childParentsAfter?: ChildParentSnapshot[]\n}\n\nconst UNDO_META_KEY: unique symbol = Symbol('directory.organization.undoMeta')\n\nfunction getUndoMeta(entity: Organization): OrganizationUndoMeta {\n return (Reflect.get(entity, UNDO_META_KEY) as OrganizationUndoMeta | undefined) ?? {}\n}\n\nfunction setUndoMeta(entity: Organization, meta: Partial<OrganizationUndoMeta>) {\n const current = getUndoMeta(entity)\n Reflect.set(entity, UNDO_META_KEY, { ...current, ...meta })\n}\n\nregisterCommand(createOrganizationCommand)\nregisterCommand(updateOrganizationCommand)\nregisterCommand(deleteOrganizationCommand)\n\nfunction setInternalTenantId(entity: Organization, tenantId: string) {\n Reflect.set(entity, '__tenantId', tenantId)\n}\n\nfunction tenantIdFromContext(ctx: CrudEmitContext<Organization>): string | null {\n return resolveTenantIdFromEntity(ctx.entity) ?? ctx.identifiers.tenantId ?? null\n}\n"],
|
|
5
|
-
"mappings": "AACA,SAAS,uBAAuB;AAChC,SAAS,qBAAqB;AAG9B,SAAS,cAAc,cAAc;AACrC,SAAS,0BAA0B,gCAAgC;AACnE;AAAA,EACE;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,SAAS;AAElB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,0BAA0B;AACnC,SAAS,2BAA2B;AACpC,SAAS,uBAAuB;AAChC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,2BAA2B;AACpC,SAAS,wBAAwB;AACjC,SAAS,eAAe;AAEjB,MAAM,yBAA2C;AAAA,EACtD,QAAQ;AAAA,EACR,QAAQ;AAAA,EACR,YAAY;AAAA,EACZ,cAAc,CAAC,QAAQ;AACrB,UAAM,SAAS;AACf,WAAO;AAAA,MACL,IAAI,OAAO,YAAY;AAAA,MACvB,UAAU,oBAAoB,MAAM;AAAA,MACpC,gBAAgB,OAAO,YAAY;AAAA,IACrC;AAAA,EACF;AACF;AAEO,MAAM,0BAA6C;AAAA,EACxD,YAAY,EAAE,UAAU;AAAA,EACxB,oBAAoB,CAAC,QAAQ;AAC3B,UAAM,SAAS;AACf,WAAO;AAAA,MACL,YAAY,EAAE,UAAU;AAAA,MACxB,UAAU,OAAO,YAAY;AAAA,MAC7B,gBAAgB,OAAO,YAAY;AAAA,MACnC,UAAU,oBAAoB,MAAM;AAAA,IACtC;AAAA,EACF;AAAA,EACA,oBAAoB,CAAC,QAAQ;AAC3B,UAAM,SAAS;AACf,WAAO;AAAA,MACL,YAAY,EAAE,UAAU;AAAA,MACxB,UAAU,OAAO,YAAY;AAAA,MAC7B,gBAAgB,OAAO,YAAY;AAAA,MACnC,UAAU,oBAAoB,MAAM;AAAA,IACtC;AAAA,EACF;AACF;AA4CO,SAAS,0BAA0B,QAAqC;AAC7E,QAAM,QAAQ;AACd,QAAM,SAAS,iBAAiB,MAAM,UAAU;AAChD,MAAI,OAAQ,QAAO;AACnB,QAAM,YAAY,MAAM;AACxB,MAAI,OAAO,cAAc,SAAU,QAAO;AAC1C,MAAI,aAAa,OAAO,cAAc,UAAU;AAC9C,UAAM,SAAS,iBAAiB,UAAU,EAAE;AAC5C,QAAI,OAAQ,QAAO;AACnB,QAAI,OAAO,UAAU,cAAc,YAAY;AAC7C,YAAM,SAAS,UAAU,UAAU;AACnC,YAAM,WAAW,SAAS,iBAAiB,OAAO,EAAE,IAAI;AACxD,UAAI,SAAU,QAAO;AAAA,IACvB;AAAA,EACF;AACA,QAAM,WAAW,iBAAiB,MAAM,QAAQ,KAAK,iBAAiB,MAAM,SAAS;AACrF,SAAO;AACT;AAEA,eAAe,8BAA8B,KAA6D;AACxG,MAAI,IAAI,gBAAgB,KAAM,QAAO,EAAE,gBAAgB,MAAM,UAAU,KAAK;AAC5E,QAAM,WAAW,kBAAkB,IAAI,MAAM,YAAY,IAAI,KAAK;AAClE,QAAM,eAAe,MAAM,oBAAoB,GAAG;AAClD,SAAO,EAAE,gBAAgB,cAAc,SAAS;AAClD;AAEA,SAAS,8BACP,IACA,OACkC;AAClC,MAAI,CAAC,MAAM,kBAAkB,CAAC,MAAM,SAAU,QAAO;AACrD,SAAO;AAAA,IACL;AAAA,IACA,WAAW;AAAA,IACX,GAAI,MAAM,iBAAiB,CAAC,IAAI,EAAE,QAAQ,MAAM,SAAS;AAAA,EAC3D;AACF;AAEA,eAAe,iCACb,IACA,IACA,KACuC;AACvC,QAAM,QAAQ,MAAM,8BAA8B,GAAG;AACrD,QAAM,SAAS,8BAA8B,IAAI,KAAK;AACtD,MAAI,CAAC,OAAQ,OAAM,IAAI,cAAc,KAAK,EAAE,OAAO,YAAY,CAAC;AAChE,QAAM,eAAe,MAAM,GAAG,QAAQ,cAAc,MAAM;AAC1D,MAAI,CAAC,aAAc,OAAM,IAAI,cAAc,KAAK,EAAE,OAAO,YAAY,CAAC;AACtE,QAAM,WAAW,0BAA0B,YAAY;AACvD,MAAI,CAAC,YAAa,CAAC,MAAM,kBAAkB,aAAa,MAAM,UAAW;AACvE,UAAM,IAAI,cAAc,KAAK,EAAE,OAAO,YAAY,CAAC;AAAA,EACrD;AACA,SAAO,EAAE,cAAc,SAAS;AAClC;AAEA,SAAS,gCACP,IACA,UAC2B;AAC3B,SAAO;AAAA,IACL;AAAA,IACA,WAAW;AAAA,IACX,QAAQ;AAAA,EACV;AACF;AAEA,eAAe,mCACb,KACA,gBACe;AACf,QAAM,QAAQ,MAAM,8BAA8B,GAAG;AACrD,MAAI,CAAC,MAAM,kBAAkB,MAAM,aAAa,gBAAgB;AAC9D,UAAM,IAAI,cAAc,KAAK,EAAE,OAAO,YAAY,CAAC;AAAA,EACrD;AACF;AAEA,SAAS,kCACP,IACA,UAC2B;AAC3B,SAAO,EAAE,IAAI,QAAQ,SAAS;AAChC;AAEA,SAAS,sBAAsB,QAAsB,QAAyC;AAC5F,SAAO;AAAA,IACL,IAAI,OAAO,OAAO,EAAE;AAAA,IACpB,UAAU,0BAA0B,MAAM;AAAA,IAC1C,MAAM,OAAO;AAAA,IACb,MAAM,OAAO,QAAQ;AAAA,IACrB,SAAS,OAAO,WAAW;AAAA,IAC3B,yBAAyB,CAAC,CAAC,OAAO;AAAA,IAClC,UAAU,CAAC,CAAC,OAAO;AAAA,IACnB,UAAU,OAAO,YAAY;AAAA,IAC7B,aAAa,MAAM,QAAQ,OAAO,WAAW,IAAI,CAAC,GAAG,OAAO,WAAW,IAAI,CAAC;AAAA,IAC5E,UAAU,MAAM,QAAQ,OAAO,QAAQ,IAAI,CAAC,GAAG,OAAO,QAAQ,IAAI,CAAC;AAAA,IACnE,eAAe,MAAM,QAAQ,OAAO,aAAa,IAAI,CAAC,GAAG,OAAO,aAAa,IAAI,CAAC;AAAA,IAClF,WAAW,OAAO,YAAY,OAAO,UAAU,YAAY,IAAI;AAAA,IAC/D,WAAW,OAAO,YAAY,OAAO,UAAU,YAAY,IAAI;AAAA,IAC/D,GAAI,UAAU,OAAO,KAAK,MAAM,EAAE,SAAS,EAAE,OAAO,IAAI,CAAC;AAAA,EAC3D;AACF;AAEA,SAAS,6BACP,QACA,cACA,QACuB;AACvB,QAAM,WAAW,0BAA0B,MAAM;AACjD,SAAO;AAAA,IACL,MAAM,sBAAsB,QAAQ,MAAM;AAAA,IAC1C,MAAM;AAAA,MACJ,IAAI,OAAO,OAAO,EAAE;AAAA,MACpB;AAAA,MACA,MAAM,OAAO;AAAA,MACb,MAAM,OAAO,QAAQ;AAAA,MACrB,SAAS,OAAO,WAAW;AAAA,MAC3B,yBAAyB,CAAC,CAAC,OAAO;AAAA,MAClC,UAAU,CAAC,CAAC,OAAO;AAAA,MACnB,UAAU,OAAO,YAAY;AAAA,MAC7B,eAAe,gBAAgB,CAAC,GAAG,IAAI,CAAC,WAAW;AAAA,QACjD,SAAS,OAAO,MAAM,OAAO;AAAA,QAC7B,UAAU,MAAM;AAAA,MAClB,EAAE;AAAA,MACF,GAAI,UAAU,OAAO,KAAK,MAAM,EAAE,SAAS,EAAE,OAAO,IAAI,CAAC;AAAA,IAC3D;AAAA,EACF;AACF;AAEA,eAAe,yBACb,IACA,UACA,UACgC;AAChC,MAAI,CAAC,SAAU,QAAO,CAAC;AACvB,QAAM,MAAM,MAAM,KAAK,IAAI,IAAI,MAAM,KAAK,YAAY,CAAC,CAAC,EAAE,IAAI,CAAC,OAAO,OAAO,EAAE,CAAC,EAAE,OAAO,OAAO,CAAC,CAAC;AAClG,MAAI,CAAC,IAAI,OAAQ,QAAO,CAAC;AACzB,QAAM,SAAoC;AAAA,IACxC,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,IAAI,EAAE,KAAK,IAAI;AAAA,EACjB;AACA,QAAM,WAAW,MAAM,GAAG,KAAK,cAAc,MAAM;AACnD,MAAI,CAAC,SAAS,OAAQ,QAAO,CAAC;AAC9B,QAAM,MAAM,IAAI,IAAI,SAAS,IAAI,CAAC,UAAU,CAAC,OAAO,MAAM,EAAE,GAAG,MAAM,WAAW,OAAO,MAAM,QAAQ,IAAI,IAAI,CAAC,CAAC;AAC/G,SAAO,IACJ,OAAO,CAAC,OAAO,IAAI,IAAI,EAAE,CAAC,EAC1B,IAAI,CAAC,QAAQ;AAAA,IACZ,SAAS;AAAA,IACT,UAAU,IAAI,IAAI,EAAE,KAAK;AAAA,EAC3B,EAAE;AACN;AAEA,eAAe,oBAAoB,IAAmB,UAAkB,WAAkC;AACxG,MAAI,CAAC,WAAW,OAAQ;AACxB,QAAM,MAAM,MAAM,KAAK,IAAI,IAAI,UAAU,IAAI,CAAC,UAAU,MAAM,OAAO,EAAE,OAAO,OAAO,CAAC,CAAC;AACvF,MAAI,CAAC,IAAI,OAAQ;AACjB,QAAM,SAAoC;AAAA,IACxC,QAAQ;AAAA,IACR,WAAW;AAAA,IACX,IAAI,EAAE,KAAK,IAAI;AAAA,EACjB;AACA,QAAM,WAAW,MAAM,GAAG,KAAK,cAAc,MAAM;AACnD,MAAI,CAAC,SAAS,OAAQ;AACtB,QAAM,UAAU,IAAI,IAAI,UAAU,IAAI,CAAC,UAAU,CAAC,MAAM,SAAS,MAAM,YAAY,IAAI,CAAC,CAAC;AACzF,QAAM,YAA4B,CAAC;AACnC,aAAW,SAAS,UAAU;AAC5B,UAAM,KAAK,OAAO,MAAM,EAAE;AAC1B,QAAI,CAAC,QAAQ,IAAI,EAAE,EAAG;AACtB,UAAM,aAAa,QAAQ,IAAI,EAAE,KAAK;AACtC,QAAI,MAAM,aAAa,YAAY;AACjC,YAAM,WAAW;AACjB,gBAAU,KAAK,KAAK;AAAA,IACtB;AAAA,EACF;AACA,MAAI,UAAU,OAAQ,OAAM,GAAG,QAAQ,SAAS,EAAE,MAAM;AAC1D;AAEA,SAAS,kBAAkB,KAAwB,SAA6B;AAC9E,QAAM,aAAa,IAAI,IAAI,OAAO;AAClC,SAAO,MAAM,KAAK,IAAI,IAAI,GAAG,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,WAAW,IAAI,EAAE,CAAC;AACpE;AAEA,eAAe,mBAAmB,IAAmB,UAAkB,UAAwC;AAC7G,MAAI,CAAC,SAAU;AACf,QAAM,eAA0C,EAAE,IAAI,UAAU,QAAQ,UAAU,WAAW,KAAK;AAClG,QAAM,SAAS,MAAM,GAAG,QAAQ,cAAc,YAAY;AAC1D,MAAI,CAAC,OAAQ,OAAM,IAAI,cAAc,KAAK,EAAE,OAAO,mBAAmB,CAAC;AACzE;AAEA,eAAe,oBAAoB,IAAmB,UAAkB,UAAmC;AACzG,MAAI,CAAC,SAAS,OAAQ;AACtB,QAAM,cAAyC,EAAE,IAAI,EAAE,KAAK,SAAS,GAAG,QAAQ,UAAU,WAAW,KAAK;AAC1G,QAAM,WAAW,MAAM,GAAG,KAAK,cAAc,WAAW;AACxD,MAAI,SAAS,WAAW,SAAS,OAAQ,OAAM,IAAI,cAAc,KAAK,EAAE,OAAO,2BAA2B,CAAC;AAC7G;AAEA,eAAe,eACb,IACA,UACA,UACA,iBACe;AACf,QAAM,YAAY,MAAM,KAAK,IAAI,IAAI,eAAe,CAAC,EAAE,OAAO,CAAC,OAAO,OAAO,QAAQ;AACrF,MAAI,CAAC,UAAU,OAAQ;AACvB,QAAM,SAAoC,EAAE,QAAQ,UAAU,WAAW,MAAM,IAAI,EAAE,KAAK,UAAU,EAAE;AACtG,QAAM,WAAW,MAAM,GAAG,KAAK,cAAc,MAAM;AACnD,QAAM,YAA4B,CAAC;AACnC,aAAW,SAAS,UAAU;AAC5B,QAAI,OAAO,MAAM,EAAE,MAAM,SAAU;AACnC,QAAI,MAAM,aAAa,UAAU;AAC/B,YAAM,WAAW;AACjB,gBAAU,KAAK,KAAK;AAAA,IACtB;AAAA,EACF;AACA,MAAI,UAAU,OAAQ,OAAM,GAAG,QAAQ,SAAS,EAAE,MAAM;AAC1D;AAEA,eAAe,qBAAqB,IAAmB,UAAkB,UAAkB,iBAA6C;AACtI,QAAM,gBAA2C,EAAE,QAAQ,UAAU,UAAU,UAAU,WAAW,KAAK;AACzG,QAAM,UAAU,MAAM,GAAG,KAAK,cAAc,aAAa;AACzD,QAAM,YAAY,QAAQ,OAAO,CAAC,UAAU,CAAC,gBAAgB,IAAI,OAAO,MAAM,EAAE,CAAC,CAAC;AAClF,MAAI,CAAC,UAAU,OAAQ;AACvB,aAAW,SAAS,UAAW,OAAM,WAAW;AAChD,QAAM,GAAG,QAAQ,SAAS,EAAE,MAAM;AACpC;AAEA,eAAe,kBAAkB,IAAmB,UAAkB,UAAkB,WAAqC;AAC3H,MAAI,YAAY;AAChB,MAAI,SAAS;AACb,QAAM,cAAc;AACpB,SAAO,SAAS,aAAa;AAC3B,UAAM,SAAoC;AAAA,MACxC,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,WAAW;AAAA,IACb;AACA,UAAM,WAAW,MAAM,GAAG,QAAQ,cAAc,MAAM;AACtD,QAAI,CAAC,YAAa,aAAa,OAAO,SAAS,EAAE,MAAM,UAAY,QAAO;AAC1E,cAAU;AACV,gBAAY,GAAG,QAAQ,IAAI,MAAM;AAAA,EACnC;AACA,SAAO,GAAG,QAAQ,IAAI,KAAK,IAAI,CAAC;AAClC;AAEA,MAAM,4BAAmF;AAAA,EACvF,IAAI;AAAA,EACJ,MAAM,QAAQ,UAAU,KAAK;AAC3B,UAAM,EAAE,QAAQ,OAAO,IAAI,sBAAsB,0BAA0B,QAAQ;AACnF,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI;AACtC,UAAM,WAAW,MAAM,uBAAuB,KAAK,OAAO,QAAQ;AAClE,QAAI,CAAC,SAAU,OAAM,IAAI,cAAc,KAAK,EAAE,OAAO,wBAAwB,CAAC;AAE9E,UAAM,WAAW,OAAO,YAAY;AACpC,UAAM,WAAW,kBAAkB,OAAO,YAAY,CAAC,GAAG,WAAW,CAAC,QAAQ,IAAI,CAAC,CAAC;AACpF,QAAI,YAAY,SAAS,SAAS,QAAQ,EAAG,OAAM,IAAI,cAAc,KAAK,EAAE,OAAO,4BAA4B,CAAC;AAEhH,UAAM,YAAY,GAAG,aAAa,QAAQ,QAAQ;AAClD,UAAM,WAAW,OAAO,OAAO,OAAO,OAAO,QAAQ,OAAO,IAAI;AAChE,UAAM,KAAM,IAAI,UAAU,QAAQ,YAAY;AAE9C,QAAI;AACJ,UAAM,gBAAgB,IAAI;AAAA,MACxB,YAAY;AACV,cAAM,mCAAmC,IAAI,QAAQ;AACrD,YAAI,UAAU;AACZ,gBAAM,mBAAmB,IAAI,UAAU,QAAQ;AAAA,QACjD;AACA,cAAM,oBAAoB,IAAI,UAAU,QAAQ;AAChD,cAAM,qBAAqB,MAAM,yBAAyB,IAAI,UAAU,QAAQ;AAChF,cAAM,OAAO,WAAW,MAAM,kBAAkB,IAAI,UAAU,QAAQ,IAAI;AAC1E,uBAAe,MAAM,GAAG,gBAAgB;AAAA,UACtC,QAAQ;AAAA,UACR,MAAM;AAAA,YACJ,QAAQ;AAAA,YACR,MAAM,OAAO;AAAA,YACb;AAAA,YACA,SAAS,OAAO,WAAW;AAAA,YAC3B,yBAAyB,OAAO,2BAA2B;AAAA,YAC3D,UAAU,OAAO,YAAY;AAAA,YAC7B;AAAA,UACF;AAAA,QACF,CAAC;AACD,4BAAoB,cAAc,QAAQ;AAC1C,cAAMA,YAAW,OAAO,aAAa,EAAE;AAEvC,YAAI,SAAS,QAAQ;AACnB,gBAAM,eAAe,IAAI,UAAUA,WAAU,QAAQ;AAAA,QACvD;AACA,cAAM,oBAAoB,MAAM,yBAAyB,IAAI,UAAU,QAAQ;AAC/E,oBAAY,cAAc,EAAE,oBAAoB,kBAAkB,CAAC;AAEnE,cAAM,qBAAqB;AAAA,UACzB,YAAY;AAAA,UACZ,UAAU,EAAE,UAAU;AAAA,UACtB,UAAAA;AAAA,UACA;AAAA,UACA,gBAAgBA;AAAA,UAChB,QAAQ;AAAA,QACV,CAAC;AAED,cAAM,0BAA0B,IAAI,QAAQ;AAAA,MAC9C;AAAA,IACF,GAAG,EAAE,aAAa,KAAK,CAAC;AAExB,UAAM,WAAW,OAAO,aAAa,EAAE;AACvC,UAAM,cAAc,EAAE,IAAI,UAAU,gBAAgB,UAAU,SAAS;AACvE,UAAM,oBAAoB;AAAA,MACxB,YAAY;AAAA,MACZ,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR;AAAA,MACA,QAAQ;AAAA,MACR,SAAS;AAAA,IACX,CAAC;AAED,WAAO;AAAA,EACT;AAAA,EACA,cAAc,OAAO,QAAQ,QAAQ,QAAQ;AAC3C,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,UAAM,WAAW,0BAA0B,MAAM;AACjD,UAAM,SAAS,MAAM,wBAAwB,IAAI;AAAA,MAC/C,UAAU,EAAE,UAAU;AAAA,MACtB,UAAU,OAAO,OAAO,EAAE;AAAA,MAC1B;AAAA,MACA,gBAAgB,OAAO,OAAO,EAAE;AAAA,IAClC,CAAC;AACD,WAAO,sBAAsB,QAAQ,MAAM;AAAA,EAC7C;AAAA,EACA,UAAU,OAAO,EAAE,QAAQ,IAAI,MAAM;AACnC,UAAM,EAAE,UAAU,IAAI,MAAM,oBAAoB;AAChD,UAAM,OAAO,YAAY,MAAM;AAC/B,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,UAAM,WAAW,0BAA0B,MAAM;AACjD,UAAM,SAAS,MAAM,wBAAwB,IAAI;AAAA,MAC/C,UAAU,EAAE,UAAU;AAAA,MACtB,UAAU,OAAO,OAAO,EAAE;AAAA,MAC1B;AAAA,MACA,gBAAgB,OAAO,OAAO,EAAE;AAAA,IAClC,CAAC;AACD,UAAM,iBAAiB,6BAA6B,QAAQ,KAAK,qBAAqB,CAAC,GAAG,MAAM;AAChG,WAAO;AAAA,MACL,aAAa,UAAU,wCAAwC,qBAAqB;AAAA,MACpF,cAAc;AAAA,MACd,YAAY,OAAO,OAAO,EAAE;AAAA,MAC5B;AAAA,MACA,eAAe,eAAe;AAAA,MAC9B,SAAS;AAAA,QACP,MAAM;AAAA,UACJ,OAAO,eAAe;AAAA,UACtB,gBAAgB,KAAK,sBAAsB,CAAC;AAAA,QAC9C;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA,MAAM,OAAO,EAAE,UAAU,IAAI,MAAM;AACjC,UAAM,UAAU,mBAA4C,QAAQ;AACpE,UAAM,QAAQ,SAAS;AACvB,UAAM,iBAAiB,SAAS,kBAAkB,CAAC;AACnD,QAAI,CAAC,MAAO;AACZ,UAAM,WAAW,MAAM;AACvB,QAAI,CAAC,SAAU;AACf,UAAM,mCAAmC,KAAK,QAAQ;AACtD,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI;AACtC,UAAM,KAAM,IAAI,UAAU,QAAQ,YAAY;AAC9C,UAAM,gBAAgB,IAAI;AAAA,MACxB,YAAY;AACV,cAAM,mCAAmC,IAAI,QAAQ;AACrD,cAAM,oBAAoB,IAAI,UAAU,cAAc;AACtD,YAAI,MAAM,UAAU,OAAO,KAAK,MAAM,MAAM,EAAE,QAAQ;AACpD,gBAAM,QAAQ,yBAAyB,QAAW,MAAM,MAAM;AAC9D,cAAI,OAAO,KAAK,KAAK,EAAE,QAAQ;AAC7B,kBAAM,cAAc;AACpB,kBAAM,GAAG,gBAAgB;AAAA,cACvB,UAAU,EAAE,UAAU;AAAA,cACtB,UAAU,MAAM;AAAA,cAChB;AAAA,cACA,gBAAgB,MAAM;AAAA,cACtB,QAAQ;AAAA,cACR,QAAQ;AAAA,YACV,CAAC;AAAA,UACH;AAAA,QACF;AACA,cAAM,GAAG,gBAAgB;AAAA,UACvB,QAAQ;AAAA,UACR,OAAO,gCAAgC,MAAM,IAAI,QAAQ;AAAA,UACzD,MAAM;AAAA,QACR,CAAC;AACD,cAAM,0BAA0B,IAAI,QAAQ;AAAA,MAC9C;AAAA,IACF,GAAG,EAAE,aAAa,KAAK,CAAC;AAAA,EAC1B;AAAA,EACA,MAAM,OAAO,EAAE,UAAU,IAAI,MAAM;AACjC,UAAM,QAAQ,oBAA8C,QAAQ;AACpE,QAAI,CAAC,MAAO,OAAM,IAAI,cAAc,KAAK,EAAE,OAAO,+DAA+D,CAAC;AAClH,UAAM,WAAW,MAAM;AACvB,QAAI,CAAC,SAAU,OAAM,IAAI,cAAc,KAAK,EAAE,OAAO,kEAAkE,CAAC;AACxH,UAAM,mCAAmC,KAAK,QAAQ;AACtD,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI;AACtC,UAAM,KAAM,IAAI,UAAU,QAAQ,YAAY;AAC9C,QAAI;AACJ,UAAM,gBAAgB,IAAI;AAAA,MACxB,YAAY;AACV,cAAM,mCAAmC,IAAI,QAAQ;AACrD,cAAM,WAAW,MAAM,GAAG,QAAQ,cAAc,kCAAkC,MAAM,IAAI,QAAQ,CAAC;AACrG,YAAI,UAAU;AACZ,mBAAS,YAAY;AACrB,mBAAS,OAAO,MAAM;AACtB,cAAI,MAAM,SAAS,OAAW,UAAS,OAAO,MAAM,QAAQ;AAC5D,cAAI,MAAM,YAAY,OAAW,UAAS,UAAU,MAAM,WAAW;AACrE,cAAI,MAAM,4BAA4B,OAAW,UAAS,0BAA0B,CAAC,CAAC,MAAM;AAC5F,mBAAS,WAAW,MAAM;AAC1B,mBAAS,WAAW,MAAM;AAC1B,gBAAM,GAAG,MAAM;AACf,yBAAe;AAAA,QACjB,OAAO;AACL,yBAAe,MAAM,GAAG,gBAAgB;AAAA,YACtC,QAAQ;AAAA,YACR,MAAM;AAAA,cACJ,IAAI,MAAM;AAAA,cACV,MAAM,MAAM;AAAA,cACZ,MAAM,MAAM,QAAQ;AAAA,cACpB,SAAS,MAAM,WAAW;AAAA,cAC1B,yBAAyB,MAAM,2BAA2B;AAAA,cAC1D,QAAQ,GAAG,aAAa,QAAQ,QAAQ;AAAA,cACxC,UAAU,MAAM;AAAA,cAChB,UAAU,MAAM;AAAA,YAClB;AAAA,UACF,CAAC;AAAA,QACH;AACA,4BAAoB,cAAc,QAAQ;AAE1C,YAAI,MAAM,UAAU,OAAO,KAAK,MAAM,MAAM,EAAE,QAAQ;AACpD,gBAAM,QAAQ,yBAAyB,MAAM,QAAQ,MAAS;AAC9D,cAAI,OAAO,KAAK,KAAK,EAAE,QAAQ;AAC7B,kBAAM,cAAc;AACpB,kBAAM,GAAG,gBAAgB;AAAA,cACvB,UAAU,EAAE,UAAU;AAAA,cACtB,UAAU,MAAM;AAAA,cAChB;AAAA,cACA,gBAAgB,MAAM;AAAA,cACtB,QAAQ;AAAA,cACR,QAAQ;AAAA,YACV,CAAC;AAAA,UACH;AAAA,QACF;AAEA,cAAM,eAAe,IAAI,UAAU,MAAM,IAAI,MAAM,aAAa,IAAI,CAAC,UAAU,MAAM,OAAO,CAAC;AAC7F,cAAM,0BAA0B,IAAI,QAAQ;AAAA,MAC9C;AAAA,IACF,GAAG,EAAE,aAAa,KAAK,CAAC;AAExB,UAAM,cAAc,EAAE,IAAI,MAAM,IAAI,gBAAgB,MAAM,IAAI,SAAS;AACvE,UAAM,oBAAoB;AAAA,MACxB,YAAY;AAAA,MACZ,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR;AAAA,MACA,QAAQ;AAAA,MACR,SAAS;AAAA,IACX,CAAC;AAED,WAAO;AAAA,EACT;AACF;AAEA,MAAM,4BAAmF;AAAA,EACvF,IAAI;AAAA,EACJ,MAAM,QAAQ,UAAU,KAAK;AAC3B,UAAM,EAAE,OAAO,IAAI,sBAAsB,0BAA0B,QAAQ;AAC3E,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI;AACtC,UAAM,EAAE,cAAc,SAAS,SAAS,IAAI,MAAM,iCAAiC,IAAI,OAAO,IAAI,GAAG;AACrG,UAAM,kBAAkB,MAAM,QAAQ,QAAQ,QAAQ,IAAI,QAAQ,WAAW,CAAC;AAC9E,UAAM,oBAAoB,MAAM,QAAQ,OAAO,QAAQ,IAAI,OAAO,WAAW,CAAC;AAC9E,UAAM,mBAAmB,oBAAI,IAAY,CAAC,GAAG,gBAAgB,IAAI,MAAM,GAAG,GAAG,kBAAkB,IAAI,MAAM,CAAC,CAAC;AAC3G,UAAM,qBAAqB,WACvB,MAAM,yBAAyB,IAAI,UAAU,gBAAgB,IAC7D,CAAC;AACL,UAAM,SAAS,MAAM,wBAAwB,IAAI;AAAA,MAC/C,UAAU,EAAE,UAAU;AAAA,MACtB,UAAU,OAAO,QAAQ,EAAE;AAAA,MAC3B;AAAA,MACA,gBAAgB,OAAO,QAAQ,EAAE;AAAA,IACnC,CAAC;AACD,WAAO,EAAE,QAAQ,6BAA6B,SAAS,oBAAoB,MAAM,EAAE;AAAA,EACrF;AAAA,EACA,MAAM,QAAQ,UAAU,KAAK;AAC3B,UAAM,EAAE,QAAQ,OAAO,IAAI,sBAAsB,0BAA0B,QAAQ;AACnF,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI;AACtC,UAAM,EAAE,SAAS,IAAI,MAAM,iCAAiC,IAAI,OAAO,IAAI,GAAG;AAE9E,UAAM,iBAAiB,OAAO,aAAa;AAC3C,UAAM,mBAAmB,OAAO,aAAa;AAC7C,UAAM,KAAM,IAAI,UAAU,QAAQ,YAAY;AAE9C,QAAI;AACJ,UAAM,gBAAgB,IAAI;AAAA,MACxB,YAAY;AACV,cAAM,mCAAmC,IAAI,QAAQ;AACrD,cAAM,WAAW,MAAM,GAAG;AAAA,UACxB;AAAA,UACA,gCAAgC,OAAO,IAAI,QAAQ;AAAA,UACnD,EAAE,SAAS,KAAK;AAAA,QAClB;AACA,YAAI,CAAC,SAAU,OAAM,IAAI,cAAc,KAAK,EAAE,OAAO,YAAY,CAAC;AAElE,cAAM,WAAW,iBAAiB,OAAO,YAAY,OAAO,SAAS,YAAY;AACjF,YAAI,kBAAkB,UAAU;AAC9B,cAAI,aAAa,OAAO,GAAI,OAAM,IAAI,cAAc,KAAK,EAAE,OAAO,wCAAwC,CAAC;AAC3G,cAAI,MAAM,QAAQ,SAAS,aAAa,KAAK,SAAS,cAAc,SAAS,QAAQ,GAAG;AACtF,kBAAM,IAAI,cAAc,KAAK,EAAE,OAAO,qCAAqC,CAAC;AAAA,UAC9E;AACA,gBAAM,mBAAmB,IAAI,UAAU,QAAQ;AAAA,QACjD;AAEA,cAAM,qBAAqB,kBAAkB,OAAO,YAAY,CAAC,GAAG,CAAC,OAAO,IAAI,iBAAiB,YAAY,KAAK,EAAE,CAAC;AACrH,YAAI,mBAAmB,KAAK,CAAC,OAAO,OAAO,QAAQ,EAAG,OAAM,IAAI,cAAc,KAAK,EAAE,OAAO,4BAA4B,CAAC;AACzH,YAAI,MAAM,QAAQ,SAAS,WAAW,KAAK,mBAAmB,KAAK,CAAC,OAAO,SAAS,YAAY,SAAS,EAAE,CAAC,GAAG;AAC7G,gBAAM,IAAI,cAAc,KAAK,EAAE,OAAO,kCAAkC,CAAC;AAAA,QAC3E;AAEA,YAAI,mBAAmB,QAAQ;AAC7B,gBAAM,oBAAoB,IAAI,UAAU,kBAAkB;AAC1D,gBAAM,cAAc;AAAA,YAClB,QAAQ;AAAA,YACR,WAAW;AAAA,YACX,IAAI,EAAE,KAAK,mBAAmB;AAAA,UAChC;AACA,gBAAM,WAAW,MAAM,GAAG,KAAK,cAAc,WAAW;AACxD,qBAAW,SAAS,UAAU;AAC5B,gBAAI,MAAM,QAAQ,MAAM,aAAa,KAAK,MAAM,cAAc,SAAS,OAAO,EAAE,GAAG;AACjF,oBAAM,IAAI,cAAc,KAAK,EAAE,OAAO,iCAAiC,CAAC;AAAA,YAC1E;AAAA,UACF;AAAA,QACF;AAEA,cAAM,mBAAmB,oBAAI,IAAY;AAAA,UACvC,GAAG,mBAAmB,IAAI,MAAM;AAAA,UAChC,GAAI,MAAM,QAAQ,SAAS,QAAQ,IAAI,SAAS,SAAS,IAAI,MAAM,IAAI,CAAC;AAAA,QAC1E,CAAC;AACD,cAAM,qBAAqB,MAAM,yBAAyB,IAAI,UAAU,gBAAgB;AAExF,YAAI;AACJ,YAAI,OAAO,SAAS,QAAW;AAC7B,yBAAe,OAAO,OAAO,MAAM,kBAAkB,IAAI,UAAU,OAAO,MAAM,OAAO,EAAE,IAAI,OAAO;AAAA,QACtG;AAEA,cAAM,eAAe,MAAM,GAAG,gBAAgB;AAAA,UAC5C,QAAQ;AAAA,UACR,OAAO,gCAAgC,OAAO,IAAI,QAAQ;AAAA,UAC1D,OAAO,CAAC,WAAW;AACjB,gBAAI,OAAO,SAAS,OAAW,QAAO,OAAO,OAAO;AACpD,gBAAI,iBAAiB,OAAW,QAAO,OAAO;AAC9C,gBAAI,OAAO,YAAY,OAAW,QAAO,UAAU,OAAO,WAAW;AACrE,gBAAI,OAAO,4BAA4B,OAAW,QAAO,0BAA0B,OAAO;AAC1F,gBAAI,OAAO,aAAa,OAAW,QAAO,WAAW,OAAO;AAC5D,gBAAI,eAAgB,QAAO,WAAW;AAAA,UACxC;AAAA,QACF,CAAC;AACD,YAAI,CAAC,aAAc,OAAM,IAAI,cAAc,KAAK,EAAE,OAAO,YAAY,CAAC;AACtE,4BAAoB,cAAc,QAAQ;AAE1C,cAAMA,YAAW,OAAO,aAAa,EAAE;AACvC,cAAM,kBAAkB,IAAI,IAAI,mBAAmB,OAAO,CAAC,OAAO,OAAOA,SAAQ,CAAC;AAClF,YAAI,kBAAkB;AACpB,gBAAM,qBAAqB,IAAI,UAAUA,WAAU,eAAe;AAClE,gBAAM,eAAe,IAAI,UAAUA,WAAU,eAAe;AAAA,QAC9D;AACA,cAAM,oBAAoB,MAAM,yBAAyB,IAAI,UAAU,gBAAgB;AACvF,oBAAY,cAAc,EAAE,oBAAoB,kBAAkB,CAAC;AAEnE,cAAM,qBAAqB;AAAA,UACzB,YAAY;AAAA,UACZ,UAAU,EAAE,UAAU;AAAA,UACtB,UAAAA;AAAA,UACA;AAAA,UACA,gBAAgBA;AAAA,UAChB,QAAQ;AAAA,QACV,CAAC;AAED,cAAM,0BAA0B,IAAI,QAAQ;AAC5C,+BAAuB;AAAA,MACzB;AAAA,IACF,GAAG,EAAE,aAAa,KAAK,CAAC;AAExB,UAAM,WAAW,OAAO,qBAAqB,EAAE;AAC/C,UAAM,cAAc,EAAE,IAAI,UAAU,gBAAgB,UAAU,SAAS;AACvE,UAAM,oBAAoB;AAAA,MACxB,YAAY;AAAA,MACZ,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR;AAAA,MACA,QAAQ;AAAA,MACR,SAAS;AAAA,IACX,CAAC;AAED,WAAO;AAAA,EACT;AAAA,EACA,cAAc,OAAO,QAAQ,QAAQ,QAAQ;AAC3C,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,UAAM,WAAW,0BAA0B,MAAM;AACjD,UAAM,SAAS,MAAM,wBAAwB,IAAI;AAAA,MAC/C,UAAU,EAAE,UAAU;AAAA,MACtB,UAAU,OAAO,OAAO,EAAE;AAAA,MAC1B;AAAA,MACA,gBAAgB,OAAO,OAAO,EAAE;AAAA,IAClC,CAAC;AACD,WAAO,sBAAsB,QAAQ,MAAM;AAAA,EAC7C;AAAA,EACA,UAAU,OAAO,EAAE,WAAW,QAAQ,IAAI,MAAM;AAC9C,UAAM,EAAE,UAAU,IAAI,MAAM,oBAAoB;AAChD,UAAM,OAAO,YAAY,MAAM;AAC/B,UAAM,kBAAkB,UAAU;AAClC,UAAM,eAAe,iBAAiB,QAAQ;AAC9C,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI,EAAoB,KAAK;AAC/D,UAAM,WAAW,0BAA0B,MAAM;AACjD,UAAM,SAAS,MAAM,wBAAwB,IAAI;AAAA,MAC/C,UAAU,EAAE,UAAU;AAAA,MACtB,UAAU,OAAO,OAAO,EAAE;AAAA,MAC1B;AAAA,MACA,gBAAgB,OAAO,OAAO,EAAE;AAAA,IAClC,CAAC;AACD,UAAM,QAAQ,sBAAsB,QAAQ,MAAM;AAClD,UAAM,UAAU,aAAa,cAAc,OAAkC,CAAC,QAAQ,QAAQ,WAAW,2BAA2B,YAAY,UAAU,CAAC;AAC3J,UAAM,aAAa,uBAAuB,cAAc,QAAQ,MAAM;AACtE,eAAW,CAAC,KAAK,IAAI,KAAK,OAAO,QAAQ,UAAU,GAAG;AACpD,cAAQ,MAAM,GAAG,EAAE,IAAI;AAAA,IACzB;AACA,WAAO;AAAA,MACL,aAAa,UAAU,wCAAwC,qBAAqB;AAAA,MACpF,cAAc;AAAA,MACd,YAAY,OAAO,OAAO,EAAE;AAAA,MAC5B;AAAA,MACA,UAAU,MAAM;AAAA,MAChB,SAAS;AAAA,QACP,MAAM;AAAA,UACJ,QAAQ,iBAAiB,QAAQ;AAAA,UACjC,OAAO,6BAA6B,QAAQ,KAAK,qBAAqB,CAAC,GAAG,MAAM,EAAE;AAAA,QACpF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA,MAAM,OAAO,EAAE,UAAU,IAAI,MAAM;AACjC,UAAM,UAAU,mBAA4C,QAAQ;AACpE,UAAM,SAAS,SAAS;AACxB,UAAM,QAAQ,SAAS;AACvB,QAAI,CAAC,OAAQ;AACb,UAAM,WAAW,OAAO;AACxB,QAAI,CAAC,SAAU;AACf,UAAM,mCAAmC,KAAK,QAAQ;AACtD,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI;AACtC,UAAM,KAAM,IAAI,UAAU,QAAQ,YAAY;AAC9C,QAAI,UAA+B;AACnC,UAAM,gBAAgB,IAAI;AAAA,MACxB,YAAY;AACV,cAAM,mCAAmC,IAAI,QAAQ;AACrD,kBAAU,MAAM,GAAG,gBAAgB;AAAA,UACjC,QAAQ;AAAA,UACR,OAAO,kCAAkC,OAAO,IAAI,QAAQ;AAAA,UAC5D,OAAO,CAAC,WAAW;AACjB,mBAAO,OAAO,OAAO;AACrB,gBAAI,OAAO,SAAS,OAAW,QAAO,OAAO,OAAO;AACpD,gBAAI,OAAO,YAAY,OAAW,QAAO,UAAU,OAAO,WAAW;AACrE,gBAAI,OAAO,4BAA4B,OAAW,QAAO,0BAA0B,CAAC,CAAC,OAAO;AAC5F,mBAAO,WAAW,OAAO;AACzB,mBAAO,WAAW,OAAO;AAAA,UAC3B;AAAA,QACF,CAAC;AACD,YAAI,CAAC,QAAS,OAAM,IAAI,cAAc,KAAK,EAAE,OAAO,YAAY,CAAC;AACjE,4BAAoB,SAAS,QAAQ;AACrC,cAAM,QAAQ,yBAAyB,OAAO,QAAQ,OAAO,MAAM;AACnE,YAAI,OAAO,KAAK,KAAK,EAAE,QAAQ;AAC7B,gBAAM,cAAc;AACpB,gBAAM,GAAG,gBAAgB;AAAA,YACvB,UAAU,EAAE,UAAU;AAAA,YACtB,UAAU,OAAO;AAAA,YACjB;AAAA,YACA,gBAAgB,OAAO;AAAA,YACvB,QAAQ;AAAA,YACR,QAAQ;AAAA,UACV,CAAC;AAAA,QACH;AACA,cAAM,iBAAiB,OAAO;AAC9B,cAAM,oBAAoB,IAAI,UAAU,cAAc;AACtD,cAAM,0BAA0B,IAAI,QAAQ;AAAA,MAC9C;AAAA,IACF,GAAG,EAAE,aAAa,KAAK,CAAC;AACxB,UAAM,wBAAwB;AAAA,MAC5B,YAAY;AAAA,MACZ,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,aAAa;AAAA,QACX,IAAI,OAAO;AAAA,QACX;AAAA,QACA,gBAAgB,OAAO;AAAA,MACzB;AAAA,MACA,QAAQ;AAAA,MACR,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AACF;AAEA,MAAM,4BAAwG;AAAA,EAC5G,IAAI;AAAA,EACJ,MAAM,QAAQ,OAAO,KAAK;AACxB,UAAM,KAAK,UAAU,OAAO,0BAA0B;AACtD,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI;AACtC,UAAM,EAAE,cAAc,UAAU,SAAS,IAAI,MAAM,iCAAiC,IAAI,IAAI,GAAG;AAC/F,UAAM,qBAAqB,WACvB,MAAM,yBAAyB,IAAI,UAAU,MAAM,QAAQ,SAAS,QAAQ,IAAI,SAAS,WAAW,CAAC,CAAC,IACtG,CAAC;AACL,UAAM,SAAS,MAAM,wBAAwB,IAAI;AAAA,MAC/C,UAAU,EAAE,UAAU;AAAA,MACtB,UAAU,OAAO,SAAS,EAAE;AAAA,MAC5B;AAAA,MACA,gBAAgB,OAAO,SAAS,EAAE;AAAA,IACpC,CAAC;AACD,WAAO,EAAE,QAAQ,6BAA6B,UAAU,oBAAoB,MAAM,EAAE;AAAA,EACtF;AAAA,EACA,MAAM,QAAQ,OAAO,KAAK;AACxB,UAAM,KAAK,UAAU,OAAO,0BAA0B;AACtD,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI;AACtC,UAAM,EAAE,cAAc,UAAU,SAAS,IAAI,MAAM,iCAAiC,IAAI,IAAI,GAAG;AAE/F,UAAM,WAAW,SAAS,YAAY;AACtC,UAAM,uBAAuB,MAAM;AAAA,MACjC;AAAA,MACA;AAAA,MACA,MAAM,QAAQ,SAAS,QAAQ,IAAI,SAAS,WAAW,CAAC;AAAA,IAC1D;AAEA,UAAM,KAAM,IAAI,UAAU,QAAQ,YAAY;AAE9C,QAAI;AACJ,UAAM,gBAAgB,IAAI;AAAA,MACxB,YAAY;AACV,cAAM,mCAAmC,IAAI,QAAQ;AACrD,cAAM,UAAU,MAAM,GAAG,gBAAgB;AAAA,UACvC,QAAQ;AAAA,UACR,OAAO,gCAAgC,IAAI,QAAQ;AAAA,UACnD,MAAM;AAAA,UACN,iBAAiB;AAAA,QACnB,CAAC;AACD,YAAI,CAAC,QAAS,OAAM,IAAI,cAAc,KAAK,EAAE,OAAO,YAAY,CAAC;AACjE,4BAAoB,SAAS,QAAQ;AACrC,gBAAQ,WAAW;AACnB,gBAAQ,WAAW;AACnB,0BAAkB;AAAA,MACpB;AAAA,MACA,YAAY;AACV,cAAM,UAAU;AAChB,cAAM,iBAA4C,EAAE,QAAQ,UAAU,UAAU,IAAI,WAAW,KAAK;AACpG,cAAM,WAAW,MAAM,GAAG,KAAK,cAAc,cAAc;AAC3D,cAAM,YAA4B,CAAC;AACnC,mBAAW,SAAS,UAAU;AAC5B,gBAAM,WAAW;AACjB,oBAAU,KAAK,KAAK;AAAA,QACtB;AACA,kBAAU,KAAK,OAAO;AACtB,YAAI,UAAU,OAAQ,IAAG,QAAQ,SAAS;AAC1C,oBAAY,SAAS,EAAE,oBAAoB,qBAAqB,CAAC;AAAA,MACnE;AAAA,MACA,YAAY;AACV,cAAM,0BAA0B,IAAI,QAAQ;AAAA,MAC9C;AAAA,IACF,GAAG,EAAE,aAAa,KAAK,CAAC;AAExB,UAAM,cAAc,EAAE,IAAI,gBAAgB,IAAI,SAAS;AACvD,UAAM,oBAAoB;AAAA,MACxB,YAAY;AAAA,MACZ,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR;AAAA,MACA,QAAQ;AAAA,MACR,SAAS;AAAA,IACX,CAAC;AAED,WAAO;AAAA,EACT;AAAA,EACA,UAAU,OAAO,EAAE,WAAW,MAAM,MAAM;AACxC,UAAM,EAAE,UAAU,IAAI,MAAM,oBAAoB;AAChD,UAAM,kBAAkB,UAAU;AAClC,UAAM,iBAAiB,iBAAiB,QAAQ;AAChD,UAAM,aAAa,iBAAiB,QAAQ;AAC5C,UAAM,KAAK,OAAO,OAAO,MAAM,MAAM,OAAO,OAAO,MAAM,EAAE;AAC3D,UAAM,aAAa,gBAAgB,MAAM;AACzC,UAAM,iBAAiB,gBAAgB,YAAY;AACnD,WAAO;AAAA,MACL,aAAa,UAAU,wCAAwC,qBAAqB;AAAA,MACpF,cAAc;AAAA,MACd,YAAY,MAAM,cAAc;AAAA,MAChC,gBAAgB,kBAAkB;AAAA,MAClC,UAAU,YAAY,YAAY;AAAA,MAClC,SAAS;AAAA,QACP,MAAM;AAAA,UACJ,QAAQ;AAAA,QACV;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA,EACA,MAAM,OAAO,EAAE,UAAU,IAAI,MAAM;AACjC,UAAM,UAAU,mBAA4C,QAAQ;AACpE,UAAM,SAAS,SAAS;AACxB,QAAI,CAAC,OAAQ;AACb,UAAM,WAAW,OAAO;AACxB,QAAI,CAAC,SAAU;AACf,UAAM,mCAAmC,KAAK,QAAQ;AACtD,UAAM,KAAM,IAAI,UAAU,QAAQ,IAAI;AACtC,UAAM,KAAM,IAAI,UAAU,QAAQ,YAAY;AAC9C,QAAI,eAAoC;AACxC,UAAM,gBAAgB,IAAI;AAAA,MACxB,YAAY;AACV,cAAM,mCAAmC,IAAI,QAAQ;AACrD,uBAAe,MAAM,GAAG;AAAA,UACtB;AAAA,UACA,kCAAkC,OAAO,IAAI,QAAQ;AAAA,QACvD;AACA,YAAI,cAAc;AAChB,uBAAa,YAAY;AACzB,uBAAa,WAAW,OAAO;AAC/B,uBAAa,OAAO,OAAO;AAC3B,cAAI,OAAO,SAAS,OAAW,cAAa,OAAO,OAAO;AAC1D,uBAAa,WAAW,OAAO;AAC/B,gBAAM,GAAG,MAAM;AACf,cAAI,SAAU,qBAAoB,cAAc,QAAQ;AAAA,QAC1D,OAAO;AACL,yBAAe,MAAM,GAAG,gBAAgB;AAAA,YACtC,QAAQ;AAAA,YACR,MAAM;AAAA,cACJ,IAAI,OAAO;AAAA,cACX,MAAM,OAAO;AAAA,cACb,MAAM,OAAO,QAAQ;AAAA,cACrB,QAAQ,WAAW,GAAG,aAAa,QAAQ,QAAQ,IAAI;AAAA,cACvD,UAAU,OAAO;AAAA,cACjB,UAAU,OAAO;AAAA,YACnB;AAAA,UACF,CAAC;AACD,cAAI,SAAU,qBAAoB,cAAc,QAAQ;AAAA,QAC1D;AACA,YAAI,UAAU;AACZ,gBAAM,eAAe,yBAAyB,OAAO,QAAQ,MAAS;AACtE,cAAI,OAAO,KAAK,YAAY,EAAE,QAAQ;AACpC,kBAAM,cAAc;AACpB,kBAAM,GAAG,gBAAgB;AAAA,cACvB,UAAU,EAAE,UAAU;AAAA,cACtB,UAAU,OAAO;AAAA,cACjB;AAAA,cACA,gBAAgB,OAAO;AAAA,cACvB,QAAQ;AAAA,cACR,QAAQ;AAAA,YACV,CAAC;AAAA,UACH;AAAA,QACF;AACA,cAAM,oBAAoB,IAAI,UAAU,OAAO,YAAY;AAC3D,cAAM,0BAA0B,IAAI,QAAQ;AAAA,MAC9C;AAAA,IACF,GAAG,EAAE,aAAa,KAAK,CAAC;AACxB,UAAM,wBAAwB;AAAA,MAC5B,YAAY;AAAA,MACZ,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,aAAa;AAAA,QACX,IAAI,OAAO;AAAA,QACX;AAAA,QACA,gBAAgB,OAAO;AAAA,MACzB;AAAA,MACA,QAAQ;AAAA,MACR,SAAS;AAAA,IACX,CAAC;AAAA,EACH;AACF;AAaA,MAAM,gBAA+B,uBAAO,iCAAiC;AAE7E,SAAS,YAAY,QAA4C;AAC/D,SAAQ,QAAQ,IAAI,QAAQ,aAAa,KAA0C,CAAC;AACtF;AAEA,SAAS,YAAY,QAAsB,MAAqC;AAC9E,QAAM,UAAU,YAAY,MAAM;AAClC,UAAQ,IAAI,QAAQ,eAAe,EAAE,GAAG,SAAS,GAAG,KAAK,CAAC;AAC5D;AAEA,gBAAgB,yBAAyB;AACzC,gBAAgB,yBAAyB;AACzC,gBAAgB,yBAAyB;AAEzC,SAAS,oBAAoB,QAAsB,UAAkB;AACnE,UAAQ,IAAI,QAAQ,cAAc,QAAQ;AAC5C;AAEA,SAAS,oBAAoB,KAAmD;AAC9E,SAAO,0BAA0B,IAAI,MAAM,KAAK,IAAI,YAAY,YAAY;AAC9E;",
|
|
4
|
+
"sourcesContent": ["import type { CommandHandler, CommandRuntimeContext } from '@open-mercato/shared/lib/commands'\nimport { registerCommand } from '@open-mercato/shared/lib/commands'\nimport { CrudHttpError } from '@open-mercato/shared/lib/crud/errors'\nimport type { EntityManager, FilterQuery } from '@mikro-orm/postgresql'\nimport type { DataEngine } from '@open-mercato/shared/lib/data/engine'\nimport { Organization, Tenant } from '@open-mercato/core/modules/directory/data/entities'\nimport { organizationCreateSchema, organizationUpdateSchema } from '@open-mercato/core/modules/directory/data/validators'\nimport {\n lockOrganizationHierarchyForTenant,\n rebuildHierarchyForTenant,\n} from '@open-mercato/core/modules/directory/lib/hierarchy'\nimport {\n enforceTenantSelection,\n normalizeTenantId,\n resolveIsSuperAdmin,\n} from '@open-mercato/core/modules/auth/lib/tenantAccess'\nimport { E } from '#generated/entities.ids.generated'\nimport type { CrudEmitContext, CrudEventsConfig, CrudIndexerConfig } from '@open-mercato/shared/lib/crud/types'\nimport {\n loadCustomFieldSnapshot,\n buildCustomFieldResetMap,\n diffCustomFieldChanges,\n} from '@open-mercato/shared/lib/commands/customFieldSnapshots'\nimport { extractUndoPayload, reviveSnapshotDates } from '@open-mercato/shared/lib/commands/undo'\nimport { resolveRedoSnapshot } from '@open-mercato/shared/lib/commands/redo'\nimport { withAtomicFlush } from '@open-mercato/shared/lib/commands/flush'\nimport {\n parseWithCustomFields,\n setCustomFieldsIfAny,\n emitCrudSideEffects,\n emitCrudUndoSideEffects,\n requireId,\n buildChanges,\n} from '@open-mercato/shared/lib/commands/helpers'\nimport { resolveTranslations } from '@open-mercato/shared/lib/i18n/server'\nimport { toOptionalString } from '@open-mercato/shared/lib/string/coerce'\nimport { slugify } from '@open-mercato/shared/lib/slugify'\n\nexport const organizationCrudEvents: CrudEventsConfig = {\n module: 'directory',\n entity: 'organization',\n persistent: true,\n buildPayload: (ctx) => {\n const orgCtx = ctx as CrudEmitContext<Organization>\n return {\n id: orgCtx.identifiers.id,\n tenantId: tenantIdFromContext(orgCtx),\n organizationId: orgCtx.identifiers.id,\n }\n },\n}\n\nexport const organizationCrudIndexer: CrudIndexerConfig = {\n entityType: E.directory.organization,\n buildUpsertPayload: (ctx) => {\n const orgCtx = ctx as CrudEmitContext<Organization>\n return {\n entityType: E.directory.organization,\n recordId: orgCtx.identifiers.id,\n organizationId: orgCtx.identifiers.id,\n tenantId: tenantIdFromContext(orgCtx),\n }\n },\n buildDeletePayload: (ctx) => {\n const orgCtx = ctx as CrudEmitContext<Organization>\n return {\n entityType: E.directory.organization,\n recordId: orgCtx.identifiers.id,\n organizationId: orgCtx.identifiers.id,\n tenantId: tenantIdFromContext(orgCtx),\n }\n },\n}\n\ntype OrganizationTenantShape = {\n __tenantId?: unknown\n tenant?: string | { id?: unknown; getEntity?: () => { id?: unknown } }\n tenantId?: unknown\n tenant_id?: unknown\n}\n\ntype SerializedOrganization = ReturnType<typeof serializeOrganization>\n\ntype ChildParentSnapshot = {\n childId: string\n parentId: string | null\n}\n\ntype OrganizationUndoSnapshot = {\n id: string\n tenantId: string | null\n createdAt?: string | null\n name: string\n slug?: string | null\n logoUrl?: string | null\n logoPreserveAspectRatio?: boolean\n isActive: boolean\n parentId: string | null\n childParents: ChildParentSnapshot[]\n custom?: Record<string, unknown>\n}\n\ntype OrganizationSnapshots = {\n view: SerializedOrganization\n undo: OrganizationUndoSnapshot\n}\n\ntype OrganizationActorScope = {\n isUnrestricted: boolean\n tenantId: string | null\n}\n\ntype AuthorizedOrganizationTarget = {\n organization: Organization\n tenantId: string\n}\n\nexport function resolveTenantIdFromEntity(entity: Organization): string | null {\n const shape = entity as unknown as OrganizationTenantShape\n const cached = toOptionalString(shape.__tenantId)\n if (cached) return cached\n const tenantRef = shape.tenant\n if (typeof tenantRef === 'string') return tenantRef\n if (tenantRef && typeof tenantRef === 'object') {\n const direct = toOptionalString(tenantRef.id)\n if (direct) return direct\n if (typeof tenantRef.getEntity === 'function') {\n const nested = tenantRef.getEntity()\n const nestedId = nested ? toOptionalString(nested.id) : null\n if (nestedId) return nestedId\n }\n }\n const fallback = toOptionalString(shape.tenantId) || toOptionalString(shape.tenant_id)\n return fallback\n}\n\nasync function resolveOrganizationActorScope(ctx: CommandRuntimeContext): Promise<OrganizationActorScope> {\n if (ctx.systemActor === true) return { isUnrestricted: true, tenantId: null }\n const tenantId = normalizeTenantId(ctx.auth?.tenantId ?? null) ?? null\n const isSuperAdmin = await resolveIsSuperAdmin(ctx)\n return { isUnrestricted: isSuperAdmin, tenantId }\n}\n\nfunction buildOrganizationTargetFilter(\n id: string,\n scope: OrganizationActorScope,\n): FilterQuery<Organization> | null {\n if (!scope.isUnrestricted && !scope.tenantId) return null\n return {\n id,\n deletedAt: null,\n ...(scope.isUnrestricted ? {} : { tenant: scope.tenantId }),\n } as FilterQuery<Organization>\n}\n\nasync function loadAuthorizedOrganizationTarget(\n em: EntityManager,\n id: string,\n ctx: CommandRuntimeContext,\n): Promise<AuthorizedOrganizationTarget> {\n const scope = await resolveOrganizationActorScope(ctx)\n const filter = buildOrganizationTargetFilter(id, scope)\n if (!filter) throw new CrudHttpError(404, { error: 'Not found' })\n const organization = await em.findOne(Organization, filter)\n if (!organization) throw new CrudHttpError(404, { error: 'Not found' })\n const tenantId = resolveTenantIdFromEntity(organization)\n if (!tenantId || (!scope.isUnrestricted && tenantId !== scope.tenantId)) {\n throw new CrudHttpError(404, { error: 'Not found' })\n }\n return { organization, tenantId }\n}\n\nfunction buildOrganizationMutationFilter(\n id: string,\n tenantId: string,\n): FilterQuery<Organization> {\n return {\n id,\n deletedAt: null,\n tenant: tenantId,\n } as FilterQuery<Organization>\n}\n\nasync function assertOrganizationUndoTenantAccess(\n ctx: CommandRuntimeContext,\n targetTenantId: string,\n): Promise<void> {\n const scope = await resolveOrganizationActorScope(ctx)\n if (!scope.isUnrestricted && scope.tenantId !== targetTenantId) {\n throw new CrudHttpError(404, { error: 'Not found' })\n }\n}\n\nfunction buildOrganizationUndoTargetFilter(\n id: string,\n tenantId: string,\n): FilterQuery<Organization> {\n return { id, tenant: tenantId } as FilterQuery<Organization>\n}\n\nfunction serializeOrganization(entity: Organization, custom?: Record<string, unknown> | null) {\n return {\n id: String(entity.id),\n tenantId: resolveTenantIdFromEntity(entity),\n name: entity.name,\n slug: entity.slug ?? null,\n logoUrl: entity.logoUrl ?? null,\n logoPreserveAspectRatio: !!entity.logoPreserveAspectRatio,\n isActive: !!entity.isActive,\n parentId: entity.parentId ?? null,\n ancestorIds: Array.isArray(entity.ancestorIds) ? [...entity.ancestorIds] : [],\n childIds: Array.isArray(entity.childIds) ? [...entity.childIds] : [],\n descendantIds: Array.isArray(entity.descendantIds) ? [...entity.descendantIds] : [],\n createdAt: entity.createdAt ? entity.createdAt.toISOString() : null,\n updatedAt: entity.updatedAt ? entity.updatedAt.toISOString() : null,\n ...(custom && Object.keys(custom).length ? { custom } : {}),\n }\n}\n\nfunction captureOrganizationSnapshots(\n entity: Organization,\n childParents: ChildParentSnapshot[],\n custom?: Record<string, unknown> | null\n): OrganizationSnapshots {\n const tenantId = resolveTenantIdFromEntity(entity)\n return {\n view: serializeOrganization(entity, custom),\n undo: {\n id: String(entity.id),\n tenantId,\n createdAt: entity.createdAt ? entity.createdAt.toISOString() : null,\n name: entity.name,\n slug: entity.slug ?? null,\n logoUrl: entity.logoUrl ?? null,\n logoPreserveAspectRatio: !!entity.logoPreserveAspectRatio,\n isActive: !!entity.isActive,\n parentId: entity.parentId ?? null,\n childParents: (childParents ?? []).map((entry) => ({\n childId: String(entry.childId),\n parentId: entry.parentId,\n })),\n ...(custom && Object.keys(custom).length ? { custom } : {}),\n },\n }\n}\n\nasync function loadChildParentSnapshots(\n em: EntityManager,\n tenantId: string | null,\n childIds: Iterable<string>\n): Promise<ChildParentSnapshot[]> {\n if (!tenantId) return []\n const ids = Array.from(new Set(Array.from(childIds ?? []).map((id) => String(id)).filter(Boolean)))\n if (!ids.length) return []\n const filter: FilterQuery<Organization> = {\n tenant: tenantId,\n deletedAt: null,\n id: { $in: ids },\n } as unknown as FilterQuery<Organization>\n const children = await em.find(Organization, filter)\n if (!children.length) return []\n const map = new Map(children.map((child) => [String(child.id), child.parentId ? String(child.parentId) : null]))\n return ids\n .filter((id) => map.has(id))\n .map((id) => ({\n childId: id,\n parentId: map.get(id) ?? null,\n }))\n}\n\nasync function restoreChildParents(em: EntityManager, tenantId: string, snapshots: ChildParentSnapshot[]) {\n if (!snapshots?.length) return\n const ids = Array.from(new Set(snapshots.map((entry) => entry.childId).filter(Boolean)))\n if (!ids.length) return\n const filter: FilterQuery<Organization> = {\n tenant: tenantId,\n deletedAt: null,\n id: { $in: ids },\n } as unknown as FilterQuery<Organization>\n const children = await em.find(Organization, filter)\n if (!children.length) return\n const desired = new Map(snapshots.map((entry) => [entry.childId, entry.parentId ?? null]))\n const toPersist: Organization[] = []\n for (const child of children) {\n const id = String(child.id)\n if (!desired.has(id)) continue\n const nextParent = desired.get(id) ?? null\n if (child.parentId !== nextParent) {\n child.parentId = nextParent\n toPersist.push(child)\n }\n }\n if (toPersist.length) await em.persist(toPersist).flush()\n}\n\nfunction normalizeChildIds(ids: readonly string[], exclude: string[]): string[] {\n const excludeSet = new Set(exclude)\n return Array.from(new Set(ids)).filter((id) => !excludeSet.has(id))\n}\n\nasync function ensureParentExists(em: EntityManager, tenantId: string, parentId: string | null): Promise<void> {\n if (!parentId) return\n const parentFilter: FilterQuery<Organization> = { id: parentId, tenant: tenantId, deletedAt: null }\n const parent = await em.findOne(Organization, parentFilter)\n if (!parent) throw new CrudHttpError(400, { error: 'Parent not found' })\n}\n\nasync function ensureChildrenValid(em: EntityManager, tenantId: string, childIds: string[]): Promise<void> {\n if (!childIds.length) return\n const childFilter: FilterQuery<Organization> = { id: { $in: childIds }, tenant: tenantId, deletedAt: null }\n const children = await em.find(Organization, childFilter)\n if (children.length !== childIds.length) throw new CrudHttpError(400, { error: 'Invalid child assignment' })\n}\n\nasync function assignChildren(\n em: EntityManager,\n tenantId: string,\n recordId: string,\n desiredChildIds: Iterable<string>\n): Promise<void> {\n const targetIds = Array.from(new Set(desiredChildIds)).filter((id) => id !== recordId)\n if (!targetIds.length) return\n const filter: FilterQuery<Organization> = { tenant: tenantId, deletedAt: null, id: { $in: targetIds } }\n const children = await em.find(Organization, filter)\n const toPersist: Organization[] = []\n for (const child of children) {\n if (String(child.id) === recordId) continue\n if (child.parentId !== recordId) {\n child.parentId = recordId\n toPersist.push(child)\n }\n }\n if (toPersist.length) await em.persist(toPersist).flush()\n}\n\nasync function clearRemovedChildren(em: EntityManager, tenantId: string, recordId: string, desiredChildIds: Set<string>): Promise<void> {\n const currentFilter: FilterQuery<Organization> = { tenant: tenantId, parentId: recordId, deletedAt: null }\n const current = await em.find(Organization, currentFilter)\n const toPersist = current.filter((child) => !desiredChildIds.has(String(child.id)))\n if (!toPersist.length) return\n for (const child of toPersist) child.parentId = null\n await em.persist(toPersist).flush()\n}\n\nasync function resolveUniqueSlug(em: EntityManager, tenantId: string, baseSlug: string, excludeId?: string): Promise<string> {\n let candidate = baseSlug\n let suffix = 0\n const maxAttempts = 50\n while (suffix < maxAttempts) {\n const filter: FilterQuery<Organization> = {\n tenant: tenantId,\n slug: candidate,\n } as unknown as FilterQuery<Organization>\n const existing = await em.findOne(Organization, filter)\n if (!existing || (excludeId && String(existing.id) === excludeId)) return candidate\n suffix += 1\n candidate = `${baseSlug}-${suffix}`\n }\n return `${baseSlug}-${Date.now()}`\n}\n\nconst createOrganizationCommand: CommandHandler<Record<string, unknown>, Organization> = {\n id: 'directory.organizations.create',\n async execute(rawInput, ctx) {\n const { parsed, custom } = parseWithCustomFields(organizationCreateSchema, rawInput)\n const em = (ctx.container.resolve('em') as EntityManager)\n const tenantId = await enforceTenantSelection(ctx, parsed.tenantId)\n if (!tenantId) throw new CrudHttpError(400, { error: 'Tenant scope required' })\n\n const parentId = parsed.parentId ?? null\n const childIds = normalizeChildIds(parsed.childIds ?? [], parentId ? [parentId] : [])\n if (parentId && childIds.includes(parentId)) throw new CrudHttpError(400, { error: 'Child cannot equal parent' })\n\n const tenantRef = em.getReference(Tenant, tenantId)\n const baseSlug = parsed.slug ? parsed.slug : slugify(parsed.name)\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n\n let organization!: Organization\n await withAtomicFlush(em, [\n async () => {\n await lockOrganizationHierarchyForTenant(em, tenantId)\n if (parentId) {\n await ensureParentExists(em, tenantId, parentId)\n }\n await ensureChildrenValid(em, tenantId, childIds)\n const childParentsBefore = await loadChildParentSnapshots(em, tenantId, childIds)\n const slug = baseSlug ? await resolveUniqueSlug(em, tenantId, baseSlug) : null\n organization = await de.createOrmEntity({\n entity: Organization,\n data: {\n tenant: tenantRef,\n name: parsed.name,\n slug,\n logoUrl: parsed.logoUrl ?? null,\n logoPreserveAspectRatio: parsed.logoPreserveAspectRatio ?? false,\n isActive: parsed.isActive ?? true,\n parentId,\n },\n })\n setInternalTenantId(organization, tenantId)\n const recordId = String(organization.id)\n\n if (childIds.length) {\n await assignChildren(em, tenantId, recordId, childIds)\n }\n const childParentsAfter = await loadChildParentSnapshots(em, tenantId, childIds)\n setUndoMeta(organization, { childParentsBefore, childParentsAfter })\n\n await setCustomFieldsIfAny({\n dataEngine: de,\n entityId: E.directory.organization,\n recordId,\n tenantId,\n organizationId: recordId,\n values: custom,\n })\n\n await rebuildHierarchyForTenant(em, tenantId)\n },\n ], { transaction: true })\n\n const recordId = String(organization.id)\n const identifiers = { id: recordId, organizationId: recordId, tenantId }\n await emitCrudSideEffects({\n dataEngine: de,\n action: 'created',\n entity: organization,\n identifiers,\n events: organizationCrudEvents,\n indexer: organizationCrudIndexer,\n })\n\n return organization\n },\n captureAfter: async (_input, result, ctx) => {\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const tenantId = resolveTenantIdFromEntity(result)\n const custom = await loadCustomFieldSnapshot(em, {\n entityId: E.directory.organization,\n recordId: String(result.id),\n tenantId,\n organizationId: String(result.id),\n })\n return serializeOrganization(result, custom)\n },\n buildLog: async ({ result, ctx }) => {\n const { translate } = await resolveTranslations()\n const meta = getUndoMeta(result)\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const tenantId = resolveTenantIdFromEntity(result)\n const custom = await loadCustomFieldSnapshot(em, {\n entityId: E.directory.organization,\n recordId: String(result.id),\n tenantId,\n organizationId: String(result.id),\n })\n const afterSnapshots = captureOrganizationSnapshots(result, meta.childParentsAfter ?? [], custom)\n return {\n actionLabel: translate('directory.audit.organizations.create', 'Create organization'),\n resourceKind: 'directory.organization',\n resourceId: String(result.id),\n tenantId,\n snapshotAfter: afterSnapshots.view,\n payload: {\n undo: {\n after: afterSnapshots.undo,\n childrenBefore: meta.childParentsBefore ?? [],\n },\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<OrganizationUndoPayload>(logEntry)\n const after = payload?.after\n const childrenBefore = payload?.childrenBefore ?? []\n if (!after) return\n const tenantId = after.tenantId\n if (!tenantId) return\n await assertOrganizationUndoTenantAccess(ctx, tenantId)\n const em = (ctx.container.resolve('em') as EntityManager)\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n let organization: Organization | null = null\n await withAtomicFlush(em, [\n async () => {\n await lockOrganizationHierarchyForTenant(em, tenantId)\n await restoreChildParents(em, tenantId, childrenBefore)\n if (after.custom && Object.keys(after.custom).length) {\n const reset = buildCustomFieldResetMap(undefined, after.custom)\n if (Object.keys(reset).length) {\n const resetValues = reset as Parameters<DataEngine['setCustomFields']>[0]['values']\n await de.setCustomFields({\n entityId: E.directory.organization,\n recordId: after.id,\n tenantId,\n organizationId: after.id,\n values: resetValues,\n notify: false,\n })\n }\n }\n organization = await de.deleteOrmEntity({\n entity: Organization,\n where: buildOrganizationMutationFilter(after.id, tenantId),\n soft: true,\n softDeleteField: 'deletedAt',\n })\n if (organization) {\n organization.isActive = false\n organization.parentId = null\n await em.flush()\n }\n await rebuildHierarchyForTenant(em, tenantId)\n },\n ], { transaction: true })\n await emitCrudUndoSideEffects({\n dataEngine: de,\n action: 'deleted',\n entity: organization,\n identifiers: { id: after.id, tenantId, organizationId: after.id },\n events: organizationCrudEvents,\n indexer: organizationCrudIndexer,\n })\n },\n redo: async ({ logEntry, ctx }) => {\n const after = resolveRedoSnapshot<OrganizationUndoSnapshot>(logEntry)\n if (!after) throw new CrudHttpError(400, { error: '[internal] redo snapshot unavailable for organization create' })\n const tenantId = after.tenantId\n if (!tenantId) throw new CrudHttpError(400, { error: '[internal] redo snapshot missing tenant for organization create' })\n await assertOrganizationUndoTenantAccess(ctx, tenantId)\n const em = (ctx.container.resolve('em') as EntityManager)\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n let organization!: Organization\n await withAtomicFlush(em, [\n async () => {\n await lockOrganizationHierarchyForTenant(em, tenantId)\n const existing = await em.findOne(Organization, buildOrganizationUndoTargetFilter(after.id, tenantId))\n if (existing) {\n existing.deletedAt = null\n existing.name = after.name\n if (after.slug !== undefined) existing.slug = after.slug ?? null\n if (after.logoUrl !== undefined) existing.logoUrl = after.logoUrl ?? null\n if (after.logoPreserveAspectRatio !== undefined) existing.logoPreserveAspectRatio = !!after.logoPreserveAspectRatio\n existing.isActive = after.isActive\n existing.parentId = after.parentId\n await em.flush()\n organization = existing\n } else {\n const snapshotAfter = logEntry.snapshotAfter\n const createdAt = after.createdAt ?? (\n snapshotAfter && typeof snapshotAfter === 'object' && 'createdAt' in snapshotAfter\n ? snapshotAfter.createdAt\n : undefined\n )\n const creationTime = typeof createdAt === 'string' || createdAt instanceof Date\n ? reviveSnapshotDates({ createdAt }, ['createdAt'])\n : {}\n organization = await de.createOrmEntity({\n entity: Organization,\n data: {\n id: after.id,\n ...creationTime,\n name: after.name,\n slug: after.slug ?? null,\n logoUrl: after.logoUrl ?? null,\n logoPreserveAspectRatio: after.logoPreserveAspectRatio ?? false,\n tenant: em.getReference(Tenant, tenantId),\n isActive: after.isActive,\n parentId: after.parentId,\n },\n })\n }\n setInternalTenantId(organization, tenantId)\n\n if (after.custom && Object.keys(after.custom).length) {\n const reset = buildCustomFieldResetMap(after.custom, undefined)\n if (Object.keys(reset).length) {\n const resetValues = reset as Parameters<DataEngine['setCustomFields']>[0]['values']\n await de.setCustomFields({\n entityId: E.directory.organization,\n recordId: after.id,\n tenantId,\n organizationId: after.id,\n values: resetValues,\n notify: false,\n })\n }\n }\n\n await assignChildren(em, tenantId, after.id, after.childParents.map((entry) => entry.childId))\n await rebuildHierarchyForTenant(em, tenantId)\n },\n ], { transaction: true })\n\n const identifiers = { id: after.id, organizationId: after.id, tenantId }\n await emitCrudSideEffects({\n dataEngine: de,\n action: 'created',\n entity: organization,\n identifiers,\n events: organizationCrudEvents,\n indexer: organizationCrudIndexer,\n })\n\n return organization\n },\n}\n\nconst updateOrganizationCommand: CommandHandler<Record<string, unknown>, Organization> = {\n id: 'directory.organizations.update',\n async prepare(rawInput, ctx) {\n const { parsed } = parseWithCustomFields(organizationUpdateSchema, rawInput)\n const em = (ctx.container.resolve('em') as EntityManager)\n const { organization: current, tenantId } = await loadAuthorizedOrganizationTarget(em, parsed.id, ctx)\n const currentChildIds = Array.isArray(current.childIds) ? current.childIds : []\n const requestedChildIds = Array.isArray(parsed.childIds) ? parsed.childIds : []\n const combinedChildIds = new Set<string>([...currentChildIds.map(String), ...requestedChildIds.map(String)])\n const childParentsBefore = tenantId\n ? await loadChildParentSnapshots(em, tenantId, combinedChildIds)\n : []\n const custom = await loadCustomFieldSnapshot(em, {\n entityId: E.directory.organization,\n recordId: String(current.id),\n tenantId,\n organizationId: String(current.id),\n })\n return { before: captureOrganizationSnapshots(current, childParentsBefore, custom) }\n },\n async execute(rawInput, ctx) {\n const { parsed, custom } = parseWithCustomFields(organizationUpdateSchema, rawInput)\n const em = (ctx.container.resolve('em') as EntityManager)\n const { tenantId } = await loadAuthorizedOrganizationTarget(em, parsed.id, ctx)\n\n const parentProvided = parsed.parentId !== undefined\n const childrenProvided = parsed.childIds !== undefined\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n\n let resolvedOrganization!: Organization\n await withAtomicFlush(em, [\n async () => {\n await lockOrganizationHierarchyForTenant(em, tenantId)\n const existing = await em.findOne(\n Organization,\n buildOrganizationMutationFilter(parsed.id, tenantId),\n { refresh: true },\n )\n if (!existing) throw new CrudHttpError(404, { error: 'Not found' })\n\n const parentId = parentProvided ? parsed.parentId ?? null : existing.parentId ?? null\n if (parentProvided && parentId) {\n if (parentId === parsed.id) throw new CrudHttpError(400, { error: 'Organization cannot be its own parent' })\n if (Array.isArray(existing.descendantIds) && existing.descendantIds.includes(parentId)) {\n throw new CrudHttpError(400, { error: 'Cannot assign descendant as parent' })\n }\n await ensureParentExists(em, tenantId, parentId)\n }\n\n const normalizedChildIds = normalizeChildIds(parsed.childIds ?? [], [parsed.id, parentProvided ? parentId ?? '' : ''])\n if (normalizedChildIds.some((id) => id === parentId)) throw new CrudHttpError(400, { error: 'Child cannot equal parent' })\n if (Array.isArray(existing.ancestorIds) && normalizedChildIds.some((id) => existing.ancestorIds.includes(id))) {\n throw new CrudHttpError(400, { error: 'Cannot assign ancestor as child' })\n }\n\n if (normalizedChildIds.length) {\n await ensureChildrenValid(em, tenantId, normalizedChildIds)\n const childFilter = {\n tenant: tenantId,\n deletedAt: null,\n id: { $in: normalizedChildIds },\n } as unknown as FilterQuery<Organization>\n const children = await em.find(Organization, childFilter)\n for (const child of children) {\n if (Array.isArray(child.descendantIds) && child.descendantIds.includes(parsed.id)) {\n throw new CrudHttpError(400, { error: 'Cannot assign descendant cycle' })\n }\n }\n }\n\n const combinedChildIds = new Set<string>([\n ...normalizedChildIds.map(String),\n ...(Array.isArray(existing.childIds) ? existing.childIds.map(String) : []),\n ])\n const childParentsBefore = await loadChildParentSnapshots(em, tenantId, combinedChildIds)\n\n let resolvedSlug: string | null | undefined\n if (parsed.slug !== undefined) {\n resolvedSlug = parsed.slug ? await resolveUniqueSlug(em, tenantId, parsed.slug, parsed.id) : parsed.slug\n }\n\n const organization = await de.updateOrmEntity({\n entity: Organization,\n where: buildOrganizationMutationFilter(parsed.id, tenantId),\n apply: (entity) => {\n if (parsed.name !== undefined) entity.name = parsed.name\n if (resolvedSlug !== undefined) entity.slug = resolvedSlug\n if (parsed.logoUrl !== undefined) entity.logoUrl = parsed.logoUrl ?? null\n if (parsed.logoPreserveAspectRatio !== undefined) entity.logoPreserveAspectRatio = parsed.logoPreserveAspectRatio\n if (parsed.isActive !== undefined) entity.isActive = parsed.isActive\n if (parentProvided) entity.parentId = parentId\n },\n })\n if (!organization) throw new CrudHttpError(404, { error: 'Not found' })\n setInternalTenantId(organization, tenantId)\n\n const recordId = String(organization.id)\n const desiredChildIds = new Set(normalizedChildIds.filter((id) => id !== recordId))\n if (childrenProvided) {\n await clearRemovedChildren(em, tenantId, recordId, desiredChildIds)\n await assignChildren(em, tenantId, recordId, desiredChildIds)\n }\n const childParentsAfter = await loadChildParentSnapshots(em, tenantId, combinedChildIds)\n setUndoMeta(organization, { childParentsBefore, childParentsAfter })\n\n await setCustomFieldsIfAny({\n dataEngine: de,\n entityId: E.directory.organization,\n recordId,\n tenantId,\n organizationId: recordId,\n values: custom,\n })\n\n await rebuildHierarchyForTenant(em, tenantId)\n resolvedOrganization = organization\n },\n ], { transaction: true })\n\n const recordId = String(resolvedOrganization.id)\n const identifiers = { id: recordId, organizationId: recordId, tenantId }\n await emitCrudSideEffects({\n dataEngine: de,\n action: 'updated',\n entity: resolvedOrganization,\n identifiers,\n events: organizationCrudEvents,\n indexer: organizationCrudIndexer,\n })\n\n return resolvedOrganization\n },\n captureAfter: async (_input, result, ctx) => {\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const tenantId = resolveTenantIdFromEntity(result)\n const custom = await loadCustomFieldSnapshot(em, {\n entityId: E.directory.organization,\n recordId: String(result.id),\n tenantId,\n organizationId: String(result.id),\n })\n return serializeOrganization(result, custom)\n },\n buildLog: async ({ snapshots, result, ctx }) => {\n const { translate } = await resolveTranslations()\n const meta = getUndoMeta(result)\n const beforeSnapshots = snapshots.before as OrganizationSnapshots | undefined\n const beforeRecord = beforeSnapshots?.view ?? null\n const em = (ctx.container.resolve('em') as EntityManager).fork()\n const tenantId = resolveTenantIdFromEntity(result)\n const custom = await loadCustomFieldSnapshot(em, {\n entityId: E.directory.organization,\n recordId: String(result.id),\n tenantId,\n organizationId: String(result.id),\n })\n const after = serializeOrganization(result, custom)\n const changes = buildChanges(beforeRecord, after as Record<string, unknown>, ['name', 'slug', 'logoUrl', 'logoPreserveAspectRatio', 'isActive', 'parentId'])\n const customDiff = diffCustomFieldChanges(beforeRecord?.custom, custom)\n for (const [key, diff] of Object.entries(customDiff)) {\n changes[`cf_${key}`] = diff\n }\n return {\n actionLabel: translate('directory.audit.organizations.update', 'Update organization'),\n resourceKind: 'directory.organization',\n resourceId: String(result.id),\n changes,\n tenantId: after.tenantId,\n payload: {\n undo: {\n before: beforeSnapshots?.undo ?? null,\n after: captureOrganizationSnapshots(result, meta.childParentsAfter ?? [], custom).undo,\n },\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<OrganizationUndoPayload>(logEntry)\n const before = payload?.before\n const after = payload?.after\n if (!before) return\n const tenantId = before.tenantId\n if (!tenantId) return\n await assertOrganizationUndoTenantAccess(ctx, tenantId)\n const em = (ctx.container.resolve('em') as EntityManager)\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n let updated: Organization | null = null\n await withAtomicFlush(em, [\n async () => {\n await lockOrganizationHierarchyForTenant(em, tenantId)\n updated = await de.updateOrmEntity({\n entity: Organization,\n where: buildOrganizationUndoTargetFilter(before.id, tenantId),\n apply: (entity) => {\n entity.name = before.name\n if (before.slug !== undefined) entity.slug = before.slug\n if (before.logoUrl !== undefined) entity.logoUrl = before.logoUrl ?? null\n if (before.logoPreserveAspectRatio !== undefined) entity.logoPreserveAspectRatio = !!before.logoPreserveAspectRatio\n entity.isActive = before.isActive\n entity.parentId = before.parentId\n },\n })\n if (!updated) throw new CrudHttpError(404, { error: 'Not found' })\n setInternalTenantId(updated, tenantId)\n const reset = buildCustomFieldResetMap(before.custom, after?.custom)\n if (Object.keys(reset).length) {\n const resetValues = reset as Parameters<DataEngine['setCustomFields']>[0]['values']\n await de.setCustomFields({\n entityId: E.directory.organization,\n recordId: before.id,\n tenantId,\n organizationId: before.id,\n values: resetValues,\n notify: false,\n })\n }\n const childSnapshots = before.childParents\n await restoreChildParents(em, tenantId, childSnapshots)\n await rebuildHierarchyForTenant(em, tenantId)\n },\n ], { transaction: true })\n await emitCrudUndoSideEffects({\n dataEngine: de,\n action: 'updated',\n entity: updated,\n identifiers: {\n id: before.id,\n tenantId,\n organizationId: before.id,\n },\n events: organizationCrudEvents,\n indexer: organizationCrudIndexer,\n })\n },\n}\n\nconst deleteOrganizationCommand: CommandHandler<{ body: any; query: Record<string, string> }, Organization> = {\n id: 'directory.organizations.delete',\n async prepare(input, ctx) {\n const id = requireId(input, 'Organization id required')\n const em = (ctx.container.resolve('em') as EntityManager)\n const { organization: existing, tenantId } = await loadAuthorizedOrganizationTarget(em, id, ctx)\n const childParentsBefore = tenantId\n ? await loadChildParentSnapshots(em, tenantId, Array.isArray(existing.childIds) ? existing.childIds : [])\n : []\n const custom = await loadCustomFieldSnapshot(em, {\n entityId: E.directory.organization,\n recordId: String(existing.id),\n tenantId,\n organizationId: String(existing.id),\n })\n return { before: captureOrganizationSnapshots(existing, childParentsBefore, custom) }\n },\n async execute(input, ctx) {\n const id = requireId(input, 'Organization id required')\n const em = (ctx.container.resolve('em') as EntityManager)\n const { organization: existing, tenantId } = await loadAuthorizedOrganizationTarget(em, id, ctx)\n\n const parentId = existing.parentId ?? null\n const childSnapshotsBefore = await loadChildParentSnapshots(\n em,\n tenantId,\n Array.isArray(existing.childIds) ? existing.childIds : [],\n )\n\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n\n let resolvedDeleted!: Organization\n await withAtomicFlush(em, [\n async () => {\n await lockOrganizationHierarchyForTenant(em, tenantId)\n const deleted = await de.deleteOrmEntity({\n entity: Organization,\n where: buildOrganizationMutationFilter(id, tenantId),\n soft: true,\n softDeleteField: 'deletedAt',\n })\n if (!deleted) throw new CrudHttpError(404, { error: 'Not found' })\n setInternalTenantId(deleted, tenantId)\n deleted.isActive = false\n deleted.parentId = null\n resolvedDeleted = deleted\n },\n async () => {\n const deleted = resolvedDeleted\n const childrenFilter: FilterQuery<Organization> = { tenant: tenantId, parentId: id, deletedAt: null }\n const children = await em.find(Organization, childrenFilter)\n const toPersist: Organization[] = []\n for (const child of children) {\n child.parentId = parentId\n toPersist.push(child)\n }\n toPersist.push(deleted)\n if (toPersist.length) em.persist(toPersist)\n setUndoMeta(deleted, { childParentsBefore: childSnapshotsBefore })\n },\n async () => {\n await rebuildHierarchyForTenant(em, tenantId)\n },\n ], { transaction: true })\n\n const identifiers = { id, organizationId: id, tenantId }\n await emitCrudSideEffects({\n dataEngine: de,\n action: 'deleted',\n entity: resolvedDeleted,\n identifiers,\n events: organizationCrudEvents,\n indexer: organizationCrudIndexer,\n })\n\n return resolvedDeleted\n },\n buildLog: async ({ snapshots, input }) => {\n const { translate } = await resolveTranslations()\n const beforeSnapshots = snapshots.before as OrganizationSnapshots | undefined\n const beforeSnapshot = beforeSnapshots?.view ?? null\n const beforeUndo = beforeSnapshots?.undo ?? null\n const id = String(input?.body?.id ?? input?.query?.id ?? '')\n const fallbackId = beforeSnapshot?.id ?? null\n const fallbackTenant = beforeSnapshot?.tenantId ?? null\n return {\n actionLabel: translate('directory.audit.organizations.delete', 'Delete organization'),\n resourceKind: 'directory.organization',\n resourceId: id || fallbackId || null,\n snapshotBefore: beforeSnapshot ?? null,\n tenantId: beforeUndo?.tenantId ?? fallbackTenant,\n payload: {\n undo: {\n before: beforeUndo,\n },\n },\n }\n },\n undo: async ({ logEntry, ctx }) => {\n const payload = extractUndoPayload<OrganizationUndoPayload>(logEntry)\n const before = payload?.before\n if (!before) return\n const tenantId = before.tenantId\n if (!tenantId) return\n await assertOrganizationUndoTenantAccess(ctx, tenantId)\n const em = (ctx.container.resolve('em') as EntityManager)\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n let organization: Organization | null = null\n await withAtomicFlush(em, [\n async () => {\n await lockOrganizationHierarchyForTenant(em, tenantId)\n organization = await em.findOne(\n Organization,\n buildOrganizationUndoTargetFilter(before.id, tenantId),\n )\n if (organization) {\n organization.deletedAt = null\n organization.isActive = before.isActive\n organization.name = before.name\n if (before.slug !== undefined) organization.slug = before.slug\n organization.parentId = before.parentId\n await em.flush()\n if (tenantId) setInternalTenantId(organization, tenantId)\n } else {\n organization = await de.createOrmEntity({\n entity: Organization,\n data: {\n id: before.id,\n name: before.name,\n slug: before.slug ?? null,\n tenant: tenantId ? em.getReference(Tenant, tenantId) : undefined,\n isActive: before.isActive,\n parentId: before.parentId,\n },\n })\n if (tenantId) setInternalTenantId(organization, tenantId)\n }\n if (tenantId) {\n const customValues = buildCustomFieldResetMap(before.custom, undefined)\n if (Object.keys(customValues).length) {\n const resetValues = customValues as Parameters<DataEngine['setCustomFields']>[0]['values']\n await de.setCustomFields({\n entityId: E.directory.organization,\n recordId: before.id,\n tenantId,\n organizationId: before.id,\n values: resetValues,\n notify: false,\n })\n }\n }\n await restoreChildParents(em, tenantId, before.childParents)\n await rebuildHierarchyForTenant(em, tenantId)\n },\n ], { transaction: true })\n await emitCrudUndoSideEffects({\n dataEngine: de,\n action: 'updated',\n entity: organization,\n identifiers: {\n id: before.id,\n tenantId,\n organizationId: before.id,\n },\n events: organizationCrudEvents,\n indexer: organizationCrudIndexer,\n })\n },\n}\n\ntype OrganizationUndoPayload = {\n before?: OrganizationUndoSnapshot | null\n after?: OrganizationUndoSnapshot | null\n childrenBefore?: ChildParentSnapshot[] | null\n}\n\ntype OrganizationUndoMeta = {\n childParentsBefore?: ChildParentSnapshot[]\n childParentsAfter?: ChildParentSnapshot[]\n}\n\nconst UNDO_META_KEY: unique symbol = Symbol('directory.organization.undoMeta')\n\nfunction getUndoMeta(entity: Organization): OrganizationUndoMeta {\n return (Reflect.get(entity, UNDO_META_KEY) as OrganizationUndoMeta | undefined) ?? {}\n}\n\nfunction setUndoMeta(entity: Organization, meta: Partial<OrganizationUndoMeta>) {\n const current = getUndoMeta(entity)\n Reflect.set(entity, UNDO_META_KEY, { ...current, ...meta })\n}\n\nregisterCommand(createOrganizationCommand)\nregisterCommand(updateOrganizationCommand)\nregisterCommand(deleteOrganizationCommand)\n\nfunction setInternalTenantId(entity: Organization, tenantId: string) {\n Reflect.set(entity, '__tenantId', tenantId)\n}\n\nfunction tenantIdFromContext(ctx: CrudEmitContext<Organization>): string | null {\n return resolveTenantIdFromEntity(ctx.entity) ?? ctx.identifiers.tenantId ?? null\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["recordId"]
|
|
7
7
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@open-mercato/core",
|
|
3
|
-
"version": "0.10.1-develop.
|
|
3
|
+
"version": "0.10.1-develop.7717.1.2befe9c634",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -265,16 +265,16 @@
|
|
|
265
265
|
"zod": "^4.4.3"
|
|
266
266
|
},
|
|
267
267
|
"peerDependencies": {
|
|
268
|
-
"@open-mercato/ai-assistant": "0.10.1-develop.
|
|
269
|
-
"@open-mercato/shared": "0.10.1-develop.
|
|
270
|
-
"@open-mercato/ui": "0.10.1-develop.
|
|
268
|
+
"@open-mercato/ai-assistant": "0.10.1-develop.7717.1.2befe9c634",
|
|
269
|
+
"@open-mercato/shared": "0.10.1-develop.7717.1.2befe9c634",
|
|
270
|
+
"@open-mercato/ui": "0.10.1-develop.7717.1.2befe9c634",
|
|
271
271
|
"react": "^19.0.0",
|
|
272
272
|
"react-dom": "^19.0.0"
|
|
273
273
|
},
|
|
274
274
|
"devDependencies": {
|
|
275
|
-
"@open-mercato/ai-assistant": "0.10.1-develop.
|
|
276
|
-
"@open-mercato/shared": "0.10.1-develop.
|
|
277
|
-
"@open-mercato/ui": "0.10.1-develop.
|
|
275
|
+
"@open-mercato/ai-assistant": "0.10.1-develop.7717.1.2befe9c634",
|
|
276
|
+
"@open-mercato/shared": "0.10.1-develop.7717.1.2befe9c634",
|
|
277
|
+
"@open-mercato/ui": "0.10.1-develop.7717.1.2befe9c634",
|
|
278
278
|
"@testing-library/dom": "^10.4.1",
|
|
279
279
|
"@testing-library/jest-dom": "^7.0.1",
|
|
280
280
|
"@testing-library/react": "^16.3.3",
|
|
@@ -21,7 +21,7 @@ import {
|
|
|
21
21
|
buildCustomFieldResetMap,
|
|
22
22
|
diffCustomFieldChanges,
|
|
23
23
|
} from '@open-mercato/shared/lib/commands/customFieldSnapshots'
|
|
24
|
-
import { extractUndoPayload } from '@open-mercato/shared/lib/commands/undo'
|
|
24
|
+
import { extractUndoPayload, reviveSnapshotDates } from '@open-mercato/shared/lib/commands/undo'
|
|
25
25
|
import { resolveRedoSnapshot } from '@open-mercato/shared/lib/commands/redo'
|
|
26
26
|
import { withAtomicFlush } from '@open-mercato/shared/lib/commands/flush'
|
|
27
27
|
import {
|
|
@@ -89,6 +89,7 @@ type ChildParentSnapshot = {
|
|
|
89
89
|
type OrganizationUndoSnapshot = {
|
|
90
90
|
id: string
|
|
91
91
|
tenantId: string | null
|
|
92
|
+
createdAt?: string | null
|
|
92
93
|
name: string
|
|
93
94
|
slug?: string | null
|
|
94
95
|
logoUrl?: string | null
|
|
@@ -227,6 +228,7 @@ function captureOrganizationSnapshots(
|
|
|
227
228
|
undo: {
|
|
228
229
|
id: String(entity.id),
|
|
229
230
|
tenantId,
|
|
231
|
+
createdAt: entity.createdAt ? entity.createdAt.toISOString() : null,
|
|
230
232
|
name: entity.name,
|
|
231
233
|
slug: entity.slug ?? null,
|
|
232
234
|
logoUrl: entity.logoUrl ?? null,
|
|
@@ -348,7 +350,6 @@ async function resolveUniqueSlug(em: EntityManager, tenantId: string, baseSlug:
|
|
|
348
350
|
const filter: FilterQuery<Organization> = {
|
|
349
351
|
tenant: tenantId,
|
|
350
352
|
slug: candidate,
|
|
351
|
-
deletedAt: null,
|
|
352
353
|
} as unknown as FilterQuery<Organization>
|
|
353
354
|
const existing = await em.findOne(Organization, filter)
|
|
354
355
|
if (!existing || (excludeId && String(existing.id) === excludeId)) return candidate
|
|
@@ -478,6 +479,7 @@ const createOrganizationCommand: CommandHandler<Record<string, unknown>, Organiz
|
|
|
478
479
|
await assertOrganizationUndoTenantAccess(ctx, tenantId)
|
|
479
480
|
const em = (ctx.container.resolve('em') as EntityManager)
|
|
480
481
|
const de = (ctx.container.resolve('dataEngine') as DataEngine)
|
|
482
|
+
let organization: Organization | null = null
|
|
481
483
|
await withAtomicFlush(em, [
|
|
482
484
|
async () => {
|
|
483
485
|
await lockOrganizationHierarchyForTenant(em, tenantId)
|
|
@@ -496,14 +498,28 @@ const createOrganizationCommand: CommandHandler<Record<string, unknown>, Organiz
|
|
|
496
498
|
})
|
|
497
499
|
}
|
|
498
500
|
}
|
|
499
|
-
await de.deleteOrmEntity({
|
|
501
|
+
organization = await de.deleteOrmEntity({
|
|
500
502
|
entity: Organization,
|
|
501
503
|
where: buildOrganizationMutationFilter(after.id, tenantId),
|
|
502
|
-
soft:
|
|
504
|
+
soft: true,
|
|
505
|
+
softDeleteField: 'deletedAt',
|
|
503
506
|
})
|
|
507
|
+
if (organization) {
|
|
508
|
+
organization.isActive = false
|
|
509
|
+
organization.parentId = null
|
|
510
|
+
await em.flush()
|
|
511
|
+
}
|
|
504
512
|
await rebuildHierarchyForTenant(em, tenantId)
|
|
505
513
|
},
|
|
506
514
|
], { transaction: true })
|
|
515
|
+
await emitCrudUndoSideEffects({
|
|
516
|
+
dataEngine: de,
|
|
517
|
+
action: 'deleted',
|
|
518
|
+
entity: organization,
|
|
519
|
+
identifiers: { id: after.id, tenantId, organizationId: after.id },
|
|
520
|
+
events: organizationCrudEvents,
|
|
521
|
+
indexer: organizationCrudIndexer,
|
|
522
|
+
})
|
|
507
523
|
},
|
|
508
524
|
redo: async ({ logEntry, ctx }) => {
|
|
509
525
|
const after = resolveRedoSnapshot<OrganizationUndoSnapshot>(logEntry)
|
|
@@ -529,10 +545,20 @@ const createOrganizationCommand: CommandHandler<Record<string, unknown>, Organiz
|
|
|
529
545
|
await em.flush()
|
|
530
546
|
organization = existing
|
|
531
547
|
} else {
|
|
548
|
+
const snapshotAfter = logEntry.snapshotAfter
|
|
549
|
+
const createdAt = after.createdAt ?? (
|
|
550
|
+
snapshotAfter && typeof snapshotAfter === 'object' && 'createdAt' in snapshotAfter
|
|
551
|
+
? snapshotAfter.createdAt
|
|
552
|
+
: undefined
|
|
553
|
+
)
|
|
554
|
+
const creationTime = typeof createdAt === 'string' || createdAt instanceof Date
|
|
555
|
+
? reviveSnapshotDates({ createdAt }, ['createdAt'])
|
|
556
|
+
: {}
|
|
532
557
|
organization = await de.createOrmEntity({
|
|
533
558
|
entity: Organization,
|
|
534
559
|
data: {
|
|
535
560
|
id: after.id,
|
|
561
|
+
...creationTime,
|
|
536
562
|
name: after.name,
|
|
537
563
|
slug: after.slug ?? null,
|
|
538
564
|
logoUrl: after.logoUrl ?? null,
|