AI Brief: hbf-reports
NestJS service that generates PDF analytics reports for organizations, delivers them by email on a cron schedule (weekly/monthly), and exposes an HTTP API for on-demand export and report schedule management.
What This Repo Does
hbf-reports pulls analytics data from hbf-core, renders it into multi-section A4 PDF documents using pdfkit (with echarts SVG charts), and either emails them to configured recipients or streams them back to the HTTP caller. Report schedules are persisted in MySQL via TypeORM. Two cron jobs fire automatically: one every Monday at midnight (weekly reports) and one on the 1st of each month at 00:05 (monthly reports).
Tech Stack
- Language: TypeScript
- Framework: NestJS 9
- Key dependencies:
pdfkit,pdfkit-table,svg-to-pdfkit,echarts,nodemailer,typeorm,mysql2,@helvia/hbf-core-api,@nestjs/schedule
Entry Points
- Main:
src/main.ts - Config:
src/env.validation.ts— class-validator schema for all env vars - ORM config:
ormconfig.ts— TypeORM datasource for migration CLI
Key Directories
| Directory | Purpose |
|---|---|
src/reports/scheduled_reports/ | CRUD for report schedules + weekly/monthly send logic |
src/reports/exports/ | On-demand export endpoint (streams PDF back to caller) |
src/generate_graphs/ | GenerateGraphsService — orchestrates PDF page layout and chart embedding |
src/resource_modules/pdf/ | DrawPdfService + template drawers for each section; table renderer |
src/resource_modules/charts/ | GenerateChartsService — echarts wrappers for pie, line, bar, stacked, gauge, vertical-bar |
src/resource_modules/scheduler/ | SchedulerService — registers weekly and monthly cron jobs |
src/hbf-core/ | HbfCoreService — analytics data fetcher (summary, live chat, decision trees, interviews, CSAT, missed questions, user feedback) |
src/clients/ | HTTP client and core API client |
src/utils/transform/ | Data transformers: core API response -> chart/table format |
src/migrations/ | TypeORM migration: initial schema |
fonts/ | NotoSans font files (Regular, Medium, SemiBold) for PDF rendering |
Scheduled Report Types
reports_schedule.type is the discriminator for every scheduled report. The service currently supports:
ANALYTICS_PDF: the legacy PDF analytics schedule.configmust benull/omitted andsectionsdrives the rendered PDF content.SESSION_XLSX: scheduled session export.configmay contain session-export filters:tags: string[],deploymentIds: string[],containsFallback,containsFeedback,containsLiveChat,containsCSATSurvey,containsUserInteraction,isRegex,matchFullWord.SURVEY_CSV: scheduled survey export.config.sourceActivityNameis required andconfig.surveyTypeis limited toINTERVIEW | LIVECHAT | USER_FEEDBACK;config.separatoris limited to,,;, or\t.
reports_schedule.tenants remains a shared filter for all three types. For SURVEY_CSV, the DTO
and console UX enforce single-tenant scheduling because activity lookup is tenant-scoped.
Scheduled Export Flow
ReportsService.handleScheduledReports() is the type dispatcher for cron-triggered and manual
run-now exports. It creates a reports_exports row in STARTED, resolves the organization once,
then switches on report.type:
ANALYTICS_PDF->runAnalyticsPdfExport()SESSION_XLSX->runSessionExport()SURVEY_CSV->runSurveyExport()
The analytics path renders a PDF via GenerateGraphsService. The session and survey paths call
HbfCoreService export wrappers, convert the returned file to an email attachment, and then mark
the export row COMPLETED.
Export Row Semantics
reports_exports intentionally distinguishes upstream client errors from upstream server errors:
4xxfrom hbf-core session/survey export endpoints are treated as a completed run with no attachment. The runner logs a warning, setsstatus = COMPLETED, setsfinishedAt, and skips email delivery.- Empty/undefined export results are treated the same as the 4xx path:
COMPLETED, no attachment, no email. 5xx, network failures, and unknown exceptions are rethrown from the runner. The outerhandleScheduledReports()catch only logs the failure, so the already-createdreports_exportsrow remains atSTARTED. This matches the existing analytics-PDF failure semantics.
Report Sections
Reports are composed of configurable sections (Sections enum in create-scheduled-report.dto.ts):
| Section | Pages drawn |
|---|---|
SUMMARY | Engagement (pie), Sessions (line), Interactions (bar), Users (line) |
AUTOMATED_ANSWERS | Usage (table) |
LIVECHAT | Usage (bar), Missed Chats (pie), Response Times (stacked-line), Duration (line) |
DECISION_TREES | Usage (pie) |
INTERVIEWS | Usage (pie), Successful/Failed (pie) |
USER_FEEDBACK | Overall feedback (pie), Live Chat feedback (pie), Agent feedback (table) |
MISSED_QUESTIONS | Total (pie), Top questions (table), Total per day (bar) |
CSAT | Overall score (gauge), Sections score (vertical-bar), Score over time (marks-line), Responses over time (stacked-bar x2) |
External Dependencies
- Analytics: hbf-core REST API (
CORE_URL,CORE_TOKEN) - Database: MySQL/MariaDB via TypeORM (
DB_HOST,DB_PORT,DB_USERNAME,DB_PASSWORD,DB_NAME) - Email: SMTP via nodemailer (
EMAIL_HOST,EMAIL_PORT,EMAIL_SECURE,EMAIL_USERNAME,EMAIL_PASSWORD,EMAIL_FROM_ADDRESS,EMAIL_FROM_NAME) - Console link in emails:
CONSOLE_URL - APM: Elastic APM (optional,
ELASTIC_APM_ACTIVE)
Running Locally
npm install
cp .env.sample .env # fill all values
npm run start:dev # watch mode, APM disabled
Tests
npm test # Jest unit tests (spec files in src/)
npm run test:e2e # e2e suite
npm run test:cov # coverage report