The analytics module in src/cluster_erp/modules/analytics/ analyses data that other modules declare to it over the EventBus. It imports no other module and knows no table of its own business; each module states which of its data can be analysed, and that declaration is also the allow-list for every query (src/cluster_erp/modules/analytics/module.py:15-27, src/cluster_erp/modules/analytics/registry.py:1-16). The module refuses to produce a number whenever it cannot produce a correct one (src/cluster_erp/modules/analytics/errors.py:1-13). This page is the overview; the sub-topics have their own pages.
At a glance¶
| Item | Value | Source |
|---|---|---|
| Package | src/cluster_erp/modules/analytics/ |
folder |
| Module class | Module |
src/cluster_erp/modules/analytics/module.py:15 |
name / version |
analytics / 0.1.0 |
src/cluster_erp/modules/analytics/module.py:29-35 |
| API prefix | /api/v1/analytics (ModuleBase.api_prefix) with the router prefix /analysis and the app gate require_app("analytics") |
src/cluster_erp/core/module_base.py:37-38, src/cluster_erp/modules/analytics/module.py:47-55, src/cluster_erp/modules/analytics/routes.py:30 |
| Sub-modules | none; 24 Python files at the top level including __init__.py, for example registry.py, query_builder.py, recipe_engine.py, statistics.py, inference.py, forecasting.py, classification.py, series.py, summaries.py, saved_models.py, reports.py, profiling.py, cross.py |
folder listing |
| Tables | 5: analytics_saved_models, analytics_reports, analytics_report_items, analytics_summary_cells, analytics_summary_state |
__tablename__ in src/cluster_erp/modules/analytics/models.py |
| Entities in metadata | 0 (entities={}) |
src/cluster_erp/modules/analytics/module.py:162 |
| Routes | 47 route decorators in the package | grep for @...router.get/post/put/patch/delete |
| Actions | 0 ActionMeta entries |
grep "ActionMeta(" in the package |
| Migrations | 4 files | files in migrations/versions/ whose text contains one of the five table names |
| Contracts | consumes 0, produces 2 | see the section "Events and queries" |
| Web app presence | Catalogue app analytics; eight custom widgets and the home widget home_model from a gated bundle |
src/cluster_erp/modules/app_store/catalog.json (entry analytics), gated_apps/analytics/app.js:4250-4251 |
| Desktop presence | generic widgets only | src/cluster_erp/desktop/modules/ has no analytics folder |
What the module does¶
- Collects the fact sets of all modules and validates them; a malformed contribution fails loudly (
src/cluster_erp/modules/analytics/registry.py:242-283). See analytics facts. - Builds safe aggregate queries from semantic keys and refuses wrong totals through correctness gates (
src/cluster_erp/modules/analytics/query_builder.py:1-31). See recipes and query builder. - Runs declarative preparation recipes and measures each step (
src/cluster_erp/modules/analytics/recipe_engine.py:1-21). - Profiles data, computes robust statistics and outlier screens, and runs hypothesis tests behind precondition gates (
src/cluster_erp/modules/analytics/profiling.py:1-33,src/cluster_erp/modules/analytics/statistics.py:1-30,src/cluster_erp/modules/analytics/inference.py:1-34). See statistics and inference. - Builds period series with visible gaps, baseline forecasts, and ABC and SBC classes (
src/cluster_erp/modules/analytics/series.py:1-36,src/cluster_erp/modules/analytics/forecasting.py:1-45,src/cluster_erp/modules/analytics/classification.py:1-35). See forecasting and classification. - Keeps saved analysis models, reports with result snapshots, pre-aggregated summary cells, and cross-fact comparisons (
src/cluster_erp/modules/analytics/saved_models.py:1-14,src/cluster_erp/modules/analytics/reports.py:1-17,src/cluster_erp/modules/analytics/summaries.py:1-30,src/cluster_erp/modules/analytics/cross.py:1-15). See reports, summaries, and cross.
Sub-modules¶
The module has no sub-module folders. Its files group into these pages:
| Area | Files | Page |
|---|---|---|
| Fact collection and queries | registry.py, query_builder.py, recipe_engine.py, recipe_schemas.py, schemas.py, service.py, errors.py |
Recipes and query builder |
| Statistics | statistics.py, inference.py, inference_service.py, distributions.py, stratification.py |
Statistics and inference |
| Time and classes | series.py, forecasting.py, classification.py, saved_models.py |
Forecasting and classification |
| Outputs | reports.py, summaries.py, profiling.py, cross.py |
Reports, summaries, and cross |
| Contributions of other modules | analytics_facts.py in nine modules |
Analytics facts |
All routes live in one router with the prefix /analysis (src/cluster_erp/modules/analytics/routes.py:30).
Data model¶
| Entity | Table | Key fields | Notes | Source |
|---|---|---|---|---|
AnalyticsSavedModel |
analytics_saved_models |
name, description, kind, fact_key, params, owner_id, is_shared, last_run_at, run_count, run_history |
stores parameters, never results | src/cluster_erp/modules/analytics/models.py:32-63 |
AnalyticsReport |
analytics_reports |
name, description, owner_id, is_shared |
a shareable document | src/cluster_erp/modules/analytics/models.py:66-84 |
AnalyticsReportItem |
analytics_report_items |
report_id, position, title, note, kind, fact_key, params, result, captured_at |
stores the result snapshot with its capture time | src/cluster_erp/modules/analytics/models.py:86-110 |
AnalyticsSummaryCell |
analytics_summary_cells |
fact_key, axis, bucket_day, dims, n, sums, counts, computed_at |
derived data on plain Base, integer id, no audit columns |
src/cluster_erp/modules/analytics/models.py:112-135 |
AnalyticsSummaryState |
analytics_summary_state |
fact_key, axis, watermark, refreshed_at, rebuilt_at, cells |
refresh watermark per fact and date axis | src/cluster_erp/modules/analytics/models.py:137-148 |
Screens and metadata¶
get_metadata declares a sidebar group Analytics (Turkish Analitik) with eight custom sections: Explore, Analysis, Series & Baselines, Classification, Tests, Cross, Models, and Reports, plus a home widget Analytics of size 2x3 (src/cluster_erp/modules/analytics/module.py:75-161). The code comment states that every screen is a custom widget because the surfaces are instruments over the semantic layer, not entity lists (src/cluster_erp/modules/analytics/module.py:91-94). The catalogue the screens read carries labels, grains, additivity, and the monetary flag of each measure, so a new contributing module needs no interface code (src/cluster_erp/modules/analytics/service.py:63-125). See gated app bundles and home widgets.
Status and actions¶
The module declares no ActionMeta. Saved models and reports are deactivated through POST .../deactivate routes (src/cluster_erp/modules/analytics/routes.py:1001, src/cluster_erp/modules/analytics/routes.py:1120).
Business rules¶
- The permission gate applies twice: the catalogue shows only fact sets whose
read_permissionthe caller holds, and a run looks the fact up in that filtered catalogue again. An unauthorised set answers as unknown, not as forbidden (src/cluster_erp/modules/analytics/service.py:1-7,src/cluster_erp/modules/analytics/registry.py:100-109,src/cluster_erp/modules/analytics/service.py:135-138). - A query references only semantic keys; physical names come only from module declarations, and values are bound parameters (
src/cluster_erp/modules/analytics/query_builder.py:5-10,src/cluster_erp/modules/analytics/schemas.py:1-11). - Results are capped at 10000 rows and say when they were truncated (
src/cluster_erp/modules/analytics/query_builder.py:60,src/cluster_erp/modules/analytics/service.py:150-155). - Refusals carry machine-readable codes such as
ANALYTICS_NON_ADDITIVE,ANALYTICS_MIXED_CURRENCY, andANALYTICS_INSUFFICIENT_DATA(src/cluster_erp/modules/analytics/errors.py:21-43).
Events and queries¶
The module consumes no contract and produces 2, counted as on the fleet module page. It does not subscribe to anything; it emits DescribeAnalyticsFacts and collects the answers (src/cluster_erp/modules/analytics/module.py:57-61).
| Direction | Contract class | Handler or emitter | Source |
|---|---|---|---|
| emits | DescribeAnalyticsFacts |
registry.collect |
src/cluster_erp/modules/analytics/registry.py:242-283 |
| builds | AnalyticsDimension |
profile_targets in profiling |
src/cluster_erp/modules/analytics/profiling.py:133 |
The collection path is on analytics facts; the full contract list is on the contracts reference.
Permissions¶
| Permission key | Used by | Source |
|---|---|---|
analysis.read |
catalogue, profile, statistics, series, tests, models and reports reads (33 routes) | src/cluster_erp/modules/analytics/routes.py (grep 'require_permission("analysis.read")') |
analysis.run |
POST /run, POST /prepare, and saved model runs (3 routes) |
src/cluster_erp/modules/analytics/routes.py (grep 'require_permission("analysis.run")') |
analysis.manage |
saved models and reports writes, summary refresh (11 routes) | src/cluster_erp/modules/analytics/routes.py (grep 'require_permission("analysis.manage")') |
On top of these keys, each fact set carries its own read_permission of the contributing module (src/cluster_erp/core/contracts.py:2126-2154).
Privacy, retention, and history¶
The module has no privacy_handlers.py and no retention_handlers.py. Saved models and reports are deactivated, not deleted (src/cluster_erp/modules/analytics/saved_models.py:12-13, src/cluster_erp/modules/analytics/reports.py:14-15). Summary cells are derived data that the refresh deletes and rewrites; the docstring states that this is not the deletion of a record (src/cluster_erp/modules/analytics/summaries.py:18-20, src/cluster_erp/modules/analytics/summaries.py:245-295).
Analytics facts¶
This module has no analytics_facts.py; it is the consumer of the other modules' files. See analytics facts.
Settings and reference data¶
The statistical parameters are server settings with a prefix analytics_, for example analytics_quantile_type, analytics_min_n_for_zscore, and the ABC cut-offs (src/cluster_erp/config/settings.py:437-476). See settings reference. A background loop refreshes the summary cells at the interval analytics_summary_refresh_seconds (src/cluster_erp/server/app.py:461-470).
Tests¶
Found by name: 18 files tests/test_analytics_*.py and 12 files web-client/_e2e_analytics*.mjs.
| Kind | File | Covers |
|---|---|---|
| pytest | tests/test_analytics_gates.py, tests/test_analytics_contributions.py |
correctness gates and module contributions |
| pytest | tests/test_analytics_recipe.py, tests/test_analytics_profiling.py |
recipes and profiling |
| pytest | tests/test_analytics_statistics.py, tests/test_analytics_inference.py, tests/test_analytics_inference2.py, tests/test_analytics_shapiro.py, tests/test_analytics_rmanova.py, tests/test_analytics_logit.py, tests/test_analytics_pca_kmeans.py, tests/test_analytics_stratification.py, tests/test_analytics_plots.py |
statistics and tests |
| pytest | tests/test_analytics_forecasting.py, tests/test_analytics_classification.py |
forecasting and classes |
| pytest | tests/test_analytics_saved_models.py, tests/test_analytics_summaries.py, tests/test_analytics_cross.py |
models, summaries, cross |
| e2e | web-client/_e2e_analytics.mjs, web-client/_e2e_analytics_app.mjs, web-client/_e2e_analytics_widget.mjs |
API, app, and home widget |
| e2e | web-client/_e2e_analytics_recipe.mjs, web-client/_e2e_analytics_profile.mjs, web-client/_e2e_analytics_statistics.mjs, web-client/_e2e_analytics_infer.mjs, web-client/_e2e_analytics_forecast.mjs, web-client/_e2e_analytics_classify.mjs, web-client/_e2e_analytics_models.mjs, web-client/_e2e_analytics_reports.mjs, web-client/_e2e_analytics_summaries.mjs |
each analytics area |
Discrepancies¶
Terms introduced¶
| Term | Code identifier | Definition | Turkish term | Source |
|---|---|---|---|---|
| semantic layer | FactCatalogue |
The validated set of fact sets that analytics may query, keyed by semantic keys. | Anlamsal katman | src/cluster_erp/modules/analytics/registry.py:57-61 |
| correctness gate | _gate_additivity, _gate_currency |
A check that refuses a query whose result would be wrong. | Doğruluk kapısı | src/cluster_erp/modules/analytics/query_builder.py:242, src/cluster_erp/modules/analytics/query_builder.py:290 |
| saved analysis model | AnalyticsSavedModel |
A named, re-runnable analysis that stores parameters, not results. | Kayıtlı analiz modeli | src/cluster_erp/modules/analytics/models.py:32 |
Related pages¶
- Modules index
- Recipes and query builder
- Statistics and inference
- Forecasting and classification
- Reports, summaries, and cross
- Analytics facts
- API reference for this module
Verified against commit 92f8051 on 2026-11-13.