import type { UniqueID } from "@repo/rdx-ddd"; import { AggregateRoot } from "@repo/rdx-ddd"; import { Result } from "@repo/rdx-utils"; import { ResourceCatalogError } from "./resource-definition"; import { ResourceRevision } from "./resource-revision.entity"; import type { ResourceSpecification, ResourceValues } from "./value-objects/resource-values.vo"; type ResourceProps = Readonly<{ companyId: UniqueID; specification: ResourceSpecification; values: ResourceValues; history: readonly ResourceRevision[]; }>; export class Resource extends AggregateRoot { private constructor(props: ResourceProps, id?: UniqueID) { super({ ...props, history: Object.freeze([...props.history]) }, id); } static create( companyId: UniqueID, specification: ResourceSpecification, values: ResourceValues, actorId: UniqueID, recordedAt: string ) { return Result.ok( new Resource({ companyId, specification, values, history: [ResourceRevision.create({ values, actorId, recordedAt })], }) ); } static rehydrate(props: ResourceProps, id: UniqueID) { return new Resource(props, id); } get companyId() { return this.props.companyId; } get specification() { return this.props.specification; } get values() { return this.props.values; } get history() { return this.props.history; } update( values: ResourceValues, actorId: UniqueID, recordedAt: string ): Result { if (values.toPrimitive().templateId !== this.values.toPrimitive().templateId) { return Result.fail(new ResourceCatalogError("TEMPLATE_FIXED")); } const previous = this.values.toPrimitive().integration; const next = values.toPrimitive().integration; if ( previous?.kind !== next?.kind || (previous?.kind === "mailbox" && next?.kind === "mailbox" && (previous.mailboxKind !== next.mailboxKind || previous.addressFieldId !== next.addressFieldId || previous.contextFieldId !== next.contextFieldId)) || (previous?.kind === "access" && next?.kind === "access" && (previous.referenceFieldId !== next.referenceFieldId || previous.resourceTypeId !== next.resourceTypeId || previous.systemId !== next.systemId || previous.environmentId !== next.environmentId)) ) { return Result.fail(new ResourceCatalogError("CONTEXT_FIXED")); } return Result.ok( this.values.equals(values) ? this : new Resource( { ...this.props, values, history: [...this.history, ResourceRevision.create({ values, actorId, recordedAt })], }, this.id ) ); } }