From ba79fbf9ae068c5acdecf799a45797640986f9d2 Mon Sep 17 00:00:00 2001 From: enlineawork Date: Sat, 12 Sep 2026 11:32:50 -0300 Subject: [PATCH 1/3] fix(api): desacoplar dossier territorial de merge --- .../asset-master/merged-inventory-dossier.service.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/api-v3/src/asset-master/merged-inventory-dossier.service.ts b/api-v3/src/asset-master/merged-inventory-dossier.service.ts index 7309767..a475880 100644 --- a/api-v3/src/asset-master/merged-inventory-dossier.service.ts +++ b/api-v3/src/asset-master/merged-inventory-dossier.service.ts @@ -5,6 +5,8 @@ import { InventoryMergeService } from './inventory-merge.service'; type LooseRecord = Record; +const MERGEABLE_DOSSIER_TYPES = new Set(['instalacion', 'subinstalacion']); + function dedupeById(items: T[]): T[] { const seen = new Set(); const result: T[] = []; @@ -34,6 +36,16 @@ export class MergedInventoryDossierService { ) {} async dossier(requestedAssetId: string): Promise> { + const requestedAsset = await this.assets.getById(requestedAssetId); + const requestedTypeCode = requestedAsset.type.code.trim().toLowerCase(); + + // La conciliación/fusión existe sólo para Instalaciones y Subinstalaciones. + // Los registros territoriales (Departamento, Área, Yacimiento) deben poder + // abrir su Actividad sin depender del subsistema de merge. + if (!MERGEABLE_DOSSIER_TYPES.has(requestedTypeCode)) { + return await this.assets.dossier(requestedAssetId) as Record; + } + const mergeStatus = await this.merges.status(requestedAssetId) as LooseRecord; const canonical = mergeStatus.canonical as LooseRecord; const requested = mergeStatus.requested as LooseRecord; From 350e26566f2cb2e41e659104fedc69888a97f749 Mon Sep 17 00:00:00 2001 From: enlineawork Date: Sat, 12 Sep 2026 11:33:45 -0300 Subject: [PATCH 2/3] =?UTF-8?q?fix(web):=20no=20bloquear=20Actividad=20por?= =?UTF-8?q?=20estado=20de=20fusi=C3=B3n?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- web-v2/src/features/assets/AssetDossierPanel.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/web-v2/src/features/assets/AssetDossierPanel.tsx b/web-v2/src/features/assets/AssetDossierPanel.tsx index 2ed5409..e907562 100644 --- a/web-v2/src/features/assets/AssetDossierPanel.tsx +++ b/web-v2/src/features/assets/AssetDossierPanel.tsx @@ -81,10 +81,12 @@ export function AssetDossierPanel({ assetId }: { assetId: string }) { const load = () => { setLoading(true); setError(''); + setMergeStatus(null); Promise.all([ getAssetDossier(assetId), getAsset(assetId), - getInventoryMergeStatus(assetId), + // La conciliación es auxiliar: nunca debe bloquear la Actividad del Inventario. + getInventoryMergeStatus(assetId).catch(() => null), ]) .then(([loadedDossier, loadedAsset, loadedMerge]) => { setDossier(loadedDossier as ExtendedDossier); From 0b21e6bc500b5d389bfba5feb3063f64c8b9e92c Mon Sep 17 00:00:00 2001 From: enlineawork Date: Sat, 12 Sep 2026 11:33:59 -0300 Subject: [PATCH 3/3] test(f7): cubrir Actividad de Yacimiento sin dependencia de merge --- .../f7-yacimiento-activity-dossier.test.ts | 25 +++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 api-v3/test/unit/f7-yacimiento-activity-dossier.test.ts diff --git a/api-v3/test/unit/f7-yacimiento-activity-dossier.test.ts b/api-v3/test/unit/f7-yacimiento-activity-dossier.test.ts new file mode 100644 index 0000000..bdbffc7 --- /dev/null +++ b/api-v3/test/unit/f7-yacimiento-activity-dossier.test.ts @@ -0,0 +1,25 @@ +import 'reflect-metadata'; +import assert from 'node:assert/strict'; +import test from 'node:test'; +import { readFileSync } from 'node:fs'; + +const mergedDossier = readFileSync('src/asset-master/merged-inventory-dossier.service.ts', 'utf8'); +const dossierPanel = readFileSync('../web-v2/src/features/assets/AssetDossierPanel.tsx', 'utf8'); +const simpleDetail = readFileSync('../web-v2/src/pages/SimpleInventoryDetailPage.tsx', 'utf8'); + +test('F7 mantiene Actividad disponible para Yacimiento', () => { + assert.match(simpleDetail, /kind === 'YACIMIENTO'/); + assert.match(simpleDetail, /setTab\('activity'\)/); + assert.match(simpleDetail, /AssetDossierPanel assetId=\{asset\.id\}/); +}); + +test('F7 no hace depender el dossier territorial del subsistema de fusión', () => { + assert.match(mergedDossier, /MERGEABLE_DOSSIER_TYPES = new Set\(\['instalacion', 'subinstalacion'\]\)/); + assert.match(mergedDossier, /if \(!MERGEABLE_DOSSIER_TYPES\.has\(requestedTypeCode\)\)/); + assert.match(mergedDossier, /return await this\.assets\.dossier\(requestedAssetId\)/); +}); + +test('F7 la consulta auxiliar de merge nunca bloquea la carga de Actividad', () => { + assert.match(dossierPanel, /getInventoryMergeStatus\(assetId\)\.catch\(\(\) => null\)/); + assert.match(dossierPanel, /getAssetDossier\(assetId\)/); +});