docs(phase-08): complete phase execution
This commit is contained in:
parent
ce0dd742bb
commit
81642cf6fc
3 changed files with 99 additions and 8 deletions
|
|
@ -70,8 +70,8 @@ Plans:
|
|||
5. PHPUnit tests cover hourly aggregation, day/hour aggregation, and filter parameter handling
|
||||
**Plans:** 2 plans
|
||||
Plans:
|
||||
- [ ] 08-01-PLAN.md — Service layer: aggregation methods, cascade queries, filter support
|
||||
- [ ] 08-02-PLAN.md — Controller: mode dispatch, cascade endpoints, TS types
|
||||
- [x] 08-01-PLAN.md — Service layer: aggregation methods, cascade queries, filter support
|
||||
- [x] 08-02-PLAN.md — Controller: mode dispatch, cascade endpoints, TS types
|
||||
|
||||
### Phase 9: Day + Combined Modes
|
||||
**Goal**: Users can view time-of-day and day/hour punchcard visualizations with a color scale legend
|
||||
|
|
|
|||
|
|
@ -4,13 +4,13 @@ milestone: v1.1
|
|||
milestone_name: Modes & Filtering
|
||||
status: executing
|
||||
stopped_at: Phase 8 context gathered
|
||||
last_updated: "2026-04-09T15:21:54.704Z"
|
||||
last_updated: "2026-04-09T20:01:00.260Z"
|
||||
last_activity: 2026-04-09
|
||||
progress:
|
||||
total_phases: 5
|
||||
completed_phases: 2
|
||||
total_plans: 4
|
||||
completed_plans: 4
|
||||
completed_phases: 3
|
||||
total_plans: 6
|
||||
completed_plans: 6
|
||||
percent: 100
|
||||
---
|
||||
|
||||
|
|
@ -25,7 +25,7 @@ See: .planning/PROJECT.md (updated 2026-04-08)
|
|||
|
||||
## Current Position
|
||||
|
||||
Phase: 8 of 10 (backend aggregation + filtering)
|
||||
Phase: 9 of 10 (day + combined modes)
|
||||
Plan: Not started
|
||||
Status: Ready to execute
|
||||
Last activity: 2026-04-09
|
||||
|
|
@ -36,7 +36,7 @@ Progress: [██░░░░░░░░] 20%
|
|||
|
||||
**Velocity (v1.0):**
|
||||
|
||||
- Total plans completed: 13
|
||||
- Total plans completed: 15
|
||||
- Phases completed: 5
|
||||
|
||||
**v1.1:**
|
||||
|
|
|
|||
|
|
@ -0,0 +1,91 @@
|
|||
---
|
||||
phase: 08-backend-aggregation-filtering
|
||||
verified: 2026-04-09T20:15:00Z
|
||||
status: passed
|
||||
score: 5/5 must-haves verified
|
||||
---
|
||||
|
||||
# Phase 8: Backend Aggregation + Filtering Verification Report
|
||||
|
||||
**Phase Goal:** Backend serves hour-level and day/hour aggregation data and accepts activity and customer filter params via custom endpoints
|
||||
**Verified:** 2026-04-09T20:15:00Z
|
||||
**Status:** passed
|
||||
**Re-verification:** No -- initial verification
|
||||
|
||||
## Goal Achievement
|
||||
|
||||
### Observable Truths
|
||||
|
||||
| # | Truth | Status | Evidence |
|
||||
|---|-------|--------|----------|
|
||||
| 1 | API endpoint accepts mode param returning hourly and day/hour aggregation data | VERIFIED | Controller `data()` uses `match($mode)` dispatching to `getHourlyAggregation` (mode=hourly) and `getDayHourAggregation` (mode=dayhour), with default falling through to daily. Response shapes: `{hours: [...], range}` and `{matrix: [...], range}`. |
|
||||
| 2 | Activity filter param narrows heatmap data to entries matching a specific activity | VERIFIED | Controller extracts `$activityId = $request->query->getInt('activity') ?: null` and passes to all service methods. Service applies `AND t.activity_id = :activity` (native SQL) or `eq('t.activity', ':activity')` (DQL) with parameterized binding. |
|
||||
| 3 | Customer filter param narrows heatmap data to all projects under a selected customer | VERIFIED | Controller extracts `$customerId` via `getInt('customer')` and passes to service. Native SQL uses subquery `t.project_id IN (SELECT p.id FROM kimai2_projects p WHERE p.customer_id = :customer)`. DQL uses `join('t.project', 'p')` + `eq('p.customer', ':customer')`. |
|
||||
| 4 | Custom cascade endpoints (/heatmap/customers, /heatmap/projects, /heatmap/activities) return entity lists using session auth | VERIFIED | Three separate controller actions with `#[Route]` attributes at `/customers`, `/projects`, `/activities`. All use `#[IsGranted('view_own_timesheet')]` (session auth, not API auth). Projects accepts optional `?customer` param for cascade filtering; activities accepts optional `?project` param. All 4 actions (data + 3 cascade) have the `view_own_timesheet` guard. |
|
||||
| 5 | PHPUnit tests cover hourly aggregation, day/hour aggregation, and filter parameter handling | VERIFIED | 21 tests, 56 assertions, all passing. Service tests: `testGetHourlyAggregationReturnsFormattedResults`, `testGetHourlyAggregationReturnsEmptyForNoData`, `testGetDayHourAggregationReturnsFormattedResults`, `testGetDayHourAggregationSundayStart`, `testGetDailyAggregationWithActivityFilter`, `testGetDailyAggregationWithCustomerFilter`. Controller tests: `testDataReturnsHourlyMode`, `testDataReturnsDayHourMode`, `testDataDefaultsToDailyMode`, `testDataPassesFilterParams`, `testCustomersEndpoint`, `testProjectsEndpoint`, `testActivitiesEndpoint`, `testActivitiesWithProjectParam`. |
|
||||
|
||||
**Score:** 5/5 truths verified
|
||||
|
||||
### Required Artifacts
|
||||
|
||||
| Artifact | Expected | Status | Details |
|
||||
|----------|----------|--------|---------|
|
||||
| `Service/HeatmapService.php` | Hourly, day/hour aggregation + filter params on all queries | VERIFIED | 7 methods total (6 public + 1 private helper). `getHourlyAggregation`, `getDayHourAggregation`, `getUserCustomers`, `getUserActivities` all implemented with real SQL/DQL. `getDailyAggregation` extended with `$customerId` and `$activityId` params. `getUserProjects` extended with optional `$customerId`. |
|
||||
| `Tests/Service/HeatmapServiceTest.php` | Unit tests for all new service methods | VERIFIED | 13 tests covering hourly, day/hour, filter params, customer/activity entity queries, sunday/monday weekStart remapping. Both `createServiceWithResults` and `createServiceWithNativeResults` helpers present. |
|
||||
| `Controller/HeatmapController.php` | Mode dispatch, filter params, cascade endpoints | VERIFIED | 4 actions: `data` (mode dispatch + filters), `customers`, `projects` (with customer cascade), `activities` (with project cascade). All routes annotated with `IsGranted`. |
|
||||
| `Tests/Controller/HeatmapControllerTest.php` | Unit tests for mode dispatch and cascade endpoints | VERIFIED | 9 tests covering hourly mode, dayhour mode, daily default, filter passthrough, customers/projects/activities endpoints, activities with project param. |
|
||||
| `assets/src/types.ts` | HourEntry, DayHourEntry, HourlyData, DayHourData types | VERIFIED | All 4 interfaces present with correct shapes matching API response contracts. |
|
||||
|
||||
### Key Link Verification
|
||||
|
||||
| From | To | Via | Status | Details |
|
||||
|------|----|-----|--------|---------|
|
||||
| Controller data() | Service getHourlyAggregation | `$service->getHourlyAggregation(...)` | WIRED | Called in match 'hourly' branch with all 6 params |
|
||||
| Controller data() | Service getDayHourAggregation | `$service->getDayHourAggregation(...)` | WIRED | Called in match 'dayhour' branch with 7 params including weekStart |
|
||||
| Controller customers() | Service getUserCustomers | `$service->getUserCustomers(...)` | WIRED | Direct call with user |
|
||||
| Controller activities() | Service getUserActivities | `$service->getUserActivities(...)` | WIRED | Called with user and optional projectId |
|
||||
| Service native SQL | DBAL Connection | `$this->entityManager->getConnection()` | WIRED | Used in getHourlyAggregation and getDayHourAggregation |
|
||||
| Service DQL queries | TimesheetRepository QueryBuilder | `$this->repository->createQueryBuilder('t')` | WIRED | Used in getDailyAggregation, getUserProjects, getUserCustomers, getUserActivities |
|
||||
|
||||
### Data-Flow Trace (Level 4)
|
||||
|
||||
Not applicable -- these are backend service/controller methods returning data from DB queries. No rendering of dynamic data occurs in this phase.
|
||||
|
||||
### Behavioral Spot-Checks
|
||||
|
||||
| Behavior | Command | Result | Status |
|
||||
|----------|---------|--------|--------|
|
||||
| PHPUnit full suite passes | `php dev/kimai/vendor/bin/phpunit --configuration Tests/phpunit.xml` | 21 tests, 56 assertions, 0 failures | PASS |
|
||||
|
||||
### Requirements Coverage
|
||||
|
||||
| Requirement | Source Plan | Description | Status | Evidence |
|
||||
|-------------|------------|-------------|--------|----------|
|
||||
| API-01 | 08-01, 08-02 | API endpoint accepts mode param returning hour-level and day/hour aggregation data | SATISFIED | Controller mode dispatch + service aggregation methods |
|
||||
| API-02 | 08-02 | API endpoint accepts activity and customer filter params with own controller endpoints | SATISFIED | Filter params on data(), plus cascade endpoints /customers, /projects, /activities |
|
||||
| FILT-02 | 08-01 | Activity filtering narrows heatmap data to a specific activity | SATISFIED | `activityId` param on all aggregation methods with parameterized WHERE |
|
||||
| FILT-03 | 08-01 | Customer filtering narrows heatmap data to all projects under a customer | SATISFIED | `customerId` param with subquery/join filtering on all aggregation methods |
|
||||
| TEST-03 | 08-01, 08-02 | PHPUnit tests for hour-level and day/hour aggregation queries | SATISFIED | 13 service tests + 9 controller tests, all passing |
|
||||
|
||||
No orphaned requirements found -- all 5 requirement IDs mapped to this phase appear in plan frontmatter.
|
||||
|
||||
### Anti-Patterns Found
|
||||
|
||||
| File | Line | Pattern | Severity | Impact |
|
||||
|------|------|---------|----------|--------|
|
||||
| None | - | - | - | - |
|
||||
|
||||
No TODOs, FIXMEs, placeholders, empty returns, or stub patterns found in any phase files.
|
||||
|
||||
### Human Verification Required
|
||||
|
||||
No human verification items needed. All truths are verifiable through code inspection and automated tests.
|
||||
|
||||
### Gaps Summary
|
||||
|
||||
No gaps found. All 5 roadmap success criteria verified against actual codebase artifacts. All requirement IDs satisfied. All tests passing.
|
||||
|
||||
---
|
||||
|
||||
_Verified: 2026-04-09T20:15:00Z_
|
||||
_Verifier: Claude (gsd-verifier)_
|
||||
Loading…
Add table
Reference in a new issue