The analytics module serves the analysis catalogue, fact profiles, descriptive statistics, statistical tests, classifications, saved models, reports, and summary refreshes over HTTP. All 47 endpoints sit under /api/v1/analytics. For business meaning see the Analytics module page.
Group facts¶
| Item | Value | Source |
|---|---|---|
| Base path | /api/v1/analytics |
src/cluster_erp/core/module_base.py:37-38, src/cluster_erp/modules/analytics/module.py:55 |
| Routers | 1 router objects in 1 files; listed in the section Endpoint summary | src/cluster_erp/modules/analytics/module.py:47 |
| Endpoints | 47, counted from the route decorators and add_api_route calls of the routers that register_routes mounts |
src/cluster_erp/modules/analytics/routes.py |
| Authentication | Bearer header or session cookie, resolved by get_current_user; see Authentication and headers |
src/cluster_erp/modules/auth/guards.py:85-167 |
| Permission guard | 47 of 47 routes declare require_permission |
src/cluster_erp/modules/auth/guards.py:205-240 |
| App entitlement gate | require_app("analytics") on every mounted router |
src/cluster_erp/modules/analytics/module.py:55 |
| Error format | JSON body {"error": {...}}; see Errors |
src/cluster_erp/server/error_handler.py:33-46 |
Endpoint summary¶
One row per sub-module folder. The router prefix is added to the base path.
| Sub-module | Routers | Endpoints | Router source |
|---|---|---|---|
routes |
router (/analysis) |
47 | src/cluster_erp/modules/analytics/routes.py:28 |
Analysis endpoints¶
One router under /analysis answers catalogue and profile reads, runs ad hoc analyses and recipes, computes tests (t-test, ANOVA, chi-square, regression, and others), classifications (ABC, SBC), PCA and k-means, and manages saved models, reports with items, and summary states.
| Method | Path | Handler | Permission | Request | Query | Response | Status | Source |
|---|---|---|---|---|---|---|---|---|
GET |
/api/v1/analytics/analysis/catalogue |
get_catalogue |
analysis.read |
none | none | dict |
200 (default) | src/cluster_erp/modules/analytics/routes.py:37 |
GET |
/api/v1/analytics/analysis/profile/{fact_key} |
profile_fact |
analysis.read |
none | columns |
dict |
200 (default) | src/cluster_erp/modules/analytics/routes.py:56 |
POST |
/api/v1/analytics/analysis/run |
run_analysis |
analysis.run |
AnalysisSpec |
none | AnalysisResult |
200 (default) | src/cluster_erp/modules/analytics/routes.py:80 |
POST |
/api/v1/analytics/analysis/prepare |
run_recipe |
analysis.run |
RecipeDefinition |
none | RecipeRunResult |
200 (default) | src/cluster_erp/modules/analytics/routes.py:96 |
GET |
/api/v1/analytics/analysis/statistics/{fact_key}/{column} |
describe_column |
analysis.read |
none | none | dict |
200 (default) | src/cluster_erp/modules/analytics/routes.py:117 |
GET |
/api/v1/analytics/analysis/outliers/{fact_key}/{column} |
screen_outliers |
analysis.read |
none | method, limit |
dict |
200 (default) | src/cluster_erp/modules/analytics/routes.py:141 |
GET |
/api/v1/analytics/analysis/series/{fact_key} |
period_series |
analysis.read |
none | date_column, grain, date_from, date_to, value_column, aggregation, gap_policy |
dict |
200 (default) | src/cluster_erp/modules/analytics/routes.py:168 |
GET |
/api/v1/analytics/analysis/baselines/{fact_key} |
baseline_comparison |
analysis.read |
none | date_column, grain, date_from, date_to, value_column, horizon, m, min_train, gap_policy |
dict |
200 (default) | src/cluster_erp/modules/analytics/routes.py:204 |
GET |
/api/v1/analytics/analysis/abc/{fact_key} |
abc_classification |
analysis.read |
none | group_by, measure, date_column, grain, date_from, date_to |
dict |
200 (default) | src/cluster_erp/modules/analytics/routes.py:243 |
GET |
/api/v1/analytics/analysis/sbc/{fact_key} |
sbc_classification |
analysis.read |
none | date_column, grain, date_from, date_to, value_column, gap_policy |
dict |
200 (default) | src/cluster_erp/modules/analytics/routes.py:277 |
GET |
/api/v1/analytics/analysis/stratified/{fact_key} |
stratified_ratio |
analysis.read |
none | group_by, stratum, numerator_field, numerator_value |
dict |
200 (default) | src/cluster_erp/modules/analytics/routes.py:310 |
GET |
/api/v1/analytics/analysis/levels/{fact_key} |
dimension_levels |
analysis.read |
none | dimension |
dict |
200 (default) | src/cluster_erp/modules/analytics/routes.py:385 |
GET |
/api/v1/analytics/analysis/tests/ttest/{fact_key} |
t_test |
analysis.read |
none | value, group_by, group_a, group_b, filters |
dict |
200 (default) | src/cluster_erp/modules/analytics/routes.py:410 |
GET |
/api/v1/analytics/analysis/tests/anova/{fact_key} |
one_way_anova |
analysis.read |
none | value, group_by, filters |
dict |
200 (default) | src/cluster_erp/modules/analytics/routes.py:445 |
GET |
/api/v1/analytics/analysis/tests/mannwhitney/{fact_key} |
mann_whitney |
analysis.read |
none | value, group_by, group_a, group_b, filters |
dict |
200 (default) | src/cluster_erp/modules/analytics/routes.py:467 |
GET |
/api/v1/analytics/analysis/tests/pairedt/{fact_key} |
paired_t |
analysis.read |
none | column_a, column_b, filters |
dict |
200 (default) | src/cluster_erp/modules/analytics/routes.py:498 |
GET |
/api/v1/analytics/analysis/tests/chisquare/{fact_key} |
chi_square |
analysis.read |
none | rows, columns, filters |
dict |
200 (default) | src/cluster_erp/modules/analytics/routes.py:524 |
GET |
/api/v1/analytics/analysis/tests/correlation/{fact_key} |
correlation |
analysis.read |
none | x, y, method, filters |
dict |
200 (default) | src/cluster_erp/modules/analytics/routes.py:547 |
GET |
/api/v1/analytics/analysis/tests/kruskal/{fact_key} |
kruskal_wallis |
analysis.read |
none | value, group_by, filters |
dict |
200 (default) | src/cluster_erp/modules/analytics/routes.py:570 |
GET |
/api/v1/analytics/analysis/tests/levene/{fact_key} |
levene |
analysis.read |
none | value, group_by, filters |
dict |
200 (default) | src/cluster_erp/modules/analytics/routes.py:593 |
GET |
/api/v1/analytics/analysis/tests/wilcoxon/{fact_key} |
wilcoxon |
analysis.read |
none | column_a, column_b, filters |
dict |
200 (default) | src/cluster_erp/modules/analytics/routes.py:615 |
GET |
/api/v1/analytics/analysis/tests/normality/{fact_key} |
normality |
analysis.read |
none | value, filters |
dict |
200 (default) | src/cluster_erp/modules/analytics/routes.py:642 |
GET |
/api/v1/analytics/analysis/tests/shapiro/{fact_key} |
shapiro |
analysis.read |
none | value, filters |
dict |
200 (default) | src/cluster_erp/modules/analytics/routes.py:664 |
GET |
/api/v1/analytics/analysis/cross/compare/{fact_a} |
cross_compare |
analysis.read |
none | dim_a, level_a, date_a, fact_b, date_b, grain, date_from, date_to, value_b, agg_b, lag, filters_a, filters_b |
dict |
200 (default) | src/cluster_erp/modules/analytics/routes.py:686 |
GET |
/api/v1/analytics/analysis/cross/correlate/{fact_a} |
cross_correlate |
analysis.read |
none | date_a, fact_b, date_b, grain, date_from, date_to, value_a, agg_a, share_dim_a, share_level_a, value_b, agg_b, lag, filters_a, filters_b |
dict |
200 (default) | src/cluster_erp/modules/analytics/routes.py:735 |
GET |
/api/v1/analytics/analysis/pca/{fact_key} |
principal_components_analysis |
analysis.read |
none | columns, filters |
dict |
200 (default) | src/cluster_erp/modules/analytics/routes.py:787 |
GET |
/api/v1/analytics/analysis/cluster/{fact_key} |
kmeans_clustering |
analysis.read |
none | columns, k, filters |
dict |
200 (default) | src/cluster_erp/modules/analytics/routes.py:812 |
GET |
/api/v1/analytics/analysis/tests/rmanova/{fact_key} |
repeated_measures_anova_test |
analysis.read |
none | columns, filters |
dict |
200 (default) | src/cluster_erp/modules/analytics/routes.py:840 |
GET |
/api/v1/analytics/analysis/tests/logistic/{fact_key} |
logistic_regression_test |
analysis.read |
none | outcome, predictors, filters |
dict |
200 (default) | src/cluster_erp/modules/analytics/routes.py:865 |
GET |
/api/v1/analytics/analysis/tests/regression/{fact_key} |
regression |
analysis.read |
none | outcome, predictors, filters |
dict |
200 (default) | src/cluster_erp/modules/analytics/routes.py:893 |
GET |
/api/v1/analytics/analysis/models |
list_saved_models |
analysis.read |
none | none | list[dict[str, Any]] |
200 (default) | src/cluster_erp/modules/analytics/routes.py:946 |
POST |
/api/v1/analytics/analysis/models |
create_saved_model |
analysis.manage |
SavedModelCreate |
none | dict |
201 |
src/cluster_erp/modules/analytics/routes.py:955 |
GET |
/api/v1/analytics/analysis/models/{model_id} |
get_saved_model |
analysis.read |
none | none | dict |
200 (default) | src/cluster_erp/modules/analytics/routes.py:973 |
PUT |
/api/v1/analytics/analysis/models/{model_id} |
update_saved_model |
analysis.manage |
SavedModelUpdate |
none | dict |
200 (default) | src/cluster_erp/modules/analytics/routes.py:982 |
POST |
/api/v1/analytics/analysis/models/{model_id}/deactivate |
deactivate_saved_model |
analysis.manage |
SavedModelDeactivate |
none | dict |
200 (default) | src/cluster_erp/modules/analytics/routes.py:1001 |
POST |
/api/v1/analytics/analysis/models/{model_id}/run |
run_saved_model |
analysis.run |
none | none | dict |
200 (default) | src/cluster_erp/modules/analytics/routes.py:1017 |
GET |
/api/v1/analytics/analysis/reports |
list_reports |
analysis.read |
none | none | list[dict[str, Any]] |
200 (default) | src/cluster_erp/modules/analytics/routes.py:1071 |
POST |
/api/v1/analytics/analysis/reports |
create_report |
analysis.manage |
ReportCreate |
none | dict |
201 |
src/cluster_erp/modules/analytics/routes.py:1080 |
GET |
/api/v1/analytics/analysis/reports/{report_id} |
get_report |
analysis.read |
none | none | dict |
200 (default) | src/cluster_erp/modules/analytics/routes.py:1094 |
PUT |
/api/v1/analytics/analysis/reports/{report_id} |
update_report |
analysis.manage |
ReportUpdate |
none | dict |
200 (default) | src/cluster_erp/modules/analytics/routes.py:1104 |
POST |
/api/v1/analytics/analysis/reports/{report_id}/deactivate |
deactivate_report |
analysis.manage |
SavedModelDeactivate |
none | dict |
200 (default) | src/cluster_erp/modules/analytics/routes.py:1120 |
POST |
/api/v1/analytics/analysis/reports/{report_id}/items |
add_report_item |
analysis.manage |
ReportItemCreate |
none | dict |
201 |
src/cluster_erp/modules/analytics/routes.py:1136 |
PUT |
/api/v1/analytics/analysis/reports/{report_id}/items/{item_id} |
update_report_item |
analysis.manage |
ReportItemUpdate |
none | dict |
200 (default) | src/cluster_erp/modules/analytics/routes.py:1156 |
POST |
/api/v1/analytics/analysis/reports/{report_id}/items/{item_id}/move |
move_report_item |
analysis.manage |
ReportItemMove |
none | list[dict[str, Any]] |
200 (default) | src/cluster_erp/modules/analytics/routes.py:1173 |
POST |
/api/v1/analytics/analysis/reports/{report_id}/items/{item_id}/remove |
remove_report_item |
analysis.manage |
none | none | dict |
200 (default) | src/cluster_erp/modules/analytics/routes.py:1190 |
GET |
/api/v1/analytics/analysis/summaries |
summary_states |
analysis.read |
none | none | dict |
200 (default) | src/cluster_erp/modules/analytics/routes.py:1207 |
POST |
/api/v1/analytics/analysis/summaries/refresh |
refresh_summaries |
analysis.manage |
SummaryRefreshRequest \| None |
none | dict |
200 (default) | src/cluster_erp/modules/analytics/routes.py:1224 |
Error codes¶
The table lists the error codes that code under src/cluster_erp/modules/analytics/ raises, found by a syntax-tree scan for AppError(...), the factories in src/cluster_erp/core/errors.py (not_found, conflict, protected, permission_denied, privilege_escalation, check_version), and HTTPException(...). A status of 400 is the AppError default (src/cluster_erp/core/errors.py:23). Guard errors (401, 403), the entitlement codes, and validation errors (422) apply to every route and are listed on Errors.
No raise site found by the scan.
Events emitted¶
The table lists the contract classes that code under src/cluster_erp/modules/analytics/ passes directly to EventBus.emit, found by a syntax-tree scan. Events built in a variable first are not counted. The contracts are described in Contracts reference.
| Contract | Sites | First site |
|---|---|---|
DescribeAnalyticsFacts |
1 | src/cluster_erp/modules/analytics/registry.py:253 |
Related pages¶
Verified against commit 92f8051 on 2026-11-13.