Auditable direct-debit risk and retry automation with MLflow, SQL, CI, and human review.
Open live dashboard | API documentation | Security and governance | Evaluation scorecard
DirectDebit IQ predicts scheduled payment failures, explains the risk, recommends a retry, and turns high-risk scores into governed operational actions. Customer-impacting retries require a reviewer decision, carry an idempotency key, and produce queryable audit and trace evidence.
Evidence boundary: the dataset and financial benefit estimates are synthetic scenarios. The project demonstrates engineering, analytics, and governance controls; it does not claim validated production performance or guaranteed financial return.
| Capability | Evidence |
|---|---|
| Risk model and out-of-time evaluation | src/train.py, docs/MODEL_CARD.md |
| SQL analytics and reproducible feature pipeline | sql/, src/feature_store.py |
| Stakeholder dashboard and modular page boundary | app/dashboard.py, app/pages.py, app/automation_page.py, app/action_api_client.py |
| Authenticated action API | api/main.py, api/auth.py |
| Human approval and retry-scheduling workflow | api/service.py, automation/n8n_retry_approval_workflow.json |
| Prediction, reviewer, and action audit records | api/models.py |
| Trace IDs, structured logs, and persisted spans | api/observability.py |
| Approval-safe optional LLM planner | src/operations_agent.py |
| Automated governance evaluation | evaluations/run_action_evaluation.py, evaluations/results/action_workflow_results.json |
| Tests, CI, containers, and cloud blueprint | tests/, .github/workflows/ci.yml, render.yaml |
flowchart LR
P["Scheduled payment"] --> M["Risk scoring"]
M --> PA["Prediction audit<br/>version + threshold + trace ID"]
PA --> D{"Risk >= threshold?"}
D -->|No| N["Normal monitoring"]
D -->|Yes| R["Retry recommendation"]
R --> A{"Human approval"}
A -->|Rejected| RJ["Record reviewer decision"]
A -->|Approved| I["Idempotent retry execution"]
I --> O["Persist action outcome"]
PA --> T["Trace spans and structured logs"]
A --> T
I --> T
The n8n workflow calls the same authenticated endpoints used by tests and the API documentation. It cannot execute a retry until a user with the reviewer or admin role records approval.
| Metric | Synthetic holdout result |
|---|---|
| Dataset size | 50,000 payments |
| ROC AUC | ~0.690 |
| Average precision | ~0.296 |
| Recall at threshold 0.30 | ~94.5% |
| Governance evaluation | 7/7 controls passing |
Model metrics are from an out-of-time synthetic holdout. Benefit and ROI values in docs/BUSINESS_IMPACT.md are explicitly scenario estimates.
git clone https://github.com/RidhanPar/directdebit-iq.git
cd directdebit-iq
python -m venv .venv
# Windows: .venv\Scripts\activate
# macOS/Linux: source .venv/bin/activate
pip install -r requirements.txt
python data/generate_data.py
pytest -q
python evaluations/run_action_evaluation.pyRun the dashboard and action API in separate terminals:
streamlit run streamlit_app.py
uvicorn api.main:app --reload --port 8000Open:
- Dashboard:
http://localhost:8501 - Action API docs:
http://localhost:8000/docs - Action API health:
http://localhost:8000/health
Or start Streamlit, FastAPI, MLflow, and n8n together:
docker compose up --buildLocal demo users are operator, reviewer, and admin; each local-only password follows <username>-demo. Configure real identity and secrets before production use.
curl -X POST http://localhost:8000/auth/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "username=operator&password=operator-demo"curl -X POST http://localhost:8000/predictions \
-H "Authorization: Bearer <operator-token>" \
-H "Content-Type: application/json" \
-d '{
"payment_id": "PAY-1001",
"payment_amount": 850,
"payment_date": "2026-06-16",
"mandate_age_days": 12,
"previous_failure_count": 4,
"estimated_balance_band": "low",
"days_since_last_success": 75
}'The response includes the prediction version, threshold, trace ID, recommendation, and a pending approval action ID when risk exceeds the action threshold.
Run:
python evaluations/run_action_evaluation.pyThe deterministic suite fails CI unless every specified workflow control passes:
- High-risk routing to approval
- Low-risk no-action behavior
- Role-based access control
- Approval-gate enforcement
- Idempotent execution
- Complete audit and trace evidence
- Approval-safe agent planning
The checked-in result reports the pass rate for these seven declared governance controls. It is separate from predictive-model accuracy.
| Layer | Technology |
|---|---|
| Analytics and ML | Python, pandas, SQL, XGBoost, scikit-learn, SHAP |
| Model lifecycle | MLflow, out-of-time holdout, model card |
| Product surfaces | Streamlit, FastAPI, OpenAPI |
| Persistence | SQLAlchemy, SQLite locally, PostgreSQL on Render |
| Automation | n8n, optional OpenAI structured planner |
| Governance | JWT/RBAC, human approval, audit events, idempotency |
| Observability | Trace IDs, JSON logs, persisted spans |
| Delivery | Docker Compose, GitHub Actions, Render Blueprint |
api/ Authenticated prediction/action API and governance services
app/ Thin dashboard entrypoint, product pages, and API client
automation/ Importable n8n approval/retry workflow
data/ Synthetic data generator and local artifacts
docs/ API, architecture, deployment, model, and governance evidence
evaluations/ Executable action-workflow control suite and results
sql/ Payment operations analyses
src/ Feature engineering, training, recommendations, and agent plan
tests/ Unit, integration, artifact, and smoke tests
render.yaml Managed PostgreSQL and FastAPI cloud Blueprint
docker-compose.yml Dashboard, action API, MLflow, and n8n stack
Before connecting to real payments:
- Replace demo users with an enterprise identity provider.
- Validate performance and calibration on governed historical data.
- Add database migrations, secret rotation, rate limiting, and encrypted backups.
- Complete privacy, fairness, operational-capacity, and rollback reviews.
- Start in shadow mode, then use a measured champion/challenger release.
See docs/SECURITY_AND_GOVERNANCE.md for implemented controls and remaining production requirements.
Resume bullet: Built a tested, Dockerized direct-debit risk platform using Python, SQL, XGBoost, and MLflow; achieved 94.5% recall on an out-of-time synthetic holdout and translated scores into prioritized retry recommendations.