Headroom - Foundation

This commit is contained in:
2026-02-17 02:10:23 -05:00
commit 04022b7e0b
46 changed files with 10488 additions and 0 deletions

View File

@@ -0,0 +1,2 @@
schema: spec-driven
created: 2026-02-17

View File

@@ -0,0 +1,559 @@
## Context
Headroom is a greenfield web application to replace manual spreadsheet-based capacity planning for engineering teams. The current spreadsheet approach is error-prone, lacks validation, provides no audit trail, and wastes manager time (2+ hours monthly on allocation work).
**Current State:**
- No existing system to migrate from
- Team uses spreadsheets for capacity planning and resource allocation
- No automation, no validation, no visibility into team headroom
**Constraints:**
- MVP must be production-ready with >70% test coverage
- Must run containerized (Docker Compose) from day 1
- Existing Nginx Proxy Manager in environment (no Caddy/Traefik)
- Must support 10-15 developers across 10-12 concurrent projects
- Monthly capacity planning cycle (not real-time)
**Stakeholders:**
- Engineering managers (primary users)
- Team members (log hours, view allocations)
- Top brass (view reports only)
- Superuser/admin (system configuration)
---
## Goals / Non-Goals
**Goals:**
- Automate capacity calculations (holidays, PTO, availability)
- Validate allocations against capacity and approved estimates
- Prevent billing errors (over/under-allocation detection)
- Provide clear visibility into team headroom
- Track planned vs actual hours for utilization analysis
- Generate 5 core reports with customizable filters
- Reduce manager allocation time from 2+ hours to <30 minutes per month
- Enforce role-based access control (4 personas)
- Maintain >70% test coverage with comprehensive E2E tests
**Non-Goals:**
- Real-time notifications (deferred to Phase 2, polling is acceptable for MVP)
- PDF/CSV report exports (deferred to Phase 2, on-screen only for MVP)
- Time-tracking tool integration (manual entry only for MVP)
- Multi-tenancy (single-tenant MVP, add tenant_id later)
- Mobile app (desktop web only)
- AI-powered forecasting (rule-based validation sufficient)
---
## Decisions
### Decision 1: Two-Container Architecture (Laravel API + SvelteKit Frontend)
**Choice:** Separate Laravel API backend and SvelteKit frontend in different containers.
**Rationale:**
- Clean separation of concerns (API vs UI)
- Easier to scale independently in future
- SvelteKit is modern and great for dashboards, worth learning curve
- Laravel provides robust API development (owner has PHP background)
**Alternatives Considered:**
- Laravel + Blade templates: Rejected (less interactive UI, harder for dashboards)
- Laravel + Vue (Inertia): Rejected (owner preferred Svelte over Vue)
- SvelteKit full-stack: Rejected (owner has PHP background, prefer Laravel for API)
**Implementation:**
- Frontend: SvelteKit (port 5173), Tailwind CSS + DaisyUI, Recharts, TanStack Table
- Backend: Laravel 12 (latest) (port 3000), PostgreSQL (latest), Redis (latest)
- Communication: REST API with Laravel API Resources for consistent JSON
- Reverse proxy: Existing Nginx Proxy Manager routes `/api/*` → Laravel, `/*` → SvelteKit
---
### Decision 2: PostgreSQL from Day 1
**Choice:** Use PostgreSQL in production and development (no SQLite).
**Rationale:**
- Avoid migration pain later (SQLite → PostgreSQL is error-prone)
- Production-grade features (JSON operators, full-text search, advanced indexing)
- Better for reporting queries (complex aggregations, window functions)
- Docker volume mount preserves portability
**Alternatives Considered:**
- SQLite for local dev, PostgreSQL for prod: Rejected (migration pain, feature parity issues)
**Implementation:**
- PostgreSQL (latest, Alpine container)
- Volume-mounted to `./data/postgres` for backup/portability
- Migrations from day 1 (Laravel migrations)
- UUIDs for primary keys (prevents ID enumeration, easier distributed systems later)
---
### Decision 3: Redis Caching from Day 1
**Choice:** Implement query and response caching with Redis from the start.
**Rationale:**
- Owner insisted: "No need to sweat on refactoring it everywhere"
- Prevents technical debt accumulation
- Expensive queries (capacity calculations, reports) benefit immediately
- Easy automatic cache invalidation with Laravel
**Alternatives Considered:**
- Defer caching to Phase 2: Rejected (owner's preference for avoiding future refactoring)
**Implementation:**
- Redis (latest, Alpine container)
- Cache keys pattern: `allocations:month:{YYYY-MM}`, `reports:forecast:{from}:{to}:{hash}`
- TTL: 1 hour (allocations), 15 min (reports), 24 hours (master data)
- Automatic invalidation on mutations (create/update/delete triggers cache flush)
- Laravel cache facade for consistency
---
### Decision 4: JWT Authentication (Token-Based)
**Choice:** JWT tokens instead of session-based authentication.
**Rationale:**
- Stateless (better for API-first architecture)
- Suitable for SPA frontend
- Easier to add mobile app later (future-proofing)
- Industry standard for REST APIs
**Alternatives Considered:**
- Laravel sessions: Rejected (owner preferred JWT for future mobile support)
**Implementation:**
- tymon/jwt-auth package
- Access token: 60 minute TTL
- Refresh token: 7 day TTL (stored in Redis, one-time use with rotation)
- Token claims: user UUID, role, permissions array
- Refresh endpoint rotates tokens on each use
---
### Decision 5: SvelteKit Frontend Stack
**Choice:** SvelteKit + Tailwind CSS + DaisyUI + Recharts + TanStack Table + Superforms + Zod
**Rationale:**
- **DaisyUI**: Fast development, opinionated but speeds up dashboard creation
- **Recharts**: Good balance of power and simplicity for charts
- **TanStack Table**: Industry standard for data grids, powerful filtering/sorting
- **Superforms + Zod**: Type-safe validation, seamless SvelteKit Form Actions integration
**Alternatives Considered:**
- Shadcn/ui: Rejected (DaisyUI faster for MVP)
- Chart.js: Rejected (Recharts more powerful)
- Custom table component: Rejected (TanStack is proven, owner unfamiliar but trusts recommendation)
**Implementation:**
- Svelte stores for minimal UI state only (filters, modals)
- Fetch API for HTTP (no Axios, native is sufficient)
- Vitest for unit tests, Playwright for E2E tests
---
### Decision 6: Allocation Validation Strategy
**Choice:** Soft validation with visual indicators (GREEN/YELLOW/RED), not hard blocks.
**Rationale:**
- Managers sometimes need flexibility to over-allocate temporarily
- Hard blocks would frustrate workflow
- Visual warnings catch errors while allowing override
- "This money is my salary!" — both over and under-allocation must be flagged
**Validation Rules:**
- GREEN: Allocation = Approved estimate (100%, within ±5% tolerance)
- YELLOW: Under-allocation (<95% of approved estimate) — will undercharge
- RED: Over-allocation (>105% of approved estimate) — will overcharge
- Person capacity: YELLOW warning at >100%, RED alert at >120%
**Implementation:**
- API returns validation status with each allocation response
- Frontend displays color-coded indicators in allocation matrix
- Tooltip shows exact variance ("Over by 20 hours, will overcharge client")
---
### Decision 7: Monthly Aggregate Actuals (Not Daily)
**Choice:** Track actual hours as monthly totals, allowing incremental weekly updates.
**Rationale:**
- Monthly planning cycle doesn't require daily granularity
- Simplifies data model and UI
- Team members can update weekly and system accumulates
- No time-tracking integration for MVP (manual entry)
**Alternatives Considered:**
- Daily time logging: Rejected (over-engineering for MVP, adds complexity)
- Weekly buckets: Rejected (monthly is sufficient given monthly planning cycle)
**Implementation:**
- Actuals table: project_id, team_member_id, month (YYYY-MM), hours_logged
- UI allows replacing or incrementing monthly total
- Utilization calculated as: (Actual hours / Capacity) × 100%
---
### Decision 8: Defer Real-Time Notifications to Phase 2
**Choice:** No WebSocket notifications in MVP, users refresh to see changes.
**Rationale:**
- Allocations are planned monthly, not time-critical
- WebSocket setup adds 6 hours of dev time
- Polling every 30s is acceptable alternative but also deferred
- Focus MVP on core allocation/reporting functionality
**Alternatives Considered:**
- WebSocket + 1 notification PoC (6 hours): Rejected (not critical for monthly planning)
- Polling-based notifications (2 hours): Rejected (also deferred, users can refresh)
**Implementation (Phase 2):**
- Laravel Broadcasting with Redis adapter
- SvelteKit WebSocket client
- Events: AllocationCreated, AllocationUpdated, EstimateApproved
---
### Decision 9: Database Schema Design
**Choice:** Normalized schema with master data tables, JSON for forecasted effort, UUIDs for primary keys.
**Key Tables:**
- `team_members`: id (UUID), name, role_id (FK), hourly_rate, active
- `projects`: id (UUID), code (unique), title, status_id (FK), type_id (FK), approved_estimate, forecasted_effort (JSON)
- `allocations`: id (UUID), project_id (FK), team_member_id (FK), month (YYYY-MM), allocated_hours
- `actuals`: id (UUID), project_id (FK), team_member_id (FK), month (YYYY-MM), hours_logged
- `roles`, `project_statuses`, `project_types`: Master data tables
- `holidays`, `ptos`: Calendar data
**Design Rationale:**
- **UUIDs**: Prevent ID enumeration attacks, easier distributed systems later
- **Normalized master data**: Roles/statuses/types in separate tables for dynamic configuration
- **Month as string (YYYY-MM)**: Simplifies queries, index-friendly, human-readable
- **JSON for forecasted effort**: Flexible structure `{"2026-02": 40, "2026-03": 60}`, easy to extend
- **Soft deletes for projects**: `deleted_at` timestamp for audit trail
- **Active flag for team members**: Preserve historical allocations when person leaves
**Indexes:**
- `allocations`: composite index on (project_id, month), (team_member_id, month)
- `actuals`: composite index on (project_id, month), (team_member_id, month)
- `team_members`: index on (role_id, active)
- `projects`: index on (status_id, type_id), unique on (code)
---
### Decision 10: API Design Pattern
**Choice:** REST API with Laravel API Resources for consistent JSON responses.
**Rationale:**
- REST is simpler than GraphQL for this use case
- Laravel API Resources provide consistent transformation layer
- Standard HTTP verbs (GET, POST, PUT, DELETE)
- Easy to document with Laravel Scribe (SwaggerUI)
**Endpoint Structure:**
```
/api/auth/login (POST)
/api/auth/logout (POST)
/api/auth/refresh (POST)
/api/team-members (GET, POST)
/api/team-members/:id (GET, PUT, DELETE)
/api/projects (GET, POST)
/api/projects/:id (GET, PUT, DELETE)
/api/allocations?month=YYYY-MM (GET, POST)
/api/allocations/bulk (POST)
/api/allocations/:id (PUT, DELETE)
/api/actuals?month=YYYY-MM (GET, POST)
/api/actuals/bulk (POST)
/api/actuals/:id (PUT)
/api/reports/forecast?from=YYYY-MM&to=YYYY-MM (GET)
/api/reports/utilization?month=YYYY-MM (GET)
/api/reports/cost?month=YYYY-MM (GET)
/api/reports/allocation?month=YYYY-MM (GET)
/api/reports/variance?month=YYYY-MM (GET)
/api/master-data/roles (GET)
/api/master-data/statuses (GET)
/api/master-data/types (GET)
```
**Response Format (Laravel API Resources):**
```json
{
"data": { /* resource */ },
"meta": { /* pagination, counts */ },
"links": { /* HATEOAS links */ }
}
```
**Error Format:**
```json
{
"message": "Validation failed",
"errors": {
"allocated_hours": ["Must be greater than 0"]
}
}
```
---
### Decision 11: Testing Strategy
**Choice:** >70% code coverage with unit + E2E + regression tests on every change.
**Test Layers:**
- **Backend Unit (PHPUnit)**: Model methods, service classes, utilities
- **Backend Feature (Pest)**: API endpoints, authentication, authorization
- **Frontend Unit (Vitest)**: Svelte components, stores, utilities
- **E2E (Playwright)**: Critical user flows (login → allocate → view reports)
**Coverage Targets:**
- Backend: >80% (easier to test server-side logic)
- Frontend: >70% (UI testing is harder)
- Overall: >70% (enforced in `/opsx-verify`)
**Test Data Strategy:**
- Database seeders for test data (Laravel seeders)
- Factories for model generation (Laravel factories)
- Test fixtures for E2E tests (Playwright fixtures)
**Regression Test Approach (MVP):**
- Run full test suite on every change
- E2E tests cover happy paths + critical error cases
- Phase 2: Issue-driven loop (E2E failure → create GitHub issue → fix → retest)
**Implementation:**
- Pre-commit hooks: Run linters + unit tests
- CI/CD: Run full suite (unit + E2E) before merge
- `openspec verify` command: Check coverage, run tests, lint
---
## Risks / Trade-offs
### Risk: SvelteKit Learning Curve
**Impact:** Owner and associate unfamiliar with Svelte, may slow initial development.
**Mitigation:**
- SvelteKit has excellent documentation
- Simpler than React/Vue (less boilerplate)
- TanStack Table is framework-agnostic (owner unfamiliar but AI will guide)
- Start with simple components, iterate
---
### Risk: Two-Container Complexity
**Impact:** More moving parts than single monolith, deployment overhead.
**Mitigation:**
- Docker Compose handles orchestration
- Code-mounted volumes for hot reload (no rebuild needed)
- Owner comfortable with Docker
- Cleaner architecture worth the overhead
---
### Risk: Over-Allocation Soft Validation
**Impact:** Managers could ignore RED flags and over-allocate anyway.
**Mitigation:**
- Visual warnings are prominent (RED color, tooltip with exact impact)
- Reports show over-allocation clearly
- Phase 2: Add email notifications when allocations exceed threshold
- Manager discipline assumed (this is their job)
---
### Risk: Manual Time Entry Accuracy
**Impact:** Team members may forget to log hours or log inaccurately.
**Mitigation:**
- Utilization reports highlight under-logging (planned > actual consistently)
- Manager can follow up with team members showing low actuals
- Phase 2: Integrate with time-tracking tools (Jira, Harvest, Toggl)
- Incremental weekly updates reduce forgetting
---
### Risk: Cache Invalidation Bugs
**Impact:** Stale data shown if cache invalidation logic fails.
**Mitigation:**
- Comprehensive test coverage for cache invalidation logic
- Redis TTL ensures eventual consistency (max 1 hour stale)
- Cache keys are scoped (project, month, person)
- Invalidation triggered on all mutations (create/update/delete)
- Manual cache flush available for admins
---
### Risk: JWT Token Security
**Impact:** Stolen tokens could allow unauthorized access.
**Mitigation:**
- Refresh token rotation (one-time use)
- Short access token TTL (60 minutes)
- Refresh tokens stored in Redis (revocable)
- HTTPS enforced via Nginx Proxy Manager
- Logout invalidates refresh token
- Token includes user role for authorization checks
---
### Trade-off: No Real-Time Notifications
**Benefit:** Saves 6 hours of dev time, keeps MVP scope tight.
**Cost:** Users must manually refresh to see allocation changes.
**Justification:** Allocations are monthly planning activity, not time-critical. Acceptable for MVP.
---
### Trade-off: No PDF/CSV Exports
**Benefit:** Faster MVP, avoids report formatting complexity.
**Cost:** Users cannot export reports for offline viewing or stakeholder sharing.
**Justification:** On-screen reports are primary value, exports are nice-to-have for Phase 2.
---
### Trade-off: Manual Time Entry
**Benefit:** Avoids vendor lock-in, no integration complexity.
**Cost:** Team members must manually enter hours monthly.
**Justification:** Monthly aggregate is low overhead (~5 minutes per person per month).
---
## Migration Plan
**Deployment Steps:**
1. **Initial Setup:**
- Run `docker-compose up` (creates 4 containers)
- Laravel migrations create database schema
- Database seeders populate master data (roles, statuses, types)
- Create superuser account via Laravel seeder
2. **Data Import (Optional):**
- If team has historical spreadsheet data, create import script
- Import team members (name, role, hourly rate)
- Import active projects (code, title, approved estimate)
- Do NOT import historical allocations (start fresh)
3. **User Onboarding:**
- Train managers on allocation workflow (1 hour session)
- Demo: capacity planning → project setup → allocation → reports
- Provide Quick Start guide (Markdown doc)
4. **Go-Live:**
- Managers create February 2026 capacity plan (holidays, PTO, availability)
- Managers allocate resources for February
- Team members log February actuals mid-month (incremental updates)
- Month-end: Review utilization reports, adjust March allocations
**Rollback Strategy:**
- MVP is greenfield (no data migration to revert)
- If critical bug discovered, roll back to previous container image
- Docker Compose down/up with previous image tag
- PostgreSQL data persisted in volume (safe across container restarts)
- Zero-downtime rollback: Blue/green deployment (Phase 2, not needed for MVP)
**Monitoring (Phase 2):**
- Application logs (Laravel log files)
- Database performance (PostgreSQL slow query log)
- Cache hit rate (Redis INFO stats)
- API response times (Laravel Telescope or custom middleware)
---
## Open Questions
### Question 1: Hourly Rate Visibility
Should developers see their own hourly rate, or only managers/top brass?
**Options:**
- A) Developers can see their own rate (transparency)
- B) Developers cannot see rates (only allocations)
**Recommendation:** A (transparency fosters trust, rate is not secret in most orgs)
**Decision:** To be finalized with owner before implementation.
---
### Question 2: Hours Per Day Configuration
Is "1.0 availability = 8 hours" globally configured, or per-project?
**Options:**
- A) Global setting (e.g., 1.0 = 8 hours for everyone)
- B) Per-team member (some people work 6-hour days)
- C) Per-project (different billing rates for different project types)
**Recommendation:** A (global setting, simplest for MVP)
**Decision:** Owner mentioned "configurable per project" but likely meant per team. Clarify.
---
### Question 3: PTO Approval Workflow
Is PTO auto-approved, or does it require manager approval?
**Options:**
- A) Auto-approved (capacity reduced immediately)
- B) Requires approval (pending state until manager approves)
**Recommendation:** B (manager approval, prevents abuse)
**Decision:** Owner likely expects approval workflow. Confirm.
---
### Question 4: Support Projects in Revenue Forecast
Should "Support" type projects appear in revenue forecasts?
**Options:**
- A) Exclude from revenue (they're ongoing ops, not billable)
- B) Include in revenue (still billable internally)
**Recommendation:** Ask owner's preference (may vary by org)
**Decision:** To be confirmed during implementation.
---
### Question 5: Allocation Tolerance Threshold
What's the tolerance for "within estimate" (GREEN indicator)?
**Current assumption:** ±5% (e.g., 100-hour project allocated 95-105 hours is GREEN)
**Confirm:** Is 5% the right threshold, or should it be configurable?
**Decision:** Start with 5%, make configurable in Phase 2 if needed.
---
**End of Design Document**
**Next Steps:**
1. Review open questions with owner
2. Finalize database schema (ERD diagram)
3. Create tasks.md (implementation checklist)
4. Begin Sprint 1: Docker Compose setup + database migrations

View File

@@ -0,0 +1,68 @@
## Why
Engineering managers juggling 10-15 developers across 10-12 concurrent projects currently use error-prone spreadsheets for capacity planning and resource allocation. This leads to billing errors (over/under-allocation), no visibility into team headroom, manual capacity calculations, and no audit trail. The business impact is severe: over-allocation causes client escalations, under-allocation loses revenue, and managers waste 2+ hours monthly on manual allocation work.
## What Changes
- **New web application**: Full-stack resource planning and capacity management system
- **Capacity planning module**: Team member management, holiday/PTO tracking, availability calculations
- **Project management module**: Project lifecycle tracking, approved estimates, forecasted effort distribution
- **Resource allocation module**: Monthly allocation matrix with validation (over/under-allocation detection)
- **Actuals tracking module**: Time logging interface, utilization calculations (running & overall)
- **Reporting module**: 5 core reports (forecast, utilization, cost, allocation, variance) with customizable filters
- **Authentication system**: JWT-based auth with 4 user roles (Superuser, Manager, Developer, Top Brass)
- **Containerized deployment**: Docker Compose setup with Laravel API, SvelteKit frontend, PostgreSQL, Redis
## Capabilities
### New Capabilities
- `team-member-management`: CRUD operations for team members with role, hourly rate, and active status tracking
- `capacity-planning`: Calculate individual and team capacity based on availability, holidays, PTO, and working days
- `project-lifecycle`: Manage projects through state machine (Initial → Estimates → Approved → Funded → In-Progress → Done) with approved estimates and forecasted effort
- `resource-allocation`: Allocate hours per person per project per month with validation against capacity and approved estimates
- `allocation-validation`: Detect and flag over/under-allocation (RED for >100%, YELLOW for <100%, GREEN for 100%)
- `actuals-tracking`: Log hours worked per project per person per month (manual entry, monthly aggregate)
- `utilization-calculations`: Calculate running utilization (YTD) and overall utilization (monthly) as percentage of capacity
- `forecast-reporting`: Multi-period forecast reports showing allocations, revenue, and variance by project/team/person
- `utilization-reporting`: Team and individual utilization trends with customizable date range and filters
- `cost-reporting`: Revenue forecasts based on allocations multiplied by hourly rates, filterable by project/client/team
- `allocation-reporting`: Monthly allocation matrix view showing who's allocated to what with utilization percentages
- `variance-reporting`: Planned vs actual analysis showing over/under-delivery by project and person
- `role-based-access`: Enforce permissions for 4 personas (Superuser, Manager, Developer, Top Brass) with different read/write access
- `master-data-management`: Configure roles, project statuses, project types, and availability options
- `authentication`: JWT-based token authentication with login, logout, and token refresh
### Modified Capabilities
<!-- No existing capabilities are being modified - this is a greenfield project -->
## Impact
**New Systems:**
- Laravel 12 (latest) API (backend container, port 3000)
- SvelteKit web app (frontend container, port 5173)
- PostgreSQL (latest) database (data container, port 5432)
- Redis (latest) cache (cache container, port 6379)
- Docker Compose orchestration
- Nginx Proxy Manager routing (`/api/*` → Laravel, `/*` → SvelteKit)
**Dependencies:**
- PHP 8.4 (latest) with Laravel 12 (latest) framework
- Node (latest) with SvelteKit (latest)
- Tailwind CSS + DaisyUI (UI components)
- Recharts (visualizations)
- TanStack Table (data grids)
- Superforms + Zod (form validation)
- Laravel Scribe (SwaggerUI API documentation)
- Testing: PHPUnit, Pest, Vitest, Playwright
**External Integrations:**
- None for MVP (manual data entry only)
**Breaking Changes:**
- None (new system)
**Migration Path:**
- Greenfield project - no data migration needed
- Users will transition from spreadsheets to web application

View File

@@ -0,0 +1,78 @@
## ADDED Requirements
### Requirement: Log hours worked
The system SHALL allow team members to log actual hours worked per project per month.
#### Scenario: Log hours for current month
- **WHEN** a team member logs 35 hours worked on "Project X" for February 2026
- **THEN** the system creates an actuals record
- **AND** the system associates the hours with the team member, project, and month
#### Scenario: Cannot log negative hours
- **WHEN** attempting to log -5 hours
- **THEN** the system rejects the request with validation error "Hours logged must be greater than or equal to 0"
#### Scenario: Cannot log hours for future months
- **WHEN** attempting to log hours for a month that hasn't started yet
- **THEN** the system rejects the request with validation error "Cannot log hours for future months"
### Requirement: Update logged hours
The system SHALL allow team members to update previously logged hours for the current month.
#### Scenario: Incremental weekly updates
- **WHEN** a team member logs 10 hours in week 1 of February
- **AND** logs an additional 8 hours in week 2 of February
- **AND** the system updates the total to 18 hours for February
- **THEN** the system accumulates the hours for the monthly aggregate
#### Scenario: Replace monthly total
- **WHEN** a team member updates February actuals from 35 hours to 40 hours
- **THEN** the system replaces the previous value with the new total
### Requirement: View actuals summary
The system SHALL display actual hours worked in a summary view similar to allocation matrix.
#### Scenario: View monthly actuals matrix
- **WHEN** a manager views actuals for February 2026
- **THEN** the system displays projects as rows and team members as columns
- **AND** each cell shows actual hours logged for that project-person combination
#### Scenario: Show actuals vs allocations
- **WHEN** viewing the actuals summary
- **THEN** the system displays allocated hours and actual hours side by side
- **AND** the system highlights variances (over or under)
### Requirement: Cannot log hours to inactive projects
The system SHALL prevent logging hours to projects in "Done" or "Cancelled" status (configurable).
#### Scenario: Attempt to log hours to done project
- **WHEN** attempting to log hours for a project with status "Done"
- **AND** the system configuration prevents logging to completed projects
- **THEN** the system rejects the request with error "Cannot log hours to completed projects"
#### Scenario: Allow logging to done project if configured
- **WHEN** the system is configured to allow logging to completed projects
- **AND** a team member logs hours to a "Done" project
- **THEN** the system accepts the hours (for edge cases where work continues after project closure)
### Requirement: Actuals data entry is manual
The system SHALL support manual entry of actual hours without integration to time-tracking tools (MVP).
#### Scenario: Manual monthly entry
- **WHEN** a team member enters actual hours worked via the web interface
- **THEN** the system accepts the input without requiring integration with external time-tracking systems
#### Scenario: No automated time import
- **WHEN** viewing actuals entry interface
- **THEN** the system does not provide options to import from Jira, Harvest, Toggl, or other time-tracking tools (deferred to Phase 2)
### Requirement: Track actuals notes
The system SHALL allow optional notes when logging hours.
#### Scenario: Log hours with notes
- **WHEN** a team member logs 40 hours with notes "Focused on API development and bug fixes"
- **THEN** the system stores the notes alongside the hours logged
#### Scenario: Update notes
- **WHEN** a team member updates the notes for a logged actuals record
- **THEN** the system updates the notes field without affecting the hours value

View File

@@ -0,0 +1,74 @@
## ADDED Requirements
### Requirement: Generate allocation report
The system SHALL generate monthly allocation reports showing who is allocated to what projects.
#### Scenario: View allocation report for month
- **WHEN** viewing allocation report for February 2026
- **THEN** the system displays allocation matrix with projects as rows
- **AND** team members as columns
- **AND** each cell shows allocated hours
#### Scenario: Allocation report with totals
- **WHEN** viewing allocation report
- **THEN** the system displays row totals (total hours per project)
- **AND** displays column totals (total hours per team member)
- **AND** displays grand total (all allocated hours for the month)
### Requirement: Show utilization percentages in allocation report
The system SHALL display utilization percentages alongside allocated hours.
#### Scenario: Display team member utilization
- **WHEN** viewing allocation report
- **THEN** for each team member column, the system displays:
- Capacity (e.g., "160h")
- Allocated hours (e.g., "140h")
- Utilization percentage (e.g., "87.5%")
#### Scenario: Display project allocation percentage
- **WHEN** viewing allocation report
- **THEN** for each project row, the system displays:
- Approved estimate (e.g., "120h")
- Allocated hours (e.g., "100h")
- Allocation percentage (e.g., "83.3%")
- Status indicator (GREEN/YELLOW/RED)
### Requirement: Filter allocation report by team
The system SHALL allow filtering allocation reports by team, role, or team member.
#### Scenario: Filter by team member
- **WHEN** filtering allocation report to show "John Doe" only
- **THEN** the system displays all projects where John has allocations
- **AND** hides other team members' columns
#### Scenario: Filter by role
- **WHEN** filtering to show "Backend Developer" role
- **THEN** the system displays only team members with that role in the matrix
### Requirement: Filter allocation report by project
The system SHALL allow filtering allocation reports by project, status, or type.
#### Scenario: Filter by project status
- **WHEN** filtering to show only "In-Progress" projects
- **THEN** the system displays only projects with that status
### Requirement: Multi-month allocation view
The system SHALL allow viewing allocations across multiple months.
#### Scenario: View quarter allocation
- **WHEN** viewing allocation report for Q1 2026 (Jan-Mar)
- **THEN** the system displays a matrix showing each month as a separate column group
- **AND** shows how allocations change month-to-month for each person
### Requirement: Highlight allocation changes
The system SHALL highlight recent allocation changes for visibility.
#### Scenario: Show new allocations
- **WHEN** viewing allocation report
- **AND** an allocation was created in the last 7 days
- **THEN** the system highlights the cell with a "NEW" badge or distinct color
#### Scenario: Show modified allocations
- **WHEN** an allocation was updated in the last 7 days
- **THEN** the system shows a "UPDATED" indicator
- **AND** optionally shows previous value on hover

View File

@@ -0,0 +1,87 @@
## ADDED Requirements
### Requirement: Detect over-allocation
The system SHALL flag allocations that exceed approved estimates with RED indicator.
#### Scenario: Project over-allocated
- **WHEN** a project has approved estimate of 100 hours
- **AND** total allocations sum to 120 hours
- **THEN** the system displays RED indicator with text "120% allocated (OVER by 20 hours)"
#### Scenario: Over-allocation threshold
- **WHEN** total allocations exceed approved estimate by more than 5%
- **THEN** the system displays RED flag
- **AND** the system shows warning message "Will overcharge client"
### Requirement: Detect under-allocation
The system SHALL flag allocations that fall short of approved estimates with YELLOW indicator.
#### Scenario: Project under-allocated
- **WHEN** a project has approved estimate of 100 hours
- **AND** total allocations sum to 80 hours
- **THEN** the system displays YELLOW indicator with text "80% allocated (UNDER by 20 hours)"
#### Scenario: Under-allocation warning
- **WHEN** total allocations are less than approved estimate by more than 5%
- **THEN** the system displays YELLOW flag
- **AND** the system shows warning message "Will undercharge client (revenue loss)"
### Requirement: Display optimal allocation
The system SHALL display GREEN indicator when allocations match approved estimates.
#### Scenario: Perfect allocation
- **WHEN** a project has approved estimate of 100 hours
- **AND** total allocations sum to exactly 100 hours
- **THEN** the system displays GREEN indicator with text "100% allocated (OPTIMAL)"
#### Scenario: Within tolerance
- **WHEN** a project has approved estimate of 100 hours
- **AND** total allocations sum to 102 hours (within 5% tolerance)
- **THEN** the system displays GREEN indicator with text "102% allocated (within tolerance)"
### Requirement: Validate person capacity
The system SHALL warn when a team member's allocations exceed their monthly capacity.
#### Scenario: Person under capacity
- **WHEN** a team member has capacity of 160 hours
- **AND** total allocations sum to 120 hours
- **THEN** the system displays utilization as 75% with no warning
#### Scenario: Person at capacity
- **WHEN** a team member has capacity of 160 hours
- **AND** total allocations sum to 160 hours
- **THEN** the system displays utilization as 100% with GREEN indicator
#### Scenario: Person over capacity
- **WHEN** a team member has capacity of 160 hours
- **AND** total allocations sum to 180 hours
- **THEN** the system displays utilization as 113% with YELLOW warning "Over-allocated by 20 hours"
#### Scenario: Person severely over capacity
- **WHEN** a team member has capacity of 160 hours
- **AND** total allocations sum to 200 hours (125% or more)
- **THEN** the system displays utilization as 125% with RED warning "Severely over-allocated by 40 hours"
### Requirement: Aggregate validation across months
The system SHALL validate allocations across multiple months for multi-month projects.
#### Scenario: Multi-month project validation
- **WHEN** a project has approved estimate of 120 hours
- **AND** forecasted effort is: Feb 40h, Mar 60h, Apr 20h
- **AND** actual allocations are: Feb 38h, Mar 62h, Apr 20h
- **THEN** the system validates total allocations (38+62+20=120) against approved estimate (120)
- **AND** displays overall GREEN indicator
- **AND** displays monthly warnings where allocations deviate from forecast
### Requirement: Real-time validation feedback
The system SHALL provide immediate validation feedback as allocations are created or modified.
#### Scenario: Immediate feedback on create
- **WHEN** a manager creates an allocation that causes a project to exceed approved estimate
- **THEN** the system immediately displays RED indicator on the allocation matrix
- **AND** the system shows tooltip "This allocation causes project over-allocation"
#### Scenario: Immediate feedback on update
- **WHEN** a manager increases an allocation and the team member becomes over-capacity
- **THEN** the system immediately updates the utilization percentage
- **AND** the system changes the team member's column header color to YELLOW or RED

View File

@@ -0,0 +1,111 @@
## ADDED Requirements
### Requirement: User login
The system SHALL authenticate users with email and password and issue JWT tokens.
#### Scenario: Successful login
- **WHEN** a user submits valid email "john@example.com" and password
- **THEN** the system validates the credentials
- **AND** generates a JWT access token (60 minute TTL)
- **AND** generates a refresh token (7 day TTL)
- **AND** returns both tokens along with user details (name, email, role)
#### Scenario: Invalid credentials
- **WHEN** a user submits incorrect email or password
- **THEN** the system returns 401 Unauthorized error
- **AND** returns error message "Invalid credentials"
#### Scenario: Account locked or inactive
- **WHEN** a user with inactive account attempts to login
- **THEN** the system returns 403 Forbidden error
- **AND** returns error message "Account is inactive"
### Requirement: Token-based authentication
The system SHALL use JWT tokens for authenticating API requests.
#### Scenario: Authenticated API request
- **WHEN** a user sends an API request with valid JWT token in Authorization header
- **THEN** the system validates the token
- **AND** extracts user ID and role from token claims
- **AND** processes the request
#### Scenario: Expired token
- **WHEN** a user sends an API request with expired JWT token
- **THEN** the system returns 401 Unauthorized error
- **AND** returns error message "Token expired"
#### Scenario: Invalid token
- **WHEN** a user sends an API request with malformed or tampered JWT token
- **THEN** the system returns 401 Unauthorized error
- **AND** returns error message "Invalid token"
#### Scenario: Missing token
- **WHEN** a user sends an API request without Authorization header
- **THEN** the system returns 401 Unauthorized error
- **AND** returns error message "Authentication required"
### Requirement: Token refresh
The system SHALL allow users to obtain new access tokens using refresh tokens.
#### Scenario: Refresh access token
- **WHEN** a user submits a valid refresh token to POST /api/auth/refresh
- **THEN** the system validates the refresh token
- **AND** generates a new access token (60 minute TTL)
- **AND** rotates the refresh token (one-time use, issues new refresh token)
- **AND** returns the new access and refresh tokens
#### Scenario: Invalid refresh token
- **WHEN** a user submits an invalid or expired refresh token
- **THEN** the system returns 401 Unauthorized error
- **AND** returns error message "Invalid or expired refresh token"
### Requirement: User logout
The system SHALL allow users to logout and invalidate their tokens.
#### Scenario: Successful logout
- **WHEN** a user sends POST /api/auth/logout with their access token
- **THEN** the system invalidates the refresh token in Redis
- **AND** returns success message "Logged out successfully"
#### Scenario: Token invalidation
- **WHEN** a user logs out
- **THEN** the system removes the refresh token from Redis
- **AND** subsequent requests with the same tokens are rejected
### Requirement: JWT token structure
The system SHALL include user information in JWT token claims.
#### Scenario: Access token claims
- **WHEN** generating an access token
- **THEN** the token payload includes:
- sub (user UUID)
- role (user role: "superuser", "manager", "developer", "top_brass")
- permissions (array of permission strings)
- iat (issued at timestamp)
- exp (expiration timestamp, 60 minutes from iat)
- jti (unique token ID)
### Requirement: Refresh token storage
The system SHALL store refresh tokens in Redis with TTL.
#### Scenario: Store refresh token
- **WHEN** a user logs in
- **THEN** the system generates a refresh token UUID
- **AND** stores it in Redis with key "refresh_token:{user_id}:{token_uuid}"
- **AND** sets TTL to 7 days (10080 minutes)
#### Scenario: Validate refresh token
- **WHEN** a user submits a refresh token
- **THEN** the system checks if the token exists in Redis
- **AND** if found and not expired, allows token refresh
- **AND** if not found or expired, rejects the request
### Requirement: Token rotation
The system SHALL rotate refresh tokens on each refresh request.
#### Scenario: Rotate refresh token
- **WHEN** a user refreshes their access token
- **THEN** the system invalidates the old refresh token (deletes from Redis)
- **AND** generates a new refresh token
- **AND** stores the new refresh token in Redis
- **AND** returns the new refresh token to the user

View File

@@ -0,0 +1,99 @@
## ADDED Requirements
### Requirement: Calculate individual capacity
The system SHALL calculate individual team member capacity for a given month based on availability, holidays, PTO, and weekends.
#### Scenario: Calculate capacity for full month
- **WHEN** calculating capacity for a team member with full availability (1.0) for all working days in February 2026
- **AND** February has 20 working days (28 days - 8 weekend days)
- **AND** the team member has no PTO or holidays
- **THEN** the system calculates individual capacity as 20 person-days
#### Scenario: Calculate capacity with half-day availability
- **WHEN** a team member has availability of 0.5 for 10 working days in a month
- **THEN** the system calculates capacity as 5 person-days (10 days × 0.5)
#### Scenario: Calculate capacity with PTO
- **WHEN** a team member has PTO for 3 working days in a month
- **AND** the month has 22 working days
- **AND** the team member has full availability (1.0) for all other days
- **THEN** the system calculates capacity as 19 person-days (22 - 3 days PTO)
#### Scenario: Calculate capacity with holidays
- **WHEN** a month has 2 company holidays
- **AND** a team member has 22 working days after removing weekends
- **AND** the team member has full availability (1.0)
- **THEN** the system calculates capacity as 20 person-days (22 - 2 holidays)
#### Scenario: Calculate capacity with mixed availability
- **WHEN** a team member has 10 days at 1.0 availability, 5 days at 0.5 availability, and 3 days at 0 availability in a month
- **THEN** the system calculates capacity as 12.5 person-days (10×1.0 + 5×0.5 + 3×0)
### Requirement: Calculate team capacity
The system SHALL calculate total team capacity by summing individual capacities for all active team members.
#### Scenario: Calculate team capacity for month
- **WHEN** Team Member A has 20 person-days capacity
- **AND** Team Member B has 18 person-days capacity
- **AND** Team Member C has 15 person-days capacity
- **THEN** the system calculates team capacity as 53 person-days
#### Scenario: Exclude inactive team members from team capacity
- **WHEN** calculating team capacity
- **AND** one team member has active status set to false
- **THEN** the system excludes the inactive team member from the team capacity calculation
### Requirement: Calculate possible revenue
The system SHALL calculate possible revenue based on team capacity and hourly rates.
#### Scenario: Calculate possible revenue for team
- **WHEN** Team Member A has 160 hours capacity at $150/hour
- **AND** Team Member B has 144 hours capacity at $125/hour
- **AND** Team Member C has 120 hours capacity at $175/hour
- **THEN** the system calculates possible revenue as $63,000 (160×$150 + 144×$125 + 120×$175)
### Requirement: Track availability per day
The system SHALL allow setting daily availability as 0 (unavailable), 0.5 (half day), or 1.0 (full day).
#### Scenario: Set full day availability
- **WHEN** setting availability for a specific date to 1.0
- **THEN** the system records the team member as fully available for that day
#### Scenario: Set half day availability
- **WHEN** setting availability for a specific date to 0.5
- **THEN** the system records the team member as half-day available for that day
#### Scenario: Set unavailable
- **WHEN** setting availability for a specific date to 0
- **THEN** the system records the team member as unavailable for that day
#### Scenario: Reject invalid availability values
- **WHEN** attempting to set availability to a value other than 0, 0.5, or 1.0
- **THEN** the system rejects the input with validation error "Availability must be 0, 0.5, or 1.0"
### Requirement: Manage holidays
The system SHALL allow defining company-wide holidays that reduce available working days for all team members.
#### Scenario: Add company holiday
- **WHEN** an admin defines December 25, 2026 as a company holiday "Christmas Day"
- **THEN** the system marks that date as a non-working day for all team members
#### Scenario: Holidays affect capacity calculation
- **WHEN** calculating capacity for a month with 2 company holidays
- **THEN** the system automatically excludes those days from all team members' capacity calculations
### Requirement: Manage PTO requests
The system SHALL allow team members to request PTO which reduces their individual capacity.
#### Scenario: Submit PTO request
- **WHEN** a team member submits PTO for February 10-12, 2026
- **THEN** the system creates a PTO record with start date, end date, and status "pending"
#### Scenario: Approve PTO request
- **WHEN** a manager approves a PTO request
- **THEN** the system updates the PTO status to "approved"
- **AND** the system automatically reduces the team member's capacity for those dates to 0
#### Scenario: PTO affects capacity calculation
- **WHEN** calculating capacity for a team member with approved PTO for 3 days
- **THEN** the system excludes those 3 days from the capacity calculation

View File

@@ -0,0 +1,85 @@
## ADDED Requirements
### Requirement: Generate cost summary report
The system SHALL generate reports showing revenue forecasts based on allocations multiplied by hourly rates.
#### Scenario: View monthly cost report
- **WHEN** viewing cost report for February 2026
- **THEN** the system displays all projects with their allocated hours
- **AND** calculates revenue for each project based on team member hourly rates
- **AND** shows total revenue forecast for the month
#### Scenario: Cost breakdown by project
- **WHEN** viewing cost report for a specific project
- **THEN** the system displays allocation breakdown by team member
- **AND** shows hours allocated and hourly rate for each team member
- **AND** calculates total project cost as sum of (hours × rate) for all team members
### Requirement: Filter cost report by project
The system SHALL allow filtering cost reports by project, client, or type.
#### Scenario: Filter by project type
- **WHEN** filtering cost report to show only "Project" type (billable)
- **THEN** the system displays revenue forecast for billable projects only
- **AND** excludes "Support" type projects
#### Scenario: Group by client
- **WHEN** grouping cost report by client
- **THEN** the system displays total revenue forecast per client
- **AND** shows breakdown of projects per client
### Requirement: Filter cost report by team
The system SHALL allow filtering cost reports by team or team member.
#### Scenario: Cost report for team member
- **WHEN** filtering cost report to show allocations for "John Doe"
- **THEN** the system displays all projects where John Doe is allocated
- **AND** calculates John's contribution to revenue (his hours × his rate)
#### Scenario: Cost report for role
- **WHEN** filtering by "Backend Developer" role
- **THEN** the system displays revenue generated by all Backend Developers
- **AND** shows average hourly rate for the role
### Requirement: Calculate total possible revenue
The system SHALL calculate maximum possible revenue if all team capacity were utilized at 100%.
#### Scenario: Possible revenue calculation
- **WHEN** viewing cost summary
- **THEN** the system calculates total team capacity (all team members' available hours)
- **AND** multiplies by each team member's hourly rate
- **AND** displays "Possible Revenue: $X if fully utilized"
### Requirement: Calculate forecasted revenue
The system SHALL calculate forecasted revenue based on current allocations.
#### Scenario: Forecasted revenue based on allocations
- **WHEN** team has 1000 hours total capacity
- **AND** currently 850 hours are allocated across projects
- **AND** the weighted average hourly rate is $140
- **THEN** the system calculates forecasted revenue as $119,000 (850 × $140)
### Requirement: Show revenue variance
The system SHALL display variance between possible revenue and forecasted revenue.
#### Scenario: Revenue gap analysis
- **WHEN** possible revenue is $150,000
- **AND** forecasted revenue is $119,000
- **THEN** the system displays revenue gap of $31,000 (20.7% underutilization)
### Requirement: Multi-period cost forecast
The system SHALL generate cost forecasts across multiple months.
#### Scenario: Quarter revenue forecast
- **WHEN** viewing cost report for Q1 2026 (Jan-Mar)
- **THEN** the system displays monthly revenue forecast for each month
- **AND** calculates total Q1 revenue forecast
- **AND** shows monthly variance from possible revenue
### Requirement: Export cost data
The system SHALL allow exporting cost report data (deferred to Phase 2 for PDF/CSV).
#### Scenario: View cost data on screen (MVP)
- **WHEN** viewing cost report
- **THEN** the system displays all cost data on screen in tabular format
- **AND** PDF/CSV export buttons are not available (Phase 2 feature)

View File

@@ -0,0 +1,70 @@
## ADDED Requirements
### Requirement: Generate multi-period forecast report
The system SHALL generate forecast reports showing allocations and revenue projections across multiple months.
#### Scenario: View 3-month forecast
- **WHEN** a manager requests a forecast report for February-April 2026
- **THEN** the system displays all projects with allocations in that period
- **AND** for each project shows month-by-month allocation breakdown
- **AND** calculates revenue forecast based on allocations × hourly rates
#### Scenario: Forecast includes variance indicators
- **WHEN** viewing the forecast report
- **THEN** the system shows forecasted hours vs approved estimate for each project
- **AND** displays GREEN/YELLOW/RED indicators for over/under-allocation
### Requirement: Filter forecast by project
The system SHALL allow filtering forecast reports by project, status, or type.
#### Scenario: Filter by project status
- **WHEN** filtering forecast report to show only "In-Progress" projects
- **THEN** the system displays only projects with that status
#### Scenario: Filter by project type
- **WHEN** filtering forecast report to show only "Project" type (billable)
- **THEN** the system excludes "Support" type projects from the report
### Requirement: Filter forecast by team
The system SHALL allow filtering forecast reports by team or team member.
#### Scenario: Filter by team member
- **WHEN** filtering forecast report to show allocations for "John Doe"
- **THEN** the system displays only projects where John Doe has allocations
#### Scenario: Filter by role/team
- **WHEN** filtering forecast report to show allocations for "Backend Developer" role
- **THEN** the system displays allocations for all team members with that role
### Requirement: Forecast revenue calculation
The system SHALL calculate revenue forecasts based on allocations multiplied by team member hourly rates.
#### Scenario: Calculate monthly revenue forecast
- **WHEN** a project has allocations: Developer A 40h @ $150/h, Developer B 30h @ $125/h
- **THEN** the system calculates monthly revenue forecast as $9,750 (40×$150 + 30×$125)
#### Scenario: Calculate total revenue forecast for period
- **WHEN** viewing forecast for Feb-Apr
- **AND** total allocations are: Feb $9,750, Mar $12,000, Apr $6,000
- **THEN** the system calculates total period revenue forecast as $27,750
### Requirement: Forecast summary aggregations
The system SHALL provide summary aggregations across all projects in the forecast.
#### Scenario: Total approved hours vs allocated hours
- **WHEN** viewing forecast summary
- **THEN** the system displays total approved estimate across all projects
- **AND** displays total allocated hours across all projects
- **AND** shows overall variance percentage
#### Scenario: Revenue forecast summary
- **WHEN** viewing forecast summary
- **THEN** the system displays total possible revenue (if all projects delivered at 100% allocation)
- **AND** displays current forecasted revenue based on actual allocations
### Requirement: Customizable date range
The system SHALL allow selecting custom date ranges for forecast reports.
#### Scenario: Select date range
- **WHEN** a manager selects "From: 2026-02" and "To: 2026-06"
- **THEN** the system generates forecast for those 5 months

View File

@@ -0,0 +1,119 @@
## ADDED Requirements
### Requirement: Manage roles
The system SHALL allow Superusers to configure team member roles.
#### Scenario: Create new role
- **WHEN** a Superuser creates a role "DevOps Engineer"
- **THEN** the system stores the role
- **AND** the role becomes available for team member assignment
#### Scenario: Update role
- **WHEN** a Superuser updates a role description
- **THEN** the system updates the role
- **AND** existing team members with that role are not affected
#### Scenario: Cannot delete role in use
- **WHEN** a Superuser attempts to delete a role that is assigned to team members
- **THEN** the system rejects the deletion with error "Cannot delete role in use by team members"
#### Scenario: View roles list
- **WHEN** a user requests the list of roles
- **THEN** the system returns all configured roles
### Requirement: Manage project statuses
The system SHALL allow Superusers to configure project status options.
#### Scenario: Create custom status
- **WHEN** a Superuser creates a new status "Client Review"
- **AND** sets the order as 5 (between "Estimate Approved" and "Funded")
- **THEN** the system adds the status to the workflow
#### Scenario: Set status as billable or non-billable
- **WHEN** configuring a status
- **THEN** the Superuser can mark it as billable (TRUE) or non-billable (FALSE)
- **AND** non-billable statuses may exclude projects from revenue forecasts
#### Scenario: Reorder statuses
- **WHEN** a Superuser changes the order of statuses
- **THEN** the system updates the status sequence
- **AND** project workflow reflects the new order
### Requirement: Manage project types
The system SHALL allow Superusers to configure project types.
#### Scenario: Default project types
- **WHEN** the system is initialized
- **THEN** it includes default types: "Project" (billable) and "Support" (ongoing ops)
#### Scenario: Create custom project type
- **WHEN** a Superuser creates a new type "Internal Initiative"
- **THEN** the system stores the type
- **AND** the type becomes available when creating projects
### Requirement: Manage availability options
The system SHALL enforce availability values as 0, 0.5, or 1.0.
#### Scenario: Availability options are fixed
- **WHEN** setting team member availability
- **THEN** the system restricts values to 0, 0.5, or 1.0
- **AND** rejects any other value
#### Scenario: Availability options are documented
- **WHEN** a user views the availability field
- **THEN** the system displays help text:
- "0 = Unavailable (PTO, holiday)"
- "0.5 = Half day"
- "1.0 = Full day"
### Requirement: Seed master data
The system SHALL provide initial master data on installation.
#### Scenario: Seed roles
- **WHEN** the system is installed
- **THEN** it creates default roles:
- Frontend Developer
- Backend Developer
- QA Engineer
- DevOps Engineer
- UX Designer
- Project Manager
- Architect
#### Scenario: Seed project statuses
- **WHEN** the system is installed
- **THEN** it creates default statuses with correct order:
1. NA/Support
2. Initial
3. Gathering Estimates
4. Estimate Pending Approval
5. Estimate Rework
6. Estimate Approved
7. Funded
8. Scheduled
9. In-Progress
10. Ready for Prod
11. Done
12. On-Hold
13. Cancelled
#### Scenario: Seed project types
- **WHEN** the system is installed
- **THEN** it creates default types:
- Project (billable)
- Support (ongoing ops)
### Requirement: Master data API endpoints
The system SHALL provide read-only API endpoints for master data.
#### Scenario: Get roles
- **WHEN** any authenticated user requests GET /api/master-data/roles
- **THEN** the system returns the list of all roles
#### Scenario: Get project statuses
- **WHEN** any authenticated user requests GET /api/master-data/statuses
- **THEN** the system returns the list of all project statuses in order
#### Scenario: Get project types
- **WHEN** any authenticated user requests GET /api/master-data/types
- **THEN** the system returns the list of all project types

View File

@@ -0,0 +1,100 @@
## ADDED Requirements
### Requirement: Create project
The system SHALL allow authorized users to create projects with project code, title, type, and status.
#### Scenario: Create new project
- **WHEN** a manager creates a project with code "PROJ-001", title "Client Dashboard Redesign", and type "Project"
- **THEN** the system creates the project with initial status "Initial"
- **AND** the system assigns a unique identifier to the project
#### Scenario: Project code must be unique
- **WHEN** attempting to create a project with a code that already exists
- **THEN** the system rejects the request with validation error "Project code must be unique"
### Requirement: Project status state machine
The system SHALL enforce project status transitions according to defined workflow states.
#### Scenario: Valid status transition
- **WHEN** a project in "Initial" status transitions to "Gathering Estimates"
- **THEN** the system updates the project status
#### Scenario: Project reaches Estimate Approved
- **WHEN** a project transitions to "Estimate Approved" status
- **THEN** the system requires approved estimate to be set
- **AND** the approved estimate must be greater than 0
#### Scenario: Project workflow progression
- **WHEN** a project progresses through statuses: Initial → Gathering Estimates → Estimate Pending Approval → Estimate Approved → Funded → Scheduled → In-Progress → Ready for Prod → Done
- **THEN** the system allows each transition in sequence
#### Scenario: Estimate rework path
- **WHEN** a project in "Estimate Pending Approval" status requires changes
- **THEN** the system allows transition back to "Estimate Rework" status
- **AND** from "Estimate Rework" the project can return to "Estimate Pending Approval"
#### Scenario: Project on hold
- **WHEN** a project is placed "On-Hold" from any active status
- **THEN** the system allows the transition
- **AND** allocations for future months are flagged but not deleted
#### Scenario: Project cancelled
- **WHEN** a project is marked as "Cancelled"
- **THEN** the system prevents new allocations
- **AND** existing allocations are preserved for historical tracking
### Requirement: Manage approved estimate
The system SHALL track the total approved billable hours for each project.
#### Scenario: Set approved estimate
- **WHEN** a project reaches "Estimate Approved" status with approved estimate of 120 hours
- **THEN** the system stores the approved estimate
- **AND** the approved estimate becomes the baseline for allocation validation
#### Scenario: Update approved estimate
- **WHEN** a manager updates the approved estimate from 120 to 150 hours
- **THEN** the system updates the approved estimate
- **AND** the system re-validates all allocations against the new estimate
### Requirement: Manage forecasted effort
The system SHALL track month-by-month breakdown of forecasted effort for each project.
#### Scenario: Set forecasted effort
- **WHEN** a manager sets forecasted effort for a 120-hour project as: February 40h, March 60h, April 20h
- **THEN** the system stores the forecasted effort as JSON: {"2026-02": 40, "2026-03": 60, "2026-04": 20}
#### Scenario: Forecasted effort must equal approved estimate
- **WHEN** the sum of forecasted effort (40 + 60 + 20 = 120) equals the approved estimate (120)
- **THEN** the system accepts the forecasted effort
#### Scenario: Forecasted effort validation fails
- **WHEN** the sum of forecasted effort (40 + 60 + 30 = 130) exceeds the approved estimate (120) by more than 5%
- **THEN** the system rejects the forecasted effort with validation error "Forecasted effort exceeds approved estimate"
#### Scenario: Under-forecasted effort
- **WHEN** the sum of forecasted effort (40 + 50 + 10 = 100) is less than the approved estimate (120)
- **THEN** the system displays a YELLOW warning "Under-forecasted by 20 hours"
### Requirement: Distinguish project types
The system SHALL differentiate between "Project" (billable) and "Support" (ongoing ops) project types.
#### Scenario: Billable project
- **WHEN** a project is created with type "Project"
- **THEN** the system tracks it as billable work
- **AND** it appears in revenue forecasts
#### Scenario: Support project
- **WHEN** a project is created with type "Support"
- **THEN** the system tracks it as ongoing operations
- **AND** it appears in capacity allocation but may have different reporting treatment
### Requirement: Cannot allocate to completed or cancelled projects
The system SHALL prevent new allocations to projects in "Done" or "Cancelled" status.
#### Scenario: Attempt to allocate to done project
- **WHEN** attempting to create an allocation for a project with status "Done"
- **THEN** the system rejects the allocation with error "Cannot allocate to completed projects"
#### Scenario: Attempt to allocate to cancelled project
- **WHEN** attempting to create an allocation for a project with status "Cancelled"
- **THEN** the system rejects the allocation with error "Cannot allocate to cancelled projects"

View File

@@ -0,0 +1,111 @@
## ADDED Requirements
### Requirement: Allocate hours to project
The system SHALL allow authorized users to allocate hours for a team member to a project for a specific month.
#### Scenario: Successful allocation
- **WHEN** a manager allocates 40 hours for "John Doe" to "Project X" for February 2026
- **THEN** the system creates the allocation record
- **AND** the system returns the allocation details including project, team member, month, and hours
#### Scenario: Allocate zero hours
- **WHEN** a manager allocates 0 hours for a team member to a project
- **THEN** the system accepts the allocation (useful for placeholder or removing allocation)
#### Scenario: Cannot allocate negative hours
- **WHEN** attempting to allocate -10 hours
- **THEN** the system rejects the request with validation error "Allocated hours must be greater than or equal to 0"
### Requirement: View allocation matrix
The system SHALL display allocations in a matrix format showing projects vs team members for a selected month.
#### Scenario: View monthly allocation matrix
- **WHEN** a manager views the allocation matrix for February 2026
- **THEN** the system displays all projects as rows
- **AND** the system displays all team members as columns
- **AND** each cell shows the allocated hours for that project-person combination
#### Scenario: Show allocation totals
- **WHEN** viewing the allocation matrix
- **THEN** the system displays total allocated hours per team member (column totals)
- **AND** the system displays total allocated hours per project (row totals)
#### Scenario: Show utilization percentage
- **WHEN** viewing the allocation matrix
- **THEN** the system displays utilization percentage per team member (allocated / capacity × 100%)
### Requirement: Update allocation
The system SHALL allow authorized users to modify existing allocations.
#### Scenario: Update allocated hours
- **WHEN** a manager updates an allocation from 40 hours to 60 hours
- **THEN** the system updates the allocation record
- **AND** the system re-validates against capacity and approved estimate
#### Scenario: Cannot update non-existent allocation
- **WHEN** attempting to update an allocation that does not exist
- **THEN** the system returns a 404 Not Found error
### Requirement: Delete allocation
The system SHALL allow authorized users to remove allocations.
#### Scenario: Delete allocation
- **WHEN** a manager deletes an allocation
- **THEN** the system removes the allocation record
- **AND** the system recalculates project and team member totals
### Requirement: Bulk allocation operations
The system SHALL allow creating or updating multiple allocations in a single operation.
#### Scenario: Bulk create allocations
- **WHEN** a manager submits 10 allocations for a project across multiple team members
- **THEN** the system creates all allocations
- **AND** the system validates each allocation individually
- **AND** the system returns results indicating success or failure for each
#### Scenario: Partial bulk failure
- **WHEN** submitting bulk allocations where 2 out of 10 fail validation
- **THEN** the system creates the 8 valid allocations
- **AND** the system returns error details for the 2 failed allocations
### Requirement: Track untracked resource allocations
The system SHALL allow allocating hours to an "untracked" resource bucket for external team time.
#### Scenario: Allocate to untracked resource
- **WHEN** a manager allocates 10 hours to "Untracked" for a project
- **THEN** the system creates the allocation without associating it to a specific team member
- **AND** the allocation counts toward project total but not toward any team member's capacity
#### Scenario: Untracked resource has no capacity limit
- **WHEN** viewing utilization for the untracked resource
- **THEN** the system displays "N/A" or infinite symbol for capacity
- **AND** no over-capacity warnings are shown for untracked allocations
### Requirement: Validate allocation against capacity
The system SHALL warn when a team member's total monthly allocation exceeds their capacity.
#### Scenario: Allocation within capacity
- **WHEN** a team member with 160 hours capacity has 140 hours total allocated
- **THEN** the system accepts the allocation
- **AND** the system displays utilization as 88% with no warning
#### Scenario: Allocation exceeds capacity
- **WHEN** a team member with 160 hours capacity has 180 hours total allocated
- **THEN** the system displays a WARNING "Team member over-allocated by 20 hours (113% utilization)"
- **AND** the allocation is still allowed but flagged
### Requirement: Validate allocation against approved estimate
The system SHALL validate that project allocations do not exceed the approved estimate.
#### Scenario: Allocation matches approved estimate
- **WHEN** a project with approved estimate of 100 hours has exactly 100 hours allocated
- **THEN** the system displays GREEN indicator "100% allocated"
#### Scenario: Under-allocation
- **WHEN** a project with approved estimate of 100 hours has 80 hours allocated
- **THEN** the system displays YELLOW indicator "80% allocated (under by 20 hours)"
#### Scenario: Over-allocation
- **WHEN** a project with approved estimate of 100 hours has 120 hours allocated
- **THEN** the system displays RED indicator "120% allocated (over by 20 hours)"
- **AND** the system warns "Project will be over-charged by 20 hours"

View File

@@ -0,0 +1,105 @@
## ADDED Requirements
### Requirement: Enforce Superuser permissions
The system SHALL grant Superusers full access to all functionality without restrictions.
#### Scenario: Superuser creates team member
- **WHEN** a Superuser creates a new team member
- **THEN** the system allows the action
#### Scenario: Superuser views all data
- **WHEN** a Superuser requests any data (projects, allocations, reports)
- **THEN** the system returns the requested data without access restrictions
### Requirement: Enforce Manager permissions
The system SHALL allow Managers to create/edit their own projects and allocate resources from their own team.
#### Scenario: Manager creates project
- **WHEN** a Manager creates a new project
- **THEN** the system associates the project with the Manager
- **AND** the Manager can edit the project
#### Scenario: Manager views all projects (read-only for others)
- **WHEN** a Manager requests the list of all projects
- **THEN** the system returns all projects
- **AND** projects owned by other Managers are marked as read-only
#### Scenario: Manager allocates own team member
- **WHEN** a Manager allocates a team member from their own team to a project
- **THEN** the system allows the allocation
#### Scenario: Manager cannot allocate other team's members
- **WHEN** a Manager attempts to allocate a team member from another Manager's team
- **THEN** the system rejects the request with error "Cannot allocate team members from other teams"
#### Scenario: Manager approves estimates
- **WHEN** a Manager approves an estimate for their own project
- **THEN** the system updates the project status and sets the approved estimate
### Requirement: Enforce Developer permissions
The system SHALL allow Developers to view their own allocations and log their own hours.
#### Scenario: Developer views own allocations
- **WHEN** a Developer requests their allocations
- **THEN** the system returns only projects where the Developer is allocated
#### Scenario: Developer logs own hours
- **WHEN** a Developer logs hours for a project they are allocated to
- **THEN** the system accepts the hours
#### Scenario: Developer cannot log hours for other team members
- **WHEN** a Developer attempts to log hours on behalf of another team member
- **THEN** the system rejects the request with error "Cannot log hours for other team members"
#### Scenario: Developer views assigned project details
- **WHEN** a Developer requests details for a project they are allocated to
- **THEN** the system returns project details (title, status, their allocation)
#### Scenario: Developer cannot view unassigned projects
- **WHEN** a Developer requests details for a project they are not allocated to
- **THEN** the system returns 403 Forbidden error
#### Scenario: Developer cannot allocate resources
- **WHEN** a Developer attempts to create or modify an allocation
- **THEN** the system rejects the request with error "Insufficient permissions"
### Requirement: Enforce Top Brass permissions
The system SHALL allow Top Brass to view all reports but prevent any modifications.
#### Scenario: Top Brass views all reports
- **WHEN** Top Brass requests forecast, utilization, cost, allocation, or variance reports
- **THEN** the system returns the requested report with all data
#### Scenario: Top Brass cannot modify data
- **WHEN** Top Brass attempts to create, update, or delete any entity (project, allocation, team member)
- **THEN** the system rejects the request with error "Read-only access"
#### Scenario: Top Brass views cross-team data
- **WHEN** Top Brass views reports
- **THEN** the system includes data from all teams without restrictions
### Requirement: Role-based API endpoints
The system SHALL protect API endpoints with role-based middleware.
#### Scenario: Unauthorized access attempt
- **WHEN** a user attempts to access an endpoint without the required role
- **THEN** the system returns 403 Forbidden error
- **AND** logs the unauthorized access attempt
#### Scenario: Token includes role information
- **WHEN** a user authenticates
- **THEN** the JWT token includes the user's role
- **AND** API middleware validates the role for each request
### Requirement: Model-level authorization
The system SHALL enforce authorization at the model level using Laravel Policies.
#### Scenario: Policy check for project update
- **WHEN** a Manager attempts to update a project
- **THEN** the system checks the ProjectPolicy to verify ownership
- **AND** allows the update only if the Manager owns the project or is a Superuser
#### Scenario: Policy check for allocation creation
- **WHEN** a user attempts to create an allocation
- **THEN** the system checks the AllocationPolicy to verify the user has permission
- **AND** for Managers, verifies the team member belongs to their team

View File

@@ -0,0 +1,60 @@
## ADDED Requirements
### Requirement: Create team member
The system SHALL allow authorized users to create new team members with name, role, hourly rate, and active status.
#### Scenario: Successful team member creation
- **WHEN** a manager creates a team member with valid name "John Doe", role "Backend Developer", and hourly rate $150
- **THEN** the system creates the team member with active status set to true by default
- **AND** the system assigns a unique identifier to the team member
- **AND** the system returns the created team member details
#### Scenario: Invalid hourly rate
- **WHEN** a manager attempts to create a team member with hourly rate of $0 or negative value
- **THEN** the system rejects the request with validation error "Hourly rate must be greater than 0"
#### Scenario: Missing required fields
- **WHEN** a manager attempts to create a team member without name or role
- **THEN** the system rejects the request with validation error listing missing required fields
### Requirement: View team members
The system SHALL allow authorized users to view the list of team members with their details.
#### Scenario: View all team members
- **WHEN** a manager requests the team members list
- **THEN** the system returns all team members with name, role, hourly rate, and active status
- **AND** the list includes both active and inactive team members
#### Scenario: Filter active team members only
- **WHEN** a manager requests team members filtered by active status
- **THEN** the system returns only team members where active is true
### Requirement: Update team member
The system SHALL allow authorized users to update team member details including role, hourly rate, and active status.
#### Scenario: Successful update
- **WHEN** a manager updates a team member's hourly rate from $150 to $175
- **THEN** the system updates the team member record
- **AND** the system returns the updated team member details
#### Scenario: Deactivate team member
- **WHEN** a manager sets a team member's active status to false
- **THEN** the system marks the team member as inactive
- **AND** the system preserves all historical allocation and actuals data for the team member
#### Scenario: Cannot update non-existent team member
- **WHEN** a manager attempts to update a team member that does not exist
- **THEN** the system returns a 404 Not Found error
### Requirement: Cannot delete team member with allocations
The system SHALL prevent deletion of team members who have active allocations or logged actuals.
#### Scenario: Attempt to delete team member with allocations
- **WHEN** a manager attempts to delete a team member who has allocations in current or future months
- **THEN** the system rejects the deletion with error "Cannot delete team member with active allocations"
- **AND** the system suggests deactivating the team member instead
#### Scenario: Attempt to delete team member with actuals
- **WHEN** a manager attempts to delete a team member who has logged actuals
- **THEN** the system rejects the deletion with error "Cannot delete team member with historical data"
- **AND** the system suggests deactivating the team member instead

View File

@@ -0,0 +1,91 @@
## ADDED Requirements
### Requirement: Calculate running utilization
The system SHALL calculate running utilization as (Allocated hours YTD) / (Capacity YTD) × 100%.
#### Scenario: Calculate YTD utilization in March
- **WHEN** a team member has capacity: Jan 160h, Feb 160h, Mar 160h (YTD total: 480h)
- **AND** the team member has allocations: Jan 140h, Feb 150h, Mar 160h (YTD total: 450h)
- **THEN** the system calculates running utilization as 93.75% (450 / 480 × 100%)
#### Scenario: Running utilization at start of year
- **WHEN** calculating running utilization in January
- **AND** the team member has capacity of 160h and allocations of 120h
- **THEN** the system calculates running utilization as 75% (120 / 160 × 100%)
### Requirement: Calculate overall utilization
The system SHALL calculate overall utilization as (Allocated hours this month) / (Capacity this month) × 100%.
#### Scenario: Calculate monthly utilization
- **WHEN** a team member has capacity of 160 hours for February
- **AND** the team member has total allocations of 140 hours for February
- **THEN** the system calculates overall utilization as 87.5% (140 / 160 × 100%)
#### Scenario: Full utilization
- **WHEN** a team member has capacity of 160 hours
- **AND** allocations of exactly 160 hours
- **THEN** the system calculates overall utilization as 100%
#### Scenario: Over-utilization
- **WHEN** a team member has capacity of 160 hours
- **AND** allocations of 180 hours
- **THEN** the system calculates overall utilization as 112.5% (180 / 160 × 100%)
### Requirement: Display utilization alongside capacity
The system SHALL display utilization percentages alongside capacity information in the allocation view.
#### Scenario: Display capacity with utilization
- **WHEN** viewing the allocation matrix for a team member
- **THEN** the system displays capacity (e.g., "160h")
- **AND** displays overall utilization percentage (e.g., "87.5%")
- **AND** displays running utilization percentage (e.g., "YTD: 93.75%")
### Requirement: Color-code utilization levels
The system SHALL use color coding to indicate utilization levels.
#### Scenario: Low utilization
- **WHEN** overall utilization is below 70%
- **THEN** the system displays the utilization in BLUE or GRAY (underutilized)
#### Scenario: Optimal utilization
- **WHEN** overall utilization is between 80% and 100%
- **THEN** the system displays the utilization in GREEN (optimal)
#### Scenario: High utilization
- **WHEN** overall utilization is between 100% and 110%
- **THEN** the system displays the utilization in YELLOW (caution)
#### Scenario: Over-utilization
- **WHEN** overall utilization exceeds 110%
- **THEN** the system displays the utilization in RED (over-allocated)
### Requirement: Calculate team-level utilization
The system SHALL calculate average utilization across all team members.
#### Scenario: Calculate team average utilization
- **WHEN** Team Member A has 87.5% utilization
- **AND** Team Member B has 93.75% utilization
- **AND** Team Member C has 75% utilization
- **THEN** the system calculates team average utilization as 85.4% ((87.5 + 93.75 + 75) / 3)
#### Scenario: Exclude inactive team members from team utilization
- **WHEN** calculating team-level utilization
- **AND** one team member is inactive
- **THEN** the system excludes the inactive team member from the average
### Requirement: Track utilization trends over time
The system SHALL provide historical utilization data for trend analysis.
#### Scenario: View utilization trend for 6 months
- **WHEN** viewing a team member's utilization history from January to June
- **THEN** the system displays monthly utilization percentages for each month
- **AND** the system shows a trend line or chart indicating increasing/decreasing utilization
### Requirement: Compare allocated vs actual utilization
The system SHALL calculate actual utilization based on logged hours for comparison with planned utilization.
#### Scenario: Calculate actual utilization
- **WHEN** a team member had 140 hours allocated (planned utilization: 87.5%)
- **AND** the team member logged 130 hours actual (actual utilization: 81.25%)
- **THEN** the system displays both planned and actual utilization side by side
- **AND** the system shows variance of -6.25 percentage points

View File

@@ -0,0 +1,71 @@
## ADDED Requirements
### Requirement: Generate utilization summary report
The system SHALL generate reports showing team and individual utilization trends over time.
#### Scenario: View team utilization report
- **WHEN** a manager requests utilization report for February-April 2026
- **THEN** the system displays team-level utilization for each month
- **AND** shows individual team member utilization for each month
- **AND** calculates average utilization across the period
#### Scenario: Utilization trend visualization
- **WHEN** viewing utilization report
- **THEN** the system displays a chart showing utilization percentage trend over time
- **AND** highlights months with low utilization (< 70%) in blue
- **AND** highlights months with optimal utilization (80-100%) in green
- **AND** highlights months with over-utilization (> 100%) in red
### Requirement: Filter utilization by team member
The system SHALL allow filtering utilization reports by individual team member or role.
#### Scenario: View individual utilization
- **WHEN** filtering to show utilization for "John Doe"
- **THEN** the system displays John's monthly utilization percentages
- **AND** shows running (YTD) utilization
- **AND** shows overall (monthly) utilization for each month
#### Scenario: View role-based utilization
- **WHEN** filtering to show utilization for "Backend Developer" role
- **THEN** the system displays average utilization for all Backend Developers
- **AND** shows individual breakdown for each team member in that role
### Requirement: Compare planned vs actual utilization
The system SHALL show variance between planned utilization (allocations) and actual utilization (logged hours).
#### Scenario: Utilization variance report
- **WHEN** a team member had 87.5% planned utilization in February
- **AND** logged hours resulting in 81.25% actual utilization
- **THEN** the system displays variance of -6.25 percentage points
- **AND** flags under-delivery
#### Scenario: Over-delivery variance
- **WHEN** a team member had 87.5% planned utilization
- **AND** logged hours resulting in 95% actual utilization
- **THEN** the system displays variance of +7.5 percentage points
- **AND** flags over-delivery (worked more than allocated)
### Requirement: Utilization distribution chart
The system SHALL display utilization distribution showing how many team members fall into each utilization band.
#### Scenario: View utilization distribution
- **WHEN** viewing team utilization report for February
- **THEN** the system shows how many team members are in each band:
- Under-utilized (< 70%): 2 team members
- Optimal (70-100%): 8 team members
- Over-utilized (> 100%): 3 team members
### Requirement: Filter by date range
The system SHALL allow selecting custom date ranges for utilization reports.
#### Scenario: Quarter-over-quarter comparison
- **WHEN** selecting Q1 2026 (Jan-Mar) and Q2 2026 (Apr-Jun)
- **THEN** the system displays utilization comparison between the two quarters
### Requirement: Identify underutilized capacity
The system SHALL highlight team members with consistently low utilization.
#### Scenario: Flag underutilized team members
- **WHEN** a team member has utilization below 70% for 3 consecutive months
- **THEN** the system flags the team member in the report with warning "Underutilized capacity"
- **AND** calculates total wasted capacity in hours

View File

@@ -0,0 +1,73 @@
## ADDED Requirements
### Requirement: Generate variance report
The system SHALL generate reports comparing planned allocations vs actual logged hours.
#### Scenario: View monthly variance report
- **WHEN** viewing variance report for February 2026
- **THEN** the system displays all projects with:
- Allocated hours (planned)
- Actual hours (logged)
- Variance (actual - planned)
- Variance percentage ((variance / planned) × 100%)
#### Scenario: Positive variance (over-delivery)
- **WHEN** a project had 40 hours allocated
- **AND** team member logged 45 hours actual
- **THEN** the system displays variance of +5 hours (+12.5%)
- **AND** flags as "Over-delivery"
#### Scenario: Negative variance (under-delivery)
- **WHEN** a project had 40 hours allocated
- **AND** team member logged 32 hours actual
- **THEN** the system displays variance of -8 hours (-20%)
- **AND** flags as "Under-delivery"
### Requirement: Variance by project
The system SHALL show variance aggregated by project.
#### Scenario: Project variance summary
- **WHEN** viewing variance for "Project X" with 120 hours allocated across 3 team members
- **AND** actual hours logged total 110 hours
- **THEN** the system displays project-level variance of -10 hours (-8.3%)
### Requirement: Variance by team member
The system SHALL show variance aggregated by team member.
#### Scenario: Person variance summary
- **WHEN** "John Doe" had 140 hours total allocated across multiple projects
- **AND** logged 135 hours actual
- **THEN** the system displays person-level variance of -5 hours (-3.6%)
#### Scenario: Consistent over-delivery
- **WHEN** a team member has positive variance for 3 consecutive months
- **THEN** the system flags the pattern "Consistently working more than allocated"
### Requirement: Filter variance report
The system SHALL allow filtering variance reports by date range, project, team, or person.
#### Scenario: Filter by date range
- **WHEN** filtering variance report for Q1 2026
- **THEN** the system displays variance for January, February, and March
- **AND** calculates total variance across the quarter
### Requirement: Variance trend analysis
The system SHALL show variance trends over time.
#### Scenario: Variance trend chart
- **WHEN** viewing variance trends for a team member over 6 months
- **THEN** the system displays a chart showing variance percentage for each month
- **AND** highlights months with significant variance (> ±15%)
### Requirement: Root cause indicators
The system SHALL highlight patterns that may explain variance.
#### Scenario: Under-delivery correlation with PTO
- **WHEN** a team member has negative variance in a month
- **AND** the team member had PTO during that month
- **THEN** the system notes "PTO may have contributed to under-delivery"
#### Scenario: Over-delivery correlation with over-allocation
- **WHEN** a team member has positive variance
- **AND** the team member was over-allocated (> 100% capacity)
- **THEN** the system notes "Team member worked extra hours beyond allocation"

View File

@@ -0,0 +1,441 @@
## 1. Project Setup & Infrastructure
- [ ] 1.1 Create Docker Compose configuration (frontend, backend, postgres, redis containers)
- [ ] 1.2 Configure Dockerfile for Laravel backend (PHP 8.4-FPM, use :latest tag)
- [ ] 1.3 Configure Dockerfile for SvelteKit frontend (Node:latest)
- [ ] 1.4 Set up volume mounts for code (hot reload) and data (PostgreSQL, Redis)
- [ ] 1.5 Configure environment variables (.env files for frontend and backend)
- [ ] 1.6 Test Docker Compose startup (all 4 containers running)
- [ ] 1.7 Configure Nginx Proxy Manager routes (/api/* → Laravel, /* → SvelteKit)
## 2. Backend Foundation (Laravel)
- [ ] 2.1 Initialize Laravel 12 (latest) project with required dependencies
- [ ] 2.2 Install tymon/jwt-auth, predis/predis, knuckleswtf/scribe
- [ ] 2.3 Install pestphp/pest, laravel/pint for testing and linting
- [ ] 2.4 Configure PostgreSQL connection in config/database.php
- [ ] 2.5 Configure Redis connection for cache and sessions
- [ ] 2.6 Set up JWT authentication configuration (60min access, 7day refresh)
- [ ] 2.7 Configure CORS for SvelteKit frontend origin
- [ ] 2.8 Create API route structure (api.php)
## 3. Frontend Foundation (SvelteKit)
- [ ] 3.1 Initialize SvelteKit project with TypeScript
- [ ] 3.2 Install Tailwind CSS and DaisyUI
- [ ] 3.3 Install Recharts, TanStack Table (@tanstack/svelte-table)
- [ ] 3.4 Install Superforms (sveltekit-superforms) and Zod
- [ ] 3.5 Install Vitest and Playwright for testing
- [ ] 3.6 Configure Tailwind with DaisyUI theme
- [ ] 3.7 Create API client service (fetch wrapper with JWT token handling)
- [ ] 3.8 Create auth store (Svelte store for user, token management)
- [ ] 3.9 Create layout components (+layout.svelte, navigation)
## 4. Database Schema & Migrations
- [ ] 4.1 Create migration: roles table (id, name, description)
- [ ] 4.2 Create migration: project_statuses table (id, name, order, is_active, is_billable)
- [ ] 4.3 Create migration: project_types table (id, name, description)
- [ ] 4.4 Create migration: team_members table (id UUID, name, role_id, hourly_rate, active)
- [ ] 4.5 Create migration: projects table (id UUID, code unique, title, status_id, type_id, approved_estimate, forecasted_effort JSON)
- [ ] 4.6 Create migration: allocations table (id UUID, project_id, team_member_id, month, allocated_hours)
- [ ] 4.7 Create migration: actuals table (id UUID, project_id, team_member_id, month, hours_logged)
- [ ] 4.8 Create migration: holidays table (id UUID, date, name, description)
- [ ] 4.9 Create migration: ptos table (id UUID, team_member_id, start_date, end_date, reason, status)
- [ ] 4.10 Create migration: users table (id UUID, name, email, password, role enum)
- [ ] 4.11 Add indexes (composite on allocations/actuals for project+month, member+month)
- [ ] 4.12 Run migrations and verify schema
## 5. Database Seeders
- [ ] 5.1 Create seeder: roles (Frontend Dev, Backend Dev, QA, DevOps, UX, PM, Architect)
- [ ] 5.2 Create seeder: project_statuses (13 statuses with correct order)
- [ ] 5.3 Create seeder: project_types (Project, Support)
- [ ] 5.4 Create seeder: users (create superuser account for testing)
- [ ] 5.5 Run seeders and verify master data populated
## 6. Laravel Models & Relationships
- [ ] 6.1 Create TeamMember model with role relationship
- [ ] 6.2 Create Project model with status, type relationships, casts for forecasted_effort JSON
- [ ] 6.3 Create Allocation model with project, team_member relationships
- [ ] 6.4 Create Actual model with project, team_member relationships
- [ ] 6.5 Create Role, ProjectStatus, ProjectType models
- [ ] 6.6 Create Holiday, PTO models
- [ ] 6.7 Create User model with JWT authentication traits
- [ ] 6.8 Define model factories for testing (TeamMemberFactory, ProjectFactory, etc.)
## 7. Authentication (Backend)
- [ ] 7.1 Create AuthController (login, logout, refresh methods)
- [ ] 7.2 Implement login endpoint (validate credentials, generate JWT tokens)
- [ ] 7.3 Implement logout endpoint (invalidate refresh token in Redis)
- [ ] 7.4 Implement refresh endpoint (validate refresh token, rotate tokens)
- [ ] 7.5 Create JWT middleware for protecting routes
- [ ] 7.6 Store refresh tokens in Redis with 7-day TTL
- [ ] 7.7 Write unit tests for AuthController
- [ ] 7.8 Write feature tests for auth endpoints
## 8. Authentication (Frontend)
- [ ] 8.1 Create login page (/login route)
- [ ] 8.2 Create login form with Superforms + Zod validation
- [ ] 8.3 Implement auth API client methods (login, logout, refresh)
- [ ] 8.4 Create auth store (persist tokens in localStorage)
- [ ] 8.5 Implement token refresh logic (interceptor for 401 responses)
- [ ] 8.6 Create auth guard for protected routes (hooks.server.ts)
- [ ] 8.7 Add logout functionality to navigation
- [ ] 8.8 Write E2E test for login flow (Playwright)
## 9. Team Member Management (Backend)
- [ ] 9.1 Create TeamMemberController (index, store, show, update, destroy)
- [ ] 9.2 Create TeamMemberRequest for validation (name required, hourly_rate > 0)
- [ ] 9.3 Create TeamMemberResource for JSON transformation
- [ ] 9.4 Create TeamMemberPolicy for authorization (managers can CRUD)
- [ ] 9.5 Implement soft delete prevention (cannot delete if allocations exist)
- [ ] 9.6 Add API routes for team members
- [ ] 9.7 Write unit tests for TeamMember model
- [ ] 9.8 Write feature tests for team member endpoints
## 10. Team Member Management (Frontend)
- [ ] 10.1 Create team members list page (/team-members route)
- [ ] 10.2 Create team member create/edit form with Superforms + Zod
- [ ] 10.3 Implement team member API client methods (CRUD)
- [ ] 10.4 Display team members in TanStack Table (sortable, filterable)
- [ ] 10.5 Add active/inactive toggle UI
- [ ] 10.6 Add hourly rate display (formatted as currency)
- [ ] 10.7 Implement delete with confirmation modal
- [ ] 10.8 Write unit tests for team member components (Vitest)
- [ ] 10.9 Write E2E test for team member CRUD (Playwright)
## 11. Project Management (Backend)
- [ ] 11.1 Create ProjectController (index, store, show, update, destroy)
- [ ] 11.2 Create ProjectRequest for validation (code unique, approved_estimate > 0 if status >= Approved)
- [ ] 11.3 Create ProjectResource for JSON transformation
- [ ] 11.4 Create ProjectPolicy for authorization (managers can edit own projects)
- [ ] 11.5 Implement project status state machine validation
- [ ] 11.6 Implement forecasted effort validation (sum must equal approved estimate ±5%)
- [ ] 11.7 Add API routes for projects
- [ ] 11.8 Write unit tests for Project model and status transitions
- [ ] 11.9 Write feature tests for project endpoints
## 12. Project Management (Frontend)
- [ ] 12.1 Create projects list page (/projects route)
- [ ] 12.2 Create project create/edit form with Superforms + Zod
- [ ] 12.3 Implement project API client methods (CRUD)
- [ ] 12.4 Display projects in TanStack Table (sortable, filterable by status/type)
- [ ] 12.5 Add status dropdown (reflect state machine transitions)
- [ ] 12.6 Add forecasted effort input (JSON editor or month-by-month fields)
- [ ] 12.7 Display validation warnings (forecasted effort ≠ approved estimate)
- [ ] 12.8 Write unit tests for project components (Vitest)
- [ ] 12.9 Write E2E test for project creation and status transitions (Playwright)
## 13. Capacity Planning (Backend)
- [ ] 13.1 Create HolidayController (index, store, destroy)
- [ ] 13.2 Create PTOController (index, store, update, destroy with approval workflow)
- [ ] 13.3 Create CapacityService for capacity calculations
- [ ] 13.4 Implement calculateIndividualCapacity method (working days × availability - PTO - holidays)
- [ ] 13.5 Implement calculateTeamCapacity method (sum of individual capacities for active members)
- [ ] 13.6 Implement calculatePossibleRevenue method (capacity × hourly rates)
- [ ] 13.7 Add API routes for capacity endpoint (/api/capacity?month=YYYY-MM)
- [ ] 13.8 Implement Redis caching for capacity calculations (1 hour TTL)
- [ ] 13.9 Write unit tests for CapacityService
- [ ] 13.10 Write feature tests for capacity endpoints
## 14. Capacity Planning (Frontend)
- [ ] 14.1 Create capacity planning page (/capacity route)
- [ ] 14.2 Create calendar component for displaying month grid
- [ ] 14.3 Implement availability editor (click day to set 0, 0.5, 1.0)
- [ ] 14.4 Display holidays (H marker on dates)
- [ ] 14.5 Display weekends (O marker on dates)
- [ ] 14.6 Create PTO request form
- [ ] 14.7 Display individual and team capacity summary
- [ ] 14.8 Display possible revenue calculation
- [ ] 14.9 Write unit tests for capacity components (Vitest)
- [ ] 14.10 Write E2E test for capacity planning workflow (Playwright)
## 15. Resource Allocation (Backend)
- [ ] 15.1 Create AllocationController (index, store, update, destroy, bulk methods)
- [ ] 15.2 Create AllocationRequest for validation (hours >= 0, month format YYYY-MM)
- [ ] 15.3 Create AllocationResource for JSON transformation
- [ ] 15.4 Create AllocationPolicy for authorization (managers can allocate own team members)
- [ ] 15.5 Implement allocation validation service (check capacity, approved estimate)
- [ ] 15.6 Implement bulk allocation endpoint (create/update multiple allocations)
- [ ] 15.7 Add API routes for allocations (/api/allocations?month=YYYY-MM)
- [ ] 15.8 Implement Redis cache invalidation on allocation mutations
- [ ] 15.9 Write unit tests for allocation validation logic
- [ ] 15.10 Write feature tests for allocation endpoints
## 16. Resource Allocation (Frontend)
- [ ] 16.1 Create allocation matrix page (/allocations route)
- [ ] 16.2 Create allocation matrix component using TanStack Table
- [ ] 16.3 Implement inline editing for allocation hours
- [ ] 16.4 Display projects as rows, team members as columns
- [ ] 16.5 Display row totals (total hours per project)
- [ ] 16.6 Display column totals (total hours per team member)
- [ ] 16.7 Display utilization percentages per team member
- [ ] 16.8 Implement color-coded indicators (GREEN/YELLOW/RED for over/under allocation)
- [ ] 16.9 Add "Untracked" resource column
- [ ] 16.10 Implement month selector (navigate between months)
- [ ] 16.11 Add bulk allocation actions (copy previous month, clear all)
- [ ] 16.12 Write unit tests for allocation matrix logic (Vitest)
- [ ] 16.13 Write E2E test for allocation workflow (Playwright)
## 17. Actuals Tracking (Backend)
- [ ] 17.1 Create ActualController (index, store, update, bulk methods)
- [ ] 17.2 Create ActualRequest for validation (hours >= 0, cannot log future months)
- [ ] 17.3 Create ActualResource for JSON transformation
- [ ] 17.4 Create ActualPolicy for authorization (developers can log own hours only)
- [ ] 17.5 Implement validation: cannot log to completed/cancelled projects (configurable)
- [ ] 17.6 Implement bulk actuals endpoint
- [ ] 17.7 Add API routes for actuals (/api/actuals?month=YYYY-MM)
- [ ] 17.8 Implement Redis cache invalidation on actuals mutations
- [ ] 17.9 Write unit tests for actuals validation
- [ ] 17.10 Write feature tests for actuals endpoints
## 18. Actuals Tracking (Frontend)
- [ ] 18.1 Create actuals entry page (/actuals route)
- [ ] 18.2 Create actuals matrix component (similar to allocations matrix)
- [ ] 18.3 Display allocated hours vs actual hours side by side
- [ ] 18.4 Highlight variances (over/under delivery)
- [ ] 18.5 Allow developers to see only their own actuals (RBAC check)
- [ ] 18.6 Implement bulk update for multiple projects
- [ ] 18.7 Write unit tests for actuals components (Vitest)
- [ ] 18.8 Write E2E test for actuals logging (Playwright)
## 19. Utilization Calculations (Backend)
- [ ] 19.1 Create UtilizationService for utilization calculations
- [ ] 19.2 Implement calculateRunningUtilization method (YTD allocated / YTD capacity)
- [ ] 19.3 Implement calculateOverallUtilization method (monthly allocated / monthly capacity)
- [ ] 19.4 Implement calculateActualUtilization method (monthly actuals / monthly capacity)
- [ ] 19.5 Implement team-level utilization aggregation
- [ ] 19.6 Add utilization data to allocation and actuals responses
- [ ] 19.7 Write unit tests for UtilizationService
- [ ] 19.8 Write feature tests for utilization calculations
## 20. Reporting - Forecast (Backend)
- [ ] 20.1 Create ReportController with forecast method
- [ ] 20.2 Implement forecast report query (multi-period allocations)
- [ ] 20.3 Calculate revenue forecast (allocations × hourly rates)
- [ ] 20.4 Display variance indicators (forecasted vs approved estimate)
- [ ] 20.5 Implement filters (project, status, type, team, date range)
- [ ] 20.6 Create ForecastReportResource for JSON transformation
- [ ] 20.7 Add API route /api/reports/forecast
- [ ] 20.8 Implement Redis caching for forecast reports (15 min TTL)
- [ ] 20.9 Write unit tests for forecast report logic
- [ ] 20.10 Write feature tests for forecast endpoint
## 21. Reporting - Forecast (Frontend)
- [ ] 21.1 Create forecast report page (/reports/forecast route)
- [ ] 21.2 Create forecast report table component
- [ ] 21.3 Display multi-period view (month columns)
- [ ] 21.4 Display variance indicators (GREEN/YELLOW/RED)
- [ ] 21.5 Implement date range selector
- [ ] 21.6 Implement filters (project, status, type, team)
- [ ] 21.7 Display summary aggregations (total approved, total allocated, variance)
- [ ] 21.8 Add revenue forecast chart (Recharts line chart)
- [ ] 21.9 Write E2E test for forecast report (Playwright)
## 22. Reporting - Utilization (Backend)
- [ ] 22.1 Add utilization method to ReportController
- [ ] 22.2 Implement utilization report query (team and individual trends)
- [ ] 22.3 Calculate planned vs actual utilization
- [ ] 22.4 Implement filters (team member, role, date range)
- [ ] 22.5 Create UtilizationReportResource for JSON transformation
- [ ] 22.6 Add API route /api/reports/utilization
- [ ] 22.7 Implement Redis caching for utilization reports
- [ ] 22.8 Write feature tests for utilization endpoint
## 23. Reporting - Utilization (Frontend)
- [ ] 23.1 Create utilization report page (/reports/utilization route)
- [ ] 23.2 Display team-level utilization summary
- [ ] 23.3 Display individual utilization breakdown
- [ ] 23.4 Add utilization trend chart (Recharts line chart)
- [ ] 23.5 Color-code utilization bands (< 70% blue, 80-100% green, > 100% yellow/red)
- [ ] 23.6 Implement filters (team member, role, date range)
- [ ] 23.7 Display utilization distribution chart (how many in each band)
- [ ] 23.8 Write E2E test for utilization report (Playwright)
## 24. Reporting - Cost (Backend)
- [ ] 24.1 Add cost method to ReportController
- [ ] 24.2 Implement cost report query (allocations × hourly rates)
- [ ] 24.3 Calculate possible revenue (full capacity utilization)
- [ ] 24.4 Calculate forecasted revenue (current allocations)
- [ ] 24.5 Calculate revenue gap (possible - forecasted)
- [ ] 24.6 Implement filters (project, client, type, team, date range)
- [ ] 24.7 Create CostReportResource for JSON transformation
- [ ] 24.8 Add API route /api/reports/cost
- [ ] 24.9 Implement Redis caching for cost reports
- [ ] 24.10 Write feature tests for cost endpoint
## 25. Reporting - Cost (Frontend)
- [ ] 25.1 Create cost report page (/reports/cost route)
- [ ] 25.2 Display monthly revenue forecast
- [ ] 25.3 Display cost breakdown by project
- [ ] 25.4 Display possible revenue vs forecasted revenue
- [ ] 25.5 Display revenue gap analysis
- [ ] 25.6 Implement filters (project, type, team, date range)
- [ ] 25.7 Add revenue chart (Recharts bar chart)
- [ ] 25.8 Write E2E test for cost report (Playwright)
## 26. Reporting - Allocation (Backend)
- [ ] 26.1 Add allocation method to ReportController
- [ ] 26.2 Implement allocation report query (monthly matrix view)
- [ ] 26.3 Include utilization percentages
- [ ] 26.4 Implement filters (team, role, project, status)
- [ ] 26.5 Create AllocationReportResource for JSON transformation
- [ ] 26.6 Add API route /api/reports/allocation
- [ ] 26.7 Implement Redis caching for allocation reports
- [ ] 26.8 Write feature tests for allocation endpoint
## 27. Reporting - Allocation (Frontend)
- [ ] 27.1 Create allocation report page (/reports/allocation route)
- [ ] 27.2 Display allocation matrix with totals
- [ ] 27.3 Display utilization percentages
- [ ] 27.4 Highlight recent allocation changes (NEW/UPDATED badges)
- [ ] 27.5 Implement multi-month view option
- [ ] 27.6 Implement filters (team, role, project, status)
- [ ] 27.7 Write E2E test for allocation report (Playwright)
## 28. Reporting - Variance (Backend)
- [ ] 28.1 Add variance method to ReportController
- [ ] 28.2 Implement variance report query (planned vs actual comparison)
- [ ] 28.3 Calculate variance (actual - planned) and percentage
- [ ] 28.4 Flag over-delivery and under-delivery patterns
- [ ] 28.5 Implement filters (project, team, person, date range)
- [ ] 28.6 Create VarianceReportResource for JSON transformation
- [ ] 28.7 Add API route /api/reports/variance
- [ ] 28.8 Implement Redis caching for variance reports
- [ ] 28.9 Write feature tests for variance endpoint
## 29. Reporting - Variance (Frontend)
- [ ] 29.1 Create variance report page (/reports/variance route)
- [ ] 29.2 Display variance table (planned, actual, variance, variance %)
- [ ] 29.3 Color-code variances (positive green, negative red)
- [ ] 29.4 Display project-level variance aggregations
- [ ] 29.5 Display person-level variance aggregations
- [ ] 29.6 Add variance trend chart (Recharts)
- [ ] 29.7 Implement filters (project, team, person, date range)
- [ ] 29.8 Write E2E test for variance report (Playwright)
## 30. Role-Based Access Control (Backend)
- [ ] 30.1 Create role middleware for route protection
- [ ] 30.2 Implement permission checks in controllers
- [ ] 30.3 Create policies for all models (TeamMember, Project, Allocation, Actual)
- [ ] 30.4 Implement Superuser full access (bypass all checks)
- [ ] 30.5 Implement Manager permissions (own projects, own team allocations)
- [ ] 30.6 Implement Developer permissions (own allocations, own actuals)
- [ ] 30.7 Implement Top Brass permissions (read-only all reports)
- [ ] 30.8 Write unit tests for policies
- [ ] 30.9 Write feature tests for authorization (401, 403 responses)
## 31. Role-Based Access Control (Frontend)
- [ ] 31.1 Add role to auth store
- [ ] 31.2 Implement route guards based on role (hooks.server.ts)
- [ ] 31.3 Hide UI elements based on permissions (v-if directives)
- [ ] 31.4 Show read-only state for Top Brass users
- [ ] 31.5 Filter visible projects for Managers (own projects editable, others read-only)
- [ ] 31.6 Filter visible data for Developers (only assigned projects)
- [ ] 31.7 Write E2E tests for RBAC (different user roles)
## 32. Master Data Management (Backend)
- [ ] 32.1 Create MasterDataController (roles, statuses, types endpoints)
- [ ] 32.2 Create RoleController for managing roles (Superuser only)
- [ ] 32.3 Create ProjectStatusController for managing statuses (Superuser only)
- [ ] 32.4 Create ProjectTypeController for managing types (Superuser only)
- [ ] 32.5 Implement validation: cannot delete role/status/type in use
- [ ] 32.6 Add API routes for master data endpoints
- [ ] 32.7 Implement Redis caching for master data (24 hour TTL)
- [ ] 32.8 Write feature tests for master data endpoints
## 33. Master Data Management (Frontend)
- [ ] 33.1 Create master data management page (/admin/master-data route, Superuser only)
- [ ] 33.2 Display roles list with CRUD actions
- [ ] 33.3 Display project statuses list with reordering and CRUD actions
- [ ] 33.4 Display project types list with CRUD actions
- [ ] 33.5 Implement master data forms (create/edit)
- [ ] 33.6 Write E2E test for master data management (Playwright)
## 34. API Documentation (Backend)
- [ ] 34.1 Add Scribe annotations to all controllers (@group, @response tags)
- [ ] 34.2 Configure Scribe (scribe.php config file)
- [ ] 34.3 Generate API documentation (php artisan scribe:generate)
- [ ] 34.4 Verify SwaggerUI accessible at /api/documentation
- [ ] 34.5 Add example requests and responses to documentation
- [ ] 34.6 Add authentication section to API docs
## 35. Testing & Code Quality
- [ ] 35.1 Write comprehensive unit tests (backend models, services, utilities)
- [ ] 35.2 Write feature tests for all API endpoints (Laravel Pest)
- [ ] 35.3 Write unit tests for frontend components (Vitest)
- [ ] 35.4 Write E2E tests for critical flows (Playwright: login, allocate, report)
- [ ] 35.5 Configure pre-commit hooks (Laravel Pint, ESLint, Prettier)
- [ ] 35.6 Run PHPStan static analysis (level 5+)
- [ ] 35.7 Generate code coverage report (verify >70%)
- [ ] 35.8 Fix all linting errors (Laravel Pint, ESLint)
- [ ] 35.9 Run security audit (composer audit, npm audit)
## 36. Polish & UX
- [ ] 36.1 Add loading states (spinners, skeleton loaders)
- [ ] 36.2 Add error states (toast notifications, error pages)
- [ ] 36.3 Add empty states (no data placeholders)
- [ ] 36.4 Implement form validation feedback (inline errors, success messages)
- [ ] 36.5 Add confirmation modals for destructive actions (delete)
- [ ] 36.6 Implement responsive design (mobile-friendly tables, navigation)
- [ ] 36.7 Add keyboard shortcuts (ESC to close modals, etc.)
- [ ] 36.8 Add accessibility features (ARIA labels, focus management)
- [ ] 36.9 Test in multiple browsers (Chrome, Firefox, Safari)
## 37. Documentation & Deployment
- [ ] 37.1 Write README.md with setup instructions
- [ ] 37.2 Document environment variables (.env.example files)
- [ ] 37.3 Create Quick Start guide for managers (capacity → allocate → reports)
- [ ] 37.4 Document API authentication flow
- [ ] 37.5 Create deployment guide (Docker Compose production setup)
- [ ] 37.6 Add health check endpoints (/api/health)
- [ ] 37.7 Configure logging (Laravel logs to stdout, Svelte client errors to console)
- [ ] 37.8 Test full deployment workflow (fresh Docker Compose up)
- [ ] 37.9 Create superuser via seeder for initial login
- [ ] 37.10 Verify Nginx Proxy Manager routing
## 38. Final Verification
- [ ] 38.1 Run full test suite (unit + E2E) and verify all pass
- [ ] 38.2 Verify code coverage >70%
- [ ] 38.3 Run linters and fix all issues
- [ ] 38.4 Test complete user flow: capacity → allocate → log actuals → reports
- [ ] 38.5 Verify RBAC working for all 4 personas
- [ ] 38.6 Verify Redis caching working (check cache hit rate)
- [ ] 38.7 Verify API documentation accessible and accurate
- [ ] 38.8 Verify Docker Compose startup works cleanly
- [ ] 38.9 Verify database migrations and seeders work
- [ ] 38.10 Conduct final security review (no secrets in code, HTTPS enforced)