Context
Reports that come to you: ReportSchedule (#9) drives recurring email delivery, and exports produce CSV/XLSX files via ts-spreadsheets (~/Code/Libraries/ts-spreadsheets). No PDF dependency exists in our library set, so delivery is a designed HTML email summary + link (and attachments) - not a half-baked PDF.
Scope
- Scheduling:
app/Scheduler.ts+ a queued job scans dueReportSchedulerows (cadence, hour, timezone-correct) and dispatches per-schedule delivery jobs; failures retry with backoff and surface on the schedule row (last_run_at, last_status). - Email: an
app/Mail/report delivery mail using the email framework's stx templates - report name, period, per-block headline numbers (BigNumber values and deltas computed via #10), and a deep link to the viewer (#13). Design the email properly (tokens from #3 translated to email-safe styles); test in thebuddy email:*tooling. - Exports: CSV and XLSX generation from a report's block result sets via
ts-spreadsheets(one sheet/section per block, typed columns, currency formats). Improvets-spreadsheetsupstream if formatting gaps appear (bun run release:patch). - On-demand export from the viewer (#13):
ReportExportrow, queued generation, stored via@stacksjs/storage, expiring signed download; UI shows progress and history. - Schedule management UI on the report: create/edit/pause schedules, recipients (must be project members or explicitly confirmed addresses - no open relay), format choice.
- Plan gating hooks: schedules and XLSX are tier-gated; enforce through the #18 limits API (soft-fail with an upgrade prompt, never a 500).
- Feature tests: due-schedule scan correctness across timezones/DST, email content numbers match engine output, export file correctness (parse the XLSX back and assert), gating.
Acceptance
- A daily schedule on the seeded report delivers a correct email (inspected via the local email tooling) and a downloadable XLSX whose numbers match the viewer.
Depends on #9, #10, #13, #18. Part of #1 (M7 Launch). Ground rules: see #1.