diff --git a/api-v3/src/dashboard/dashboard.service.ts b/api-v3/src/dashboard/dashboard.service.ts index 56e5daa..d77ce32 100644 --- a/api-v3/src/dashboard/dashboard.service.ts +++ b/api-v3/src/dashboard/dashboard.service.ts @@ -1,7 +1,7 @@ import { Injectable } from '@nestjs/common'; import { DataSource } from 'typeorm'; -export interface DashboardAuditItem { +export interface DashboardInspectorActivityItem { id: string; occurredAt: Date; actorUsername: string | null; @@ -19,6 +19,7 @@ interface DashboardCountsRow { inactiveUsers: number | string; activeSessions: number | string; openFindings: number | string; + actsInFollowUp: number | string; findingsWithoutControlDate: number | string; overdueControls: number | string; controlsNext30Days: number | string; @@ -49,9 +50,14 @@ export class DashboardService { return this.dataSource.transaction('REPEATABLE READ', async (manager) => { const [counts] = (await manager.query(` SELECT - (SELECT COUNT(*) FROM assets WHERE information_status <> 'INACTIVE') AS "totalAssets", - (SELECT COUNT(*) FROM assets WHERE information_status NOT IN ('VALIDATED','INACTIVE')) AS "assetsNeedValidation", - (SELECT COUNT(*) FROM assets asset WHERE asset.information_status <> 'INACTIVE' AND NOT EXISTS (SELECT 1 FROM asset_geometries geometry WHERE geometry.asset_id=asset.id)) AS "assetsWithoutGeometry", + (SELECT COUNT(*) FROM assets WHERE is_inventory_instance=true AND information_status <> 'INACTIVE') AS "totalAssets", + (SELECT COUNT(*) FROM assets WHERE is_inventory_instance=true AND information_status NOT IN ('VALIDATED','INACTIVE')) AS "assetsNeedValidation", + ( + SELECT COUNT(*) FROM assets asset + WHERE asset.is_inventory_instance=true + AND asset.information_status <> 'INACTIVE' + AND NOT EXISTS (SELECT 1 FROM asset_geometries geometry WHERE geometry.asset_id=asset.id) + ) AS "assetsWithoutGeometry", (SELECT COUNT(*) FROM inspection_visits WHERE status='PLANNED') AS "plannedInspections", (SELECT COUNT(*) FROM users WHERE status = 'ACTIVE') AS "activeUsers", (SELECT COUNT(*) FROM users WHERE status = 'INACTIVE') AS "inactiveUsers", @@ -61,9 +67,22 @@ export class DashboardService { WHERE revoked_at IS NULL AND expires_at > CURRENT_TIMESTAMP ) AS "activeSessions", + (SELECT COUNT(*) FROM inspection_findings WHERE status = 'OPEN') AS "openFindings", ( - SELECT COUNT(*) FROM inspection_findings WHERE status = 'OPEN' - ) AS "openFindings", + SELECT COUNT(*) + FROM inspection_acts act + WHERE act.status IN ('SEALED','CLOSED','RECTIFIED') + AND NOT ( + EXISTS ( + SELECT 1 FROM inspection_findings finding + WHERE finding.act_id=act.id AND finding.status<>'VOIDED' + ) + AND NOT EXISTS ( + SELECT 1 FROM inspection_findings finding + WHERE finding.act_id=act.id AND finding.status='OPEN' + ) + ) + ) AS "actsInFollowUp", ( SELECT COUNT(*) FROM inspection_findings finding @@ -115,7 +134,7 @@ export class DashboardService { ) AS "sealedActsWithoutReport" `)) as DashboardCountsRow[]; - const recentAudit = (await manager.query(` + const recentInspectorActivity = (await manager.query(` SELECT event.id, event.occurred_at AS "occurredAt", @@ -124,9 +143,25 @@ export class DashboardService { event.entity_type AS "entityType", event.entity_id AS "entityId" FROM audit_events event + WHERE event.actor_user_id IS NOT NULL + AND ( + EXISTS ( + SELECT 1 FROM inspection_visit_members member + WHERE member.user_id=event.actor_user_id AND member.included=true + ) + OR EXISTS ( + SELECT 1 FROM inspection_visits visit + WHERE visit.lead_inspector_user_id=event.actor_user_id + ) + ) + AND ( + event.action LIKE 'INSPECTION_%' + OR event.action LIKE 'ASSET_%' + OR event.action LIKE 'FINDING_%' + ) ORDER BY event.occurred_at DESC, event.id DESC - LIMIT 6 - `)) as DashboardAuditItem[]; + LIMIT 8 + `)) as DashboardInspectorActivityItem[]; const upcomingControls = (await manager.query(` SELECT @@ -168,6 +203,7 @@ export class DashboardService { inactiveUsers: Number(counts?.inactiveUsers ?? 0), activeSessions: Number(counts?.activeSessions ?? 0), openFindings: Number(counts?.openFindings ?? 0), + actsInFollowUp: Number(counts?.actsInFollowUp ?? 0), findingsWithoutControlDate: Number(counts?.findingsWithoutControlDate ?? 0), overdueControls: Number(counts?.overdueControls ?? 0), controlsNext30Days: Number(counts?.controlsNext30Days ?? 0), @@ -175,7 +211,7 @@ export class DashboardService { reportsOfficialized: Number(counts?.reportsOfficialized ?? 0), sealedActsWithoutReport: Number(counts?.sealedActsWithoutReport ?? 0), }, - recentAudit, + recentInspectorActivity, upcomingControls, generatedAt: new Date().toISOString(), };