import type { UniqueID } from "@repo/rdx-ddd"; import { AggregateRoot } from "@repo/rdx-ddd"; import { Result } from "@repo/rdx-utils"; import { z } from "zod/v4"; import { MailboxRevision } from "./mailbox-revision.entity"; import { MailboxError } from "./mailbox-values"; import type { MailboxValues } from "./value-objects/mailbox-values.vo"; type MailboxProps = Readonly<{ companyId: UniqueID; values: MailboxValues; history: readonly MailboxRevision[]; }>; export class Mailbox extends AggregateRoot { private constructor(props: MailboxProps, id?: UniqueID) { super(Object.freeze({ ...props, history: Object.freeze([...props.history]) }), id); } static create( companyId: UniqueID, values: MailboxValues, actorId: UniqueID, recordedAt: string ): Result { if (!z.iso.datetime().safeParse(recordedAt).success) { return Result.fail(new MailboxError("INVALID_REQUEST")); } return Result.ok( new Mailbox({ companyId, values, history: [MailboxRevision.create({ values, actorId, recordedAt })], }) ); } static rehydrate(props: MailboxProps, id: UniqueID) { return new Mailbox(props, id); } get companyId() { return this.props.companyId; } get values() { return this.props.values; } get history() { return this.props.history; } update( values: MailboxValues, actorId: UniqueID, recordedAt: string ): Result { if (this.values.equals(values)) { return Result.ok(this); } if (this.values.kind !== values.kind) { return Result.fail(new MailboxError("MAILBOX_KIND_IMMUTABLE")); } if ( !z.iso.datetime().safeParse(recordedAt).success || recordedAt < (this.history.at(-1)?.recordedAt ?? "") ) { return Result.fail(new MailboxError("INVALID_REQUEST")); } return Result.ok( new Mailbox( { ...this.props, values, history: [...this.history, MailboxRevision.create({ values, actorId, recordedAt })], }, this.id ) ); } }