2026-10-04 19:04:14 +00:00
|
|
|
import { Name, UniqueID } from "@repo/rdx-ddd";
|
|
|
|
|
import { Maybe, Result } from "@repo/rdx-utils";
|
|
|
|
|
|
|
|
|
|
import { AssetCatalogError } from "../asset-definition";
|
|
|
|
|
import { type WorkstationInput, WorkstationInputSchema } from "../workstation-values";
|
|
|
|
|
export class WorkstationValues {
|
|
|
|
|
private constructor(
|
|
|
|
|
public readonly name: Name,
|
|
|
|
|
public readonly active: boolean,
|
|
|
|
|
public readonly siteId: Maybe<UniqueID>,
|
|
|
|
|
public readonly personId: Maybe<UniqueID>,
|
2026-10-05 07:53:29 +00:00
|
|
|
public readonly assetIds: readonly UniqueID[],
|
|
|
|
|
public readonly sharedAssetIds: readonly UniqueID[]
|
2026-10-04 19:04:14 +00:00
|
|
|
) {
|
|
|
|
|
Object.freeze(this);
|
|
|
|
|
}
|
|
|
|
|
static create(input: WorkstationInput): Result<WorkstationValues, AssetCatalogError> {
|
|
|
|
|
const parsed = WorkstationInputSchema.safeParse(input);
|
|
|
|
|
const name = Name.create(input.name, 100);
|
|
|
|
|
const site = optionalIdentity(input.siteId);
|
|
|
|
|
const person = optionalIdentity(input.personId);
|
|
|
|
|
if (!(parsed.success && name.isSuccess && site.isSuccess && person.isSuccess)) {
|
|
|
|
|
return Result.fail(new AssetCatalogError("INVALID_REQUEST"));
|
|
|
|
|
}
|
|
|
|
|
const ids: UniqueID[] = [];
|
2026-10-05 07:53:29 +00:00
|
|
|
const shared: UniqueID[] = [];
|
2026-10-04 19:04:14 +00:00
|
|
|
for (const value of parsed.data.assetIds) {
|
|
|
|
|
const id = UniqueID.create(value);
|
|
|
|
|
if (!id.isSuccess || ids.some((previous) => previous.equals(id.data))) {
|
|
|
|
|
return Result.fail(new AssetCatalogError("INVALID_MEMBERS"));
|
|
|
|
|
}
|
|
|
|
|
ids.push(id.data);
|
|
|
|
|
}
|
2026-10-05 07:53:29 +00:00
|
|
|
for (const value of parsed.data.sharedAssetIds) {
|
|
|
|
|
const id = UniqueID.create(value);
|
|
|
|
|
if (!id.isSuccess || [...ids, ...shared].some((previous) => previous.equals(id.data))) {
|
|
|
|
|
return Result.fail(new AssetCatalogError("INVALID_MEMBERS"));
|
|
|
|
|
}
|
|
|
|
|
shared.push(id.data);
|
|
|
|
|
}
|
2026-10-04 19:04:14 +00:00
|
|
|
return Result.ok(
|
2026-10-05 07:53:29 +00:00
|
|
|
new WorkstationValues(
|
|
|
|
|
name.data,
|
|
|
|
|
input.active,
|
|
|
|
|
site.data,
|
|
|
|
|
person.data,
|
|
|
|
|
Object.freeze(ids),
|
|
|
|
|
Object.freeze(shared)
|
|
|
|
|
)
|
2026-10-04 19:04:14 +00:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
toPrimitive(): WorkstationInput {
|
|
|
|
|
return {
|
|
|
|
|
name: this.name.toPrimitive(),
|
|
|
|
|
active: this.active,
|
|
|
|
|
siteId: this.siteId.getOrUndefined()?.toPrimitive() ?? null,
|
|
|
|
|
personId: this.personId.getOrUndefined()?.toPrimitive() ?? null,
|
|
|
|
|
assetIds: this.assetIds.map((id) => id.toPrimitive()),
|
2026-10-05 07:53:29 +00:00
|
|
|
sharedAssetIds: this.sharedAssetIds.map((id) => id.toPrimitive()),
|
2026-10-04 19:04:14 +00:00
|
|
|
};
|
|
|
|
|
}
|
|
|
|
|
equals(other: WorkstationValues) {
|
|
|
|
|
const a = this.toPrimitive();
|
|
|
|
|
const b = other.toPrimitive();
|
|
|
|
|
return (
|
|
|
|
|
a.name === b.name &&
|
|
|
|
|
a.active === b.active &&
|
|
|
|
|
a.siteId === b.siteId &&
|
|
|
|
|
a.personId === b.personId &&
|
|
|
|
|
a.assetIds.length === b.assetIds.length &&
|
2026-10-05 07:53:29 +00:00
|
|
|
a.assetIds.every((id) => b.assetIds.includes(id)) &&
|
|
|
|
|
a.sharedAssetIds.length === b.sharedAssetIds.length &&
|
|
|
|
|
a.sharedAssetIds.every((id) => b.sharedAssetIds.includes(id))
|
2026-10-04 19:04:14 +00:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function optionalIdentity(value: string | null): Result<Maybe<UniqueID>, AssetCatalogError> {
|
|
|
|
|
if (!value) {
|
|
|
|
|
return Result.ok(Maybe.none());
|
|
|
|
|
}
|
|
|
|
|
const id = UniqueID.create(value);
|
|
|
|
|
return id.isSuccess
|
|
|
|
|
? Result.ok(Maybe.some(id.data))
|
|
|
|
|
: Result.fail(new AssetCatalogError("INVALID_REQUEST"));
|
|
|
|
|
}
|