---
name: reporting-feature
description: Async report generation with filters + scheduling + export (PDF / XLSX).
---

# Blueprint: Reporting Feature

## Frontend

- Routes: `/reports`, `/reports/:id`.
- Components: filter form, "Generate" button, recent reports list, download link.
- Reports are async — show a status (queued → running → ready) via polling or realtime.

## Backend

- `RequestReportCommand` enqueues a job (per `queue-worker` skill); returns a `reportId`.
- Worker generates the report (XLSX via exceljs or PDF via Puppeteer/QuestPDF), stores via `em-file-storage`, updates `Report.status='ready' + storageKey`.
- `GET /api/reports/:id` returns metadata + signed download URL.

## Database

- `Report` (requestedBy, filters JSON, status, storageKey, expiresAt).
- Auto-delete after `expiresAt` (cron job).

## API contract

- `requestReportSchema`, `reportStatusSchema`, `reportListSchema`.

## UI

- Don't block while generating; let user navigate away.
- Re-download from the list within the expiry window.

## Validation

- Filter shape per-report-type; cap the date range to avoid 10-year scans.

## Testing

- Job idempotency; storage round-trip; expiry cleanup; XLSX/PDF render with Thai text.

## Observability

- Time-to-generate metric per report type; failure rate.

## Security

- Permission: `<report-type>.export`.
- Tenant-scoped data only.
- Signed URLs expire (≤ 1 hour for sensitive reports).
