docs(ui): Add UI layout refactor plan and OpenSpec changes

- Update decision-log with UI layout decisions (Feb 18, 2026)
- Update architecture with frontend layout patterns
- Update config.yaml with TDD, documentation, UI standards rules
- Create p00-api-documentation change (Scribe annotations)
- Create p01-ui-foundation change (types, stores, Lucide)
- Create p02-app-layout change (AppLayout, Sidebar, TopBar)
- Create p03-dashboard-enhancement change (PageHeader, StatCard)
- Create p04-content-patterns change (DataTable, FilterBar)
- Create p05-page-migrations change (page migrations)
- Fix E2E auth tests (11/11 passing)
- Add JWT expiry validation to dashboard guard
This commit is contained in:
2026-02-18 13:03:08 -05:00
parent f935754df4
commit 3e36ea8888
29 changed files with 3341 additions and 59 deletions

View File

@@ -0,0 +1,144 @@
# Design: API Documentation with Scribe
## Technical Approach
### Scribe Configuration
File: `config/scribe.php`
```php
return [
'title' => 'Headroom API',
'description' => 'Resource planning and capacity management API',
'base_url' => env('APP_URL') . '/api',
'auth' => [
'enabled' => true,
'default' => true,
'in' => 'bearer',
'use_value' => 'Bearer {token}',
],
'routes' => [
[
'match' => ['api/*'],
'include' => [],
'exclude' => [],
],
],
];
```
### Annotation Patterns
#### Authentication Endpoint Example
```php
/**
* @group Authentication
*
* Authenticate user and issue JWT tokens.
*
* @bodyParam email string required User's email address. Example: user@example.com
* @bodyParam password string required User's password. Example: secret123
*
* @response 200 {
* "data": {
* "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
* "refresh_token": "abc123def456...",
* "token_type": "bearer",
* "expires_in": 3600
* }
* }
* @response 401 {
* "message": "Invalid credentials",
* "errors": {
* "email": ["These credentials do not match our records."]
* }
* }
* @response 422 {
* "message": "Validation failed",
* "errors": {
* "email": ["The email field is required."],
* "password": ["The password field is required."]
* }
* }
*/
public function login(LoginRequest $request): JsonResponse
```
#### CRUD Endpoint Example
```php
/**
* @group Team Members
* @authenticated
*
* List all team members with optional filters.
*
* @queryParam active boolean Filter by active status. Example: true
* @queryParam role_id int Filter by role ID. Example: 1
*
* @response 200 {
* "data": [
* {
* "id": "550e8400-e29b-41d4-a716-446655440000",
* "name": "Alice Johnson",
* "role": {"id": 1, "name": "Frontend Dev"},
* "hourly_rate": 75.00,
* "active": true
* }
* ],
* "meta": {"total": 10}
* }
*/
public function index(Request $request): JsonResponse
```
### Group Organization
| Group | Controller | Endpoints |
|----------------|-----------------------|-----------|
| Authentication | AuthController | 5 |
| Team Members | TeamMemberController | 5 |
| Projects | ProjectController | 8 |
| Allocations | AllocationController | 6 |
| Actuals | ActualController | 5 |
| Capacity | CapacityController | 6 |
| Reports | ReportController | 5 |
| Master Data | MasterDataController | 9 |
### Authentication Documentation
Include a dedicated section explaining:
1. How to obtain tokens (login endpoint)
2. How to use tokens (Authorization: Bearer {token})
3. Token refresh flow
4. Token expiration (60 min access, 7 day refresh)
## Implementation Order
1. Configure Scribe (`config/scribe.php`)
2. Annotate AuthController (most critical, used by all)
3. Annotate TeamMemberController
4. Annotate ProjectController
5. Annotate AllocationController
6. Annotate ActualController
7. Annotate CapacityController
8. Annotate ReportController
9. Annotate MasterDataController
10. Generate documentation (`php artisan scribe:generate`)
11. Verify SwaggerUI at `/api/documentation`
## File Changes
### New Files
- `config/scribe.php` - Scribe configuration
### Modified Files
- `backend/app/Http/Controllers/Api/AuthController.php`
- `backend/app/Http/Controllers/Api/TeamMemberController.php`
- `backend/app/Http/Controllers/Api/ProjectController.php`
- `backend/app/Http/Controllers/Api/AllocationController.php`
- `backend/app/Http/Controllers/Api/ActualController.php`
- `backend/app/Http/Controllers/Api/CapacityController.php`
- `backend/app/Http/Controllers/Api/ReportController.php`
- `backend/app/Http/Controllers/Api/MasterDataController.php`
## Testing
- Run `php artisan scribe:generate` - must complete without errors
- Verify generated docs at `/api/documentation`
- Test "Try it out" functionality for login endpoint

View File

@@ -0,0 +1,56 @@
# Proposal: API Documentation with Scribe
## Overview
Add comprehensive API documentation annotations to all Laravel controllers using Laravel Scribe. This enables auto-generated SwaggerUI documentation accessible at `/api/documentation`.
## Goals
- Annotate ALL existing API controllers with Scribe annotations
- Generate browsable API documentation
- Ensure documentation stays in sync with implementation
- Enable frontend developers to reference accurate API specs
## Non-Goals
- Creating new API endpoints
- Modifying existing API responses
- Setting up API versioning
## Priority
**HIGH** - This is a prerequisite for UI changes (p01-p05) to ensure API contracts are documented.
## Scope
### Controllers to Document
1. **AuthController** - Login, logout, token refresh endpoints
2. **TeamMemberController** - CRUD for team members
3. **ProjectController** - CRUD, status transitions, estimates
4. **AllocationController** - CRUD, bulk operations, matrix view
5. **ActualController** - CRUD, logging hours
6. **CapacityController** - Capacity calculations, holidays, PTO
7. **ReportController** - Forecast, utilization, costs, variance reports
8. **MasterDataController** - Roles, statuses, types management
### Annotations Required
Each endpoint must have:
- `@group` - Logical grouping (e.g., "Authentication", "Team Members")
- `@authenticated` - For protected endpoints
- `@bodyParam` - Request body parameters
- `@response` - Example success response
- `@response 401|403|422` - Error responses
## Success Criteria
- [ ] All controllers have Scribe annotations
- [ ] `php artisan scribe:generate` runs without errors
- [ ] SwaggerUI accessible at `/api/documentation`
- [ ] All endpoints documented with request/response examples
- [ ] Authentication section explains JWT flow
## Estimated Effort
2-3 hours
## Dependencies
- Existing Laravel backend with controllers
- tymon/jwt-auth for authentication examples
## References
- docs/headroom-decision-log.md → Architecture Decisions → API Documentation
- openspec/config.yaml → documentation rules

View File

@@ -0,0 +1,94 @@
# Tasks: API Documentation with Scribe
## Phase 1: Configure Scribe
- [ ] 0.1 Install Scribe (if not already installed): `composer require knuckleswtf/scribe`
- [ ] 0.2 Publish Scribe config: `php artisan vendor:publish --tag=scribe-config`
- [ ] 0.3 Configure `config/scribe.php` with Headroom settings
- [ ] 0.4 Add `/api/documentation` to CORS allowed paths
## Phase 2: Annotate Controllers
### AuthController
- [ ] 0.5 Add `@group Authentication` to class
- [ ] 0.6 Document `POST /api/auth/login` with @bodyParam, @response
- [ ] 0.7 Document `POST /api/auth/refresh` with @authenticated, @response
- [ ] 0.8 Document `POST /api/auth/logout` with @authenticated, @response
- [ ] 0.9 Add authentication section to Scribe config
### TeamMemberController
- [ ] 0.10 Add `@group Team Members` to class
- [ ] 0.11 Document `GET /api/team-members` with @queryParam filters
- [ ] 0.12 Document `POST /api/team-members` with @bodyParam
- [ ] 0.13 Document `GET /api/team-members/{id}`
- [ ] 0.14 Document `PUT /api/team-members/{id}`
- [ ] 0.15 Document `DELETE /api/team-members/{id}`
### ProjectController
- [ ] 0.16 Add `@group Projects` to class
- [ ] 0.17 Document `GET /api/projects` with @queryParam filters
- [ ] 0.18 Document `POST /api/projects` with @bodyParam
- [ ] 0.19 Document `GET /api/projects/{id}`
- [ ] 0.20 Document `PUT /api/projects/{id}`
- [ ] 0.21 Document `PUT /api/projects/{id}/status`
- [ ] 0.22 Document `PUT /api/projects/{id}/estimate`
- [ ] 0.23 Document `PUT /api/projects/{id}/forecast`
### AllocationController
- [ ] 0.24 Add `@group Allocations` to class
- [ ] 0.25 Document `GET /api/allocations` (matrix view)
- [ ] 0.26 Document `POST /api/allocations`
- [ ] 0.27 Document `PUT /api/allocations/{id}`
- [ ] 0.28 Document `DELETE /api/allocations/{id}`
- [ ] 0.29 Document `POST /api/allocations/bulk`
### ActualController
- [ ] 0.30 Add `@group Actuals` to class
- [ ] 0.31 Document `GET /api/actuals`
- [ ] 0.32 Document `POST /api/actuals`
- [ ] 0.33 Document `PUT /api/actuals/{id}`
- [ ] 0.34 Document validation rules (future month rejection)
### CapacityController
- [ ] 0.35 Add `@group Capacity` to class
- [ ] 0.36 Document `GET /api/capacity`
- [ ] 0.37 Document `GET /api/capacity/team`
- [ ] 0.38 Document `GET /api/capacity/revenue`
- [ ] 0.39 Document `POST /api/holidays`
- [ ] 0.40 Document `POST /api/ptos`
### ReportController
- [ ] 0.41 Add `@group Reports` to class
- [ ] 0.42 Document `GET /api/reports/forecast`
- [ ] 0.43 Document `GET /api/reports/utilization`
- [ ] 0.44 Document `GET /api/reports/costs`
- [ ] 0.45 Document `GET /api/reports/variance`
- [ ] 0.46 Document `GET /api/reports/allocation`
### MasterDataController
- [ ] 0.47 Add `@group Master Data` to class
- [ ] 0.48 Document `GET /api/roles`
- [ ] 0.49 Document `POST /api/roles`
- [ ] 0.50 Document `PUT /api/roles/{id}`
- [ ] 0.51 Document `DELETE /api/roles/{id}`
- [ ] 0.52 Document project-statuses endpoints
- [ ] 0.53 Document project-types endpoints
## Phase 3: Generate & Verify
- [ ] 0.54 Run `php artisan scribe:generate`
- [ ] 0.55 Verify no errors in generation
- [ ] 0.56 Access `/api/documentation` in browser
- [ ] 0.57 Verify all endpoints appear in documentation
- [ ] 0.58 Test "Try it out" for login endpoint
- [ ] 0.59 Verify authentication flow is documented
## Commits
1. `chore(docs): Configure Laravel Scribe for API documentation`
2. `docs(api): Add Scribe annotations to AuthController`
3. `docs(api): Add Scribe annotations to TeamMemberController`
4. `docs(api): Add Scribe annotations to ProjectController`
5. `docs(api): Add Scribe annotations to AllocationController`
6. `docs(api): Add Scribe annotations to remaining controllers`
7. `docs(api): Generate and verify SwaggerUI documentation`