Overview
This is the most urgently needed backend endpoint. The frontend dashboard (frontend/app/(dashboard)/dashboard/page.tsx) and reports page (frontend/app/(dashboard)/reports/page.tsx) both call GET /reports/summary. Without it, these pages show nothing. The dashboard is the first thing users see after login.
Context
- Frontend API:
frontend/lib/api/reports.ts getSummary() calls GET /reports/summary
- Frontend React Query hook:
frontend/lib/query/hooks/useReports.ts useReportsSummary
- Expected response shape (from frontend types):
{ total, byStatus: { ACTIVE, ASSIGNED, MAINTENANCE, RETIRED }, byCategory: [{ name, count }], byDepartment: [{ name, count }], recentAssets: Asset[], totalValue: number }
- All queries must use TypeORM aggregate functions — not multiple round-trips
Acceptance Criteria
Overview
This is the most urgently needed backend endpoint. The frontend dashboard (
frontend/app/(dashboard)/dashboard/page.tsx) and reports page (frontend/app/(dashboard)/reports/page.tsx) both callGET /reports/summary. Without it, these pages show nothing. The dashboard is the first thing users see after login.Context
frontend/lib/api/reports.tsgetSummary()callsGET /reports/summaryfrontend/lib/query/hooks/useReports.tsuseReportsSummary{ total, byStatus: { ACTIVE, ASSIGNED, MAINTENANCE, RETIRED }, byCategory: [{ name, count }], byDepartment: [{ name, count }], recentAssets: Asset[], totalValue: number }Acceptance Criteria
ReportsModule,ReportsController,ReportsServiceGET /reports/summary— single endpoint performing: total asset count, count grouped bystatus(all 4 statuses), count grouped bycategory.name(top 10), count grouped bydepartment.name(all), sum ofcurrentValueastotalValue, 10 most recently created assets with relationsCacheInterceptor) with 5-minute TTL; invalidate on any asset write operationReportsModuleinAppModuleJwtAuthGuard