Fraud — engineering¶
Runtime shape¶
One Cloud Run service (fraud-detection-ai-backend) fronts checks and report via different Pub/Sub subscriptions. Three stream services score transactions and publish/return predictions.
Layout¶
fraud-detection-ai-backend/
src/app.py # routes
src/config/appconfig.py # env, topic names
src/constant.py # cold start, anomaly weights
src/models/ # temporal / location / transaction pipelines
src/report_team/ # contract validate, policy, AI summary
src/auth/ # bidirectional JWT utils
docs/fraud-output-contract.md
fraud-detection-ai-backend-stream/
ml_service/ rule_service/ case_management_service/
Happy-path code trail (batch → report)¶
POST /batch_check→ publish toprocess-customer-statistics-<env>(src/app.py)- Push →
/temporal_check|/location_check|/transaction_check→ load history from Postgres → write profiles unless cold start (COLD_START_MIN_TRANSACTIONS=10) - Stream
POST /call-and-predictor/rule_based_engine(JWT +x-tenant-id) → prediction - Push →
POST /report→report_teamvalidate/normalize/policy/summary →POST {backend_api}/transaction/create-report
Auth implementation¶
src/auth/bidirectional_jwt_service.py— RS256; incomingiss=software-serviceaud=ai-serviceAuthorization: ApiKey <jwt>AUTH_ENFORCEMENT_ENABLEDbypass for local- Keys:
AI_PRIVATE_KEY,BACKEND_PUBLIC_KEY
DB config contradiction (document, don’t “fix” in docs)¶
README.mdemphasises JSONDB_CREDENTIALS.src/config/db_credentials.pyprefersDB_CREDENTIALS, falls back toDB_HOST/DB_DATABASE/DB_USER/DB_PASSWORD/DB_PORT.appconfig.pystill reads individualDB_*fields for some legacy attributes.
TreatDB_CREDENTIALSas the production shape; keep fallbacks for local.
Invariants¶
- LLM does not decide approve/pend/block (
report_team/policy.py). - Mixed ML+rule identity keys rejected by contract.
- Anomaly weights must match ML service copy.
Local¶
Stream: see each service README (ports 8080/8081/8082).
Deploy¶
cloudbuild.yaml: ensure topics/DLTs → build/push → Cloud Run → recreate push subscriptions to new URL.