Both changes are implemented and merged (#539, #541). Promote their deltas into openspec/specs/, move the changes to changes/archive/2026-06-14-*, and add the two capabilities to the CAPABILITIES index. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1.5 KiB
1.5 KiB
1. Aggregate query
- 1.1 Added
getWeeklyDistance(ownerId, { publicOnly, weeks = 12 })toactivities.server.ts:sum(distance)per week, viewer-scoped. - 1.2 Gap-fill done in SQL (
generate_seriesof week-starts LEFT JOINed to the activities) — returns exactly N contiguous{ weekStart, distance }rows, oldest→newest, and guarantees the week boundaries match Postgresdate_trunc('week', …)(no JS/Postgres boundary drift). Filter conditions live in the JOIN's ON clause so empty weeks survive.
2. Loader & view
- 2.1 Profile loader fetches it in parallel with the stats, same
publicOnly: !isOwnscoping, only when content is visible. - 2.2
WeeklyDistanceChart: SVG bars normalized to the busiest week, per-bartitledistance (viastats.ts), localized label; renders nothing when every week is 0. Mounted underProfileStats.
3. i18n
- 3.1 Added
journal.profileStats.weeklyDistance(label) to en + de. Per-bar readout is the language-neutral km distance.
4. Tests & checks
- 4.1 Gap-fill is in SQL (no JS helper to unit-test) → covered by the e2e (a real activity produces a non-zero bar over a full 12-week axis).
- 4.2 Component (jsdom): one bar per week incl. zero weeks; nothing when all zero; heights normalized to the busiest week.
- 4.3 E2E
profile-weekly-distance.test.ts: create an activity with distance → the weekly chart renders on the profile. Passes locally. - 4.4 typecheck + lint + unit (journal 321) green; new e2e passes locally. Full
pnpm test:e2eruns in CI.