import type { UniqueID } from "@repo/rdx-ddd"; import { AggregateRoot } from "@repo/rdx-ddd"; import { Maybe, Result } from "@repo/rdx-utils"; import { z } from "zod/v4"; import { AssetCatalogError } from "./asset-definition"; import type { AssetRelationshipValues } from "./value-objects/asset-relationship-values.vo"; type RelationshipProps = Readonly<{ companyId: UniqueID; values: AssetRelationshipValues; createdBy: UniqueID; createdAt: string; endedBy: Maybe; endedAt: Maybe; }>; export class AssetRelationship extends AggregateRoot { private constructor(props: RelationshipProps, id?: UniqueID) { super(Object.freeze({ ...props }), id); } static create( companyId: UniqueID, values: AssetRelationshipValues, actor: UniqueID, now: string ): Result { if (!z.iso.datetime().safeParse(now).success) { return Result.fail(new AssetCatalogError("INVALID_REQUEST")); } return Result.ok( new AssetRelationship({ companyId, values, createdBy: actor, createdAt: now, endedBy: Maybe.none(), endedAt: Maybe.none(), }) ); } static rehydrate(props: RelationshipProps, id: UniqueID) { return new AssetRelationship(props, id); } get companyId() { return this.props.companyId; } get values() { return this.props.values; } get createdBy() { return this.props.createdBy; } get createdAt() { return this.props.createdAt; } get endedBy() { return this.props.endedBy; } get endedAt() { return this.props.endedAt; } get active() { return !this.endedAt.getOrUndefined(); } end(actor: UniqueID, now: string): Result { if (!this.active) { return Result.ok(this); } if (!z.iso.datetime().safeParse(now).success || now < this.createdAt) { return Result.fail(new AssetCatalogError("INVALID_REQUEST")); } return Result.ok( new AssetRelationship( { ...this.props, endedBy: Maybe.some(actor), endedAt: Maybe.some(now) }, this.id ) ); } }