This page describes four files of the analytics module in src/cluster_erp/modules/analytics/: series.py (period series with visible gaps), forecasting.py (baseline forecasts and error metrics), classification.py (ABC and SBC classes), and saved_models.py (named, re-runnable analyses). Forecasting and classification use Decimal arithmetic throughout (src/cluster_erp/modules/analytics/forecasting.py:1-4, src/cluster_erp/modules/analytics/classification.py:1-4).
Scope and source¶
- Defined in:
period_series,values_of,grouped_period_totals,stratified_counts(src/cluster_erp/modules/analytics/series.py:79-478);forecast_baseline,scaling_denominator,accuracy,rolling_origin,compare_baselines(src/cluster_erp/modules/analytics/forecasting.py:88-373);classify_abc,classify_sbc(src/cluster_erp/modules/analytics/classification.py:56,src/cluster_erp/modules/analytics/classification.py:246);SavedModelService(src/cluster_erp/modules/analytics/saved_models.py:88). - Routes:
GET /analysis/series/{fact_key},GET /analysis/baselines/{fact_key},GET /analysis/abc/{fact_key},GET /analysis/sbc/{fact_key}, and the/analysis/modelsroutes (src/cluster_erp/modules/analytics/routes.py:168-310,src/cluster_erp/modules/analytics/routes.py:946-1069).
Period series¶
period_series returns one value per period for every period in the window, by generating the periods and joining the aggregate onto them (src/cluster_erp/modules/analytics/series.py:1-36, src/cluster_erp/modules/analytics/series.py:79-95).
| Parameter | Values | Source |
|---|---|---|
grain |
the grains declared on the date dimension | src/cluster_erp/modules/analytics/series.py:57-75 |
aggregation |
sum, avg, min, max; a missing value column counts rows |
src/cluster_erp/modules/analytics/series.py:76, src/cluster_erp/modules/analytics/series.py:93-94 |
gap_policy |
gap (default, a period without rows is null with has_rows false) or zero (the caller chooses zero, and the answer records it) |
src/cluster_erp/modules/analytics/series.py:53, src/cluster_erp/modules/analytics/series.py:18-36 |
filters |
equality-only selections on declared categorical dimensions | src/cluster_erp/modules/analytics/series.py:93-95 |
The docstring explains the rule: a month without rows must not look like a month with zero demand, because that hides stockouts and misclassifies lumpy items (src/cluster_erp/modules/analytics/series.py:7-30).
Baseline forecasts and errors¶
| Item | Values | Source |
|---|---|---|
| Baselines | mean, naive, seasonal_naive, drift |
src/cluster_erp/modules/analytics/forecasting.py:55 |
| Metrics computed | mase, rmsse, mae, rmse |
src/cluster_erp/modules/analytics/forecasting.py:59 |
| Metrics refused with an explanation | mape, smape, mdape, gmrae |
src/cluster_erp/modules/analytics/forecasting.py:60 |
Rules (src/cluster_erp/modules/analytics/forecasting.py:24-45):
- Accuracy is only computed out of sample, with a rolling origin; no in-sample accuracy figure is produced (
src/cluster_erp/modules/analytics/forecasting.py:247). - MASE and RMSSE scale by the in-sample error of the naive forecast over the training span only; a zero denominator is refused (
src/cluster_erp/modules/analytics/forecasting.py:163-197). - A seasonal series uses the seasonal denominator; seasonal naive needs the period and one full cycle.
- A series with a gap is refused for methods that need a contiguous history, and the refusal names the periods.
GET /analysis/baselines/{fact_key} compares the baselines on a series (src/cluster_erp/modules/analytics/routes.py:204-241, src/cluster_erp/modules/analytics/forecasting.py:330).
ABC and SBC classification¶
| Method | Classes | Parameters from settings | Source |
|---|---|---|---|
| ABC by usage value | A, B, C, UNCLASSIFIED |
analytics_abc_cutoff_a_pct 80, analytics_abc_cutoff_b_pct 95, analytics_abc_hysteresis_pct 2, analytics_abc_min_periods 3 |
src/cluster_erp/modules/analytics/classification.py:46, src/cluster_erp/modules/analytics/classification.py:56-70, src/cluster_erp/config/settings.py:458-471 |
| SBC by demand pattern | smooth, intermittent, erratic, lumpy, UNCLASSIFIED |
analytics_sbc_adi_threshold 1.32, analytics_sbc_cv2_threshold 0.49, analytics_sbc_min_occurrences 3 |
src/cluster_erp/modules/analytics/classification.py:48, src/cluster_erp/modules/analytics/classification.py:246-262, src/cluster_erp/config/settings.py:476-479 |
Rules (src/cluster_erp/modules/analytics/classification.py:7-35):
- Separate up and down thresholds (hysteresis) keep items from churning between classes; the previous class is passed in.
- Items with short history get
UNCLASSIFIED, never a defaultC. - The drivers of each score are returned, so a single large order is visible.
- SBC refuses a series with unknown periods; CV squared is computed on non-zero values only (
src/cluster_erp/modules/analytics/classification.py:258-262,src/cluster_erp/modules/analytics/classification.py:290-310).
Saved analysis models¶
A saved model stores a kind, a fact key, and parameters, never results and never physical names. Each run goes through the normal service path under the runner's current permissions (src/cluster_erp/modules/analytics/saved_models.py:1-14).
| Rule | Detail | Source |
|---|---|---|
| Kinds | 24 kinds, from analysis, series, and baselines to cross_compare, cross_correlate, and regression |
src/cluster_erp/modules/analytics/saved_models.py:34-59 |
| Parameter size | at most 16384 bytes | src/cluster_erp/modules/analytics/saved_models.py:61 |
| Run history | the last 8 runs are kept | src/cluster_erp/modules/analytics/saved_models.py:85 |
| Visibility | the owner sees own models; is_shared opens read and run to everyone entitled to the app; editing and deactivation are owner-only |
src/cluster_erp/modules/analytics/saved_models.py:10-11, src/cluster_erp/modules/analytics/saved_models.py:142-174 |
| Removal | deactivation needs a reason and sets deleted_at, deleted_by, and deactivation_reason |
src/cluster_erp/modules/analytics/saved_models.py:215-228 |
The model routes are list, create, read, update, deactivate, and run (src/cluster_erp/modules/analytics/routes.py:946-1069).
Constraints and validation¶
- An unknown model kind is refused with the list of available kinds (
src/cluster_erp/modules/analytics/saved_models.py:93-99). - A model saved by someone with broader access widens nothing: the runner's catalogue does not contain the fact, and the run reports it unknown (
src/cluster_erp/modules/analytics/saved_models.py:6-9).
Terms introduced¶
| Term | Code identifier | Definition | Turkish term | Source |
|---|---|---|---|---|
| calendar spine | period_series |
The full list of periods in a window, onto which values are joined so gaps stay visible. | Takvim omurgası | src/cluster_erp/modules/analytics/series.py:79 |
| baseline forecast | forecast_baseline |
A simple reference forecast that any forecast must beat. | Temel tahmin | src/cluster_erp/modules/analytics/forecasting.py:88 |
| ABC class | classify_abc |
A class by share of usage value that decides how an item is managed. | ABC sınıfı | src/cluster_erp/modules/analytics/classification.py:56 |
| SBC class | classify_sbc |
A demand pattern class from inter-demand interval and variability. | SBC sınıfı | src/cluster_erp/modules/analytics/classification.py:246 |
Related pages¶
Verified against commit 92f8051 on 2026-11-13.