F5 · Inventario operativo, territorio y catálogo autorizado (#25)
* 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
This commit is contained in:
@@ -2,27 +2,28 @@ import { strict as assert } from 'node:assert';
|
||||
import test from 'node:test';
|
||||
import { DashboardService } from '../../src/dashboard/dashboard.service';
|
||||
|
||||
test('DashboardService returns F4 operational counts and recent activity consistently', async () => {
|
||||
test('DashboardService returns F5 operational counts and inspector activity consistently', async () => {
|
||||
const recent = [{
|
||||
id: 'event-id',
|
||||
occurredAt: new Date('2026-08-13T12:00:00.000Z'),
|
||||
actorUsername: 'admin',
|
||||
action: 'AUTH_LOGIN_SUCCESS',
|
||||
entityType: 'auth_session',
|
||||
entityId: 'session-id',
|
||||
occurredAt: new Date('2026-09-08T12:00:00.000Z'),
|
||||
actorUsername: 'inspector1',
|
||||
action: 'INSPECTION_STARTED',
|
||||
entityType: 'inspection_visit',
|
||||
entityId: 'visit-id',
|
||||
}];
|
||||
const manager = {
|
||||
query: async (sql: string) => {
|
||||
if (sql.includes('COUNT(*) FROM users')) {
|
||||
return [{
|
||||
activeUsers: '4', inactiveUsers: '2', activeSessions: '3',
|
||||
totalAssets: '12', assetsNeedValidation: '4', assetsWithoutGeometry: '6', plannedInspections: '2',
|
||||
openFindings: '8', findingsWithoutControlDate: '5', overdueControls: '2', controlsNext30Days: '3',
|
||||
totalAssets: '0', assetsNeedValidation: '0', assetsWithoutGeometry: '0', plannedInspections: '2',
|
||||
openFindings: '8', actsInFollowUp: '6', findingsWithoutControlDate: '5', overdueControls: '2', controlsNext30Days: '3',
|
||||
reportsWorking: '1', reportsOfficialized: '2', sealedActsWithoutReport: '4',
|
||||
}];
|
||||
}
|
||||
if (sql.includes('FROM inspection_findings finding')) return [];
|
||||
return recent;
|
||||
if (sql.includes('FROM audit_events event')) return recent;
|
||||
if (sql.includes('next_control_on AS "nextControlOn"')) return [];
|
||||
throw new Error(`Unexpected DashboardService query in test: ${sql}`);
|
||||
},
|
||||
};
|
||||
const dataSource = {
|
||||
@@ -31,14 +32,15 @@ test('DashboardService returns F4 operational counts and recent activity consist
|
||||
|
||||
const result = await new DashboardService(dataSource as never).summary();
|
||||
assert.deepEqual(result.counts, {
|
||||
totalAssets: 12,
|
||||
assetsNeedValidation: 4,
|
||||
assetsWithoutGeometry: 6,
|
||||
totalAssets: 0,
|
||||
assetsNeedValidation: 0,
|
||||
assetsWithoutGeometry: 0,
|
||||
plannedInspections: 2,
|
||||
activeUsers: 4,
|
||||
inactiveUsers: 2,
|
||||
activeSessions: 3,
|
||||
openFindings: 8,
|
||||
actsInFollowUp: 6,
|
||||
findingsWithoutControlDate: 5,
|
||||
overdueControls: 2,
|
||||
controlsNext30Days: 3,
|
||||
@@ -46,7 +48,8 @@ test('DashboardService returns F4 operational counts and recent activity consist
|
||||
reportsOfficialized: 2,
|
||||
sealedActsWithoutReport: 4,
|
||||
});
|
||||
assert.equal(result.recentAudit, recent);
|
||||
assert.deepEqual(result.recentInspectorActivity, recent);
|
||||
assert.equal('recentAudit' in result, false);
|
||||
assert.deepEqual(result.upcomingControls, []);
|
||||
assert.equal(typeof result.generatedAt, 'string');
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user