iachat/lib
Shivam Mishra 9967101b48
feat(rollup): add models and write path [1/3] (#13796)
## PR#1: Reporting events rollup — model and write path

Reporting queries currently hit the `reporting_events` table directly.
This works, but the table grows linearly with event volume, and
aggregation queries (counts, averages over date ranges) get
progressively slower as accounts age.

This PR introduces a pre-aggregated `reporting_events_rollups` table
that stores daily per-metric, per-dimension (account/agent/inbox)
totals. The write path is intentionally decoupled from the read path —
rollup rows are written inline from the event listener via upsert, and a
backfill service exists to rebuild historical data from raw events.
Nothing reads from this table yet.

The write path activates when an account has a `reporting_timezone` set
(new account setting). The `reporting_events_rollup` feature flag
controls only the future read path, not writes — so rollup data
accumulates silently once timezone is configured. A `MetricRegistry`
maps raw event names to rollup column semantics in one place, keeping
the write and (future) read paths aligned.

### What changed

- Migration for `reporting_events_rollups` with a unique composite index
for upsert
- `ReportingEventsRollup` model
- `reporting_timezone` account setting with IANA timezone validation
- `MetricRegistry` — single source of truth for event-to-metric mappings
- `RollupService` — real-time upsert from event listener
- `BackfillService` — rebuilds rollups for a given account + date from
raw events
- Rake tasks for interactive backfill and timezone setup
- `reporting_events_rollup` feature flag (disabled by default)

### How to test

1. Set a `reporting_timezone` on an account
(`Account.first.update!(reporting_timezone: 'Asia/Kolkata')`)
2. Resolve a conversation or trigger a first response
3. Check `ReportingEventsRollup.where(account_id: ...)` — rows should
appear
4. Run backfill: `bundle exec rake reporting_events_rollup:backfill` and
verify historical data populates

---------

Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
2026-03-19 13:12:36 +05:30
..
action_view/template/handlers feat: Customisable Email Templates (#1095) 2020-08-06 15:21:06 +05:30
assets Initial Commit 2019-08-14 15:18:44 +05:30
captain feat: captain decides if conversation should be resolved or kept open (#13336) 2026-03-13 10:03:58 +05:30
custom_exceptions fix: PDF errors not loading in CI (#13236) 2026-01-12 15:22:15 +05:30
events feat: captain decides if conversation should be resolved or kept open (#13336) 2026-03-13 10:03:58 +05:30
filters fix: country_code should be checked against the contact (#13186) 2026-01-13 14:47:27 +05:30
integrations feat(linear): Support refresh tokens and migrate legacy OAuth tokens (#13721) 2026-03-17 13:09:03 +04:00
linear fix: escape special characters in Linear GraphQL queries (#13490) 2026-02-09 16:18:04 +05:30
llm feat: new Captain Editor (#13235) 2026-01-21 13:39:07 +05:30
redis fix: call authorization_error! on IMAP auth failures (#13560) (revert) (#13671) 2026-02-26 18:45:18 -08:00
seeders Revert "chore: Upgrade Rails to 7.2.2 and update Gemfile dependencies (#11037)" 2026-02-03 21:09:42 -08:00
tasks feat(rollup): add models and write path [1/3] (#13796) 2026-03-19 13:12:36 +05:30
test_data chore: Generate test data for bulk insertion (#11229) 2025-05-06 11:13:11 +05:30
webhooks fix(agent-bot): stabilize webhook delivery for transient upstream failures (#13521) 2026-03-02 14:18:29 +04:00
base_markdown_renderer.rb feat: support image height in markdown rendering of messages (#8177) 2023-11-02 13:51:54 -07:00
chatwoot_app.rb feat: search documentation tool for reply suggestions (#13340) 2026-01-30 16:18:33 +05:30
chatwoot_captcha.rb feat: Add hCaptcha for public forms (#4017) 2022-02-18 20:02:50 +05:30
chatwoot_exception_tracker.rb fix: modify exception tracker to log even if sentry configured (#7563) 2023-07-21 11:58:49 +03:00
chatwoot_hub.rb chore(hub): clean up legacy Captain hub flow (#13640) 2026-02-24 20:29:53 -08:00
chatwoot_markdown_renderer.rb feat: Standardize rich editor across all channels (#12600) 2025-12-08 14:43:45 +05:30
config_loader.rb chore: Add display manifest to whitelabel settings (#8708) 2024-01-16 09:50:23 +04:00
current.rb feat: captain decides if conversation should be resolved or kept open (#13336) 2026-03-13 10:03:58 +05:30
custom_markdown_renderer.rb feat: move embedding config to a yaml file (#11611) 2025-05-30 16:26:40 +05:30
dyte.rb feat: Upgrade Dyte apis to v2 (#10706) 2025-02-19 14:47:48 -08:00
exception_list.rb fix: call authorization_error! on IMAP auth failures (#13560) (revert) (#13671) 2026-02-26 18:45:18 -08:00
global_config_service.rb fix(signup): normalize account signup config checks (#13745) 2026-03-10 16:35:09 +05:30
global_config.rb chore: Add display manifest to whitelabel settings (#8708) 2024-01-16 09:50:23 +04:00
limits.rb feat: Advanced Search Backend (#12917) 2026-01-07 15:30:49 +05:30
linear.rb feat(linear): Support refresh tokens and migrate legacy OAuth tokens (#13721) 2026-03-17 13:09:03 +04:00
llm_constants.rb fix: default model for captain assistant (#13496) 2026-02-10 14:53:53 +05:30
microsoft_graph_auth.rb Revert "feat: Support Azure single-tenant application using the Graph… (#7436) 2023-06-29 16:50:18 -07:00
online_status_tracker.rb perf: reduce presence update frequency and fix background tab throttling (#13726) 2026-03-09 18:23:44 +05:30
opentelemetry_config.rb feat: Add support for Langfuse LLM Tracing via OTEL (#12905) 2025-11-21 16:31:45 -08:00
regex_helper.rb fix: Escape closing bracket in mention regex (#11877) 2025-07-04 10:35:11 +05:30
test_data.rb chore: Generate test data for bulk insertion (#11229) 2025-05-06 11:13:11 +05:30
url_helper.rb fix: Referer URL validation (#4309) 2022-03-30 14:36:22 +05:30
vapid_service.rb chore: Switch to web-push gem (#6390) 2023-02-03 18:55:22 +05:30