This project is a backend service for populating PDF forms from structured application data. It uses a ports-and-adapters design so business rules stay independent from infrastructure integrations.
- Selects required forms based on case inputs (bank, product, and profile type)
- Loads field mapping rules from YAML schemas
- Pulls values from multiple data providers with priority fallback
- Writes resolved values into PDF fields
- Returns a per-form execution result (
filled,flagged, orerror)
The codebase follows hexagonal architecture:
domain/: core models, ports, and business servicesapplication/: workflow orchestration (ProcessingPipeline)mapping/: schema loader, resolvers, strategy implementationsinfrastructure/: concrete adapters (PDF reader/writer)stubs/: local test doubles for running without external systemsconfig/: form registry and environment-related settings
When resolving values for form fields, sources are checked in this order:
- Info sheet source
- Document source
- CRM source
For each field key, the first non-null value wins.
- Python 3.11+
pip install -r requirements.txtThis executes a sample case using local in-memory data sources.
python run.pyuvicorn main:app --reloadPOST /manifest
Content-Type: application/json
{
"case_id": "CASE-001",
"applicant_id": "APP-001",
"bank": "dib",
"product": "conventional",
"profile_type": "salaried_resident"
}{
"case_id": "CASE-001",
"total_forms": 2,
"filled": 2,
"flagged": 0,
"errors": 0,
"forms": [
{
"form_id": "App Form",
"status": "filled",
"pdf_bytes": "..."
}
]
}To add support for additional form variants:
- Add schema file in
mapping/schemas/{bank}_{product}.yaml - Implement or update strategy in
mapping/strategies/ - Register strategy in dependency wiring
- Update
config/form_registry.yamlwith required forms
- FastAPI
- Pydantic
- PyPDFForm
- PyYAML