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"; import { ResourceSpecification, ResourceValues } from "../domain/value-objects/resource-values.vo"; import { directoryDomainInput } from "./directory-domain-input"; import type { InventoryContext } from "./resource.repository"; import { mapSmbAccessInput } from "./smb-access-input"; 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")); } const captured = previous ? Result.ok(previous.specification) : captureResourceSpecification(input, companyId, context); if (!captured.isSuccess) { return captured; } const specification = captured.data; const directory = directoryDomainInput(input, context.catalog); if (!directory.isSuccess) { return directory; } const normalized = directory.data ? { ...input, characteristics: { ...directory.data.characteristics, [directory.data.dnsId]: directory.data.identity.dnsName, [directory.data.netbiosId]: directory.data.identity.netbiosName ?? "", }, } : input; const mailboxInput = withMailboxIntegration(normalized, context); const integrated = mapSmbAccessInput(mailboxInput, context, previous); if (!integrated.isSuccess) { return integrated; } const compatibleInput = integrated.data; 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; } export function captureResourceSpecification( input: Pick, companyId: UniqueID, context: Pick, options: { existing?: boolean } = {} ) { const template = context.catalog .visible(Maybe.some(companyId)) .find((item) => item.id.toPrimitive() === input.templateId.toLowerCase()); if ( !template || template.values.data.kind !== "template" || !(options.existing || 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."); } 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, ...(binding.sectionId ? { sectionId: binding.sectionId } : {}), }; }); const created = ResourceSpecification.create({ templateId: template.id.toPrimitive(), templateName: template.values.data.name, ...(template.values.data.sections ? { sections: [...template.values.data.sections] } : {}), 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."); } compatibleInput.integration = { kind: "mailbox", addressFieldId, contextFieldId, mailboxKind: "corporate", accountId: null, }; } } 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); }