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"; }