LST-59 (3.1) backend. New native reporting module that aggregates across
TimeTracking/ProjectManagement/Absence with ZERO direct inter-module imports —
coupled only to the physical SQL schema via read-only DBAL (AuditLog provider
pattern).
- 4 read-only reports (ApiResource + DBAL provider + readonly DTO,
paginationEnabled false, security reporting.view): /api/reports/
{time-per-project, time-per-user, tasks-by-status, absences-by-type}.
All filters bound-param, dates validated YYYY-MM-DD (default = current month),
int filters validated by regex (cs-fixer-stable).
- No Doctrine entity, no migration. ReportFilterTrait centralises validation.
Absence status compared by literal 'approved' to avoid importing the enum.
- ReportingModule registered (id reporting, reporting.view/export perms);
sidebar /reporting item gated by module + permission (ROLE_ADMIN section).
169 tests green (163 + 6), 4 routes exposed, cs-fixer clean.
Tranche 3 of LST-65. Task and Project adopt TimestampableBlamableTrait.
- Additive migration on task and project: created_at/updated_at (nullable),
created_by/updated_by (nullable INT, FK to "user" ON DELETE SET NULL) +
indexes + COMMENT ON COLUMN. down() drops only the added objects.
- Trait fields stay out of the existing API groups (trait carries its own).
- Functional test (TaskTimestampableTest) confirms created_at on persist and
updated_at refresh on update.
161 tests green, no destructive migration.
First business module of Phase 2 (LST-64, rodage). Strangler-style,
additive move — no behavioural change to the public API or MCP tools.
- New module App\Module\TimeTracking (TimeTrackingModule, id "time-tracking",
declares time-tracking.entries.view/export permissions in the RBAC catalog;
operation security left on ROLE_USER, not re-wired here).
- Move TimeEntry entity, repository (now interface + Doctrine impl bound in
services.yaml), ActiveTimeEntryProvider, export service/controller and the
4 MCP TimeEntry tools into the module. #[ApiResource] (operations, security,
uriTemplates /time_entries/*), filters and serialization groups preserved.
- Doctrine mapping "TimeTracking" added; table time_entry unchanged.
- Sidebar item gated with module "time-tracking" (SidebarFilter disables the
route when the module is inactive).
- Timestampable/Blamable adopted (first adopter): additive migration adds
created_at/updated_at/created_by/updated_by (nullable, FK SET NULL) +
COMMENT ON COLUMN. Functional test confirms created_at on persist and
updated_at refresh on update — the suspected preUpdate recompute issue does
not occur (Doctrine ORM 3.6.2 recomputes change sets after preUpdate).
159 tests green, schema mapping valid, php-cs-fixer clean.