feat(roadmap-planner): W7 — 365-day backfill + release-quarter API mode#194
Conversation
| // 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 { |
There was a problem hiding this comment.
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)` |
There was a problem hiding this comment.
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. |
There was a problem hiding this comment.
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) |
There was a problem hiding this comment.
Suggestion (consistency/period-constant): Consider using contributions.PeriodReleaseQuarter constant instead of string literal "release_quarter" for maintainability.
🤖 AI Code Review
SummaryThis PR implements W7 of the roadmap-planner audit follow-up, adding 365-day backfill support and a new Review Statistics
Critical Issues
No critical issues found. Warnings
Suggestions
Positive Feedback
Review by: alaudabot ℹ️ About this reviewThis review was automatically generated using the
|
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>
393f344 to
2d45779
Compare
Audit follow-up B13 — 2026-05-19.
Delivered in this PR
storage.backfill_daysdefault flips from 180 → 365.RebuildRecentdefault window 187 → 400 days (cap 730) — the first rebuild after a fresh deploy fully populates the year.0008_quarter_assignments.sql—(issue_key, quarter_label, source)empty table.contributions.QuarterResolver(period.go) does the lookup: table hit →source=milestone; miss + timestamp →CalendarQuarter(t)withsource=fallback; miss + zero time →source=none.MemberSummary.PeriodTotalspopulated when API receives?period=release_quarter. Read-time fold over the existing weekly rollup viaFoldWeeksByCalendarQuarter.parseQuerydefault window expands to 364 days for?period=release_quarterrequests so the chart shows a full year without explicitfrom/to.Deferred to a follow-up PR
Spelled out in
CHANGES.md:^(\d{4}Q[1-4])[::]from the summary (full-width Chinese colon:U+FF1A!), follows theBlocksinward link to the Epic, and writes(epic_key, quarter_label)intoquarter_assignments.?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 ./...— greenTestCalendarQuartercovers all four quarter boundaries + cross-yearTestFoldWeeksByCalendarQuartercovers cross-year foldsTestQuarterResolverMilestoneAndFallbackcovers milestone hit, calendar fallback, dangling input?period=release_quarterreturns folded bucketsRollback
storage.backfill_days: 180into the ConfigMap to revert the window bump.quarter_assignmentstable is additive — no rollback needed.?period=release_quarterquery mode is opt-in; clients that don't ask for it see the unchangedweek_totalsshape.🤖 Generated with Claude Code