import type { Result as DomainResult } from "@repo/rdx-utils"; import type { InferAttributes } from "sequelize"; import { CompanyInputMapper } from "../../application/company-input.mapper"; import { Company } from "../../domain/company.aggregate"; import { Contact } from "../../domain/contact.entity"; import { Site } from "../../domain/site.entity"; import type { CompanyModel, ContactModel, SiteModel } from "./company.model"; export type CompanyRecord = { company: InferAttributes; contacts: InferAttributes[]; sites: InferAttributes[]; }; function persisted(result: DomainResult): T { if (!result.isSuccess) { throw new Error("Persistencia de compañía inconsistente."); } return result.data; } export class CompanyPersistenceMapper { private readonly input = new CompanyInputMapper(); toDomain(record: CompanyRecord): Company { const id = persisted(this.input.id(record.company.id)); const props = persisted(this.input.company(record.company)); const contacts = record.contacts.map((row) => { const companyId = persisted(this.input.id(row.companyId)); if (!companyId.equals(id)) { throw new Error("Persistencia de contacto inconsistente."); } return Contact.rehydrate( { ...persisted(this.input.contact(row)), companyId }, persisted(this.input.id(row.id)) ); }); const sites = record.sites.map((row) => { const companyId = persisted(this.input.id(row.companyId)); if (!companyId.equals(id)) { throw new Error("Persistencia de sede inconsistente."); } return Site.rehydrate( { ...persisted(this.input.site(row)), companyId }, persisted(this.input.id(row.id)) ); }); return Company.rehydrate({ ...props, contacts, sites }, id); } toPersistence(company: Company): CompanyRecord { return { company: { id: company.id.toPrimitive(), name: company.name.toPrimitive(), active: company.active, }, contacts: company.contacts.map((contact) => ({ id: contact.id.toPrimitive(), companyId: contact.companyId.toPrimitive(), name: contact.name.toPrimitive(), position: contact.position.toPrimitive(), email: contact.email.toPrimitive(), phone: contact.phone.toPrimitive(), active: contact.active, })), sites: company.sites.map((site) => ({ id: site.id.toPrimitive(), companyId: site.companyId.toPrimitive(), name: site.name.toPrimitive(), address: site.address.getOrUndefined()?.toPrimitive() ?? null, })), }; } }