Skip to content

Segments improvements: static RPM detector, dashboard queries, batch perf#249

Open
zer0stars wants to merge 2 commits intomainfrom
segments-improvements
Open

Segments improvements: static RPM detector, dashboard queries, batch perf#249
zer0stars wants to merge 2 commits intomainfrom
segments-improvements

Conversation

@zer0stars
Copy link
Member

@zer0stars zer0stars commented Feb 12, 2026

Summary

Single squashed commit with all segments-improvements work.

Features

  • Static RPM (idling) segment detectormechanism: staticRpm for contiguous idle-RPM segments; configurable maxIdleRpm, minSegmentDurationSeconds.
  • Daily activitydailyActivity query: one record per calendar day (segment count, total active time, locations, optional signal/event summaries). Max 30 days; ignitionDetection, frequencyAnalysis, or changePointDetection only (no staticRpm).
  • Segments APIsegments with signalSummaries / eventSummaries for per-segment aggregates and event counts; pagination via limit / after; default signal set when summaries requested but not specified.
  • Attestation — schema/API updates for attestations.
  • E2ELoadSampleDataInto in clickhouse_container_test.go for loading sample_data CSVs (used by local_data_test); errcheck-safe defer for file closes.
  • Chartscharts/ aligned with main.
  • Lint — Removed unused batchFloatCaseExpr / batchLocationCaseExpr in internal/service/ch/queries.go; errcheck fixes for Close().

@zer0stars zer0stars force-pushed the segments-improvements branch 3 times, most recently from a59b4fa to f145702 Compare February 12, 2026 18:52
…l/event summaries

- New detectors: RechargeDetector (SoC trough-to-peak), RefuelDetector
  (fuel rise windows), IdlingDetector (RPM-based), plus improvements to
  FrequencyDetector, ChangePointDetector, and IgnitionDetector.
- Daily activity query with per-day segment + event summaries.
- Batch aggregation queries (signals and events) for segment summaries
  with start/end SignalLocation.
- Shared utilities: mergeTimeRanges, clipTimeRange, getLevelSamples,
  getWindowedSignalCounts with unified merge pipeline.
- GraphQL schema extensions for new mechanisms, configs, and response types.
- E2E and unit tests for all new detectors.

Co-authored-by: Cursor <cursoragent@cursor.com>
@zer0stars zer0stars force-pushed the segments-improvements branch from f145702 to 91ce65f Compare February 14, 2026 07:30
@elffjs
Copy link
Member

elffjs commented Feb 18, 2026

Still reviewing this, but one comment I'd like to make is that when reviewing it's nice for me, at least, having not too many memory cells, to have focused PRs. The unrelated changes to events, attestations, etc., make it harder to get at the heart of the matter.

I'm going to try to just ignore the "other" stuff and focus on segments.

Copy link
Member

@elffjs elffjs left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we should merge. Whatever quibbles I have about the .graphql have already been set in stone. The implementation seems fine, I need more time to digest it, but it seems fine.

eventDataSummary: [eventDataSummary!]!
}

type eventDataSummary {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand why all the types are lowercased. I don't think I've ever seen that. See, e.g., the official site.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess Kevin had this pattern here before? This is truly bizarre.

Result of aggregating a float signal over an interval. Used by segments and daily activity summaries.
Same shape as one row of aggregated signal data (name, aggregation type, computed value).
"""
type SignalAggregationValue {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this speaks to how the segment stuff has a fundamentally different structure. Are we okay with this? It's sort of the difference between wide and thin tables. Originally our schema was

windowedQuery(start: "..", end: "..", step: "..") {
  windowTimestamp
  speed(agg: MAX): Float
  ..
}

and now it's, I think,

windowedQuery(start: "..", end: "..", step: "..", signals: []) {
  windowTimestamp
  aggregations {
    signalName
    aggregation
    value
  }
}

Very different. It's nice to be consistent but it's not the end of the world, but I guess I'd like to see some reasoning.

"""
Idling: Segments are contiguous periods where engine RPM remains in idle range.
"""
idling
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why are these enums lowercased? This doesn't seem typical and we didn't do it for the aggregations.

Segment IDs are stable and consistent across queries as long as the segment start
is captured in the underlying data source.

Each segment includes summary: signals, start/end location, and (when requested) eventCounts.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing a word, maybe?. "a summary"?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

Comments