metis-desk/modules/companies/src/api/application/directory-context-plan.ts

113 lines
3.7 KiB
TypeScript
Raw Normal View History

2026-10-20 11:20:22 +00:00
import type { IDirectoryContextWriter } from "@metis/resources/services";
import type { UniqueID } from "@repo/rdx-ddd";
import { Maybe, Result } from "@repo/rdx-utils";
import type { AccessDefinition } from "../domain/access/access-definition";
import { AccessError } from "../domain/access/access-error";
import type { AuditContext } from "../domain/access/access-item.entity";
import { AccessItem } from "../domain/access/access-item.entity";
import { AccessValues } from "../domain/access/access-values.vo";
import type { AccessContext, AccessWorkspace } from "../domain/access/access-workspace.aggregate";
import type { AccessSnapshot } from "./access.repository";
export type DirectoryContextSnapshot = AccessSnapshot & {
directorySystems: readonly string[];
directoryEnvironments: readonly string[];
};
function createContextItem(
workspace: AccessWorkspace,
context: AccessContext,
companyId: UniqueID,
audit: AuditContext,
data: Extract<AccessDefinition, { kind: "system" | "environment" }>
) {
const values = AccessValues.create(data);
if (!values.isSuccess) {
return values;
}
const item = AccessItem.create(Maybe.some(companyId), values.data, audit);
const changed = workspace.save(item, context);
return changed.isSuccess ? Result.ok({ workspace: changed.data, item }) : changed;
}
/** Preparación pura: un contexto nuevo es dedicado; uno existente nunca se sustituye ni se mueve. */
export function planDirectoryContext(
snapshot: DirectoryContextSnapshot,
input: Parameters<IDirectoryContextWriter["ensure"]>[0]
) {
if (!snapshot.workspace.companyId.getOrUndefined()?.equals(input.companyId)) {
return Result.fail(new AccessError("SCOPE_MISMATCH"));
}
let workspace = snapshot.workspace;
const audit = { actorId: input.actorId, recordedAt: input.recordedAt };
const systemId = snapshot.directorySystems[0];
let system = systemId
? workspace.items.find((item) => item.id.toPrimitive() === systemId)
: undefined;
if (systemId && !system) {
return Result.fail(new AccessError("SCOPE_MISMATCH"));
}
if (!system) {
const created = createContextItem(workspace, snapshot.context, input.companyId, audit, {
kind: "system",
name: "Active Directory",
active: true,
});
if (!created.isSuccess) {
return created;
}
workspace = created.data.workspace;
system = created.data.item;
}
if (system.values.data.kind !== "system" || !system.values.data.active) {
return Result.fail(new AccessError("INACTIVE_TARGET"));
}
return planEnvironment(workspace, snapshot, input, system.id.toPrimitive(), audit);
}
function planEnvironment(
workspace: AccessWorkspace,
snapshot: DirectoryContextSnapshot,
input: Parameters<IDirectoryContextWriter["ensure"]>[0],
systemId: string,
audit: AuditContext
) {
const environmentId = input.environmentId;
if (environmentId) {
const environment = workspace.items.find((item) => item.id.toPrimitive() === environmentId);
if (
!snapshot.directoryEnvironments.includes(environmentId) ||
environment?.values.data.kind !== "environment" ||
environment.values.data.systemId !== systemId ||
!environment.values.data.active
) {
return Result.fail(new AccessError("SCOPE_MISMATCH"));
}
return Result.ok({ workspace, environmentId, systemId });
}
const created = createContextItem(workspace, snapshot.context, input.companyId, audit, {
kind: "environment",
name: input.dnsName,
systemId,
active: true,
});
return created.isSuccess
? Result.ok({
workspace: created.data.workspace,
environmentId: created.data.item.id.toPrimitive(),
systemId,
})
: created;
}