metis-desk/modules/assets/src/api/infrastructure/persistence/workstation-persistence.mapper.ts

102 lines
3.7 KiB
TypeScript
Raw Normal View History

2026-10-04 19:04:14 +00:00
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,
})),
};
}
}