metis-desk/modules/assets/src/api/application/asset.repository.ts

41 lines
1.5 KiB
TypeScript
Raw Normal View History

import type { UniqueID } from "@repo/rdx-ddd";
import { Result } from "@repo/rdx-utils";
import type { Asset } from "../domain/asset.aggregate";
import type { AssetCatalog } from "../domain/asset-catalog.aggregate";
import { AssetCatalogError } from "../domain/asset-definition";
import type { AssetValues } from "../domain/value-objects/asset-values";
export type InventoryContext = Readonly<{
catalog: AssetCatalog;
assets: readonly Asset[];
sites: readonly UniqueID[];
people: readonly { id: UniqueID; active: boolean }[];
actorNames: ReadonlyMap<string, string>;
}>;
export interface IAssetRepository {
get(companyId: UniqueID): Promise<Result<InventoryContext, AssetCatalogError>>;
save(
companyId: UniqueID,
action: (context: InventoryContext) => Result<Asset, AssetCatalogError>
): Promise<Result<{ asset: Asset; actorNames: ReadonlyMap<string, string> }, AssetCatalogError>>;
}
export function validateAssetReferences(
context: InventoryContext,
values: AssetValues,
previous?: Asset
) {
const next = values.toPrimitive();
const current = previous?.values.toPrimitive();
if (next.siteId && !context.sites.some((site) => site.toPrimitive() === next.siteId)) {
return Result.fail(new AssetCatalogError("SITE_NOT_FOUND"));
}
if (next.personId) {
const person = context.people.find((person) => person.id.toPrimitive() === next.personId);
if (!person || (!person.active && current?.personId !== next.personId)) {
return Result.fail(new AssetCatalogError("PERSON_UNAVAILABLE"));
}
}
return Result.ok<true>(true);
}