Prediction Domain¶
The prediction_domain bounded context contains the churn model, risk scoring, and SHAP explanation logic. It consumes entities from customer_domain and usage_domain but has no knowledge of infrastructure.
Entities¶
src.domain.prediction.entities ¶
PredictionResult entity – output of the Prediction domain services.
Classes¶
ShapFeature
dataclass
¶
A single SHAP feature contribution to a prediction.
Provides model explainability for CS teams to understand why a customer was flagged, enabling targeted interventions.
Source code in src/domain/prediction/entities.py
PredictionResult
dataclass
¶
The complete output of a churn + risk prediction for one customer.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
customer_id
|
str
|
The customer this prediction belongs to. |
required |
churn_probability
|
ChurnProbability
|
Calibrated P(churn in 90 days). |
required |
risk_score
|
RiskScore
|
Composite compliance/usage risk score. |
required |
top_shap_features
|
list[ShapFeature]
|
Top-N SHAP drivers (sorted by |shap_impact|). |
list()
|
model_version
|
str
|
Semantic version of the model artifact used. |
'0.0.0'
|
predicted_at
|
datetime
|
UTC timestamp of when the prediction was generated. |
(lambda: now(UTC))()
|
Source code in src/domain/prediction/entities.py
Value Objects¶
src.domain.prediction.value_objects ¶
Value objects for the Prediction domain.
Classes¶
ChurnProbability
dataclass
¶
P(churn in next 90 days) output from the churn model.
Calibrated probability in [0, 1]. The 0.5 threshold is the default operating point; business impact analysis should inform the actual threshold used for CS outreach triggers.
Source code in src/domain/prediction/value_objects.py
RiskScore
dataclass
¶
Composite compliance + usage risk score in [0, 1].
Combines compliance_gap_score, vendor_risk_flags, and usage_decay_score. Distinct from churn probability — a customer can have high risk score but low churn probability if they are contractually locked in.
Source code in src/domain/prediction/value_objects.py
Churn Model Service¶
src.domain.prediction.churn_model_service ¶
ChurnModelService – domain service for churn probability prediction.
Domain services encapsulate operations that don't naturally belong to a single entity. The model artifact is injected as a dependency (no direct file I/O here).
Classes¶
ChurnFeatureVector ¶
Bases: Protocol
Protocol for feature extraction – implemented in infrastructure layer.
Phase 4 update: the extractor queries the dbt mart directly (single DuckDB read), so events no longer need to be passed from the use case layer. This keeps the protocol minimal and moves feature logic into dbt.
Source code in src/domain/prediction/churn_model_service.py
Functions¶
Extract the model's feature vector for a customer.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
customer
|
Customer
|
Active Customer entity (used to look up mart row by ID). |
required |
Returns:
| Type | Description |
|---|---|
dict[str, float | str]
|
Flat dict of feature_name → value (numerics as float, categoricals |
dict[str, float | str]
|
as lowercase string for sklearn OrdinalEncoder compatibility). |
dict[str, float | str]
|
All feature engineering lives in mart_customer_churn_features. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the customer is not found in the mart (e.g. churned customers are excluded from the mart). |
Source code in src/domain/prediction/churn_model_service.py
ChurnModelPort ¶
Bases: ABC
Abstract port for the underlying ML model.
Concrete implementations in src/infrastructure/ml/ load the trained XGBoost/survival model artifact.
Source code in src/domain/prediction/churn_model_service.py
ChurnModelService ¶
Orchestrates feature extraction → model inference → result construction.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
ChurnModelPort
|
Concrete ML model (injected from infrastructure layer). |
required |
feature_extractor
|
ChurnFeatureVector
|
Queries the dbt mart for the customer's feature vector. |
required |
Source code in src/domain/prediction/churn_model_service.py
Functions¶
Generate a full PredictionResult for a customer.
Business Context: Feature extraction, model inference, and SHAP computation are all delegated to injected dependencies. This service only owns the assembly logic, keeping it testable in isolation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
customer
|
Customer
|
Active Customer entity. |
required |
risk_score
|
RiskScore
|
Pre-computed composite risk score (from RiskModelService). |
required |
Returns:
| Type | Description |
|---|---|
PredictionResult
|
PredictionResult with calibrated churn probability, SHAP explanations, |
PredictionResult
|
and a deterministic recommended CS action. |
Source code in src/domain/prediction/churn_model_service.py
Risk Model Service¶
src.domain.prediction.risk_model_service ¶
RiskModelService – domain service for compliance + usage risk scoring.
Classes¶
RiskSignals
dataclass
¶
Raw risk inputs from the risk_signals table.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
compliance_gap_score
|
float
|
0–1 score of open compliance gaps. |
required |
vendor_risk_flags
|
int
|
Count of third-party vendor risk alerts. |
required |
usage_decay_score
|
float
|
0–1 score of recent usage decline (computed from events). |
required |
Source code in src/domain/prediction/risk_model_service.py
RiskModelService ¶
Computes a composite risk score from compliance and usage signals.
Weights are calibrated to business impact: - Usage decay is the strongest leading indicator of near-term churn - Compliance gaps drive risk but not always churn (contractual stickiness) - Vendor risk flags have lower weight but non-zero contribution
These weights should be revisited quarterly using SHAP analysis on the full churn model to ensure they remain calibrated to observed outcomes.
Source code in src/domain/prediction/risk_model_service.py
Functions¶
Compute a composite RiskScore from raw signals.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
signals
|
RiskSignals
|
The three risk signal components. |
required |
Returns:
| Type | Description |
|---|---|
RiskScore
|
RiskScore value object in [0, 1]. |