# Enterprise Agile Platform V2 — Implementation Report

**Date:** 2026-06-04  
**Module:** `app/Modules/Projects` only (no separate Agile module)  
**Core principle:** Tickets remain the single work item model (`tickets.work_type`).

---

## Validation status

| Check | Result |
|-------|--------|
| `php artisan test` | **212 passed** |
| `npm run type-check` | **Pass** |
| `npm run lint` | **Pass** |
| `npm run build` | **Pass** |
| `npm run test -- --run` | **159 passed** |

---

## Architecture

```
Project
 ├── Releases (project_releases)
 ├── Epics (project_epics)
 ├── Product Backlog + Scrum Sprint Board (Scrum; not Kanban)
 ├── Sprints (capacity_points, capacity_hours)
 ├── Work Items → Tickets (epic_id, release_id, estimates)
 ├── Milestones
 ├── Risks (project_risks)
 └── Gantt Timeline (+ ticket_dependencies)
```

Tickets reuse existing capabilities: comments, attachments, notifications, collaborators, realtime, audit, SLA.

**Work types:** `helpdesk_ticket`, `project_task`, `bug`, `improvement`, `backlog_item`, `story`, `spike`, `technical_task`.

---

## Data model (V2 migration)

**Migration:** `database/migrations/2026_06_04_100000_enterprise_agile_platform_v2.php`

| Table | Purpose |
|-------|---------|
| `project_epics` | Epic hierarchy |
| `project_releases` | Release train (planned/active/released/cancelled) |
| `project_risks` | Risk register |
| `ticket_time_entries` | Time tracking |
| `ticket_dependencies` | FS/SS/FF/SF (UI V1: FS only) |
| `project_kanban_mappings` | Sprint board column → ticket status (internal name; UI: Scrum Sprint Board) |

**Ticket extensions:** `epic_id`, `release_id`, `estimate_hours`  
**Sprint extensions:** `capacity_points`, `capacity_hours`  
**Removed:** `blocked_by_ticket_id` (migrated to `ticket_dependencies` type FS)

---

## APIs (v1, Sanctum)

| Endpoint | Description |
|----------|-------------|
| `GET/POST/PATCH projects/{project}/epics` | Epic CRUD |
| `GET/POST/PATCH projects/{project}/releases` | Release CRUD |
| `GET/POST/PATCH projects/{project}/risks` | Risk register + metrics |
| `GET projects/{project}/board` | **Scrum Sprint Board** (Sprint Backlog items only) |
| `PATCH projects/{project}/board/tickets/{ticket}` | Move sprint task across columns |
| `GET projects/{project}/sprint-board` | Alias of board |
| `GET projects/{project}/sprints/{sprint}/board` | Board for one sprint |
| `GET projects/{project}/kanban` | **Deprecated** — use `/board` |
| `GET projects/{project}/burndown` | Project burndown series |
| `GET projects/{project}/sprints/{sprint}/burndown` | Sprint burndown |
| `GET projects/{project}/velocity` | Velocity + windows (3/5/10) |
| `GET projects/{project}/health` | Health score 0–100 |
| `GET projects/{project}/workload` | Team load % |
| `GET projects/{project}/sprints/{sprint}/capacity` | Capacity summary + exceeded flag |
| `GET projects/portfolio` | Portfolio dashboard |
| `GET/POST projects/{project}/dependencies` | Dependency list / create (FS default) |
| Time entries | `start`, `log`, `stop`, `index` on tickets |

---

## Permissions

Reuses `ProjectPolicy` + `ProjectVisibilityService`: company/department scoping, project roles (owner, manager, member, viewer). Portfolio uses `viewAny` on `Project` (company users with project access).

---

## Services

| Service | Role |
|---------|------|
| `ProjectBoardService` | Scrum Sprint Board (primary) |
| `ProjectKanbanService` | **Deprecated** legacy `/kanban` API |
| `SprintCapacityService` | Used/remaining capacity, warning only |
| `TicketTimeTrackingService` | Timer + manual log |
| `TicketDependencyService` | Cycle-safe dependencies |
| `BurndownService` | Ideal/actual/remaining (max 90 days) |
| `VelocityService` | Per-sprint metrics + rolling windows |
| `ProjectHealthService` | 5 components → score + level |
| `ProjectWorkloadService` | Balanced / overloaded / underloaded |
| `PortfolioService` | Aggregated project cards |
| `ProjectGanttService` | Epics, releases, dependencies in payload |

**Bug fix (critical):** `VelocityService::windowAverage` previously called `projectVelocity` recursively → OOM; fixed to query sprints directly.

---

## Frontend (V2 pages)

| Page | Route |
|------|-------|
| `ProjectBoardPage` | `/projects/:id/board` (Scrum Sprint Board) |
| `ProjectBurndownPage` | `/projects/:id/burndown` |
| `SprintBurndownPage` | `/projects/:id/sprints/:sprintId/burndown` |
| `ProjectVelocityPage` | `/projects/:id/velocity` |
| `ProjectWorkloadPage` | `/projects/:id/workload` |
| `ProjectRisksPage` | `/projects/:id/risks` |
| `PortfolioDashboardPage` | `/projects/portfolio` |

Charts use existing `ChartShell` / `chartTheme` (not raw Recharts defaults). The **Scrum Sprint Board** uses `@dnd-kit` drag-and-drop. `/kanban` redirects to `/board`. See `docs/SCRUM_SPRINT_BOARD_MIGRATION.md`. Realtime: `useProjectRealtime` on `private-project.{id}`.

Gantt: collapsible epics/releases/sprints/work items; year/quarter/month range controls.

---

## Notifications & realtime

**Types added:** `PROJECT_RELEASE_DUE`, `PROJECT_RISK_CREATED`, `PROJECT_RISK_CRITICAL`, `SPRINT_CAPACITY_EXCEEDED`, `PROJECT_HEALTH_CRITICAL`, `WORKLOAD_OVERLOADED`.

**Templates:** EN/AR in-app + email in `NotificationTemplateSeeder`.

**Broadcasts:** `ProjectActivityBroadcast` on `private-project.{id}` and `private-department.{id}.projects` — actions include `kanban.updated`, sprint/health/velocity/risk/release events (listeners in `BroadcastProjectUpdated`).

**Dedupe:** Use `NotificationService` + `NotificationDedupeService` where wired (V1 overdue patterns).

---

## Tests

**Backend:** `tests/Feature/Projects/EnterpriseAgileV2Test.php` (epic/release/risk, kanban/capacity, time/dependencies, analytics/portfolio) + `ProjectApiTest.php` (V1).

**Frontend:** `ProjectV2Pages.test.tsx` (kanban, burndown, velocity, risks, portfolio).

---

## Migration & backward compatibility

- Run migration on deploy; idempotent guards for partial dev runs.
- Existing tickets without `project_id` unchanged.
- Clients using `blocked_by_ticket_id` must switch to `GET/POST .../dependencies` (`from`/`to`/`type`).
- Sprint board requires `project_kanban_mappings` (seeded on project create; internal table name unchanged). See `docs/SCRUM_SPRINT_BOARD_MIGRATION.md`.

---

## Completed vs deferred

### Completed (this delivery)

- Epics, releases, risks (API + UI)
- Scrum Sprint Board (columns + DnD moves + realtime invalidate)
- Sprint capacity fields + warnings (non-blocking)
- Time entries API
- Ticket dependencies (all types API; FS in UI)
- Burndown, velocity, health, workload, portfolio APIs + UI
- Gantt payload: epics, releases, dependencies; UI hierarchy + month view
- Notification enum + templates
- Velocity OOM fix
- Full validation suite green

### Deferred / partial

| Item | Notes |
|------|-------|
| Legacy `/kanban` page | Redirects to `/board`; API deprecated with flag |
| Gantt dependency lines | Count hint only; no SVG connectors |
| Time tracking UI on ticket detail | API only; no timer buttons on ticket page |
| Epic/release management UI | API exists; no dedicated epic/release pages |
| Portfolio role gate | Visible to company users with `viewAny`; not restricted to dept heads only |
| Automated V2 notification jobs | Templates exist; not all listeners/jobs fire capacity/health/workload alerts |
| `MonitorProjectDueDatesJob` for releases | Release due monitoring not fully wired |
| FS dependency picker in UI | Create/list API; no ticket-detail dependency form |
| Sprint burndown nav link | Route exists; link from sprint page optional |

---

## Risks

1. **Portfolio cost:** Loads health + velocity per project; may need caching for large portfolios.
2. **Sprint board status mapping:** Depends on department ticket statuses matching seeded mappings.
3. **Migration:** Dropping `blocked_by_ticket_id` is irreversible after migrate.
4. **Realtime:** Queued broadcasts (`ShouldQueue`) — slight delay acceptable.

---

## Readiness score

**7.5 / 10**

- **Strengths:** End-to-end APIs, tests pass, ticket-centric model preserved, enterprise UI patterns, critical velocity bug fixed.
- **Gaps:** Incomplete notification automation, time tracking UI, Gantt dependency visualization, epic/release admin screens.

---

## Future roadmap

1. Sprint board optimistic DnD polish + column WIP hints  
2. Ticket detail: timer, manual log, dependency FS picker  
3. Epic/release management pages + ticket linking  
4. Gantt SVG dependency lines + true month/quarter API range on project gantt  
5. Portfolio caching + strict role filter (dept head / admin only)  
6. Scheduled jobs: release due, capacity exceeded, health critical, workload overloaded  
7. Sprint burndown widgets on sprint board  
