metis-desk/modules/resources/src/api/application/resource-input.mapper.ts

143 lines
5.0 KiB
TypeScript
Raw Normal View History

2026-10-05 11:13:51 +00:00
import type { UniqueID } from "@repo/rdx-ddd";
import { Maybe, Result } from "@repo/rdx-utils";
import type { Resource } from "../domain/resource.aggregate";
import { ResourceCatalogError } from "../domain/resource-definition";
import type { ResourceInput } from "../domain/resource-values";
2026-10-09 08:38:19 +00:00
import { ResourceSpecification, ResourceValues } from "../domain/value-objects/resource-values.vo";
2026-10-05 11:13:51 +00:00
import type { InventoryContext } from "./resource.repository";
export function mapResourceInput(
input: ResourceInput,
companyId: UniqueID,
context: InventoryContext,
previous?: Resource
) {
if (previous && previous.values.toPrimitive().templateId !== input.templateId.toLowerCase()) {
return Result.fail(new ResourceCatalogError("TEMPLATE_FIXED"));
}
2026-10-05 15:01:32 +00:00
const captured = previous
? Result.ok(previous.specification)
: captureSpecification(input, companyId, context);
if (!captured.isSuccess) {
return captured;
}
const specification = captured.data;
const compatibleInput = withMailboxIntegration(input, context);
const templateKey = context.catalog.definitions
.find((item) => item.id.toPrimitive() === input.templateId.toLowerCase())
?.stockKey.getOrUndefined();
if (templateKey === "template:access" && compatibleInput.integration?.kind !== "access") {
return Result.fail(new ResourceCatalogError("REFERENCE_UNAVAILABLE"));
}
const references = validateReferences(compatibleInput, context);
if (!references.isSuccess) {
return references;
}
const values = ResourceValues.create(compatibleInput, specification);
return values.isSuccess ? Result.ok({ specification, values: values.data }) : values;
}
function captureSpecification(
input: ResourceInput,
companyId: UniqueID,
context: InventoryContext
) {
const template = context.catalog
.visible(Maybe.some(companyId))
.find((item) => item.id.toPrimitive() === input.templateId.toLowerCase());
if (
!template ||
template.values.data.kind !== "template" ||
!context.catalog.active(template, Maybe.some(companyId))
) {
return Result.fail(new ResourceCatalogError("TEMPLATE_UNAVAILABLE"));
}
const fields = template.values.data.fields.map((binding) => {
const field = context.catalog.definitions.find(
(item) => item.id.toPrimitive() === binding.fieldId
);
if (!field || field.values.data.kind !== "field") {
throw new Error("Plantilla persistida inconsistente.");
2026-10-05 11:13:51 +00:00
}
2026-10-05 15:01:32 +00:00
return {
fieldId: field.id.toPrimitive(),
name: field.values.data.name,
type: field.values.data.type,
unit: field.values.data.unit,
choices: [...field.values.data.choices],
required: binding.required,
};
});
const created = ResourceSpecification.create({
templateId: template.id.toPrimitive(),
templateName: template.values.data.name,
fields,
});
if (!created.isSuccess) {
return created;
}
return created;
}
function withMailboxIntegration(input: ResourceInput, context: InventoryContext): ResourceInput {
const compatibleInput = { ...input };
if (!compatibleInput.integration) {
const template = context.catalog.definitions.find(
(item) => item.id.toPrimitive() === input.templateId.toLowerCase()
);
if (template?.stockKey.getOrUndefined() === "template:mailbox") {
const addressFieldId = context.catalog.definitions
.find((item) => item.stockKey.getOrUndefined() === "field:email")
?.id.toPrimitive();
const contextFieldId = context.catalog.definitions
.find((item) => item.stockKey.getOrUndefined() === "field:context")
?.id.toPrimitive();
if (!(addressFieldId && contextFieldId)) {
throw new Error("Campos de buzón ausentes.");
2026-10-05 11:13:51 +00:00
}
2026-10-05 15:01:32 +00:00
compatibleInput.integration = {
kind: "mailbox",
addressFieldId,
contextFieldId,
mailboxKind: "corporate",
accountId: null,
2026-10-05 11:13:51 +00:00
};
}
}
2026-10-05 15:01:32 +00:00
return compatibleInput;
}
function validateReferences(compatibleInput: ResourceInput, context: InventoryContext) {
const integration = compatibleInput.integration;
if (integration) {
const expected =
integration.kind === "mailbox"
? ([[integration.accountId, "account"]] as const)
: ([
[integration.resourceTypeId, "resource_type"],
[integration.systemId, "system"],
[integration.environmentId, "environment"],
] as const);
for (const [id, kind] of expected) {
if (
id &&
!context.references.some((item) => item.id === id.toLowerCase() && item.kind === kind)
) {
return Result.fail(new ResourceCatalogError("REFERENCE_UNAVAILABLE"));
}
}
if (
integration.kind === "access" &&
integration.environmentId &&
!context.references.some(
(item) =>
item.id === integration.environmentId?.toLowerCase() &&
item.systemId === integration.systemId
)
) {
return Result.fail(new ResourceCatalogError("REFERENCE_UNAVAILABLE"));
}
}
return Result.ok(true);
2026-10-05 11:13:51 +00:00
}