# Roadmap: Kimai Heatmap Plugin ## Overview Build a Kimai dashboard widget that displays a GitHub-style activity heatmap of time tracking data. The path goes: reproducible dev environment, then prove the plugin loads and serves data, then render the heatmap visualization, then add interaction (click-through, filtering), then polish with stats and visual refinements. Tests are written alongside each feature phase (TDD), not deferred. ## Phases **Phase Numbering:** - Integer phases (1, 2, 3): Planned milestone work - Decimal phases (2.1, 2.2): Urgent insertions (marked with INSERTED) Decimal phases appear between their surrounding integers in numeric order. - [x] **Phase 1: Dev Environment** - Nix flake with local Kimai instance and seeded test data - [x] **Phase 2: Plugin Scaffold + Data Layer** - Symfony bundle, dashboard widget, aggregation API with PHPUnit tests - [x] **Phase 3: Core Heatmap Rendering** - d3.js calendar grid with color mapping, labels, tooltips, theme integration, and JS tests - [x] **Phase 4: Heatmap Interaction** - Click-through navigation, project/activity filtering, interaction tests (completed 2026-04-08) - [ ] **Phase 5: Polish** - Streak indicator, summary stats, weekend styling ## Phase Details ### Phase 1: Dev Environment **Goal**: Developer can run `nix develop` and have a working Kimai instance with test data, ready for plugin development **Depends on**: Nothing (first phase) **Requirements**: DEV-01, DEV-02, DEV-03 **Success Criteria** (what must be TRUE): 1. Running `nix develop` drops into a shell with PHP 8.2+, Composer, and Node available 2. A local Kimai instance starts and is accessible in the browser 3. The Kimai instance contains seeded time entry data spanning multiple months 4. A plugin directory is symlinked/mounted so code changes are reflected without reinstallation **Plans**: phase-1/PLAN.md Plans: - [x] 01-01: Nix flake, process-compose, setup script, .gitignore - [x] 01-02: Plugin scaffold + Kimai bootstrap verification ### Phase 2: Plugin Scaffold + Data Layer **Goal**: Plugin is recognized by Kimai, shows a widget on the dashboard, and serves aggregated daily time data via API **Depends on**: Phase 1 **Requirements**: PLUG-01, PLUG-02, PLUG-03, TEST-01, TEST-02 **Success Criteria** (what must be TRUE): 1. Kimai discovers the plugin and lists it in the plugin admin page 2. A widget placeholder appears on the Kimai dashboard 3. The API endpoint returns JSON with per-day aggregated hours and entry counts, correctly grouped by the user's timezone 4. PHPUnit tests pass for the data aggregation service and API endpoint **Plans**: phase-2/PLAN.md Plans: - [x] 02-01: HeatmapService, PHPUnit tests, API controller - [x] 02-02: Dashboard widget + template + DashboardSubscriber ### Phase 3: Core Heatmap Rendering **Goal**: The dashboard widget renders a fully styled d3.js calendar heatmap from live Kimai data **Depends on**: Phase 2 **Requirements**: HEAT-01, HEAT-02, HEAT-03, HEAT-04, HEAT-05, HEAT-06, HEAT-08, TEST-03 **Success Criteria** (what must be TRUE): 1. The widget displays a weeks-by-days calendar grid with cells colored by hours tracked (darker = more hours) 2. Hovering any cell shows a tooltip with date, hours, and entry count 3. Day-of-week labels appear on the Y-axis and month boundary labels along the top 4. Days with no tracked time render with a distinct "no data" color 5. Colors use Kimai's theme CSS variables (works with both light and dark themes) **Plans**: phase-3/PLAN.md **UI hint**: yes Plans: - [x] 03-01: JS toolchain — npm, esbuild, TypeScript, Vitest - [x] 03-02: d3 calendar heatmap with color scale, labels, tooltips + Vitest tests - [x] 03-03: Twig template integration + asset serving ### Phase 4: Heatmap Interaction **Goal**: Users can click through to daily details and filter the heatmap by project or activity **Depends on**: Phase 3 **Requirements**: HEAT-07, INTR-01, TEST-04 **Success Criteria** (what must be TRUE): 1. Clicking a day cell navigates to Kimai's timesheet view filtered to that specific date 2. A dropdown allows filtering the heatmap to show data for a single project or activity 3. Filtering updates the heatmap in place without a full page reload 4. JavaScript tests verify click navigation and tooltip interaction behavior **Plans:** 2/2 plans complete **UI hint**: yes Plans: - [x] 04-01: Day cell click navigation + project filter dropdown - [x] 04-02: Vitest tests for click navigation and filter behavior ### Phase 5: Polish **Goal**: The widget provides at-a-glance context beyond the heatmap itself -- streaks, stats, and visual cues for weekends **Depends on**: Phase 4 **Requirements**: POLI-01, POLI-02, POLI-03 **Success Criteria** (what must be TRUE): 1. A streak indicator shows the current number of consecutive days with tracked time 2. A summary stats row displays total hours, average hours/day, and the busiest day 3. Weekend days are visually distinct from weekdays (subtle border or opacity difference) **Plans**: TBD **UI hint**: yes Plans: - [ ] 05-01: TBD - [ ] 05-02: TBD ## Progress **Execution Order:** Phases execute in numeric order: 1 -> 2 -> 3 -> 4 -> 5 | Phase | Plans Complete | Status | Completed | |-------|----------------|--------|-----------| | 1. Dev Environment | 2/2 | Done | 2026-04-08 | | 2. Plugin Scaffold + Data Layer | 2/2 | Done | 2026-04-08 | | 3. Core Heatmap Rendering | 3/3 | Done | 2026-04-08 | | 4. Heatmap Interaction | 2/2 | Complete | 2026-04-08 | | 5. Polish | 0/2 | Not started | - |