Based on the provided specification, I will summarize the changes and
address each point.
**Changes Summary**
This specification updates the `headroom-foundation` change set to
include actuals tracking. The new feature adds a `TeamMember` model for
team members and a `ProjectStatus` model for project statuses.
**Summary of Changes**
1. **Add Team Members**
* Created the `TeamMember` model with attributes: `id`, `name`,
`role`, and `active`.
* Implemented data migration to add all existing users as
`team_member_ids` in the database.
2. **Add Project Statuses**
* Created the `ProjectStatus` model with attributes: `id`, `name`,
`order`, and `is_active`.
* Defined initial project statuses as "Initial" and updated
workflow states accordingly.
3. **Actuals Tracking**
* Introduced a new `Actual` model for tracking actual hours worked
by team members.
* Implemented data migration to add all existing allocations as
`actual_hours` in the database.
* Added methods for updating and deleting actual records.
**Open Issues**
1. **Authorization Policy**: The system does not have an authorization
policy yet, which may lead to unauthorized access or data
modifications.
2. **Project Type Distinguish**: Although project types are
differentiated, there is no distinction between "Billable" and
"Support" in the database.
3. **Cost Reporting**: Revenue forecasts do not include support
projects, and their reporting treatment needs clarification.
**Implementation Roadmap**
1. **Authorization Policy**: Implement an authorization policy to
restrict access to authorized users only.
2. **Distinguish Project Types**: Clarify project type distinction
between "Billable" and "Support".
3. **Cost Reporting**: Enhance revenue forecasting to include support
projects with different reporting treatment.
**Task Assignments**
1. **Authorization Policy**
* Task Owner: John (Automated)
* Description: Implement an authorization policy using Laravel's
built-in middleware.
* Deadline: 2026-03-25
2. **Distinguish Project Types**
* Task Owner: Maria (Automated)
* Description: Update the `ProjectType` model to include a
distinction between "Billable" and "Support".
* Deadline: 2026-04-01
3. **Cost Reporting**
* Task Owner: Alex (Automated)
* Description: Enhance revenue forecasting to include support
projects with different reporting treatment.
* Deadline: 2026-04-15
This commit is contained in:
121
openspec/specs/actuals-grid/spec.md
Normal file
121
openspec/specs/actuals-grid/spec.md
Normal file
@@ -0,0 +1,121 @@
|
||||
# Purpose
|
||||
|
||||
Provide a Cartesian grid view for managers to compare allocated hours vs actual hours logged across projects and team members for a selected month.
|
||||
|
||||
# Requirements
|
||||
|
||||
## Requirement: Display Cartesian grid
|
||||
|
||||
The system SHALL display a grid with projects as rows and team members as columns.
|
||||
|
||||
### Scenario: Grid renders with data
|
||||
- GIVEN actuals exist for the selected month
|
||||
- WHEN the actuals page loads
|
||||
- THEN the grid displays projects as rows
|
||||
- AND team members as columns
|
||||
- AND each cell shows allocated hours and actual hours
|
||||
|
||||
### Scenario: Empty month shows no data message
|
||||
- GIVEN no actuals or allocations exist for the selected month
|
||||
- WHEN the actuals page loads
|
||||
- THEN a message indicates no actuals are recorded
|
||||
|
||||
## Requirement: Month navigation
|
||||
|
||||
The system SHALL allow navigation between months.
|
||||
|
||||
### Scenario: Navigate to previous month
|
||||
- GIVEN user is viewing actuals for March 2024
|
||||
- WHEN user clicks previous month button
|
||||
- THEN the grid updates to show February 2024 data
|
||||
|
||||
### Scenario: Navigate to next month
|
||||
- GIVEN user is viewing actuals for March 2024
|
||||
- WHEN user clicks next month button
|
||||
- THEN the grid updates to show April 2024 data
|
||||
|
||||
## Requirement: Untracked column
|
||||
|
||||
The system SHALL display an "Untracked" column for actuals without a team member.
|
||||
|
||||
### Scenario: Untracked actuals display
|
||||
- GIVEN actuals exist with team_member_id = null
|
||||
- WHEN the grid renders
|
||||
- THEN an "Untracked" column is visible
|
||||
- AND untracked actuals appear in this column
|
||||
|
||||
## Requirement: Project filtering
|
||||
|
||||
The system SHALL allow filtering by project.
|
||||
|
||||
### Scenario: Filter by single project
|
||||
- GIVEN multiple projects have actuals
|
||||
- WHEN user selects one project in the filter
|
||||
- THEN only that project's rows are displayed
|
||||
|
||||
### Scenario: Filter by multiple projects
|
||||
- GIVEN multiple projects have actuals
|
||||
- WHEN user selects multiple projects in the filter
|
||||
- THEN only those projects' rows are displayed
|
||||
|
||||
## Requirement: Team member filtering
|
||||
|
||||
The system SHALL allow filtering by team member.
|
||||
|
||||
### Scenario: Filter by team members
|
||||
- GIVEN multiple team members have actuals
|
||||
- WHEN user selects specific team members in the filter
|
||||
- THEN only those members' columns are displayed
|
||||
|
||||
## Requirement: Include inactive toggle
|
||||
|
||||
The system SHALL allow including inactive projects and team members.
|
||||
|
||||
### Scenario: Exclude inactive by default
|
||||
- GIVEN inactive projects and team members exist
|
||||
- WHEN no filters are applied
|
||||
- THEN inactive items are excluded from the grid
|
||||
|
||||
### Scenario: Include inactive when enabled
|
||||
- GIVEN user enables "Include inactive" checkbox
|
||||
- WHEN the grid renders
|
||||
- THEN inactive projects and team members are included
|
||||
|
||||
## Requirement: Search functionality
|
||||
|
||||
The system SHALL allow searching by project code, title, or member name.
|
||||
|
||||
### Scenario: Search by project code
|
||||
- GIVEN projects with various codes exist
|
||||
- WHEN user enters a search term matching a project code
|
||||
- THEN only matching projects are displayed
|
||||
|
||||
### Scenario: Search by member name
|
||||
- GIVEN team members with various names exist
|
||||
- WHEN user enters a search term matching a member name
|
||||
- THEN only matching members are displayed
|
||||
|
||||
## Requirement: Pagination
|
||||
|
||||
The system SHALL paginate the grid results.
|
||||
|
||||
### Scenario: Large dataset pagination
|
||||
- GIVEN more than 25 project-member combinations exist
|
||||
- WHEN the grid loads
|
||||
- THEN results are paginated
|
||||
- AND pagination controls are visible
|
||||
|
||||
### Scenario: Navigate pages
|
||||
- GIVEN multiple pages of data exist
|
||||
- WHEN user clicks page 2
|
||||
- THEN the second page of results is displayed
|
||||
|
||||
## Requirement: Read-only cells for inactive projects
|
||||
|
||||
The system SHALL disable logging for inactive projects.
|
||||
|
||||
### Scenario: Completed project cells are read-only
|
||||
- GIVEN a project has status Done, Cancelled, or Closed
|
||||
- WHEN the grid renders
|
||||
- THEN cells for that project are visually dimmed
|
||||
- AND clicking the cell does not open the logging modal
|
||||
100
openspec/specs/actuals-logging/spec.md
Normal file
100
openspec/specs/actuals-logging/spec.md
Normal file
@@ -0,0 +1,100 @@
|
||||
# Purpose
|
||||
|
||||
Enable users to log, update, and delete actual hours worked for project-member-month combinations.
|
||||
|
||||
# Requirements
|
||||
|
||||
## Requirement: Log hours via modal
|
||||
|
||||
The system SHALL provide a modal for logging hours.
|
||||
|
||||
### Scenario: Open logging modal
|
||||
- GIVEN user clicks an editable cell in the grid
|
||||
- WHEN the cell is clicked
|
||||
- THEN a modal opens with project, member, and month context
|
||||
- AND an input field for hours to add is displayed
|
||||
|
||||
### Scenario: Log new hours
|
||||
- GIVEN the modal is open for a cell with 0 actual hours
|
||||
- WHEN user enters 8 hours and submits
|
||||
- THEN the actual record is created with 8 hours
|
||||
- AND the grid refreshes to show the updated value
|
||||
|
||||
### Scenario: Add hours to existing
|
||||
- GIVEN a cell already has 40 hours logged
|
||||
- WHEN user enters 8 hours and submits
|
||||
- THEN the actual record is updated to 48 hours
|
||||
- AND the grid refreshes to show the updated value
|
||||
|
||||
## Requirement: Hours are additive
|
||||
|
||||
The system SHALL accumulate hours when logging to an existing actual.
|
||||
|
||||
### Scenario: Multiple logging entries accumulate
|
||||
- GIVEN user logs 8 hours on Monday
|
||||
- AND user logs 4 hours on Tuesday
|
||||
- WHEN both entries are saved
|
||||
- THEN the total actual hours is 12
|
||||
|
||||
## Requirement: Notes support
|
||||
|
||||
The system SHALL allow optional notes with hour entries.
|
||||
|
||||
### Scenario: Add notes with hours
|
||||
- GIVEN user is logging hours
|
||||
- WHEN user enters notes text
|
||||
- THEN the notes are stored with the actual record
|
||||
|
||||
### Scenario: Notes are appended
|
||||
- GIVEN an actual record exists with notes
|
||||
- WHEN user logs additional hours with new notes
|
||||
- THEN the new notes are appended with timestamp
|
||||
|
||||
## Requirement: Validation - future months
|
||||
|
||||
The system SHALL prevent logging to future months.
|
||||
|
||||
### Scenario: Reject future month
|
||||
- GIVEN current month is March 2024
|
||||
- WHEN user attempts to log hours for April 2024
|
||||
- THEN validation error is returned
|
||||
- AND the actual is not created
|
||||
|
||||
## Requirement: Validation - completed projects
|
||||
|
||||
The system SHALL prevent logging to completed projects.
|
||||
|
||||
### Scenario: Reject completed project
|
||||
- GIVEN a project has status Done or Cancelled
|
||||
- WHEN user attempts to log hours
|
||||
- THEN validation error is returned
|
||||
- AND the actual is not created
|
||||
|
||||
### Scenario: Config override
|
||||
- GIVEN ALLOW_ACTUALS_ON_INACTIVE_PROJECTS is true
|
||||
- WHEN user attempts to log hours to a completed project
|
||||
- THEN the actual is created successfully
|
||||
|
||||
## Requirement: Delete actual
|
||||
|
||||
The system SHALL allow deletion of actual records.
|
||||
|
||||
### Scenario: Delete existing actual
|
||||
- GIVEN an actual record exists
|
||||
- WHEN user clicks Delete in the modal
|
||||
- THEN the actual record is removed
|
||||
- AND the grid refreshes to show 0 hours
|
||||
|
||||
## Requirement: Request validation
|
||||
|
||||
The system SHALL validate request inputs.
|
||||
|
||||
### Scenario: Invalid hours rejected
|
||||
- GIVEN user enters negative hours
|
||||
- WHEN form is submitted
|
||||
- THEN validation error is returned
|
||||
|
||||
### Scenario: Missing required fields
|
||||
- GIVEN user submits without hours
|
||||
- WHEN form is submitted
|
||||
- THEN validation error is returned
|
||||
85
openspec/specs/actuals-tracking/spec.md
Normal file
85
openspec/specs/actuals-tracking/spec.md
Normal file
@@ -0,0 +1,85 @@
|
||||
# actuals-tracking Specification
|
||||
|
||||
## Purpose
|
||||
Enable team members to track actual hours worked per project per month for comparison against allocations.
|
||||
## 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 (incremental)
|
||||
The system SHALL allow team members to update previously logged hours using incremental updates.
|
||||
|
||||
#### 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
|
||||
- **AND** the system preserves all notes from each update
|
||||
|
||||
### Requirement: View actuals summary with variance
|
||||
The system SHALL display actual hours worked in a matrix view showing allocated, actual, and variance data.
|
||||
|
||||
#### 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:
|
||||
- **Allocated hours** (from allocation records)
|
||||
- **Actual hours** (from actuals records)
|
||||
- **Variance %** = ((Actual - Allocated) / Allocated) × 100
|
||||
- **Variance indicator**: GREEN (≤5%), YELLOW (5-20%), RED (>20%)
|
||||
|
||||
#### Scenario: Show variance indicators
|
||||
- **WHEN** viewing the actuals matrix
|
||||
- **THEN** cells are color-coded based on variance:
|
||||
- GREEN: Within ±5% of allocation (on track)
|
||||
- YELLOW: 5-20% variance (attention needed)
|
||||
- RED: >20% variance (significant deviation)
|
||||
|
||||
### Requirement: Cannot log hours to inactive projects
|
||||
The system SHALL prevent logging hours to projects in "Done" or "Cancelled" status (configurable via global setting).
|
||||
|
||||
#### Scenario: Attempt to log hours to done project
|
||||
- **WHEN** attempting to log hours for a project with status "Done"
|
||||
- **AND** the global system configuration `allow_actuals_on_inactive_projects` is false
|
||||
- **THEN** the system rejects the request with error "Cannot log hours to completed projects"
|
||||
|
||||
#### Scenario: Allow logging to done project if configured
|
||||
- **WHEN** the global configuration `allow_actuals_on_inactive_projects` is true
|
||||
- **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: View notes in matrix
|
||||
- **WHEN** viewing the actuals matrix
|
||||
- **THEN** clicking on a cell shows the history of logged hours with timestamps and notes
|
||||
|
||||
97
openspec/specs/actuals-variance/spec.md
Normal file
97
openspec/specs/actuals-variance/spec.md
Normal file
@@ -0,0 +1,97 @@
|
||||
# Purpose
|
||||
|
||||
Calculate and display variance between allocated hours and actual hours logged, with color-coded indicators for quick assessment.
|
||||
|
||||
# Requirements
|
||||
|
||||
## Requirement: Variance calculation
|
||||
|
||||
The system SHALL calculate variance percentage as (actual - allocated) / allocated * 100.
|
||||
|
||||
### Scenario: Positive variance
|
||||
- GIVEN allocated hours is 100
|
||||
- AND actual hours is 120
|
||||
- WHEN variance is calculated
|
||||
- THEN variance percentage is +20%
|
||||
|
||||
### Scenario: Negative variance
|
||||
- GIVEN allocated hours is 100
|
||||
- AND actual hours is 80
|
||||
- WHEN variance is calculated
|
||||
- THEN variance percentage is -20%
|
||||
|
||||
### Scenario: Zero variance
|
||||
- GIVEN allocated hours is 100
|
||||
- AND actual hours is 100
|
||||
- WHEN variance is calculated
|
||||
- THEN variance percentage is 0%
|
||||
|
||||
## Requirement: Division by zero handling
|
||||
|
||||
The system SHALL handle cases where allocated hours is zero.
|
||||
|
||||
### Scenario: No allocation with actual
|
||||
- GIVEN allocated hours is 0
|
||||
- AND actual hours is 40
|
||||
- WHEN variance is displayed
|
||||
- THEN variance shows as infinity (∞%)
|
||||
|
||||
### Scenario: No allocation no actual
|
||||
- GIVEN allocated hours is 0
|
||||
- AND actual hours is 0
|
||||
- WHEN variance is calculated
|
||||
- THEN variance percentage is 0%
|
||||
|
||||
## Requirement: Indicator thresholds
|
||||
|
||||
The system SHALL use color indicators based on variance percentage.
|
||||
|
||||
### Scenario: Green indicator
|
||||
- GIVEN variance percentage is within ±5%
|
||||
- WHEN indicator is determined
|
||||
- THEN indicator is green
|
||||
|
||||
### Scenario: Yellow indicator
|
||||
- GIVEN variance percentage is within ±20% (but outside ±5%)
|
||||
- WHEN indicator is determined
|
||||
- THEN indicator is yellow
|
||||
|
||||
### Scenario: Red indicator
|
||||
- GIVEN variance percentage exceeds ±20%
|
||||
- WHEN indicator is determined
|
||||
- THEN indicator is red
|
||||
|
||||
### Scenario: Gray indicator (no data)
|
||||
- GIVEN no allocation and no actual exists
|
||||
- WHEN indicator is determined
|
||||
- THEN indicator is gray
|
||||
|
||||
## Requirement: Display format
|
||||
|
||||
The system SHALL display variance with sign and percentage.
|
||||
|
||||
### Scenario: Positive display
|
||||
- GIVEN variance percentage is 15.5%
|
||||
- WHEN displayed
|
||||
- THEN shows "+15.5%"
|
||||
|
||||
### Scenario: Negative display
|
||||
- GIVEN variance percentage is -8.2%
|
||||
- WHEN displayed
|
||||
- THEN shows "-8.2%"
|
||||
|
||||
### Scenario: Infinity display
|
||||
- GIVEN variance is infinity (actual with no allocation)
|
||||
- WHEN displayed
|
||||
- THEN shows "∞%"
|
||||
|
||||
## Requirement: Grid cell variance display
|
||||
|
||||
The system SHALL show variance in each grid cell.
|
||||
|
||||
### Scenario: Cell shows all metrics
|
||||
- GIVEN a cell has allocation and actual data
|
||||
- WHEN the grid renders
|
||||
- THEN the cell shows allocated hours
|
||||
- AND the cell shows actual hours
|
||||
- AND the cell shows variance badge with color
|
||||
78
openspec/specs/allocation-reporting/spec.md
Normal file
78
openspec/specs/allocation-reporting/spec.md
Normal file
@@ -0,0 +1,78 @@
|
||||
# allocation-reporting Specification
|
||||
|
||||
## Purpose
|
||||
TBD - created by archiving change headroom-foundation. Update Purpose after archive.
|
||||
## 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
|
||||
|
||||
91
openspec/specs/allocation-validation/spec.md
Normal file
91
openspec/specs/allocation-validation/spec.md
Normal file
@@ -0,0 +1,91 @@
|
||||
# allocation-validation Specification
|
||||
|
||||
## Purpose
|
||||
TBD - created by archiving change headroom-foundation. Update Purpose after archive.
|
||||
## 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
|
||||
|
||||
132
openspec/specs/authentication/spec.md
Normal file
132
openspec/specs/authentication/spec.md
Normal file
@@ -0,0 +1,132 @@
|
||||
# authentication Specification
|
||||
|
||||
## Purpose
|
||||
TBD - created by archiving change headroom-foundation. Update Purpose after archive.
|
||||
## 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: Authenticated user redirect
|
||||
The system SHALL redirect authenticated users away from login page to dashboard.
|
||||
|
||||
#### Scenario: Authenticated user accesses login page
|
||||
- **GIVEN** a user has valid access token in localStorage
|
||||
- **WHEN** the user navigates to /login
|
||||
- **THEN** the system detects the valid token
|
||||
- **AND** redirects the user to /dashboard
|
||||
- **AND** does not display the login form
|
||||
|
||||
#### Scenario: Auth state persists after page refresh
|
||||
- **GIVEN** a user is logged in with valid tokens
|
||||
- **WHEN** the user refreshes the page
|
||||
- **THEN** the system reads tokens from localStorage
|
||||
- **AND** restores authentication state
|
||||
- **AND** displays the authenticated content (not blank page)
|
||||
|
||||
### 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
|
||||
|
||||
113
openspec/specs/capacity-planning/spec.md
Normal file
113
openspec/specs/capacity-planning/spec.md
Normal file
@@ -0,0 +1,113 @@
|
||||
# capacity-planning Specification
|
||||
|
||||
## Purpose
|
||||
TBD - created by archiving change headroom-foundation. Update Purpose after archive.
|
||||
## 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 "approved"
|
||||
|
||||
#### 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: Delete PTO request
|
||||
- **WHEN** a manager deletes an existing PTO request
|
||||
- **THEN** the PTO record is removed
|
||||
- **AND** individual, team, and revenue capacity caches for affected months are refreshed
|
||||
|
||||
#### 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
|
||||
|
||||
#### Scenario: Override PTO day availability
|
||||
- **WHEN** a PTO day is manually set to half day availability (0.5)
|
||||
- **THEN** the system keeps the PTO marker for that date
|
||||
- **AND** the capacity calculation uses the explicit availability override instead of forcing 0
|
||||
|
||||
89
openspec/specs/cost-reporting/spec.md
Normal file
89
openspec/specs/cost-reporting/spec.md
Normal file
@@ -0,0 +1,89 @@
|
||||
# cost-reporting Specification
|
||||
|
||||
## Purpose
|
||||
TBD - created by archiving change headroom-foundation. Update Purpose after archive.
|
||||
## 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)
|
||||
|
||||
74
openspec/specs/forecast-reporting/spec.md
Normal file
74
openspec/specs/forecast-reporting/spec.md
Normal file
@@ -0,0 +1,74 @@
|
||||
# forecast-reporting Specification
|
||||
|
||||
## Purpose
|
||||
TBD - created by archiving change headroom-foundation. Update Purpose after archive.
|
||||
## 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
|
||||
|
||||
123
openspec/specs/master-data-management/spec.md
Normal file
123
openspec/specs/master-data-management/spec.md
Normal file
@@ -0,0 +1,123 @@
|
||||
# master-data-management Specification
|
||||
|
||||
## Purpose
|
||||
TBD - created by archiving change headroom-foundation. Update Purpose after archive.
|
||||
## 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
|
||||
|
||||
104
openspec/specs/project-lifecycle/spec.md
Normal file
104
openspec/specs/project-lifecycle/spec.md
Normal file
@@ -0,0 +1,104 @@
|
||||
# project-lifecycle Specification
|
||||
|
||||
## Purpose
|
||||
TBD - created by archiving change headroom-foundation. Update Purpose after archive.
|
||||
## 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"
|
||||
|
||||
Reference in New Issue
Block a user