Skip to content

feat(roadmap-planner): W8 — review_latency_p50_hours per (reviewer, week)#195

Merged
danielfbm merged 1 commit into
mainfrom
feat/metrics-w8-review-latency
May 19, 2026
Merged

feat(roadmap-planner): W8 — review_latency_p50_hours per (reviewer, week)#195
danielfbm merged 1 commit into
mainfrom
feat/metrics-w8-review-latency

Conversation

@danielfbm

Copy link
Copy Markdown
Contributor

Audit follow-up B3 — 2026-05-19. Depends on W2 (#190) for the first_human_review_at column + is_bot tagging, so this PR is based on the W2 branch. Will be retargeted to main once W2 lands.

Summary

Aggregator.Rebuild gets a new step that walks pr_reviews ⨝ pull_requests for the rebuild window:

  1. For each non-bot review (is_bot = 0) whose submitted_at equals the PR's first_human_review_at (i.e., the review that defined the first-human touch), record the hours from pr.created_at.
  2. Group by (reviewer_id, week_of_pr.created_at).
  3. p50 per group, computed in Go for SQLite + Postgres portability.
  4. UPSERT into member_week_metrics.review_latency_p50_hours via the existing PK.

Implementation notes

  • The week_start INSERT value is formatted as YYYY-MM-DD so the PK matches what the four sibling INSERTs in Rebuild emit via dialect.WeekStart(). Without this, SQLite stores a separate row keyed on the time.Time driver format and the team-overview read shows two rows for the same (member, week).
  • New scanTimeAny / parseDateString helpers — SQLite returns week_start through strftime as TEXT; Postgres returns time.Time directly. The helper handles both.

Test plan

  • go test ./... + go vet ./... — green
  • TestAggregatorReviewLatency — 3 PRs (latencies 1h / 4h / 9h, all reviewed by alice) + a bot comment that must be ignored → p50 = 4.0
  • Dev deploy: member_week_metrics.review_latency_p50_hours populates after W2 is enabled on the dev cluster (bot consolidation must run first so first_human_review_at is populated; otherwise the new step's WHERE first_human_review_at IS NOT NULL filters out everything)

Sequencing

W1 → W2 → W8 (this PR). The PR is based on the W2 branch; once W2 merges to main, this PR rebases to main.

🤖 Generated with Claude Code

@alaudabot

alaudabot commented May 19, 2026

Copy link
Copy Markdown
Contributor

🤖 AI Code Review

Property Value
Model opencode/minimax-m2.5-free
Style strict
Issues Found 0
Config Source centralized
Profile ❌ Not Found
Personalized Prompt ❌ No
Prompt Path .github/review/profiles/alaudadevops/toolbox/pr-review.md
Alauda Skills ✅ base-acp-operator-list, base-acp-operator-release, base-authoring, base-m365, base-ocp-operator-list, base-skill-setup, builders-alauda-component-e2e-release, builders-alauda-component-upgrade, builders-alauda-pipeline, builders-claudetask-submit, builders-component-knowledge, builders-confluence, builders-dev-mesh-qa, builders-edge-ci-trace, builders-gitlab-ops, builders-helm-operator-generator, builders-install-cluster-plugin, builders-jira, builders-notify-wecom, builders-olm-operator-lifecycle, builders-prd-to-testcase, builders-publish-errata, builders-roadmap-studio, builders-story-split, builders-violet, builders-webapp-testing, cross-repo-add-mirror, cross-repo-publish, devops-add-bug-release-notes, devops-autodns, devops-bundle-csv-baseline-diff, devops-candidate-version-supervisor, devops-connectors-acceptance-test, devops-connectors-explore, devops-connectors-poc-case, devops-connectors-review, devops-connectors-unit-test, devops-connectors-upgrade-test, devops-connectors-write-user-docs, devops-creating-tekton-pipelines, devops-fix-go-vulns, devops-fork-alauda-binary-release, devops-gen-advanced-form-descriptors, devops-jira-rfd-acceptance, devops-knowledge-adoption, devops-pr-review, devops-refresh-containerfile-digests, devops-refresh-containerfile-tags, devops-replace-strings, devops-scan-docker-keywords, devops-sync-alauda-github-releases, devops-tekton-dynamic-form-optimizer, devops-tekton-operator-task-e2e, devops-tekton-pipeline-delivery, devops-tekton-refresh-results-tag, devops-tekton-task-delivery, devops-tekton-task-overview-template, devops-tekton-task-version-upgrade, devops-tekton-upgrade-notes, devops-tool-report-troubleshoot, devops-ui-e2e-code-audit, devops-ui-e2e-fix-base-on-report, devops-ui-e2e-regression-and-fix, devops-ui-generate-e2e-from-feature, devops-ui-pre-setup, devops-upgrade-go, devops-upstream-backport-cve, devops-upstream-upgrade
Reviewed at 2026-05-19 22:29:47 UTC

Summary

This PR implements W8 (review_latency_p50_hours) and W2 (bot consolidation) for the roadmap-planner team analytics. It adds tracking of human review latency per reviewer × week, filters out bot reviews from metrics, and consolidates bot activity under a synthetic "bot" member. The implementation is well-structured with comprehensive tests.

Review Statistics

Category Count
Critical Issues 0
Warnings 1
Suggestions 1
Files Reviewed 14

Critical Issues

Issues that MUST be addressed before merging (security, bugs, breaking changes)

None identified.

Warnings

Issues that SHOULD be addressed but are not blocking

  • [roadmap-planner/backend/cmd/server/main.go:218-227] The ConsolidateBots function logs errors as warnings and continues execution. If backfill fails, the system will run with potentially inconsistent data (is_bot flags not set, first_human_review_at not populated). Consider whether failures should halt startup or have a retry mechanism.

Suggestions

Recommendations for improvement (nice to have)

  • [roadmap-planner/backend/internal/contributions/aggregator_test.go] Consider adding an integration test that runs ConsolidateBots followed by Rebuild to verify the end-to-end flow with actual bot consolidation happening before the metric computation. Currently, the test directly inserts data without going through the consolidation path.

Positive Feedback

  • The scanTimeAny and parseDateString helpers correctly handle both SQLite (TEXT from strftime) and Postgres (time.Time from date_trunc) driver differences, ensuring portability.
  • The review latency query correctly filters rv.is_bot = 0 and matches on rv.submitted_at = pr.first_human_review_at to identify the first human touch.
  • The p50 calculation in Go is appropriate for small datasets per (reviewer, week) - avoids database-specific percentile functions.
  • The test TestAggregatorReviewLatency correctly validates the core logic with 3 PRs (1h, 4h, 9h latencies) yielding p50=4.0, and includes a bot review that must be ignored.
  • The ConsolidateBots function is properly idempotent - subsequent runs on already-consolidated data result in 0 rows affected.
  • The BotSet uses case-folded matching which is consistent with the lowercase storage of reviewer_login throughout the codebase.


ℹ️ About this review

This review was automatically generated using the run-actions workflow.

  • Shared prompt: .github/prompts/code-review.md
  • Config source: centralized
  • Profile path: Not Found
  • Profile ref: e75e733e9aa1b417a8b3c6441e53495dbcb418ad
  • No repository-specific prompt configured
  • Alauda skills: base-acp-operator-list, base-acp-operator-release, base-authoring, base-m365, base-ocp-operator-list, base-skill-setup, builders-alauda-component-e2e-release, builders-alauda-component-upgrade, builders-alauda-pipeline, builders-claudetask-submit, builders-component-knowledge, builders-confluence, builders-dev-mesh-qa, builders-edge-ci-trace, builders-gitlab-ops, builders-helm-operator-generator, builders-install-cluster-plugin, builders-jira, builders-notify-wecom, builders-olm-operator-lifecycle, builders-prd-to-testcase, builders-publish-errata, builders-roadmap-studio, builders-story-split, builders-violet, builders-webapp-testing, cross-repo-add-mirror, cross-repo-publish, devops-add-bug-release-notes, devops-autodns, devops-bundle-csv-baseline-diff, devops-candidate-version-supervisor, devops-connectors-acceptance-test, devops-connectors-explore, devops-connectors-poc-case, devops-connectors-review, devops-connectors-unit-test, devops-connectors-upgrade-test, devops-connectors-write-user-docs, devops-creating-tekton-pipelines, devops-fix-go-vulns, devops-fork-alauda-binary-release, devops-gen-advanced-form-descriptors, devops-jira-rfd-acceptance, devops-knowledge-adoption, devops-pr-review, devops-refresh-containerfile-digests, devops-refresh-containerfile-tags, devops-replace-strings, devops-scan-docker-keywords, devops-sync-alauda-github-releases, devops-tekton-dynamic-form-optimizer, devops-tekton-operator-task-e2e, devops-tekton-pipeline-delivery, devops-tekton-refresh-results-tag, devops-tekton-task-delivery, devops-tekton-task-overview-template, devops-tekton-task-version-upgrade, devops-tekton-upgrade-notes, devops-tool-report-troubleshoot, devops-ui-e2e-code-audit, devops-ui-e2e-fix-base-on-report, devops-ui-e2e-regression-and-fix, devops-ui-generate-e2e-from-feature, devops-ui-pre-setup, devops-upgrade-go, devops-upstream-backport-cve, devops-upstream-upgrade

@danielfbm danielfbm force-pushed the feat/metrics-w2-bot-consolidation branch from ee78c5b to df4d8bf Compare May 19, 2026 22:28
Base automatically changed from feat/metrics-w2-bot-consolidation to main May 19, 2026 22:28
// review rows ingested before this feature shipped, reassign bot
// author/reviewer ids to the synthetic `bot` member, and compute
// first_human_review_at. Idempotent — safe to run on every boot.
if bots.Size() > 0 {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Warning (bug/error-handling): Errors from ConsolidateBots are logged as warnings and execution continues. If the backfill fails, the system will run with inconsistent data (is_bot flags not set, first_human_review_at not populated). Consider whether failures should halt startup or implement a retry mechanism.

…eek)

Audit follow-up B3 (2026-05-19). Depends on W2 (this PR is based on
feat/metrics-w2-bot-consolidation so the `first_human_review_at`
column + `is_bot` tagging are available).

Aggregator.Rebuild gains a new step that walks pr_reviews ⨝
pull_requests for the rebuild window. For each non-bot review whose
submitted_at equals the PR's first_human_review_at (i.e., the row
that defined the first-human touch), we compute latency in hours
from PR creation. p50 per (reviewer_id, week_of_pr_created_at) goes
into member_week_metrics.review_latency_p50_hours via an
ON CONFLICT upsert that reuses the existing PK.

Two implementation notes:
- p50 is computed in Go using the existing percentile() helper —
  portable across SQLite + Postgres without percentile_cont().
- The week_start INSERT value is formatted as YYYY-MM-DD so the PK
  matches what the four sibling INSERTs above emit via
  dialect.WeekStart(); otherwise SQLite stores a separate row keyed
  on the time.Time driver-format and the latency falls off the
  team-overview read.

Also adds:
- scanTimeAny / parseDateString helpers — SQLite returns week_start
  as TEXT through the strftime expression; Postgres returns
  time.Time directly. The helper handles both.

Tests:
- TestAggregatorReviewLatency seeds 3 PRs with latencies 1/4/9h all
  reviewed by `alice`, plus a bot comment that must be ignored.
  Verifies p50 = 4.0.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@danielfbm danielfbm force-pushed the feat/metrics-w8-review-latency branch from a237770 to 8c862ac Compare May 19, 2026 22:31
@danielfbm danielfbm merged commit c0c4fb6 into main May 19, 2026
6 of 8 checks passed
@danielfbm danielfbm deleted the feat/metrics-w8-review-latency branch May 19, 2026 22:31
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