Move unique stats duration calculation to Heartbeatable - #1660
skyfallwastaken wants to merge 1 commit into
Conversation
Amp-Thread-ID: https://ampcode.com/threads/T-01a05ac9-4592-70ce-b851-bf90e6be971a Co-authored-by: Amp <amp@ampcode.com>
Greptile SummaryThe PR moves project-filtered unique heartbeat duration calculation from the stats controller into
Confidence Score: 5/5The PR appears safe to merge with no actionable correctness, security, or quality issues identified. The filtered relation remains intact through Active Record relation scoping, and the new PostgreSQL aggregation preserves the former positive-gap, inclusive two-minute timeout, ordering, and timestamp-validity behavior with targeted endpoint coverage. Important Files Changed
Reviews (1): Last reviewed commit: "Move unique stats duration to Heartbeata..." | Re-trigger Greptile |
There was a problem hiding this comment.
Pull request overview
This PR moves the calculation of unique_total_seconds out of StatsController#user_stats and into the Heartbeatable concern, so heartbeat duration semantics (timeout gap handling and timestamp validity filtering) live with the model layer rather than being duplicated in the controller.
Changes:
- Replaced the controller-local
unique_heartbeat_secondsimplementation with a delegated relation-level calculation. - Added
Heartbeatable.duration_seconds_excluding_gaps_over_timeoutto compute coding duration while excluding gaps larger than the heartbeat timeout. - Added regression tests asserting the endpoint’s
unique_total_secondsmatches the authoritative relation result across timeout, project filter and timestamp validity scenarios (includingtest_parammode).
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
app/controllers/api/v1/stats_controller.rb |
Delegates unique_total_seconds computation to the Heartbeatable relation method and removes the controller-local implementation. |
app/models/concerns/heartbeatable.rb |
Introduces a SQL/window-function based duration calculator that excludes gaps over the timeout threshold. |
test/controllers/api/v1/stats_controller_test.rb |
Adds controller-level regression coverage ensuring API results match the new authoritative model-layer calculation. |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
| def duration_seconds_excluding_gaps_over_timeout(scope = all) | ||
| scope = scope.with_valid_timestamps | ||
| heartbeat_gaps = scope.select("LAG(time) OVER (ORDER BY time, #{quoted_table_name}.id) as duration_start, time as duration_end").where.not(time: nil) | ||
| timeout = heartbeat_timeout_duration.to_i |
f1786c8 to
6101271
Compare
Summary of the problem
StatsController#user_statscalculatedunique_total_secondswith controller-local timestamp ordering and timeout handling even though Heartbeatable owns heartbeat duration semantics.Describe your changes
Moved the distinct over-timeout gap calculation into a narrowly named Heartbeatable relation method and made the endpoint delegate to it. The established coding-only, valid timestamp and project filter behaviour is preserved, including exact timeout and date boundary handling. Added endpoint regression coverage against the authoritative relation result, including
test_parammode.Screenshots / Media
Not applicable. There are no visual changes.