[FEAT] : Generate multiple related forms from one structured incident record#294
Conversation
- Add BatchOrchestrator to process multiple templates in one run
- Add per-template mapping and compatibility reports
- Ensure per-template failures do not block successful forms
- Add batch ZIP package generation and download endpoint
- Add /forms/fill-batch and /forms/batch-download/{batch_id} APIs
- Extend controller and file manipulator for batch flow
- Add tests for orchestration and API behavior
There was a problem hiding this comment.
Pull request overview
This PR adds multi-document “batch fill” automation so a single structured incident record can generate multiple related agency PDFs in one run, returning per-template validation/mapping results and a downloadable ZIP package.
Changes:
- Introduces a batch orchestration engine that validates/matches incident data to template schemas, fills PDFs per template, and packages outputs into a ZIP with a
batch_report.json. - Adds API support for batch submission (
POST /forms/fill-batch) and batch ZIP download (GET /forms/batch-download/{batch_id}), plus new request/response schemas. - Adds tests covering the batch orchestrator behavior and the new batch API flows.
Reviewed changes
Copilot reviewed 11 out of 11 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
src/batch_orchestrator.py |
New batch engine: per-template validation, isolated failure handling, ZIP packaging + report generation. |
src/filler.py |
Adds “fill from structured incident record” path to bypass LLM extraction when JSON is already available. |
src/file_manipulator.py |
Wires the batch orchestrator into the existing manipulation layer and exposes fill_multiple_forms. |
src/controller.py |
Exposes controller method for multi-template batch filling. |
api/routes/forms.py |
Adds batch fill and batch download endpoints. |
api/schemas/forms.py |
Adds Pydantic models for batch request/response and per-template mapping reports. |
api/db/repositories.py |
Adds repository helper to fetch multiple templates by ID. |
api/main.py |
Registers custom exception handlers (for AppError) on app startup. |
tests/test_batch_orchestrator.py |
New tests for orchestrator isolation of template failures + ZIP/report output. |
tests/test_forms_batch.py |
New tests for batch endpoints (success path + missing template behavior + download). |
src/inputs/input.txt |
Updates sample input text fixture content. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
You can also share your feedback on Copilot code review. Take the survey.
| @router.get("/batch-download/{batch_id}") | ||
| def download_batch_package(batch_id: str): | ||
| zip_path = os.path.join("src", "outputs", "batches", f"{batch_id}.zip") | ||
| if not os.path.exists(zip_path): | ||
| raise AppError("Batch package not found", status_code=404) | ||
|
|
||
| return FileResponse( | ||
| path=zip_path, | ||
| media_type="application/zip", | ||
| filename=f"{batch_id}.zip", | ||
| ) |
| return list(session.exec(statement).all()) | ||
|
|
| class FormBatchFillResponse(BaseModel): | ||
| batch_id: str | ||
| total_templates: int | ||
| successful_count: int | ||
| failed_count: int | ||
| package_zip_path: str | ||
| download_url: str | ||
| results: list[BatchTemplateResult] No newline at end of file |
| target_file.write_bytes(b"zip-content") | ||
|
|
||
| response = client.get(f"/forms/batch-download/{batch_id}") | ||
|
|
||
| assert response.status_code == 200 | ||
| assert response.headers["content-type"] == "application/zip" |
|
@copilot apply changes based on the comments in this thread |
|
This is a really impactful feature — it aligns well with FireForm’s “report once, file everywhere” goal. I especially like the batch orchestration and per-template validation reporting. One thing I noticed from the Copilot review is the potential path traversal risk in the batch download endpoint. It might be worth validating the batch_id or ensuring the resolved path stays within the intended directory. I’ll try testing this locally to better understand the batch flow. |
|
@copilot apply changes based on the comments in this thread |
Summary
Implements multi-document automation so one structured incident record can generate many agency forms in a single run (fire, medical, insurance/claims), with per-template validation/mapping reports, non-blocking failure handling, and downloadable batch packaging.
Why
First responders often submit the same incident details across multiple agency forms. This feature reduces repeated manual entry and improves operational throughput by enabling report-once, file-everywhere behavior.
What Changed
API
POST /forms/fill-batch
GET /forms/batch-download/{batch_id}
Behavior Details
Batch orchestration iterates selected templates and attempts fill per template.
Each template returns compatible, missing_fields, extra_fields, unmapped_fields, type_mismatches, warnings, matched_fields
Validation/runtime failures are isolated to template-level results (failed_validation or failed_runtime), while others still complete.
A ZIP is generated containing successful PDFs plus batch_report.json, accessible via download endpoint.
Testing
Executed targeted tests for new functionality:
Result:
5 passed
Acceptance Criteria Checklist
Notes