import { z } from "zod/v4"; import { WorkstationValues } from "../../domain/value-objects/workstation-values"; import { Workstation } from "../../domain/workstation.aggregate"; import { WorkstationRevision } from "../../domain/workstation-revision.entity"; import { WorkstationInputSchema } from "../../domain/workstation-values"; import { inventoryIdentity } from "./asset-persistence.mapper"; import type { WorkstationAssetModel, WorkstationModel, WorkstationRevisionModel, } from "./workstation.model"; function valuesOf(raw: unknown, siteId: string | null, personId: string | null) { const values = WorkstationValues.create(WorkstationInputSchema.parse(raw)); if ( !values.isSuccess || values.data.toPrimitive().siteId !== siteId || values.data.toPrimitive().personId !== personId ) { throw new Error("Valores de puesto persistidos inconsistentes."); } return values.data; } export class WorkstationPersistenceMapper { toDomain( row: WorkstationModel, revisions: readonly WorkstationRevisionModel[], references: readonly WorkstationAssetModel[] ) { const values = valuesOf(row.values, row.siteId, row.personId); const ordered = [...revisions].sort((a, b) => a.position - b.position); const history = ordered.map((revision, position) => { if ( revision.position !== position || !z.iso.datetime().safeParse(revision.recordedAt).success || revision.recordedAt < (ordered[position - 1]?.recordedAt ?? "") ) { throw new Error("Historial de puesto inconsistente."); } return WorkstationRevision.rehydrate( { values: valuesOf(revision.values, revision.siteId, revision.personId), actorId: inventoryIdentity(revision.actorId), recordedAt: revision.recordedAt, }, inventoryIdentity(revision.id) ); }); if (!(history.length && history.at(-1)?.values.equals(values))) { throw new Error("Última revisión de puesto inconsistente."); } const expected = new Set(history.flatMap((item) => item.values.toPrimitive().assetIds)); if ( references.length !== expected.size || references.some( (item) => item.companyId !== row.companyId || !expected.has(item.assetId) || item.activeKey !== (values.active && values.assetIds.some((id) => id.toPrimitive() === item.assetId) ? `${row.companyId}:${item.assetId}` : null) ) ) { throw new Error("Referencias de puesto inconsistentes."); } return Workstation.rehydrate( { companyId: inventoryIdentity(row.companyId), values, history }, inventoryIdentity(row.id) ); } toPersistence(item: Workstation) { const values = item.values.toPrimitive(); const companyId = item.companyId.toPrimitive(); const id = item.id.toPrimitive(); return { workstation: { id, companyId, values, siteId: values.siteId, personId: values.personId }, revisions: item.history.map((revision, position) => ({ id: revision.id.toPrimitive(), workstationId: id, actorId: revision.actorId.toPrimitive(), recordedAt: revision.recordedAt, values: revision.values.toPrimitive(), position, siteId: revision.values.toPrimitive().siteId, personId: revision.values.toPrimitive().personId, })), references: [ ...new Set(item.history.flatMap((revision) => revision.values.toPrimitive().assetIds)), ].map((assetId) => ({ workstationId: id, companyId, assetId, activeKey: values.active && values.assetIds.includes(assetId) ? `${companyId}:${assetId}` : null, })), }; } }