@open-mercato/core 0.6.6-develop.5505.1.f08e81a6fe → 0.6.6-develop.5523.1.e223ca1915
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.
- package/.turbo/turbo-build.log +1 -1
- package/dist/bootstrap.js +46 -6
- package/dist/bootstrap.js.map +2 -2
- package/dist/generated/entities/organization/index.js +2 -0
- package/dist/generated/entities/organization/index.js.map +2 -2
- package/dist/generated/entity-fields-registry.js +1 -0
- package/dist/generated/entity-fields-registry.js.map +2 -2
- package/dist/modules/auth/api/admin/nav.js +9 -0
- package/dist/modules/auth/api/admin/nav.js.map +2 -2
- package/dist/modules/auth/lib/backendChrome.js +35 -2
- package/dist/modules/auth/lib/backendChrome.js.map +2 -2
- package/dist/modules/directory/api/organization-branding/route.js +214 -0
- package/dist/modules/directory/api/organization-branding/route.js.map +7 -0
- package/dist/modules/directory/api/organizations/route.js +7 -0
- package/dist/modules/directory/api/organizations/route.js.map +3 -3
- package/dist/modules/directory/backend/directory/branding/page.js +214 -0
- package/dist/modules/directory/backend/directory/branding/page.js.map +7 -0
- package/dist/modules/directory/backend/directory/branding/page.meta.js +26 -0
- package/dist/modules/directory/backend/directory/branding/page.meta.js.map +7 -0
- package/dist/modules/directory/commands/organizations.js +8 -1
- package/dist/modules/directory/commands/organizations.js.map +2 -2
- package/dist/modules/directory/data/entities.js +3 -0
- package/dist/modules/directory/data/entities.js.map +2 -2
- package/dist/modules/directory/data/validators.js +9 -0
- package/dist/modules/directory/data/validators.js.map +2 -2
- package/dist/modules/directory/migrations/Migration20260607222259_directory.js +13 -0
- package/dist/modules/directory/migrations/Migration20260607222259_directory.js.map +7 -0
- package/generated/entities/organization/index.ts +1 -0
- package/generated/entity-fields-registry.ts +1 -0
- package/package.json +7 -7
- package/src/bootstrap.ts +65 -7
- package/src/modules/auth/api/admin/nav.ts +9 -0
- package/src/modules/auth/lib/backendChrome.tsx +37 -1
- package/src/modules/directory/api/organization-branding/route.ts +238 -0
- package/src/modules/directory/api/organizations/route.ts +7 -0
- package/src/modules/directory/backend/directory/branding/page.meta.ts +24 -0
- package/src/modules/directory/backend/directory/branding/page.tsx +248 -0
- package/src/modules/directory/commands/organizations.ts +9 -1
- package/src/modules/directory/data/entities.ts +3 -0
- package/src/modules/directory/data/validators.ts +12 -0
- package/src/modules/directory/i18n/de.json +21 -0
- package/src/modules/directory/i18n/en.json +21 -0
- package/src/modules/directory/i18n/es.json +21 -0
- package/src/modules/directory/i18n/pl.json +21 -0
- package/src/modules/directory/migrations/.snapshot-open-mercato.json +40 -0
- package/src/modules/directory/migrations/Migration20260607222259_directory.ts +13 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/modules/directory/commands/organizations.ts"],
|
|
4
|
-
"sourcesContent": ["import type { CommandHandler } 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 { rebuildHierarchyForTenant } from '@open-mercato/core/modules/directory/lib/hierarchy'\nimport { enforceTenantSelection } 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 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\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\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 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 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 ?? null)\n if (!tenantId) throw new CrudHttpError(400, { error: 'Tenant scope required' })\n\n const parentId = parsed.parentId ?? null\n if (parentId) {\n await ensureParentExists(em, tenantId, parentId)\n }\n\n const childIds = normalizeChildIds(parsed.childIds ?? [], parentId ? [parentId] : [])\n if (parentId && childIds.includes(parentId)) throw new CrudHttpError(400, { error: 'Child cannot equal parent' })\n await ensureChildrenValid(em, tenantId, childIds)\n const childParentsBefore = await loadChildParentSnapshots(em, tenantId, childIds)\n\n const tenantRef = em.getReference(Tenant, tenantId)\n const baseSlug = parsed.slug ? parsed.slug : slugify(parsed.name)\n const slug = baseSlug ? await resolveUniqueSlug(em, tenantId, baseSlug) : null\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n\n let organization!: Organization\n await withAtomicFlush(em, [\n async () => {\n organization = await de.createOrmEntity({\n entity: Organization,\n data: {\n tenant: tenantRef,\n name: parsed.name,\n slug,\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: ctx.auth?.tenantId ?? resolveTenantIdFromEntity(result),\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 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 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: { id: after.id, deletedAt: null } as FilterQuery<Organization>,\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 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 const existing = await em.findOne(Organization, { id: after.id })\n if (existing) {\n existing.deletedAt = null\n existing.name = after.name\n if (after.slug !== undefined) existing.slug = after.slug ?? null\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 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 current = await em.findOne(Organization, { id: parsed.id, deletedAt: null })\n if (!current) throw new CrudHttpError(404, { error: 'Not found' })\n const tenantId = resolveTenantIdFromEntity(current)\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 existing = await em.findOne(Organization, { id: parsed.id, deletedAt: null })\n if (!existing) throw new CrudHttpError(404, { error: 'Not found' })\n\n const tenantId = await enforceTenantSelection(ctx, parsed.tenantId ?? resolveTenantIdFromEntity(existing))\n if (!tenantId) throw new CrudHttpError(400, { error: 'Tenant scope required' })\n\n const parentId = parsed.parentId ?? null\n if (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, 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 const de = (ctx.container.resolve('dataEngine') as DataEngine)\n\n let resolvedOrganization!: Organization\n await withAtomicFlush(em, [\n async () => {\n const organization = await de.updateOrmEntity({\n entity: Organization,\n where: { id: parsed.id, deletedAt: null } as FilterQuery<Organization>,\n apply: (entity) => {\n if (parsed.name !== undefined) entity.name = parsed.name\n if (resolvedSlug !== undefined) entity.slug = resolvedSlug\n if (parsed.isActive !== undefined) entity.isActive = parsed.isActive\n 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 await clearRemovedChildren(em, tenantId, recordId, desiredChildIds)\n await assignChildren(em, tenantId, recordId, desiredChildIds)\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', '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: ctx.auth?.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 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 updated = await de.updateOrmEntity({\n entity: Organization,\n where: { id: before.id } as FilterQuery<Organization>,\n apply: (entity) => {\n entity.name = before.name\n if (before.slug !== undefined) entity.slug = before.slug\n entity.isActive = before.isActive\n entity.parentId = before.parentId\n },\n })\n if (updated && tenantId) {\n setInternalTenantId(updated, tenantId)\n }\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 existing = await em.findOne(Organization, { id, deletedAt: null })\n if (!existing) return {}\n const tenantId = resolveTenantIdFromEntity(existing)\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 existing = await em.findOne(Organization, { id, deletedAt: null })\n if (!existing) throw new CrudHttpError(404, { error: 'Not found' })\n\n const tenantId = await enforceTenantSelection(ctx, resolveTenantIdFromEntity(existing))\n if (!tenantId) throw new CrudHttpError(400, { error: 'Tenant scope required' })\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 const deleted = await de.deleteOrmEntity({\n entity: Organization,\n where: { id, deletedAt: null } as FilterQuery<Organization>,\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, ctx }) => {\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: ctx.auth?.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 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 organization = await em.findOne(Organization, { id: before.id })\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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",
|
|
4
|
+
"sourcesContent": ["import type { CommandHandler } 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 { rebuildHierarchyForTenant } from '@open-mercato/core/modules/directory/lib/hierarchy'\nimport { enforceTenantSelection } 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 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\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\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 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 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 ?? null)\n if (!tenantId) throw new CrudHttpError(400, { error: 'Tenant scope required' })\n\n const parentId = parsed.parentId ?? null\n if (parentId) {\n await ensureParentExists(em, tenantId, parentId)\n }\n\n const childIds = normalizeChildIds(parsed.childIds ?? [], parentId ? [parentId] : [])\n if (parentId && childIds.includes(parentId)) throw new CrudHttpError(400, { error: 'Child cannot equal parent' })\n await ensureChildrenValid(em, tenantId, childIds)\n const childParentsBefore = await loadChildParentSnapshots(em, tenantId, childIds)\n\n const tenantRef = em.getReference(Tenant, tenantId)\n const baseSlug = parsed.slug ? parsed.slug : slugify(parsed.name)\n const slug = baseSlug ? await resolveUniqueSlug(em, tenantId, baseSlug) : null\n const de = (ctx.container.resolve('dataEngine') as DataEngine)\n\n let organization!: Organization\n await withAtomicFlush(em, [\n async () => {\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 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: ctx.auth?.tenantId ?? resolveTenantIdFromEntity(result),\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 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 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: { id: after.id, deletedAt: null } as FilterQuery<Organization>,\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 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 const existing = await em.findOne(Organization, { id: after.id })\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 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 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 current = await em.findOne(Organization, { id: parsed.id, deletedAt: null })\n if (!current) throw new CrudHttpError(404, { error: 'Not found' })\n const tenantId = resolveTenantIdFromEntity(current)\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 existing = await em.findOne(Organization, { id: parsed.id, deletedAt: null })\n if (!existing) throw new CrudHttpError(404, { error: 'Not found' })\n\n const tenantId = await enforceTenantSelection(ctx, parsed.tenantId ?? resolveTenantIdFromEntity(existing))\n if (!tenantId) throw new CrudHttpError(400, { error: 'Tenant scope required' })\n\n const parentId = parsed.parentId ?? null\n if (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, 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 const de = (ctx.container.resolve('dataEngine') as DataEngine)\n\n let resolvedOrganization!: Organization\n await withAtomicFlush(em, [\n async () => {\n const organization = await de.updateOrmEntity({\n entity: Organization,\n where: { id: parsed.id, deletedAt: null } as FilterQuery<Organization>,\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.isActive !== undefined) entity.isActive = parsed.isActive\n 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 await clearRemovedChildren(em, tenantId, recordId, desiredChildIds)\n await assignChildren(em, tenantId, recordId, desiredChildIds)\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', '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: ctx.auth?.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 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 updated = await de.updateOrmEntity({\n entity: Organization,\n where: { id: before.id } as FilterQuery<Organization>,\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 entity.isActive = before.isActive\n entity.parentId = before.parentId\n },\n })\n if (updated && tenantId) {\n setInternalTenantId(updated, tenantId)\n }\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 existing = await em.findOne(Organization, { id, deletedAt: null })\n if (!existing) return {}\n const tenantId = resolveTenantIdFromEntity(existing)\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 existing = await em.findOne(Organization, { id, deletedAt: null })\n if (!existing) throw new CrudHttpError(404, { error: 'Not found' })\n\n const tenantId = await enforceTenantSelection(ctx, resolveTenantIdFromEntity(existing))\n if (!tenantId) throw new CrudHttpError(400, { error: 'Tenant scope required' })\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 const deleted = await de.deleteOrmEntity({\n entity: Organization,\n where: { id, deletedAt: null } as FilterQuery<Organization>,\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, ctx }) => {\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: ctx.auth?.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 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 organization = await em.findOne(Organization, { id: before.id })\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
|
}
|
|
@@ -68,6 +68,9 @@ __decorateClass([
|
|
|
68
68
|
__decorateClass([
|
|
69
69
|
Property({ type: "text", nullable: true })
|
|
70
70
|
], Organization.prototype, "slug", 2);
|
|
71
|
+
__decorateClass([
|
|
72
|
+
Property({ name: "logo_url", type: "text", nullable: true })
|
|
73
|
+
], Organization.prototype, "logoUrl", 2);
|
|
71
74
|
__decorateClass([
|
|
72
75
|
Property({ name: "is_active", type: "boolean", default: true })
|
|
73
76
|
], Organization.prototype, "isActive", 2);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/modules/directory/data/entities.ts"],
|
|
4
|
-
"sourcesContent": ["import { Collection } from '@mikro-orm/core'\nimport { Entity, ManyToOne, OneToMany, PrimaryKey, Property, Unique } from '@mikro-orm/decorators/legacy'\n\n@Entity({ tableName: 'tenants' })\nexport class Tenant {\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @Property({ type: 'text' })\n name!: string\n\n @Property({ name: 'is_active', type: 'boolean', default: true })\n isActive: boolean = true\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'updated_at', type: Date, onUpdate: () => new Date() })\n updatedAt: Date = new Date()\n\n @Property({ name: 'deleted_at', type: Date, nullable: true })\n deletedAt?: Date | null\n\n @OneToMany(() => Organization, (o) => o.tenant)\n organizations = new Collection<Organization>(this)\n}\n\n@Entity({ tableName: 'organizations' })\n@Unique({ name: 'organizations_tenant_slug_uniq', properties: ['tenant', 'slug'] })\nexport class Organization {\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @ManyToOne(() => Tenant)\n tenant!: Tenant\n\n @Property({ type: 'text' })\n name!: string\n\n @Property({ type: 'text', nullable: true })\n slug?: string | null\n\n @Property({ name: 'is_active', type: 'boolean', default: true })\n isActive: boolean = true\n\n @Property({ name: 'parent_id', type: 'uuid', nullable: true })\n parentId: string | null = null\n\n @Property({ name: 'root_id', type: 'uuid', nullable: true })\n rootId: string | null = null\n\n @Property({ name: 'tree_path', type: 'text', nullable: true })\n treePath: string | null = null\n\n @Property({ type: 'int', default: 0 })\n depth: number = 0\n\n @Property({ name: 'ancestor_ids', type: 'jsonb', default: [], nullable: false })\n ancestorIds: string[] = []\n\n @Property({ name: 'child_ids', type: 'jsonb', default: [], nullable: false })\n childIds: string[] = []\n\n @Property({ name: 'descendant_ids', type: 'jsonb', default: [], nullable: false })\n descendantIds: string[] = []\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'updated_at', type: Date, onUpdate: () => new Date() })\n updatedAt: Date = new Date()\n\n @Property({ name: 'deleted_at', type: Date, nullable: true })\n deletedAt?: Date | null\n}\n"],
|
|
5
|
-
"mappings": ";;;;;;;;;;AAAA,SAAS,kBAAkB;AAC3B,SAAS,QAAQ,WAAW,WAAW,YAAY,UAAU,cAAc;AAGpE,IAAM,SAAN,MAAa;AAAA,EAAb;AAQL,oBAAoB;AAGpB,qBAAkB,oBAAI,KAAK;AAG3B,qBAAkB,oBAAI,KAAK;AAM3B,yBAAgB,IAAI,WAAyB,IAAI;AAAA;AACnD;AAnBE;AAAA,EADC,WAAW,EAAE,MAAM,QAAQ,YAAY,oBAAoB,CAAC;AAAA,GADlD,OAEX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,OAAO,CAAC;AAAA,GAJf,OAKX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,aAAa,MAAM,WAAW,SAAS,KAAK,CAAC;AAAA,GAPpD,OAQX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,cAAc,MAAM,MAAM,UAAU,MAAM,oBAAI,KAAK,EAAE,CAAC;AAAA,GAV7D,OAWX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,cAAc,MAAM,MAAM,UAAU,MAAM,oBAAI,KAAK,EAAE,CAAC;AAAA,GAb7D,OAcX;AAGA;AAAA,EADC,SAAS,EAAE,MAAM,cAAc,MAAM,MAAM,UAAU,KAAK,CAAC;AAAA,GAhBjD,OAiBX;AAGA;AAAA,EADC,UAAU,MAAM,cAAc,CAAC,MAAM,EAAE,MAAM;AAAA,GAnBnC,OAoBX;AApBW,SAAN;AAAA,EADN,OAAO,EAAE,WAAW,UAAU,CAAC;AAAA,GACnB;AAyBN,IAAM,eAAN,MAAmB;AAAA,EAAnB;
|
|
4
|
+
"sourcesContent": ["import { Collection } from '@mikro-orm/core'\nimport { Entity, ManyToOne, OneToMany, PrimaryKey, Property, Unique } from '@mikro-orm/decorators/legacy'\n\n@Entity({ tableName: 'tenants' })\nexport class Tenant {\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @Property({ type: 'text' })\n name!: string\n\n @Property({ name: 'is_active', type: 'boolean', default: true })\n isActive: boolean = true\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'updated_at', type: Date, onUpdate: () => new Date() })\n updatedAt: Date = new Date()\n\n @Property({ name: 'deleted_at', type: Date, nullable: true })\n deletedAt?: Date | null\n\n @OneToMany(() => Organization, (o) => o.tenant)\n organizations = new Collection<Organization>(this)\n}\n\n@Entity({ tableName: 'organizations' })\n@Unique({ name: 'organizations_tenant_slug_uniq', properties: ['tenant', 'slug'] })\nexport class Organization {\n @PrimaryKey({ type: 'uuid', defaultRaw: 'gen_random_uuid()' })\n id!: string\n\n @ManyToOne(() => Tenant)\n tenant!: Tenant\n\n @Property({ type: 'text' })\n name!: string\n\n @Property({ type: 'text', nullable: true })\n slug?: string | null\n\n @Property({ name: 'logo_url', type: 'text', nullable: true })\n logoUrl?: string | null\n\n @Property({ name: 'is_active', type: 'boolean', default: true })\n isActive: boolean = true\n\n @Property({ name: 'parent_id', type: 'uuid', nullable: true })\n parentId: string | null = null\n\n @Property({ name: 'root_id', type: 'uuid', nullable: true })\n rootId: string | null = null\n\n @Property({ name: 'tree_path', type: 'text', nullable: true })\n treePath: string | null = null\n\n @Property({ type: 'int', default: 0 })\n depth: number = 0\n\n @Property({ name: 'ancestor_ids', type: 'jsonb', default: [], nullable: false })\n ancestorIds: string[] = []\n\n @Property({ name: 'child_ids', type: 'jsonb', default: [], nullable: false })\n childIds: string[] = []\n\n @Property({ name: 'descendant_ids', type: 'jsonb', default: [], nullable: false })\n descendantIds: string[] = []\n\n @Property({ name: 'created_at', type: Date, onCreate: () => new Date() })\n createdAt: Date = new Date()\n\n @Property({ name: 'updated_at', type: Date, onUpdate: () => new Date() })\n updatedAt: Date = new Date()\n\n @Property({ name: 'deleted_at', type: Date, nullable: true })\n deletedAt?: Date | null\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -9,10 +9,18 @@ const tenantUpdateSchema = z.object({
|
|
|
9
9
|
isActive: z.boolean().optional()
|
|
10
10
|
});
|
|
11
11
|
const slugField = z.string().trim().toLowerCase().regex(/^[a-z0-9\-_]+$/).max(150).optional().nullable();
|
|
12
|
+
const logoUrlField = z.union([
|
|
13
|
+
z.string().trim().url().max(2048).refine(
|
|
14
|
+
(value) => value.startsWith("https://") || value.startsWith("http://"),
|
|
15
|
+
{ message: "Logo URL must use http or https." }
|
|
16
|
+
),
|
|
17
|
+
z.string().trim().regex(/^\/api\/attachments\/(?:image|file)\/[A-Za-z0-9%_.~/?=&-]+$/).max(2048)
|
|
18
|
+
]).optional().nullable();
|
|
12
19
|
const organizationCreateSchema = z.object({
|
|
13
20
|
tenantId: z.string().uuid().optional(),
|
|
14
21
|
name: z.string().min(1).max(200),
|
|
15
22
|
slug: slugField,
|
|
23
|
+
logoUrl: logoUrlField,
|
|
16
24
|
isActive: z.boolean().optional(),
|
|
17
25
|
parentId: z.string().uuid().nullable().optional(),
|
|
18
26
|
childIds: z.array(z.string().uuid()).optional()
|
|
@@ -22,6 +30,7 @@ const organizationUpdateSchema = z.object({
|
|
|
22
30
|
tenantId: z.string().uuid().optional(),
|
|
23
31
|
name: z.string().min(1).max(200).optional(),
|
|
24
32
|
slug: slugField,
|
|
33
|
+
logoUrl: logoUrlField,
|
|
25
34
|
isActive: z.boolean().optional(),
|
|
26
35
|
parentId: z.string().uuid().nullable().optional(),
|
|
27
36
|
childIds: z.array(z.string().uuid()).optional()
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/modules/directory/data/validators.ts"],
|
|
4
|
-
"sourcesContent": ["import { z } from 'zod'\n\nexport const tenantCreateSchema = z.object({\n name: z.string().min(1).max(200),\n isActive: z.boolean().optional(),\n})\n\nexport const tenantUpdateSchema = z.object({\n id: z.string().uuid(),\n name: z.string().min(1).max(200).optional(),\n isActive: z.boolean().optional(),\n})\n\nconst slugField = z.string().trim().toLowerCase().regex(/^[a-z0-9\\-_]+$/).max(150).optional().nullable()\n\nexport const organizationCreateSchema = z.object({\n tenantId: z.string().uuid().optional(),\n name: z.string().min(1).max(200),\n slug: slugField,\n isActive: z.boolean().optional(),\n parentId: z.string().uuid().nullable().optional(),\n childIds: z.array(z.string().uuid()).optional(),\n})\n\nexport const organizationUpdateSchema = z.object({\n id: z.string().uuid(),\n tenantId: z.string().uuid().optional(),\n name: z.string().min(1).max(200).optional(),\n slug: slugField,\n isActive: z.boolean().optional(),\n parentId: z.string().uuid().nullable().optional(),\n childIds: z.array(z.string().uuid()).optional(),\n})\n\nexport type TenantCreateInput = z.infer<typeof tenantCreateSchema>\nexport type TenantUpdateInput = z.infer<typeof tenantUpdateSchema>\nexport type OrganizationCreateInput = z.infer<typeof organizationCreateSchema>\nexport type OrganizationUpdateInput = z.infer<typeof organizationUpdateSchema>\n"],
|
|
5
|
-
"mappings": "AAAA,SAAS,SAAS;AAEX,MAAM,qBAAqB,EAAE,OAAO;AAAA,EACzC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG;AAAA,EAC/B,UAAU,EAAE,QAAQ,EAAE,SAAS;AACjC,CAAC;AAEM,MAAM,qBAAqB,EAAE,OAAO;AAAA,EACzC,IAAI,EAAE,OAAO,EAAE,KAAK;AAAA,EACpB,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,EAC1C,UAAU,EAAE,QAAQ,EAAE,SAAS;AACjC,CAAC;AAED,MAAM,YAAY,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS;
|
|
4
|
+
"sourcesContent": ["import { z } from 'zod'\n\nexport const tenantCreateSchema = z.object({\n name: z.string().min(1).max(200),\n isActive: z.boolean().optional(),\n})\n\nexport const tenantUpdateSchema = z.object({\n id: z.string().uuid(),\n name: z.string().min(1).max(200).optional(),\n isActive: z.boolean().optional(),\n})\n\nconst slugField = z.string().trim().toLowerCase().regex(/^[a-z0-9\\-_]+$/).max(150).optional().nullable()\nconst logoUrlField = z\n .union([\n z.string().trim().url().max(2048).refine(\n (value) => value.startsWith('https://') || value.startsWith('http://'),\n { message: 'Logo URL must use http or https.' },\n ),\n z.string().trim().regex(/^\\/api\\/attachments\\/(?:image|file)\\/[A-Za-z0-9%_.~/?=&-]+$/).max(2048),\n ])\n .optional()\n .nullable()\n\nexport const organizationCreateSchema = z.object({\n tenantId: z.string().uuid().optional(),\n name: z.string().min(1).max(200),\n slug: slugField,\n logoUrl: logoUrlField,\n isActive: z.boolean().optional(),\n parentId: z.string().uuid().nullable().optional(),\n childIds: z.array(z.string().uuid()).optional(),\n})\n\nexport const organizationUpdateSchema = z.object({\n id: z.string().uuid(),\n tenantId: z.string().uuid().optional(),\n name: z.string().min(1).max(200).optional(),\n slug: slugField,\n logoUrl: logoUrlField,\n isActive: z.boolean().optional(),\n parentId: z.string().uuid().nullable().optional(),\n childIds: z.array(z.string().uuid()).optional(),\n})\n\nexport type TenantCreateInput = z.infer<typeof tenantCreateSchema>\nexport type TenantUpdateInput = z.infer<typeof tenantUpdateSchema>\nexport type OrganizationCreateInput = z.infer<typeof organizationCreateSchema>\nexport type OrganizationUpdateInput = z.infer<typeof organizationUpdateSchema>\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,SAAS;AAEX,MAAM,qBAAqB,EAAE,OAAO;AAAA,EACzC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG;AAAA,EAC/B,UAAU,EAAE,QAAQ,EAAE,SAAS;AACjC,CAAC;AAEM,MAAM,qBAAqB,EAAE,OAAO;AAAA,EACzC,IAAI,EAAE,OAAO,EAAE,KAAK;AAAA,EACpB,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,EAC1C,UAAU,EAAE,QAAQ,EAAE,SAAS;AACjC,CAAC;AAED,MAAM,YAAY,EAAE,OAAO,EAAE,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,EAAE,IAAI,GAAG,EAAE,SAAS,EAAE,SAAS;AACvG,MAAM,eAAe,EAClB,MAAM;AAAA,EACL,EAAE,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,IAAI,EAAE;AAAA,IAChC,CAAC,UAAU,MAAM,WAAW,UAAU,KAAK,MAAM,WAAW,SAAS;AAAA,IACrE,EAAE,SAAS,mCAAmC;AAAA,EAChD;AAAA,EACA,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,6DAA6D,EAAE,IAAI,IAAI;AACjG,CAAC,EACA,SAAS,EACT,SAAS;AAEL,MAAM,2BAA2B,EAAE,OAAO;AAAA,EAC/C,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS;AAAA,EACrC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG;AAAA,EAC/B,MAAM;AAAA,EACN,SAAS;AAAA,EACT,UAAU,EAAE,QAAQ,EAAE,SAAS;AAAA,EAC/B,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS;AAAA,EAChD,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,SAAS;AAChD,CAAC;AAEM,MAAM,2BAA2B,EAAE,OAAO;AAAA,EAC/C,IAAI,EAAE,OAAO,EAAE,KAAK;AAAA,EACpB,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS;AAAA,EACrC,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,EAC1C,MAAM;AAAA,EACN,SAAS;AAAA,EACT,UAAU,EAAE,QAAQ,EAAE,SAAS;AAAA,EAC/B,UAAU,EAAE,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS;AAAA,EAChD,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,SAAS;AAChD,CAAC;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { Migration } from "@mikro-orm/migrations";
|
|
2
|
+
class Migration20260607222259_directory extends Migration {
|
|
3
|
+
up() {
|
|
4
|
+
this.addSql(`alter table "organizations" add "logo_url" text null;`);
|
|
5
|
+
}
|
|
6
|
+
down() {
|
|
7
|
+
this.addSql(`alter table "organizations" drop column "logo_url";`);
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
export {
|
|
11
|
+
Migration20260607222259_directory
|
|
12
|
+
};
|
|
13
|
+
//# sourceMappingURL=Migration20260607222259_directory.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../../../src/modules/directory/migrations/Migration20260607222259_directory.ts"],
|
|
4
|
+
"sourcesContent": ["import { Migration } from '@mikro-orm/migrations';\n\nexport class Migration20260607222259_directory extends Migration {\n\n override up(): void | Promise<void> {\n this.addSql(`alter table \"organizations\" add \"logo_url\" text null;`);\n }\n\n override down(): void | Promise<void> {\n this.addSql(`alter table \"organizations\" drop column \"logo_url\";`);\n }\n\n}\n"],
|
|
5
|
+
"mappings": "AAAA,SAAS,iBAAiB;AAEnB,MAAM,0CAA0C,UAAU;AAAA,EAEtD,KAA2B;AAClC,SAAK,OAAO,uDAAuD;AAAA,EACrE;AAAA,EAES,OAA6B;AACpC,SAAK,OAAO,qDAAqD;AAAA,EACnE;AAEF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
|
@@ -2,6 +2,7 @@ export const id = "id";
|
|
|
2
2
|
export const tenant = "tenant";
|
|
3
3
|
export const name = "name";
|
|
4
4
|
export const slug = "slug";
|
|
5
|
+
export const logo_url = "logo_url";
|
|
5
6
|
export const is_active = "is_active";
|
|
6
7
|
export const parent_id = "parent_id";
|
|
7
8
|
export const root_id = "root_id";
|
|
@@ -1537,6 +1537,7 @@ export const entityFieldsRegistry: Record<string, Record<string, string>> = {
|
|
|
1537
1537
|
"tenant": "tenant",
|
|
1538
1538
|
"name": "name",
|
|
1539
1539
|
"slug": "slug",
|
|
1540
|
+
"logo_url": "logo_url",
|
|
1540
1541
|
"is_active": "is_active",
|
|
1541
1542
|
"parent_id": "parent_id",
|
|
1542
1543
|
"root_id": "root_id",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@open-mercato/core",
|
|
3
|
-
"version": "0.6.6-develop.
|
|
3
|
+
"version": "0.6.6-develop.5523.1.e223ca1915",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"scripts": {
|
|
@@ -245,16 +245,16 @@
|
|
|
245
245
|
"zod": "^4.4.3"
|
|
246
246
|
},
|
|
247
247
|
"peerDependencies": {
|
|
248
|
-
"@open-mercato/ai-assistant": "0.6.6-develop.
|
|
249
|
-
"@open-mercato/shared": "0.6.6-develop.
|
|
250
|
-
"@open-mercato/ui": "0.6.6-develop.
|
|
248
|
+
"@open-mercato/ai-assistant": "0.6.6-develop.5523.1.e223ca1915",
|
|
249
|
+
"@open-mercato/shared": "0.6.6-develop.5523.1.e223ca1915",
|
|
250
|
+
"@open-mercato/ui": "0.6.6-develop.5523.1.e223ca1915",
|
|
251
251
|
"react": "^19.0.0",
|
|
252
252
|
"react-dom": "^19.0.0"
|
|
253
253
|
},
|
|
254
254
|
"devDependencies": {
|
|
255
|
-
"@open-mercato/ai-assistant": "0.6.6-develop.
|
|
256
|
-
"@open-mercato/shared": "0.6.6-develop.
|
|
257
|
-
"@open-mercato/ui": "0.6.6-develop.
|
|
255
|
+
"@open-mercato/ai-assistant": "0.6.6-develop.5523.1.e223ca1915",
|
|
256
|
+
"@open-mercato/shared": "0.6.6-develop.5523.1.e223ca1915",
|
|
257
|
+
"@open-mercato/ui": "0.6.6-develop.5523.1.e223ca1915",
|
|
258
258
|
"@testing-library/dom": "^10.4.1",
|
|
259
259
|
"@testing-library/jest-dom": "^6.9.1",
|
|
260
260
|
"@testing-library/react": "^16.3.1",
|
package/src/bootstrap.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { asValue } from 'awilix'
|
|
|
3
3
|
import { createEventBus } from '@open-mercato/events/index'
|
|
4
4
|
import { setGlobalEventBus } from '@open-mercato/shared/modules/events'
|
|
5
5
|
import { createCacheService } from '@open-mercato/cache'
|
|
6
|
+
import type { CacheStrategy } from '@open-mercato/cache'
|
|
6
7
|
import { createKmsService } from '@open-mercato/shared/lib/encryption/kms'
|
|
7
8
|
import { TenantDataEncryptionService } from '@open-mercato/shared/lib/encryption/tenantDataEncryptionService'
|
|
8
9
|
import { registerTenantEncryptionSubscriber } from '@open-mercato/shared/lib/encryption/subscriber'
|
|
@@ -21,6 +22,59 @@ import type { EntityManager } from '@mikro-orm/postgresql'
|
|
|
21
22
|
const RL_GLOBAL_KEY = '__openMercatoRateLimiterService__'
|
|
22
23
|
const RL_SHUTDOWN_KEY = '__openMercatoRateLimiterShutdown__'
|
|
23
24
|
|
|
25
|
+
const CACHE_GLOBAL_KEY = '__openMercatoCacheService__'
|
|
26
|
+
const CACHE_SHUTDOWN_KEY = '__openMercatoCacheShutdown__'
|
|
27
|
+
|
|
28
|
+
// Escape hatch: set OM_CACHE_SINGLETON=off to fall back to the legacy
|
|
29
|
+
// per-request cache instance (e.g. to isolate a regression). Default ON.
|
|
30
|
+
function isCacheSingletonEnabled(): boolean {
|
|
31
|
+
const raw = process.env.OM_CACHE_SINGLETON
|
|
32
|
+
if (raw === undefined) return true
|
|
33
|
+
const normalized = raw.trim().toLowerCase()
|
|
34
|
+
if (!normalized.length) return true
|
|
35
|
+
return !(normalized === '0' || normalized === 'off' || normalized === 'false' || normalized === 'no')
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Process-wide cache service singleton, mirroring getCachedRateLimiterService.
|
|
40
|
+
*
|
|
41
|
+
* bootstrap() previously built a fresh cache per request container, so under
|
|
42
|
+
* the default memory strategy every cross-request cache was a no-op (each
|
|
43
|
+
* instance is process-local) and under sqlite each request leaked a native
|
|
44
|
+
* handle. Reusing one instance is safe by construction: tenant scope resolves
|
|
45
|
+
* per-call via AsyncLocalStorage (packages/cache/src/tenantContext.ts), so the
|
|
46
|
+
* service holds no request-bound state.
|
|
47
|
+
*
|
|
48
|
+
* Returns null when disabled via the escape hatch or when creation fails, so
|
|
49
|
+
* the caller falls back to a per-request instance.
|
|
50
|
+
*/
|
|
51
|
+
export function getCachedCacheService(): CacheStrategy | null {
|
|
52
|
+
if (!isCacheSingletonEnabled()) return null
|
|
53
|
+
let service = (globalThis as any)[CACHE_GLOBAL_KEY] as CacheStrategy | null ?? null
|
|
54
|
+
if (!service) {
|
|
55
|
+
try {
|
|
56
|
+
try {
|
|
57
|
+
service = createCacheService()
|
|
58
|
+
} catch (err) {
|
|
59
|
+
console.warn('Cache service initialization failed; falling back to memory strategy:', (err as Error)?.message || err)
|
|
60
|
+
service = createCacheService({ strategy: 'memory' })
|
|
61
|
+
}
|
|
62
|
+
;(globalThis as any)[CACHE_GLOBAL_KEY] = service
|
|
63
|
+
|
|
64
|
+
// Register shutdown hook once to close persistent handles (sqlite/redis) on process exit
|
|
65
|
+
if (!(globalThis as any)[CACHE_SHUTDOWN_KEY]) {
|
|
66
|
+
const shutdown = () => { service?.close?.().catch(() => {}) }
|
|
67
|
+
process.once('SIGTERM', shutdown)
|
|
68
|
+
process.once('SIGINT', shutdown)
|
|
69
|
+
;(globalThis as any)[CACHE_SHUTDOWN_KEY] = true
|
|
70
|
+
}
|
|
71
|
+
} catch (err) {
|
|
72
|
+
console.warn('[cache] Failed to create cache service:', (err as Error)?.message || err)
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return service
|
|
76
|
+
}
|
|
77
|
+
|
|
24
78
|
export function getCachedRateLimiterService(): RateLimiterService | null {
|
|
25
79
|
let service = (globalThis as any)[RL_GLOBAL_KEY] as RateLimiterService | null ?? null
|
|
26
80
|
if (!service) {
|
|
@@ -50,13 +104,17 @@ export function getCachedRateLimiterService(): RateLimiterService | null {
|
|
|
50
104
|
}
|
|
51
105
|
|
|
52
106
|
export async function bootstrap(container: AwilixContainer) {
|
|
53
|
-
//
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
107
|
+
// Register the cache service. Prefer the process-wide singleton so caches
|
|
108
|
+
// survive across request containers; fall back to a per-request instance
|
|
109
|
+
// when the singleton is disabled or fails to build.
|
|
110
|
+
let cache: any = getCachedCacheService()
|
|
111
|
+
if (!cache) {
|
|
112
|
+
try {
|
|
113
|
+
cache = createCacheService()
|
|
114
|
+
} catch (err: any) {
|
|
115
|
+
console.warn('Cache service initialization failed; falling back to memory strategy:', err?.message || err)
|
|
116
|
+
cache = createCacheService({ strategy: 'memory' })
|
|
117
|
+
}
|
|
60
118
|
}
|
|
61
119
|
container.register({ cache: asValue(cache) })
|
|
62
120
|
|
|
@@ -69,6 +69,13 @@ const sectionGroupSchema = z.object({
|
|
|
69
69
|
})
|
|
70
70
|
|
|
71
71
|
const adminNavResponseSchema = z.object({
|
|
72
|
+
brand: z.object({
|
|
73
|
+
name: z.string().optional(),
|
|
74
|
+
logo: z.object({
|
|
75
|
+
src: z.string(),
|
|
76
|
+
alt: z.string().optional(),
|
|
77
|
+
}).nullable().optional(),
|
|
78
|
+
}).nullable().optional(),
|
|
72
79
|
groups: z.array(
|
|
73
80
|
z.object({
|
|
74
81
|
id: z.string().optional(),
|
|
@@ -160,6 +167,8 @@ export async function GET(req: Request) {
|
|
|
160
167
|
`nav:entities:${cacheScopeTenantId || 'null'}`,
|
|
161
168
|
`nav:locale:${locale}`,
|
|
162
169
|
`nav:sidebar:user:${auth.sub}`,
|
|
170
|
+
cacheScopeTenantId ? `nav:sidebar:tenant:${cacheScopeTenantId}` : undefined,
|
|
171
|
+
cacheScopeOrganizationId ? `nav:sidebar:organization:${cacheScopeOrganizationId}` : undefined,
|
|
163
172
|
`nav:sidebar:scope:${auth.sub}:${cacheScopeTenantId || 'null'}:${cacheScopeOrganizationId || 'null'}:${locale}`,
|
|
164
173
|
...((Array.isArray(auth.roles) ? auth.roles : []).map((role) => `nav:sidebar:role:${role}`)),
|
|
165
174
|
].filter(Boolean) as string[]
|