Skip to content

feat: add session time metrics (active time tracking per contribution)#528

Open
leecoder wants to merge 1 commit into
junhoyeo:mainfrom
leecoder:feat/session-time-metrics
Open

feat: add session time metrics (active time tracking per contribution)#528
leecoder wants to merge 1 commit into
junhoyeo:mainfrom
leecoder:feat/session-time-metrics

Conversation

@leecoder
Copy link
Copy Markdown
Contributor

@leecoder leecoder commented May 8, 2026

Summary

Add active time tracking per contribution, enabling users to see how much time they actually spent coding.

Changes

CLI (Rust)

  • Add time-metrics subcommand showing active time, longest session, and concurrency stats
  • Sessionize contributions and populate activeTimeMs in graph/submit payloads

Frontend

  • Add active_time_ms column to daily_breakdown table (migration 0006)
  • Store and aggregate active time in submit route
  • Show time metrics in leaderboard period tabs
  • Add time formatting utilities and update profile/stats components

Testing

  • Submitted data successfully to staging server
  • Verified leaderboard displays time metrics correctly

Summary by cubic

Adds end-to-end session time metrics so users can see active coding time, longest continuous session, and peak concurrency. Leaderboards and profiles now surface time (including sort by time), and the CLI adds a time-metrics report.

  • New Features

    • Core (crates/tokscale-core): Added sessionize with a 3‑min idle gap; computes per‑day activeTimeMs and global timeMetrics (total active, wall, longest continuous with idle‑gap merge, max concurrency incl. zero‑duration, session count); graph payloads include activeTimeMs and timeMetrics; added get_time_metrics_report.
    • CLI (crates/tokscale-cli): New time-metrics subcommand with date/client filters, --json, and --no-spinner; prints total active, wall‑clock, longest continuous, max concurrency, sessions, and processing time; graph JSON includes timeMetrics and per‑day activeTimeMs; skips pricing init for faster runs.
    • API/DB/UI (packages/frontend): Submit API accepts timeMetrics; persists submission metrics (total_active_time_ms, longest_continuous_ms, max_concurrent_sessions, session_count) and daily active_time_ms; leaderboard APIs and user rank support sortBy=time; leaderboard adds a “Time” column and period totals; profile and graph stats show “Active Time” and “Sessions” (hidden when a client filter is active); added formatDuration; submission validation updated to allow timeMetrics and per‑day activeTimeMs.
  • Migration

    • Run DB migration 0007_add_time_metrics_to_submissions.sql.

Written for commit 4ac6a96. Summary will update on new commits.

@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented May 8, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
tokscale Ready Ready Preview, Comment May 11, 2026 0:47am

Request Review

Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

9 issues found across 24 files

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="packages/frontend/src/lib/format.ts">

<violation number="1" location="packages/frontend/src/lib/format.ts:48">
P3: `formatDuration`'s example documentation does not match its actual output for sub-second durations.</violation>
</file>

<file name="packages/frontend/__tests__/api/leaderboard.test.ts">

<violation number="1" location="packages/frontend/__tests__/api/leaderboard.test.ts:68">
P1: Test expects two extra positional args for `getLeaderboardData`, so the assertion will never match the real 5-arg call.</violation>
</file>

<file name="packages/frontend/src/lib/db/migrations/0006_add_time_metrics_to_submissions.sql">

<violation number="1" location="packages/frontend/src/lib/db/migrations/0006_add_time_metrics_to_submissions.sql:1">
P1: Migration omits the `daily_breakdown.active_time_ms` column required by the updated submit path, causing runtime SQL failures.</violation>
</file>

<file name="packages/frontend/src/lib/db/schema.ts">

<violation number="1" location="packages/frontend/src/lib/db/schema.ts:184">
P1: daily_breakdown is missing the active_time_ms column even though submit/leaderboard code reads and writes it, creating schema drift and risking loss of per-day active-time data.</violation>
</file>

<file name="packages/frontend/src/components/GraphContainer.tsx">

<violation number="1" location="packages/frontend/src/components/GraphContainer.tsx:184">
P2: StatsPanel mixes filtered contribution stats with unfiltered active-time/session totals, so client filtering can make the numbers inconsistent.</violation>
</file>

<file name="packages/frontend/src/app/(main)/leaderboard/LeaderboardClient.tsx">

<violation number="1" location="packages/frontend/src/app/(main)/leaderboard/LeaderboardClient.tsx:1232">
P2: The new Time sort option is not supported by the user-rank API, so the current-user rank request silently falls back to tokens and shows inconsistent results.</violation>
</file>

<file name="crates/tokscale-core/src/lib.rs">

<violation number="1" location="crates/tokscale-core/src/lib.rs:1594">
P2: Time-metrics report loads and applies pricing even though the output does not use cost data, adding avoidable latency/work (and possible network/cache fetch) for no benefit.</violation>
</file>

<file name="crates/tokscale-core/src/sessionize.rs">

<violation number="1" location="crates/tokscale-core/src/sessionize.rs:127">
P1: `longest_continuous_ms` is calculated as the max single-session active duration and the `idle_gap_ms` parameter is ignored, so the metric does not match the documented merged-window semantics.</violation>

<violation number="2" location="crates/tokscale-core/src/sessionize.rs:182">
P2: `compute_max_concurrent` undercounts zero-duration sessions; single-message sessions can report 0 concurrent sessions even though the code intends them to count as 1.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread packages/frontend/__tests__/api/leaderboard.test.ts Outdated
Comment thread packages/frontend/src/lib/db/schema.ts
Comment thread crates/tokscale-core/src/sessionize.rs
Comment thread packages/frontend/src/components/GraphContainer.tsx Outdated
Comment thread packages/frontend/src/app/(main)/leaderboard/LeaderboardClient.tsx
Comment thread crates/tokscale-core/src/lib.rs Outdated
Comment thread crates/tokscale-core/src/sessionize.rs Outdated
Comment thread packages/frontend/src/lib/format.ts Outdated
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 6 files (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="crates/tokscale-core/src/sessionize.rs">

<violation number="1" location="crates/tokscale-core/src/sessionize.rs:149">
P2: `longest_continuous_ms` is computed from wall-clock session spans, so long idle gaps inside a session are counted as continuous time and inflate the metric.</violation>
</file>

Reply with feedback, questions, or to request a fix. Tag @cubic-dev-ai to re-run a review.

Comment thread crates/tokscale-core/src/sessionize.rs Outdated
Copy link
Copy Markdown
Contributor

@cubic-dev-ai cubic-dev-ai Bot left a comment

Choose a reason for hiding this comment

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

1 issue found across 1 file (changes from recent commits).

Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="crates/tokscale-core/src/sessionize.rs">

<violation number="1" location="crates/tokscale-core/src/sessionize.rs:151">
P2: Collapsing each session to `start_ts + active_duration_ms` loses intra-session timing and can miscompute the longest continuous activity window.</violation>
</file>

Tip: Review your code locally with the cubic CLI to iterate faster.

Comment thread crates/tokscale-core/src/sessionize.rs
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.

1 participant