Skip to content

feat(roadmap-planner): W7 — 365-day backfill + release-quarter API mode#194

Merged
danielfbm merged 1 commit into
mainfrom
feat/metrics-w7-quarter-buckets
May 19, 2026
Merged

feat(roadmap-planner): W7 — 365-day backfill + release-quarter API mode#194
danielfbm merged 1 commit into
mainfrom
feat/metrics-w7-quarter-buckets

Conversation

@danielfbm

Copy link
Copy Markdown
Contributor

Audit follow-up B13 — 2026-05-19.

Delivered in this PR

Area Change
Config storage.backfill_days default flips from 180 → 365.
Aggregator RebuildRecent default window 187 → 400 days (cap 730) — the first rebuild after a fresh deploy fully populates the year.
Schema Migration 0008_quarter_assignments.sql(issue_key, quarter_label, source) empty table.
Backend contributions.QuarterResolver (period.go) does the lookup: table hit → source=milestone; miss + timestamp → CalendarQuarter(t) with source=fallback; miss + zero time → source=none.
Backend MemberSummary.PeriodTotals populated when API receives ?period=release_quarter. Read-time fold over the existing weekly rollup via FoldWeeksByCalendarQuarter.
Backend parseQuery default window expands to 364 days for ?period=release_quarter requests so the chart shows a full year without explicit from/to.

Deferred to a follow-up PR

Spelled out in CHANGES.md:

  • Jira sync pass that walks every Milestone, parses ^(\d{4}Q[1-4])[::] from the summary (full-width Chinese colon U+FF1A!), follows the Blocks inward link to the Epic, and writes (epic_key, quarter_label) into quarter_assignments.
  • The Story / Bug → Epic Link walk that picks up parent-Epic milestone-quarter automatically.
  • Frontend ?period= tab on the Team Dashboard.

Until the Jira pass lands, every quarter label comes from CalendarQuarter(week_start) — accurate for calendar-quarter installs and a reasonable approximation for release-cadence shapes.

Test plan

  • go test ./... + go vet ./... — green
  • TestCalendarQuarter covers all four quarter boundaries + cross-year
  • TestFoldWeeksByCalendarQuarter covers cross-year folds
  • TestQuarterResolverMilestoneAndFallback covers milestone hit, calendar fallback, dangling input
  • Dev deploy: confirm migration 0008 applies and ?period=release_quarter returns folded buckets

Rollback

  • Drop storage.backfill_days: 180 into the ConfigMap to revert the window bump.
  • The quarter_assignments table is additive — no rollback needed.
  • The ?period=release_quarter query mode is opt-in; clients that don't ask for it see the unchanged week_totals shape.

🤖 Generated with Claude Code

// populates `quarter_assignments` is a follow-up to W7; until it
// lands, every resolve goes through the calendar-quarter fallback,
// and the `source` field on the returned label reflects that.
type QuarterResolver struct {

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 (design/cache-growth): The cache map grows unbounded for the lifetime of the resolver. Long-running processes could accumulate thousands of entries. Consider documenting the expected memory footprint or using a bounded cache.

// quarter label instead of a week_start timestamp. Returned by the
// W7 (2026-05-19) `?period=release_quarter` API mode.
//
// The current resolver derives the label from `CalendarQuarter(weekStart)`

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.

Suggestion (docs/json-fields): The Points field lacks a JSON tag comment. While it serializes as "points", consider adding documentation for API consumers.

// Default window is the last 400 days (W7 2026-05-19, was 187), capped
// at 730. Pass days=0 to use the default. The bump matches the
// 365-day Storage.BackfillDays so the first rebuild after a fresh
// deploy fully populates the year of rollup rows.

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.

Suggestion (consistency/naming): The comment says "was 187" but could include the W7 date (2026-05-19) for future maintainers.

}
if c.Query("period") == contributions.PeriodReleaseQuarter {
for i := range out {
out[i].PeriodTotals = contributions.FoldWeeksByCalendarQuarter(out[i].WeekTotals)

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.

Suggestion (consistency/period-constant): Consider using contributions.PeriodReleaseQuarter constant instead of string literal "release_quarter" for maintainability.

@alaudabot

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 16:04:40 UTC

Summary

This PR implements W7 of the roadmap-planner audit follow-up, adding 365-day backfill support and a new ?period=release_quarter API mode that folds weekly contribution buckets into calendar quarter labels. The changes include a new migration, new period resolution logic, and updated default configuration values. The implementation is well-tested and follows existing patterns.

Review Statistics

Category Count
Critical Issues 0
Warnings 2
Suggestions 3
Files Reviewed 8

Critical Issues

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

No critical issues found.

Warnings

Issues that SHOULD be addressed but are not blocking

  • [roadmap-planner/backend/internal/contributions/period.go:35] (design/cache-growth): The QuarterResolver.cache map grows unbounded for the lifetime of the resolver instance. While documented as per-resolver design, long-running processes could accumulate thousands of entries. Consider adding a bounded LRU cache or documenting the expected memory footprint.

  • [roadmap-planner/backend/internal/contributions/period.go] (dead-code/intent): The QuarterResolver implementation is scaffolded but not currently used in production code. The PR description states this is intentional for a future Jira sync pass. Consider adding a TODO comment or checking that this doesn't cause static analysis warnings.

Suggestions

Recommendations for improvement (nice to have)

  • [roadmap-planner/backend/internal/contributions/service.go:99] (docs/json-fields): The PeriodBucket.Points field lacks a JSON tag comment. While it correctly serializes as "points", consider adding explicit documentation for API consumers. Current: Points float64, serialized as "points".

  • [roadmap-planner/backend/internal/contributions/aggregator.go:261] (consistency/naming): The comment says "was 187" but could be clearer. Consider documenting the W7 date for future maintainers: "W7 2026-05-19: bumped from 187 to 400".

  • [roadmap-planner/backend/internal/api/handlers/contributions.go:78] (consistency/period-constant): Using string literal "release_quarter" in the parseQuery function while using constant contributions.PeriodReleaseQuarter in the handlers. Consider using the constant consistently for maintainability.

Positive Feedback

  • Excellent test coverage with TestCalendarQuarter covering all four quarter boundaries including cross-year transitions
  • Good edge case handling in TestQuarterResolverMilestoneAndFallback covering milestone hit, calendar fallback, and dangling input scenarios
  • The FoldWeeksByCalendarQuarter function correctly sums all Bucket fields into PeriodBucket
  • Migration 0008 is additive with no breaking changes - rollback path is well-documented in PR description
  • The default window expansion (84 → 364 days) for ?period=release_quarter provides a full year view without explicit from/to parameters
  • Clear documentation in CHANGES.md explaining what's delivered vs deferred
  • Proper use of UTC time handling throughout

Review by: alaudabot
PR: #194


ℹ️ 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

Audit follow-up B13 (2026-05-19). Bumps the storage window to a full
year and adds a quarter-bucket read-time fold so the dashboard can
show year-long trends grouped by release cadence.

Delivered here:
- storage.backfill_days viper default 180 -> 365.
- aggregator.RebuildRecent default window 187 -> 400 days (cap 730)
  so the first rebuild after a fresh deploy populates the year.
- New migration 0008_quarter_assignments.sql
  (issue_key, quarter_label, source). Empty on install.
- contributions.QuarterResolver (period.go) routes lookups through
  the table on hit and falls back to CalendarQuarter(t) on miss.
- MemberSummary.PeriodTotals []PeriodBucket. Populated by the
  contributions handler when ?period=release_quarter is set;
  computed via FoldWeeksByCalendarQuarter over the existing weekly
  rollup so this PR ships without a new aggregator pass.
- parseQuery default window expands to 364 days for
  ?period=release_quarter requests so the chart shows a full year
  without explicit from/to.

Tests:
- TestCalendarQuarter pins the Jan-Mar=Q1 etc. mapping at quarter
  boundaries.
- TestFoldWeeksByCalendarQuarter covers cross-year folds.
- TestQuarterResolverMilestoneAndFallback proves both paths
  (table hit + calendar fallback + dangling-input).

Deferred to a follow-up PR (explicitly called out in CHANGES.md):
- Jira sync pass that walks every Milestone, parses the
  `^(\d{4}Q[1-4])[::]` prefix (full-width Chinese colon!), follows
  the Blocks inward link to the Epic, and writes
  (epic_key, quarter_label) into quarter_assignments.
- The Story/Bug -> Epic Link walk that picks up parent-Epic
  milestone-quarter.
- Frontend ?period= tab on the Team Dashboard.

Until the Jira pass lands, every quarter label comes from
CalendarQuarter(week_start) — accurate for calendar-quarter
installs and a usable approximation for release-cadence shapes.

🤖 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-w7-quarter-buckets branch from 393f344 to 2d45779 Compare May 19, 2026 22:19
@danielfbm danielfbm merged commit 6131c41 into main May 19, 2026
@danielfbm danielfbm deleted the feat/metrics-w7-quarter-buckets branch May 19, 2026 22:19
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