74 lines
2.6 KiB
TypeScript
74 lines
2.6 KiB
TypeScript
|
|
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<CompanyModel>;
|
||
|
|
contacts: InferAttributes<ContactModel>[];
|
||
|
|
sites: InferAttributes<SiteModel>[];
|
||
|
|
};
|
||
|
|
function persisted<T>(result: DomainResult<T, Error>): 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,
|
||
|
|
})),
|
||
|
|
};
|
||
|
|
}
|
||
|
|
}
|