113 lines
3.7 KiB
TypeScript
113 lines
3.7 KiB
TypeScript
|
|
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;
|
||
|
|
}
|