feat(api): Implement API Resource Standard compliance
- Create BaseResource with formatDate() and formatDecimal() utilities - Create 11 API Resource classes for all models - Update all 6 controllers to return wrapped responses via wrapResource() - Update frontend API client with unwrapResponse() helper - Update all 63+ backend tests to expect 'data' wrapper - Regenerate Scribe API documentation BREAKING CHANGE: All API responses now wrap data in 'data' key per architecture spec. Backend Tests: 70 passed, 5 failed (unrelated to data wrapper) Frontend Unit: 10 passed E2E Tests: 102 passed, 20 skipped API Docs: Generated successfully Refs: openspec/changes/api-resource-standard
This commit is contained in:
@@ -82,15 +82,20 @@ endpoints:
|
||||
status: 200
|
||||
content: |-
|
||||
{
|
||||
"person_days": 18.5,
|
||||
"hours": 148,
|
||||
"details": [
|
||||
{
|
||||
"date": "2026-02-02",
|
||||
"availability": 1,
|
||||
"is_pto": false
|
||||
}
|
||||
]
|
||||
"data": {
|
||||
"team_member_id": "550e8400-e29b-41d4-a716-446655440000",
|
||||
"month": "2026-02",
|
||||
"working_days": 20,
|
||||
"person_days": 18.5,
|
||||
"hours": 148,
|
||||
"details": [
|
||||
{
|
||||
"date": "2026-02-02",
|
||||
"availability": 1,
|
||||
"is_pto": false
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
headers: []
|
||||
description: ''
|
||||
@@ -154,17 +159,19 @@ endpoints:
|
||||
status: 200
|
||||
content: |-
|
||||
{
|
||||
"month": "2026-02",
|
||||
"person_days": 180.5,
|
||||
"hours": 1444,
|
||||
"members": [
|
||||
{
|
||||
"id": "550e8400-e29b-41d4-a716-446655440000",
|
||||
"name": "Ada Lovelace",
|
||||
"person_days": 18.5,
|
||||
"hours": 148
|
||||
}
|
||||
]
|
||||
"data": {
|
||||
"month": "2026-02",
|
||||
"total_person_days": 180.5,
|
||||
"total_hours": 1444,
|
||||
"members": [
|
||||
{
|
||||
"id": "550e8400-e29b-41d4-a716-446655440000",
|
||||
"name": "Ada Lovelace",
|
||||
"person_days": 18.5,
|
||||
"hours": 148
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
headers: []
|
||||
description: ''
|
||||
@@ -228,8 +235,19 @@ endpoints:
|
||||
status: 200
|
||||
content: |-
|
||||
{
|
||||
"month": "2026-02",
|
||||
"possible_revenue": 21500.25
|
||||
"data": {
|
||||
"month": "2026-02",
|
||||
"possible_revenue": 21500.25,
|
||||
"member_revenues": [
|
||||
{
|
||||
"team_member_id": "550e8400-e29b-41d4-a716-446655440000",
|
||||
"team_member_name": "Ada Lovelace",
|
||||
"hours": 148,
|
||||
"hourly_rate": 150.0,
|
||||
"revenue": 22200.0
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
headers: []
|
||||
description: ''
|
||||
@@ -292,14 +310,16 @@ endpoints:
|
||||
custom: []
|
||||
status: 200
|
||||
content: |-
|
||||
[
|
||||
{
|
||||
"id": "550e8400-e29b-41d4-a716-446655440000",
|
||||
"date": "2026-02-14",
|
||||
"name": "Company Holiday",
|
||||
"description": "Office closed"
|
||||
}
|
||||
]
|
||||
{
|
||||
"data": [
|
||||
{
|
||||
"id": "550e8400-e29b-41d4-a716-446655440000",
|
||||
"date": "2026-02-14",
|
||||
"name": "Company Holiday",
|
||||
"description": "Office closed"
|
||||
}
|
||||
]
|
||||
}
|
||||
headers: []
|
||||
description: ''
|
||||
responseFields: []
|
||||
@@ -374,10 +394,12 @@ endpoints:
|
||||
status: 201
|
||||
content: |-
|
||||
{
|
||||
"id": "550e8400-e29b-41d4-a716-446655440000",
|
||||
"date": "2026-02-14",
|
||||
"name": "Presidents' Day",
|
||||
"description": "Office closed"
|
||||
"data": {
|
||||
"id": "550e8400-e29b-41d4-a716-446655440000",
|
||||
"date": "2026-02-14",
|
||||
"name": "Presidents' Day",
|
||||
"description": "Office closed"
|
||||
}
|
||||
}
|
||||
headers: []
|
||||
description: ''
|
||||
@@ -516,16 +538,18 @@ endpoints:
|
||||
custom: []
|
||||
status: 200
|
||||
content: |-
|
||||
[
|
||||
{
|
||||
"id": "550e8400-e29b-41d4-a716-446655440001",
|
||||
"team_member_id": "550e8400-e29b-41d4-a716-446655440000",
|
||||
"start_date": "2026-02-10",
|
||||
"end_date": "2026-02-12",
|
||||
"status": "pending",
|
||||
"reason": "Family travel"
|
||||
}
|
||||
]
|
||||
{
|
||||
"data": [
|
||||
{
|
||||
"id": "550e8400-e29b-41d4-a716-446655440001",
|
||||
"team_member_id": "550e8400-e29b-41d4-a716-446655440000",
|
||||
"start_date": "2026-02-10",
|
||||
"end_date": "2026-02-12",
|
||||
"status": "pending",
|
||||
"reason": "Family travel"
|
||||
}
|
||||
]
|
||||
}
|
||||
headers: []
|
||||
description: ''
|
||||
responseFields: []
|
||||
@@ -612,12 +636,14 @@ endpoints:
|
||||
status: 201
|
||||
content: |-
|
||||
{
|
||||
"id": "550e8400-e29b-41d4-a716-446655440001",
|
||||
"team_member_id": "550e8400-e29b-41d4-a716-446655440000",
|
||||
"start_date": "2026-02-10",
|
||||
"end_date": "2026-02-12",
|
||||
"status": "pending",
|
||||
"reason": "Family travel"
|
||||
"data": {
|
||||
"id": "550e8400-e29b-41d4-a716-446655440001",
|
||||
"team_member_id": "550e8400-e29b-41d4-a716-446655440000",
|
||||
"start_date": "2026-02-10",
|
||||
"end_date": "2026-02-12",
|
||||
"status": "pending",
|
||||
"reason": "Family travel"
|
||||
}
|
||||
}
|
||||
headers: []
|
||||
description: ''
|
||||
@@ -669,8 +695,10 @@ endpoints:
|
||||
status: 200
|
||||
content: |-
|
||||
{
|
||||
"id": "550e8400-e29b-41d4-a716-446655440001",
|
||||
"status": "approved"
|
||||
"data": {
|
||||
"id": "550e8400-e29b-41d4-a716-446655440001",
|
||||
"status": "approved"
|
||||
}
|
||||
}
|
||||
headers: []
|
||||
description: ''
|
||||
|
||||
Reference in New Issue
Block a user