import { Result } from "@repo/rdx-utils"; import type { SoftwareInstallation } from "../domain/software-installation.aggregate"; import type { SoftwareInstallationInput } from "../domain/software-installation-values"; import { SoftwareInstallationError } from "../domain/software-installation-values"; import { SoftwareInstallationValues } from "../domain/value-objects/software-installation-values.vo"; import type { SoftwareContext } from "./software-installation.repository"; import { softwareAvailable, softwareReferences } from "./software-installation-policy"; export function mapSoftwareInput( input: SoftwareInstallationInput, context: SoftwareContext, previous?: SoftwareInstallation ) { const parsed = SoftwareInstallationValues.create(input); if (!parsed.isSuccess) { return parsed; } const values = parsed.data; if (previous && !previous.values.sameTarget(values)) { return Result.fail(new SoftwareInstallationError("SOFTWARE_TARGET_IMMUTABLE")); } if (!softwareReferences(values, context)) { return Result.fail(new SoftwareInstallationError("SOFTWARE_REFERENCE_NOT_FOUND")); } const reconfiguring = !previous || previous.values.state !== values.state || previous.values.version.getOrUndefined() !== values.version.getOrUndefined(); if ( ["pending", "configured"].includes(values.state) && reconfiguring && !softwareAvailable(values, context) ) { return Result.fail(new SoftwareInstallationError("SOFTWARE_REFERENCE_UNAVAILABLE")); } const others = context.configurations.filter( (item) => !(item.id.equals(previous?.id) || item.values.closed) ); if (!values.closed && others.some((item) => item.values.sameTarget(values))) { return Result.fail(new SoftwareInstallationError("SOFTWARE_ALREADY_OPEN")); } return parsed; }