Credit Intelligence
Credit Intelligence is a standalone scoring service. It can be consumed by partners or internal services without writing to Fineract. Core is only needed when an approved score becomes an actual MobiCred credit product.
The service has two connected branches:
- Data ingestion and normalization.
- Feature materialization and score production.
Identity Model
Partners create and keep their own tenant-local users. If one person appears in four partner systems, each partner can have its own customer row and customer reference. Credit Intelligence links those references to one canonical MobiCred subject for scoring and audit.
When credit is actually issued, Core maps that canonical subject to the single Core/Fineract customer. Credit Intelligence does not create Fineract customers, accounts, loans, or disbursements.
Ingestion
The ingestion branch needs adapters for API feeds, flat files, batch exports, webhooks, and manual uploads. Sources can include MobiCred account activity, Fineract loan history, Orange, MTN, Moov, WAE, partner transactions, POS activity, and mobile app telemetry.
Ingestion must preserve lineage: who provided the data, when it arrived, what consent or contract allows its use, and which normalized subject it was linked to.
Standalone Score Request
Use the Credit Intelligence API reference or the
Bruno collection in bruno/mobicred-partner-credit-demo.
The partner scoring request identifies the person with:
tenant_idpartner_codesubject.source_systemsubject.external_subject_ref
Core or the gateway should also send trusted boundary headers:
X-MobiCred-Tenant-Id and X-MobiCred-Partner-Code. In strict mode, Credit
Intelligence rejects the request unless those headers match tenant_id and
partner_code in the body. This keeps a partner from choosing another tenant or
partner code by editing the payload.
For traceability, send X-Request-Id for the current HTTP attempt and
X-Correlation-Id for the full customer/operator flow. Core, Credit
Intelligence, and the scoring-admin proxy echo those headers so one mobile
registration, pay-in, scoring request, or operator review can be followed across
service logs without putting secrets in payloads.
It does not send core_customer_id or fineract_client_id. Those values come
from a verified subject link when the score must be handed off to Core for
credit execution.
Scoring Admin Dashboard APIs
The scoring admin dashboard can run in two modes:
- Live mode: a Keycloak scoring-admin bearer token is stored in the dashboard session, and the dashboard reads Credit Intelligence admin APIs.
- Seeded demo mode: no token is present, so the dashboard clearly shows seeded demo data rather than pretending it is live production data.
Live mode uses these Keycloak-protected read models:
GET /score-decisions/admin/dashboard-summaryGET /score-decisions/admin/searchPOST /score-decisions/admin/search/reindexGET /score-decisions/admin/search/sync-statusPOST /score-decisions/admin/search/sync-retryGET /score-decisions/admin/filter-facetsGET /score-decisions/admin/geo-aggregatesGET /score-decisions/admin/geo-intelligenceGET /score-decisions/admin/subjects/{subjectId}GET /score-decisions/admin/sessionGET /score-decisions/admin/notificationsPOST /score-decisions/admin/{decisionId}/review-actions
The database remains the source of truth. Elasticsearch is an acceleration and
exploration layer for search, audit, analytics, and facets; writes still land in
the database first, then sync to search. Operator review actions are recorded in
the score decision trace and reindexed for search/audit exploration. If
Elasticsearch was unavailable or a staging environment was rebuilt after data
already existed, run GET /score-decisions/admin/search/sync-status first. Use
POST /score-decisions/admin/search/sync-retry for short Elasticsearch outages
where writes were recorded in the retry outbox. Use POST /score-decisions/admin/search/reindex for broader staging resets, template
changes, or historical replay from Postgres into the search indexes. The sync
status response now reports synced, catching_up, or blocked freshness plus
pending, failed, dead-letter, retry-ready, and oldest retryable age totals.
Geo Intelligence uses GET /score-decisions/admin/geo-intelligence for the
operator dashboard panels. It composes live score geography with identity-link
coverage, source freshness, partner footprint, country policy packs, and zone
references. The response keeps Postgres as the source of truth and marks
geography as context only, never an approval or decline reason by itself. Small
zone cohorts suppress score and decision-mix fields so the dashboard can show
coverage without exposing sensitive credit-outcome patterns.
Feature Materialization
The feature branch turns raw facts into stable scoring inputs:
- Demographics and declared profile completeness.
- Payment habits, repayment behavior, defaults, reversals, and disputes.
- Location and zoning signals such as Cocody versus Abobo, without making neighborhood a hidden unfair substitute for protected characteristics.
- Mobility pattern stability based on app position, with explicit consent and retention limits.
- Account age, income proxy, balance volatility, transaction regularity, and device risk.
Decision Rule
Every score response should return a score, a band, the model version, the data freshness window, and human-readable reason codes. A score without explainable reason codes is not partner-ready.