- Asociar entornos locales con activos y conservar su trazabilidad. - Registrar la cuenta de acceso del mapeo con historial de cambios. - Calcular cobertura documental específica sin alterar la cobertura general. - Añadir migraciones, validaciones, endpoints protegidos, pruebas y documentación.
114 lines
3.7 KiB
TypeScript
114 lines
3.7 KiB
TypeScript
import { projectAccess } from "../domain/access/access-projection";
|
|
import type { FolderMappingValues } from "../domain/value-objects/folder-mapping-values.vo";
|
|
|
|
import type { FolderContext } from "./folder-mapping.repository";
|
|
import { folderAvailable, folderReferences } from "./folder-mapping-policy";
|
|
|
|
/** Una cuenta compartida requiere también asociación documental con la persona del perfil. */
|
|
export function folderAccountUsable(values: FolderMappingValues, context: FolderContext) {
|
|
const id = values.accessAccountId.getOrUndefined()?.toPrimitive();
|
|
const profile = context.profiles.find((item) => item.id.equals(values.profileId));
|
|
const account = context.items.find((item) => item.id.toPrimitive() === id)?.values.data;
|
|
|
|
if (
|
|
!profile ||
|
|
account?.kind !== "account" ||
|
|
!account.active ||
|
|
(account.expiresOn !== null && account.expiresOn < context.today)
|
|
) {
|
|
return false;
|
|
}
|
|
const catalogActive = [account.systemId, account.environmentId].every(
|
|
(key) =>
|
|
key === null ||
|
|
context.items.some(
|
|
(item) =>
|
|
item.id.toPrimitive() === key && "active" in item.values.data && item.values.data.active
|
|
)
|
|
);
|
|
|
|
return (
|
|
catalogActive &&
|
|
context.items.some((item) => {
|
|
const data = item.values.data;
|
|
|
|
return (
|
|
data.kind === "account_person" &&
|
|
data.accountId === id &&
|
|
data.personId === profile.values.personId.toPrimitive() &&
|
|
data.startDate <= context.today &&
|
|
data.endDate === null &&
|
|
(data.configuration === "pending" ||
|
|
data.configuration === "configured" ||
|
|
data.configuration === null)
|
|
);
|
|
})
|
|
);
|
|
}
|
|
|
|
/** Restringe Coverage a vías cuya relación account_person identifica exactamente la cuenta elegida. */
|
|
export function folderAccountCoverage(
|
|
values: FolderMappingValues,
|
|
context: FolderContext
|
|
): "unknown" | "covered" | "not-covered" {
|
|
const accountId = values.accessAccountId.getOrUndefined()?.toPrimitive();
|
|
|
|
if (!accountId) {
|
|
return "unknown";
|
|
}
|
|
if (!(folderAvailable(values, context) && folderAccountUsable(values, context))) {
|
|
return "not-covered";
|
|
}
|
|
const references = folderReferences(values, context);
|
|
|
|
if (!references) {
|
|
return "not-covered";
|
|
}
|
|
const accountPeople = new Set(
|
|
context.items
|
|
.filter(
|
|
(item) =>
|
|
item.values.data.kind === "account_person" &&
|
|
item.values.data.accountId === accountId &&
|
|
item.values.data.personId === references.need.personId
|
|
)
|
|
.map((item) => item.id.toPrimitive())
|
|
);
|
|
const current = context.items.filter((item) => {
|
|
const data = item.values.data;
|
|
|
|
if ("startDate" in data && data.startDate > context.today) {
|
|
return false;
|
|
}
|
|
if (data.kind !== "coverage") {
|
|
return true;
|
|
}
|
|
if (!accountPeople.has(data.accountPersonId) || data.needId !== values.needId.toPrimitive()) {
|
|
return false;
|
|
}
|
|
const grant = context.items.find((entry) => entry.id.toPrimitive() === data.grantId)?.values
|
|
.data;
|
|
|
|
if (grant?.kind !== "grant" || grant.resourceId !== references.need.resourceId) {
|
|
return false;
|
|
}
|
|
if (grant.accountId !== null) {
|
|
return grant.accountId === accountId && data.membershipId === null;
|
|
}
|
|
const membership = context.items.find((entry) => entry.id.toPrimitive() === data.membershipId)
|
|
?.values.data;
|
|
|
|
return (
|
|
membership?.kind === "membership" &&
|
|
membership.accountId === accountId &&
|
|
membership.groupId === grant.groupId
|
|
);
|
|
});
|
|
|
|
return projectAccess(current, context.people, context.today).coverage.some(
|
|
(item) => item.needId === values.needId.toPrimitive() && item.covered
|
|
)
|
|
? "covered"
|
|
: "not-covered";
|
|
}
|