* fix(web): simplify inventory administration menu * fix(web): remove legacy imports and function catalog routes * fix(web): remove redundant inspections lifecycle legend * feat(inventory): distinguish physical instances from structural records * fix(dashboard): align inventory and act follow-up metrics * fix(web): align dashboard summary contract * fix(web): clarify dashboard act and report concepts * feat(inventory): mark field-created records as real instances * feat(inventory): map physical instance flag on asset entity * fix(inventory): keep field yacimientos structural * feat(inventory): classify future concrete instances at database level * fix(inventory): count only installation and subinstallation instances * feat(inventory): add authoritative F5 source snapshot * feat(inventory): preload authoritative territory model * feat(inventory): preload authoritative technical catalog * fix(findings): use only authoritative F5 family catalog * fix(inventory): preserve non-hierarchical operator snapshot compatibility * feat(inventory): add inventory-only asset filter * feat(inventory): add inventory-only tree filter * feat(inventory): add inventory browser query contract * feat(inventory): add area-owned inventory browser * feat(inventory): expose area-owned inventory browser * refactor(inventory): remove function catalog and add inventory browser * fix(inventory): make operator relation temporal and non-owning * feat(web): add inventory browser API client * feat(inventory): extend inventory browser filters * feat(inventory): add real inventory list endpoint logic * feat(inventory): expose real inventory list * feat(web): add real inventory list client * refactor(web): make inventory hierarchy area-owned * fix(web): show only real inventory instances * fix(web): style act follow-up tabs and F5 inventory context * fix(web): load F5 flow styles * fix(inventory): apply area-owned operational guard on F5 up * fix(inventory): treat company on asset as non-owning creation snapshot * fix(inventory): resolve field inventory by area hierarchy, not company ownership * fix(inventory): preserve custom catalog and apply authoritative universal findings * fix(inventory): harden authoritative catalog migration checks * fix(inventory): make authoritative territory preload safely reversible * feat(inventory): allow independent company master creation * fix(inventory): make guided creation area-owned and support companies * feat(web): expose independent company master in inventory setup * feat(web): create companies independently from physical inventory hierarchy * fix(inventory): merge by physical area and preserve sealed documents * test(inventory): lock F5 authoritative model and merge invariants * feat(inventory): add family administration DTOs * feat(inventory): administer installation and subinstallation classifications * feat(inventory): expose family classification administration * feat(web): add inventory classification administration API * fix(web): configure finding applicability by inventory classification * fix(web): redefine inventory configuration around hierarchy classifications and columns * chore(release): identify F5 inventory model * chore(release): bump API for F5 inventory model * test(release): expect F5 health metadata * chore(release): align WEB package with F5 inventory cut * chore(release): expose F5 WEB phase * test(dashboard): expect inspector activity and act follow-up metrics * test(dashboard): route F5 summary query mocks explicitly * ci: rehearse all migrations on clean PostGIS before merge * ci: prove F5 migrations revert and reapply cleanly * test(f5): align operational navigation contract * test(f5): align operator lifecycle with area-owned inventory * test(f5): make merge compatibility area-based * test(f5): distinguish literal and normalized yacimiento counts * test(f5): model normalized yacimiento collision explicitly * ci(f5): bootstrap historical admin prerequisite in clean migration rehearsal * ci(f5): bypass irreversible historical reset in clean rehearsal * fix(f5): make territory SQL parameter types explicit * fix(f5): guarantee canonical inventory hierarchy before territory preload * ci(f5): include canonical hierarchy migration in rollback gate * fix(f5): type relation backup markers explicitly * fix(f5): make catalog SQL text parameter types explicit
57 lines
2.7 KiB
TypeScript
57 lines
2.7 KiB
TypeScript
import 'reflect-metadata';
|
|
import assert from 'node:assert/strict';
|
|
import test from 'node:test';
|
|
import { readFileSync } from 'node:fs';
|
|
|
|
const migration = readFileSync(
|
|
'src/database/migrations/1789844600000-phase-f3-1-asset-chronological-merge.ts',
|
|
'utf8',
|
|
);
|
|
const service = readFileSync('src/asset-master/inventory-merge.service.ts', 'utf8');
|
|
const controller = readFileSync('src/asset-master/inventory-merge.controller.ts', 'utf8');
|
|
|
|
test('F3.1 registra cada fusión como evento append-only con snapshots', () => {
|
|
assert.match(migration, /CREATE TABLE asset_merges/);
|
|
assert.match(migration, /source_snapshot jsonb NOT NULL/);
|
|
assert.match(migration, /canonical_snapshot jsonb NOT NULL/);
|
|
assert.match(migration, /UNIQUE \(source_asset_id\)/);
|
|
assert.match(migration, /BEFORE UPDATE OR DELETE ON asset_merges/);
|
|
assert.match(migration, /append-only/);
|
|
});
|
|
|
|
test('F3.1/F5 sólo permite fusionar Instalaciones o Subinstalaciones compatibles dentro de la misma Área física', () => {
|
|
assert.match(service, /MERGEABLE_TYPES = new Set\(\['instalacion', 'subinstalacion'\]\)/);
|
|
assert.match(service, /INVENTORY_MERGE_TYPE_INVALID/);
|
|
assert.match(service, /resolvePhysicalAreaId/);
|
|
assert.match(service, /INVENTORY_MERGE_AREA_MISMATCH/);
|
|
assert.match(service, /INVENTORY_MERGE_PARENT_MISMATCH/);
|
|
assert.match(service, /INVENTORY_MERGE_CHILD_FAMILY_CONFLICT/);
|
|
assert.doesNotMatch(service, /source\.operatorCompanyId\s*!==\s*canonical\.operatorCompanyId/);
|
|
});
|
|
|
|
test('F3.1 preserva referencias históricas y sólo reubica hijos actuales', () => {
|
|
assert.match(service, /historyPolicy: 'HISTORICAL_REFERENCES_PRESERVED'/);
|
|
assert.match(service, /historicalReferencesRewritten: false/);
|
|
assert.doesNotMatch(service, /UPDATE\s+inspection_findings/i);
|
|
assert.doesNotMatch(service, /UPDATE\s+inspection_act_assets/i);
|
|
assert.doesNotMatch(service, /UPDATE\s+inspection_visit_assets/i);
|
|
assert.match(service, /Reparentado por fusión cronológica/);
|
|
assert.match(service, /AssetVersionChangeType\.UPDATED/);
|
|
});
|
|
|
|
test('F3.1 expone estado/merge en WEB y conciliación de alta nacida en la inspección para APK', () => {
|
|
assert.match(controller, /:id\/merge-status/);
|
|
assert.match(controller, /:id\/merge/);
|
|
assert.match(controller, /:assetId\/merge/);
|
|
assert.match(controller, /assets\.create/);
|
|
assert.match(controller, /inspections\.execute/);
|
|
assert.match(service, /FIELD_MERGE_SOURCE_MUST_BE_DISCOVERY/);
|
|
assert.match(service, /assertMobileInspector\(principal\)/);
|
|
});
|
|
|
|
test('F3.1 resuelve cadenas de merge hacia un canónico final y detecta ciclos', () => {
|
|
assert.match(service, /WITH RECURSIVE chain/);
|
|
assert.match(service, /INVENTORY_MERGE_CYCLE/);
|
|
assert.match(service, /aliasesFor/);
|
|
});
|