docs(08): capture phase context
This commit is contained in:
parent
2730f4b7d5
commit
17b0865045
2 changed files with 128 additions and 0 deletions
|
|
@ -0,0 +1,94 @@
|
|||
# Phase 8: Backend Aggregation + Filtering - Context
|
||||
|
||||
**Gathered:** 2026-04-09
|
||||
**Status:** Ready for planning
|
||||
|
||||
<domain>
|
||||
## Phase Boundary
|
||||
|
||||
Backend serves hour-level and day/hour aggregation data for day-mode and combined-mode renderers (Phase 9), plus activity and customer filter params on the existing data endpoint, and cascade entity endpoints for the TomSelect pickers (Phase 10). No frontend rendering changes — this phase builds the data layer.
|
||||
|
||||
</domain>
|
||||
|
||||
<decisions>
|
||||
## Implementation Decisions
|
||||
|
||||
### Claude's Discretion
|
||||
User deferred all decisions to Claude. The following defaults are based on existing codebase patterns:
|
||||
|
||||
- **D-01:** Extend `HeatmapService` with `getHourlyAggregation()` and `getDayHourAggregation()` methods alongside the existing `getDailyAggregation()` — separate methods, not one flexible method, matching the existing service pattern
|
||||
- **D-02:** Extend the existing `/heatmap/data` endpoint with optional `mode` query param (`daily` default, `hourly`, `dayhour`) rather than separate endpoints per mode — keeps frontend fetch logic simple (one URL, add `?mode=X`)
|
||||
- **D-03:** Add `activity` and `customer` query params to the existing `/heatmap/data` endpoint — additive AND logic with existing `project` filter. Customer filter queries all projects under that customer.
|
||||
- **D-04:** Cascade endpoints: `/heatmap/customers`, `/heatmap/projects?customer={id}`, `/heatmap/activities?project={id}` — session auth (same as existing), scoped to user's own entities (timesheets they've created)
|
||||
- **D-05:** Cascade endpoint response format: `[{id: number, name: string}]` — matches existing `getUserProjects()` return shape
|
||||
- **D-06:** Hourly aggregation returns `{hour: number (0-23), hours: float, count: int}` — groups by hour-of-day across entire date range
|
||||
- **D-07:** Day/hour aggregation returns `{day: number (0-6), hour: number (0-23), hours: float, count: int}` — 7x24 matrix data, day index relative to weekStart
|
||||
- **D-08:** Timezone handling: use Kimai's user timezone setting (available via `$user->getTimezone()`) for hour grouping — entries are stored UTC, grouping must respect user's local time
|
||||
- **D-09:** Frontend extends the existing fetch call with mode/filter params — no new fetch functions, just URL parameter construction
|
||||
|
||||
</decisions>
|
||||
|
||||
<canonical_refs>
|
||||
## Canonical References
|
||||
|
||||
**Downstream agents MUST read these before planning or implementing.**
|
||||
|
||||
### Existing Backend
|
||||
- `Controller/HeatmapController.php` — Current `/heatmap/data` endpoint with project filter
|
||||
- `Service/HeatmapService.php` — `getDailyAggregation()` and `getUserProjects()` query patterns
|
||||
- `Tests/Controller/HeatmapControllerTest.php` — Existing controller test pattern with mock service
|
||||
|
||||
### Renderer Architecture (for understanding data consumers)
|
||||
- `assets/src/types.ts` — HeatmapData, DayEntry types that backend produces
|
||||
- `assets/src/heatmap.ts` — Frontend fetch and state management
|
||||
|
||||
### Requirements
|
||||
- `.planning/REQUIREMENTS.md` — API-01 (mode param), API-02 (filter params), FILT-02 (activity filter), FILT-03 (customer filter), TEST-03 (PHPUnit tests)
|
||||
|
||||
### Kimai Internals
|
||||
- Kimai's `TimesheetRepository` — base for all queries (injected into HeatmapService)
|
||||
- Kimai's entity relationships: Timesheet → Project → Customer, Timesheet → Activity
|
||||
- `App\Entity\User::getTimezone()` — user timezone for hour grouping
|
||||
|
||||
</canonical_refs>
|
||||
|
||||
<code_context>
|
||||
## Existing Code Insights
|
||||
|
||||
### Reusable Assets
|
||||
- `HeatmapService`: extend with new aggregation methods — same QueryBuilder pattern
|
||||
- `HeatmapController`: extend with new action methods and filter params
|
||||
- `getUserProjects()`: reference for cascade endpoint response shape
|
||||
- Existing test pattern: mock service, mock user via container/tokenStorage
|
||||
|
||||
### Established Patterns
|
||||
- Symfony route attributes (`#[Route]`, `#[IsGranted]`)
|
||||
- QueryBuilder with parameter binding for SQL injection safety
|
||||
- JSON response with simple array structure
|
||||
- Session auth via `IS_AUTHENTICATED_REMEMBERED` (not API auth)
|
||||
|
||||
### Integration Points
|
||||
- New controller actions register automatically via Symfony routing
|
||||
- Frontend fetch adds query params to existing `data-url` base URL
|
||||
- Cascade endpoints consumed by TomSelect pickers in Phase 10
|
||||
|
||||
</code_context>
|
||||
|
||||
<specifics>
|
||||
## Specific Ideas
|
||||
|
||||
No specific requirements — open to standard approaches
|
||||
|
||||
</specifics>
|
||||
|
||||
<deferred>
|
||||
## Deferred Ideas
|
||||
|
||||
None — discussion stayed within phase scope
|
||||
|
||||
</deferred>
|
||||
|
||||
---
|
||||
|
||||
*Phase: 08-backend-aggregation-filtering*
|
||||
*Context gathered: 2026-04-09*
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
# Phase 8: Backend Aggregation + Filtering - Discussion Log
|
||||
|
||||
> **Audit trail only.** Do not use as input to planning, research, or execution agents.
|
||||
> Decisions are captured in CONTEXT.md — this log preserves the alternatives considered.
|
||||
|
||||
**Date:** 2026-04-09
|
||||
**Phase:** 08-backend-aggregation-filtering
|
||||
**Areas discussed:** None (user deferred all to Claude's discretion)
|
||||
|
||||
---
|
||||
|
||||
## Gray Areas Presented
|
||||
|
||||
| Area | Description | Selected |
|
||||
|------|-------------|----------|
|
||||
| Aggregation query design | Query structure, timezone handling | |
|
||||
| Filter param handling | Activity + customer filter integration | |
|
||||
| Cascade endpoints | Entity list endpoints shape and scoping | |
|
||||
| Frontend data flow | Fetch URL extension vs separate endpoints | |
|
||||
|
||||
**User's choice:** "Nothing" — deferred all areas to Claude's discretion
|
||||
**Notes:** All decisions made by Claude based on existing codebase patterns (HeatmapService, HeatmapController)
|
||||
|
||||
## Claude's Discretion
|
||||
|
||||
All 4 areas deferred. Decisions D-01 through D-09 in CONTEXT.md are Claude's defaults based on:
|
||||
- Existing `getDailyAggregation()` query pattern
|
||||
- Existing controller route/auth pattern
|
||||
- Existing `getUserProjects()` response shape
|
||||
- Requirements constraints (session auth, own endpoints)
|
||||
|
||||
## Deferred Ideas
|
||||
|
||||
None
|
||||
Loading…
Add table
Reference in a new issue