Headroom - Foundation
This commit is contained in:
2
openspec/changes/headroom-foundation/.openspec.yaml
Normal file
2
openspec/changes/headroom-foundation/.openspec.yaml
Normal file
@@ -0,0 +1,2 @@
|
||||
schema: spec-driven
|
||||
created: 2026-02-17
|
||||
559
openspec/changes/headroom-foundation/design.md
Normal file
559
openspec/changes/headroom-foundation/design.md
Normal 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
|
||||
68
openspec/changes/headroom-foundation/proposal.md
Normal file
68
openspec/changes/headroom-foundation/proposal.md
Normal 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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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)
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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"
|
||||
@@ -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"
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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"
|
||||
441
openspec/changes/headroom-foundation/tasks.md
Normal file
441
openspec/changes/headroom-foundation/tasks.md
Normal 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)
|
||||
Reference in New Issue
Block a user