import assert from "node:assert/strict"; import type { Sequelize } from "sequelize"; import { AccessUseCases } from "../../../modules/companies/src/api/application/access.use-cases"; import { FolderMappingUseCases } from "../../../modules/companies/src/api/application/folder-mapping.use-cases"; import { buildFolderResponse } from "../../../modules/companies/src/api/application/folder-mapping-response.builder"; import { WorkProfileUseCases } from "../../../modules/companies/src/api/application/work-profile.use-cases"; import { AccessPersistenceMapper, SequelizeAccessRepository, } from "../../../modules/companies/src/api/infrastructure/persistence/access-persistence"; import { CompanyPersistenceMapper } from "../../../modules/companies/src/api/infrastructure/persistence/company-persistence.mapper"; import { migrateFolderMappings } from "../../../modules/companies/src/api/infrastructure/persistence/folder-mapping-migration"; import { SequelizeCompanyRepository } from "../../../modules/companies/src/api/infrastructure/persistence/sequelize-company.repository"; import { SequelizeFolderMappingRepository } from "../../../modules/companies/src/api/infrastructure/persistence/sequelize-folder-mapping.repository"; import { SequelizeWorkProfileRepository } from "../../../modules/companies/src/api/infrastructure/persistence/sequelize-work-profile.repository"; import { migrateWorkProfiles } from "../../../modules/companies/src/api/infrastructure/persistence/work-profile-migration"; import { UniqueID } from "../../../packages/rdx-ddd/src/index"; import type { prepareMembershipFixture } from "./asset-directory-memberships.fixture"; /** Comprueba un mapeo persistido real; todos los datos pertenecen a la compañía de fixture. */ export async function verifyFolderCompatibility( database: Sequelize, fixture: Awaited>, company: string, actor: string ) { await migrateWorkProfiles(database); await migrateFolderMappings(database); const personId = UniqueID.generateNewID().toPrimitive(); const asset = await fixture.asset(company, "desktop"); const inventory = { list: async () => [{ id: asset.id, notRetired: true, isProfileHost: true }] }; const access = new AccessUseCases( new SequelizeAccessRepository( database, new SequelizeCompanyRepository(database, new CompanyPersistenceMapper()), new AccessPersistenceMapper() ) ); const profiles = new WorkProfileUseCases(new SequelizeWorkProfileRepository(database, inventory)); const folders = new FolderMappingUseCases( new SequelizeFolderMappingRepository(database, inventory) ); const loaded = await fixture.resourceUseCases.get(company); assert.ok(loaded.isSuccess); const resource = loaded.data.resources.find( (item) => item.values.toPrimitive().integration?.kind === "access" ); assert.ok(resource); const values = resource.values.toPrimitive(); assert.ok(values.integration?.kind === "access"); const { referenceFieldId, resourceTypeId } = values.integration; const originalPath = values.characteristics[referenceFieldId]; assert.equal(typeof originalPath, "string"); assert.ok(typeof originalPath === "string"); await database.query( "INSERT INTO company_contacts (id,companyId,name,isContact,active) VALUES (:personId,:company,'SMB person fixture',0,1)", { replacements: { personId, company } } ); try { const permission = await access.save( company, undefined, { kind: "permission", name: "SMB read fixture", active: true, description: null, resourceTypeId, }, actor ); assert.ok(permission.isSuccess); const permissionItem = permission.data.workspace.items.find( (item) => item.values.data.kind === "permission" ); assert.ok(permissionItem); const need = await access.save( company, undefined, { kind: "need", personId, resourceId: resource.id.toPrimitive(), permissionIds: [permissionItem.id.toPrimitive()], startDate: "2020-01-01", endDate: null, notes: null, }, actor ); assert.ok(need.isSuccess); const needItem = need.data.workspace.items.find((item) => item.values.data.kind === "need"); assert.ok(needItem); const profile = await profiles.save( company, undefined, { name: "SMB profile fixture", personId, assetId: asset.id.toPrimitive(), accountId: null, active: true, notes: null, }, actor ); assert.ok(profile.isSuccess); const mapping = await folders.save( company, undefined, { profileId: profile.data.profile.id.toPrimitive(), needId: needItem.id.toPrimitive(), path: originalPath, driveLetter: "F:", state: "configured", notes: null, }, actor ); assert.ok(mapping.isSuccess); const before = buildFolderResponse(mapping.data.mapping, mapping.data.context); assert.equal(before.needsReview, false); assert.equal(before.permissionsCovered, false); const changed = await fixture.resourceUseCases.save( company, resource.id.toPrimitive(), { ...values, characteristics: { ...values.characteristics, [referenceFieldId]: String.raw`\\NAS\NuevaDireccion`, }, }, actor ); assert.ok(changed.isSuccess); const after = await folders.get(company); assert.ok(after.isSuccess); const persisted = after.data.mappings.find((item) => item.id.equals(mapping.data.mapping.id)); assert.ok(persisted); const response = buildFolderResponse(persisted, after.data); assert.deepEqual(response.values, before.values); assert.deepEqual(response.history, before.history); assert.equal(response.values.driveLetter, "F"); assert.equal(response.needsReview, true); assert.equal(response.permissionsCovered, false); const blocked = await fixture.resourceUseCases.remove(company, resource.id.toPrimitive()); assert.ok(!blocked.isSuccess); assert.equal(blocked.error.code, "RESOURCE_IN_USE"); } finally { for (const [table, column, parent] of [ ["folder_mapping_revisions", "mappingId", "folder_mappings"], ["work_profile_revisions", "profileId", "work_profiles"], ]) { await database.query( `DELETE FROM ${table} WHERE ${column} IN (SELECT id FROM ${parent} WHERE companyId=:company)`, { replacements: { company } } ); } for (const table of ["folder_mappings", "work_profiles"]) { await database.query(`DELETE FROM ${table} WHERE companyId=:company`, { replacements: { company }, }); } for (const kind of ["need", "permission"]) { if (kind === "need") { await database.query( "DELETE p FROM access_need_permissions p JOIN access_items i ON i.id=p.ownerId JOIN access_workspaces w ON w.id=i.workspaceId WHERE w.companyId=:company", { replacements: { company } } ); await database.query( "DELETE p FROM access_need_revision_permissions p JOIN access_revisions r ON r.id=p.ownerId JOIN access_items i ON i.id=r.itemId JOIN access_workspaces w ON w.id=i.workspaceId WHERE w.companyId=:company", { replacements: { company } } ); } await database.query( `DELETE v FROM access_${kind}_values v JOIN access_items i ON i.id=v.ownerId JOIN access_workspaces w ON w.id=i.workspaceId WHERE w.companyId=:company`, { replacements: { company } } ); await database.query( `DELETE v FROM access_${kind}_revision_values v JOIN access_revisions r ON r.id=v.ownerId JOIN access_items i ON i.id=r.itemId JOIN access_workspaces w ON w.id=i.workspaceId WHERE w.companyId=:company`, { replacements: { company } } ); } await database.query("DELETE FROM access_person_references WHERE personId=:personId", { replacements: { personId }, }); for (const table of ["access_references", "access_revisions"]) { const column = "itemId"; await database.query( `DELETE v FROM ${table} v JOIN access_items i ON i.id=v.${column} JOIN access_workspaces w ON w.id=i.workspaceId WHERE w.companyId=:company AND i.kind IN ('need','permission')`, { replacements: { company } } ); } await database.query( "DELETE i FROM access_items i JOIN access_workspaces w ON w.id=i.workspaceId WHERE w.companyId=:company AND i.kind IN ('need','permission')", { replacements: { company } } ); await database.query("DELETE FROM company_contacts WHERE id=:personId AND companyId=:company", { replacements: { personId, company }, }); } }