import { DomainValidationError } from "@erp/core/api"; import { ValueObject } from "@repo/rdx-ddd"; import { Result } from "@repo/rdx-utils"; interface ICustomerStatusProps { value: string; } export enum CUSTOMER_STATUS { ACTIVE = "active", INACTIVE = "inactive", } export class CustomerStatus extends ValueObject { private static readonly ALLOWED_STATUSES = ["active", "inactive"]; private static readonly FIELD = "status"; private static readonly ERROR_CODE = "INVALID_STATUS"; private static readonly TRANSITIONS: Record = { active: [CUSTOMER_STATUS.INACTIVE], inactive: [CUSTOMER_STATUS.ACTIVE], }; static create(value: string): Result { if (!CustomerStatus.ALLOWED_STATUSES.includes(value)) { const detail = `Status value not valid: ${value}`; return Result.fail( new DomainValidationError(CustomerStatus.ERROR_CODE, CustomerStatus.FIELD, detail) ); } return Result.ok( value === "active" ? CustomerStatus.createActive() : CustomerStatus.createInactive() ); } public static createActive(): CustomerStatus { return new CustomerStatus({ value: CUSTOMER_STATUS.ACTIVE }); } public static createInactive(): CustomerStatus { return new CustomerStatus({ value: CUSTOMER_STATUS.INACTIVE }); } isActive(): boolean { return this.props.value === CUSTOMER_STATUS.ACTIVE; } getValue(): string { return this.props.value; } toPrimitive() { return this.getValue(); } canTransitionTo(nextStatus: string): boolean { return CustomerStatus.TRANSITIONS[this.props.value].includes(nextStatus); } transitionTo(nextStatus: string): Result { if (!this.canTransitionTo(nextStatus)) { return Result.fail( new Error(`Transition not allowed from ${this.props.value} to ${nextStatus}`) ); } return CustomerStatus.create(nextStatus); } toString(): string { return this.getValue(); } }