Skip to content

feat: implement periodic report generation API (#557) - #737

Open
Aliussman wants to merge 2 commits into
fireform-core:developmentfrom
Aliussman:557-feat-periodic-report-generation
Open

Aliussman wants to merge 2 commits into
fireform-core:developmentfrom
Aliussman:557-feat-periodic-report-generation

Conversation

@Aliussman

Copy link
Copy Markdown
Contributor

Description

Implements periodic report generation API endpoints and async worker execution for monthly, quarterly, and annual department reporting in FireForm as outlined in #557 (part of contract tracker #541).

Key Additions:

  • Endpoints:
    • POST /api/v1/reports/generate: Asynchronously kicks off periodic report generation; returns 202 Accepted with report_id, job_id, and poll_url.
    • GET /api/v1/reports/{report_id}: Polling and result retrieval. Returns 202 Accepted with retry_after_seconds while generating; returns 200 OK with PDF binary or JSON payload (PeriodicReport schema) upon completion; returns 404 Not Found if missing.
  • Contract & Schemas:
    • Added contracts/path/reporting.yaml and contracts/schemas/reporting.yaml, mounted in contracts/openapi.yaml.
    • Added Pydantic schemas in app/api/schemas/reporting.py and updated AsyncJobResponse in app/api/schemas/common.py.
  • Database Repositories:
    • Added create_report, get_report, update_report, get_incidents_in_date_range (with strict UTC timezone awareness), get_forms_for_incidents, and get_extractions_by_ids in app/db/repositories.py.
  • Business Logic & PDF Generation:
    • Implemented app/services/reporting.py with period boundary computation & validation, future period rejection (422 Unprocessable Entity with code FUTURE_PERIOD), metrics aggregation (incident types, statuses, forms generated, completeness score, processing time), compliance metrics (NERIS submission rate, delay, overdue count), and ReportLab-based PDF generation.
  • Background Worker:
    • Implemented Celery task generate_periodic_report in app/tasks/report.py and registered it in app/core/celery.py.
  • Dependencies:
    • Added reportlab to requirements.txt for PDF rendering.

Fixes #557

Type of change

  • New feature (non-breaking change which adds functionality)

How Has This Been Tested?

  • Added unit and integration tests in tests/test_v1_reports.py (18 tests):
    • Async generation request acceptance (POST /api/v1/reports/generate -> 202).
    • Monthly, quarterly, and annual period calculations.
    • Rejection of future periods (422 Unprocessable Entity with FUTURE_PERIOD).
    • Validation of invalid month and quarter values.
    • Polling status check (GET /api/v1/reports/{id} -> 202).
    • Completed PDF generation and binary download (Content-Type: application/pdf).
    • Completed JSON report retrieval matching PeriodicReport schema.
    • Handling of non-existent report IDs (404 Not Found).
    • Queue failure handling when Redis is unavailable (503 Service Unavailable).
    • Empty incident range handling.
    • Multi-incident aggregations across quarterly boundaries.
    • Direct Celery task execution with session patching.
  • Full test suite executed locally: PYTHONPATH=. pytest → 331 passed.
  • Linter executed: python -m ruff check app/ tests/ → All checks passed!

Test Configuration:

  • Python version: 3.13.5
  • Docker/Compose version: N/A (tested against SQLite test engine and mocked queue)
  • OS: Ubuntu Linux (x86_64)

Checklist:

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published in downstream modules
  • The Lint workflow check passes on this PR ✅
  • The Tests workflow check passes on this PR ✅

@marcvergees

Copy link
Copy Markdown
Member

Hi @Aliussman, we should be having a frontend implementation for that feature. Feel free to create issue and PR.

Thanks,
Marc

@vharkins1

Copy link
Copy Markdown
Collaborator

Hey @Aliussman, thanks for putting this together, it's a big one and the tests look really thorough!

Before I review it for merge there are a few things. Like Marc said, this needs a frontend side, so could you open an issue + PR in fireform-frontend and link them here? It's also conflicting with development in router.py now, so it'll need a rebase.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Periodic report generation - API Contracts

3 participants