feat(freight-api): replace canned reports with a generic report engine

Nuke the 17 hand-written raw-SQL reports (no pagination, hard LIMITs) and
the reports module built around them. Replace with a resolver contract:
a report declares columns/filters/permission and a TypeORM QueryBuilder;
ReportRunnerService applies filtering, a whitelisted sort, offset/limit
paging, and a COUNT(*) FROM (query) wrapper for the total (getCount() is
wrong for GROUP BY). ReportExportService re-runs the same resolver
unpaginated for xlsx (exceljs) and pdf (existing PdfRenderService, now
landscape-capable) exports.

Ships with 4 reports: bookings-list, revenue-by-customer,
aging-receivables, contract-utilization. Catalog + per-report permission
checks live in the controller; adding a report is one new definitions/
file plus a REPORT_KEYS entry, no frontend change.
This commit is contained in:
Nathnael
2026-08-13 07:52:20 +00:00
parent 08804c84e9
commit b7583df426
19 changed files with 976 additions and 1056 deletions

View File

@@ -1,13 +1,14 @@
import { Module } from '@nestjs/common';
import { DocumentsModule } from '../billing/documents/documents.module';
import { UserTradeAccessModule } from '../user-trade-access/user-trade-access.module';
import { ReportExportService } from './report-export.service';
import { ReportRunnerService } from './report-runner.service';
import { ReportsController } from './reports.controller';
import { ReportsRepository } from './reports.repository';
import { ReportsService } from './reports.service';
@Module({
imports: [UserTradeAccessModule],
imports: [UserTradeAccessModule, DocumentsModule],
controllers: [ReportsController],
providers: [ReportsService, ReportsRepository],
providers: [ReportRunnerService, ReportExportService],
})
export class ReportsModule {}