Factorizer/Cluster ERP WikiCluster ERP Türkçe
Home / Business modules

Reference

Analytics reports, summaries, and cross

Reference for analytics reports with result snapshots, the pre-aggregated summary cells and their refresh, data profiling, and cross-fact comparison.

This page describes four files of the analytics module in src/cluster_erp/modules/analytics/: reports.py (documents built from captured results), summaries.py (pre-aggregated summary cells), profiling.py (data profiles and the shared column allow-list), and cross.py (alignment of two fact sets on a period axis).

Scope and source

  • Defined in: ReportService (src/cluster_erp/modules/analytics/reports.py:73), the summary functions load_states, refresh, and plan (src/cluster_erp/modules/analytics/summaries.py:345-500), profile_targets and Profiler (src/cluster_erp/modules/analytics/profiling.py:118-142), and the pure functions of cross.py (src/cluster_erp/modules/analytics/cross.py:28-157).
  • Tables: analytics_reports, analytics_report_items, analytics_summary_cells, analytics_summary_state (src/cluster_erp/modules/analytics/models.py:66-148).
  • Routes: /analysis/reports (9 routes), /analysis/summaries and /analysis/summaries/refresh, /analysis/profile/{fact_key}, /analysis/cross/compare/{fact_a}, and /analysis/cross/correlate/{fact_a} (src/cluster_erp/modules/analytics/routes.py:56-78, src/cluster_erp/modules/analytics/routes.py:686-785, src/cluster_erp/modules/analytics/routes.py:1071-1237).

Reports

A report is a named document of captured analysis results. A report item stores the kind, fact, and parameters, and also the result snapshot with its capture time, so a report never changes when the data does (src/cluster_erp/modules/analytics/reports.py:1-17).

Rule Detail Source
Visibility owner plus organisation-wide is_shared; editing is owner-only src/cluster_erp/modules/analytics/reports.py:10-12
Access answers a foreign private report answers not found; a shared report edited by a non-owner answers forbidden src/cluster_erp/modules/analytics/reports.py:12-14
Content snapshots contain semantic keys and computed numbers only src/cluster_erp/modules/analytics/reports.py:15-17
Items add, update, move, and remove items src/cluster_erp/modules/analytics/reports.py:222-362
Removal a report is deactivated with a reason src/cluster_erp/modules/analytics/reports.py:198-220

Summary cells

The summary cells keep, per fact set and per date axis, one row per day and combination of summary dimensions, with the row count and the sum and non-null count of every decomposable measure. A report that fits the cells is answered from them, and the current day is always read live (src/cluster_erp/modules/analytics/summaries.py:1-17).

flowchart LR
 F["fact table rows"] -->|refresh by updated_at watermark| C["AnalyticsSummaryCell per day and dims"]
 F -->|full rebuild| C
 C --> P{"summaries.plan"}
 T["today rows, live"] --> P
 P -->|fits| S["answer source summary"]
 P -->|Ineligible with reason| L["answer source live"]

In prose:

  • Cells are keyed by every text and boolean dimension and by the reference dimensions that the contributing module marked rollup (src/cluster_erp/modules/analytics/summaries.py:89-99).
  • A measure is served from cells only when its aggregation decomposes: count, sum, and avg as sum over count. count_distinct, median, min, and max stay live (src/cluster_erp/modules/analytics/summaries.py:21-23).
  • A query that uses a dimension outside the summary set, a second date axis, or an ordering operator on text runs live; the result states its source and the reason (src/cluster_erp/modules/analytics/summaries.py:24-26, src/cluster_erp/modules/analytics/summaries.py:399-426, src/cluster_erp/modules/analytics/service.py:157-168).
  • Cells exclude the rows the live filter excludes; a deactivation changes updated_at, so its day is recomputed (src/cluster_erp/modules/analytics/summaries.py:27-28).
  • The refresh is incremental by updated_at every analytics_summary_refresh_seconds (default 60); a full rebuild runs every analytics_summary_rebuild_minutes (default 60). A fact set is served from cells only after its first refresh (src/cluster_erp/modules/analytics/summaries.py:29-40, src/cluster_erp/config/settings.py:528-531, src/cluster_erp/server/app.py:461-470).
  • GET /analysis/summaries shows the state per fact and axis; POST /analysis/summaries/refresh runs a refresh or a rebuild on demand (src/cluster_erp/modules/analytics/routes.py:1207-1237, src/cluster_erp/modules/analytics/service.py:170-198).

The docstring states that cells are derived data, so deleting and rewriting a cell is not the deletion of a record (src/cluster_erp/modules/analytics/summaries.py:18-20).

Profiling

A profile covers table-level and column-level metrics by default; dependency discovery runs only on demand and on a sample (src/cluster_erp/modules/analytics/profiling.py:1-14).

  • profile_targets turns a fact's declared dimensions and measure columns into the list of profilable columns. It is the shared allow-list used by statistics, inference, series, and recipes (src/cluster_erp/modules/analytics/profiling.py:118-140).
  • Deactivated rows are excluded through live_scope (src/cluster_erp/modules/analytics/profiling.py:55-68).
  • Quantiles use percentile_disc; there is no round() and no float cast in the generated SQL (src/cluster_erp/modules/analytics/profiling.py:24-27).
  • A relation larger than analytics_profile_exact_max_rows (default 200000) is profiled on a sample of analytics_profile_sample_rows (default 50000), and the profile says so (src/cluster_erp/modules/analytics/profiling.py:29-33, src/cluster_erp/modules/analytics/profiling.py:166, src/cluster_erp/config/settings.py:485-486).
  • For a monetary column whose rows span several currencies, the numeric and ordered metrics are not computed (src/cluster_erp/modules/analytics/profiling.py:216-250).

Cross-fact comparison

cross.py aligns two fact sets on a shared period axis built by the same series engine (src/cluster_erp/modules/analytics/cross.py:1-15):

  • The join is inner on periods defined on both sides; each side's exclusive periods are counted, not dropped (src/cluster_erp/modules/analytics/cross.py:41-80).
  • An optional lag shifts side B by whole periods.
  • A categorical side is derived from counts as presence or share, and the derivation is reported (src/cluster_erp/modules/analytics/cross.py:82-115).

Both fact sets resolve through the caller's permission-filtered catalogue; an unreadable side makes the whole question unknown (src/cluster_erp/modules/analytics/service.py:535-563).

Constraints and validation

  • Report items and saved models never store physical names (src/cluster_erp/modules/analytics/reports.py:15-17).
  • The summary refresh is a background loop on the server; a deployment with the refresh switched off answers everything live (src/cluster_erp/modules/analytics/summaries.py:38-39).

Terms introduced

Term Code identifier Definition Turkish term Source
summary cell AnalyticsSummaryCell One pre-aggregated row per fact, date axis, day, and dimension combination. Özet hücresi src/cluster_erp/modules/analytics/models.py:112
report item AnalyticsReportItem A captured analysis inside a report, with its result snapshot. Rapor kalemi src/cluster_erp/modules/analytics/models.py:86
profile target profile_targets A declared column that profiling and statistics may read. Profil hedefi src/cluster_erp/modules/analytics/profiling.py:118

Verified against commit 92f8051 on 2026-11-13.

Verified against commit 92f8051 · 2026-11-13