Phase 05: Visibility and Client Portal - 5 plans in 3 waves - 2 parallel (wave 1), 1 sequential (wave 2), 2 parallel (wave 3) - Ready for execution Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
142 lines
5.4 KiB
Markdown
142 lines
5.4 KiB
Markdown
---
|
|
phase: 05-visibility-and-client-portal
|
|
plan: 04
|
|
type: execute
|
|
wave: 3
|
|
depends_on: ["05-01", "05-02", "05-03"]
|
|
files_modified:
|
|
- src/lib/__tests__/integration/api-rbac.test.ts
|
|
autonomous: true
|
|
|
|
must_haves:
|
|
truths:
|
|
- "All API endpoints return 401 for unauthenticated requests"
|
|
- "Role-restricted endpoints return 403 for unauthorized roles"
|
|
- "Tenant A data is never returned to Tenant B users"
|
|
- "COLLECTOR cannot access billing or subscriber management write endpoints"
|
|
- "TECHNICIAN cannot access payment or invoice endpoints"
|
|
- "CLIENT role can only read their own data"
|
|
artifacts:
|
|
- path: "src/lib/__tests__/integration/api-rbac.test.ts"
|
|
provides: "Comprehensive API RBAC integration tests"
|
|
min_lines: 200
|
|
key_links:
|
|
- from: "src/lib/__tests__/integration/api-rbac.test.ts"
|
|
to: "src/lib/middleware/authorize.ts"
|
|
via: "tests verify withPermission enforcement"
|
|
pattern: "withPermission|401|403"
|
|
---
|
|
|
|
<objective>
|
|
Create integration tests that verify API-layer RBAC enforcement across all endpoints, including unauthorized access assertions and two-tenant cross-contamination tests.
|
|
|
|
Purpose: INFRA-03 — prove that the authorization layer cannot be bypassed at the API level.
|
|
Output: Comprehensive integration test suite covering all roles and endpoints.
|
|
</objective>
|
|
|
|
<execution_context>
|
|
@C:\Users\KevinAsprec\.claude/get-shit-done/workflows/execute-plan.md
|
|
@C:\Users\KevinAsprec\.claude/get-shit-done/templates/summary.md
|
|
</execution_context>
|
|
|
|
<context>
|
|
@.planning/PROJECT.md
|
|
@.planning/ROADMAP.md
|
|
@.planning/STATE.md
|
|
|
|
@src/lib/middleware/authorize.ts
|
|
@src/lib/casl/permissions.ts
|
|
@src/lib/casl/types.ts
|
|
@src/middleware.ts
|
|
</context>
|
|
|
|
<tasks>
|
|
|
|
<task type="auto">
|
|
<name>Task 1: API RBAC integration test suite</name>
|
|
<files>src/lib/__tests__/integration/api-rbac.test.ts</files>
|
|
<action>
|
|
Create a comprehensive integration test file that tests API-layer authorization. Since Next.js API routes cannot be easily called via HTTP in test mode without starting the server, test at the SERVICE + MIDDLEWARE layer instead — test the withPermission HOF behavior and service-level tenant isolation.
|
|
|
|
**Approach:** Test the authorization logic directly by:
|
|
1. Creating users with different roles in the test database
|
|
2. Calling service methods with different tenant contexts
|
|
3. Verifying CASL ability checks for each role against each subject
|
|
|
|
**Test structure:**
|
|
|
|
```
|
|
describe("API RBAC Integration Tests")
|
|
describe("Authentication (401)")
|
|
- Verify getCurrentUser returns null for no session -> would produce 401
|
|
- Verify withPermission returns 401 when no user (mock getCurrentUser to return null)
|
|
|
|
describe("Authorization by Role (403)")
|
|
For each role, test what they CAN and CANNOT access:
|
|
|
|
describe("ADMIN")
|
|
- Can access all subjects (manage all)
|
|
|
|
describe("OFFICE_STAFF")
|
|
- Can manage Subscriber, Invoice, Payment, Ticket, JobOrder, Inventory, Expense, Vendor
|
|
- Can read Report, Account
|
|
- CANNOT create/update/delete Account
|
|
|
|
describe("COLLECTOR")
|
|
- Can read Subscriber, Zone
|
|
- Can create Payment, read Payment
|
|
- CANNOT read Report, manage Invoice, manage Subscriber, manage Ticket
|
|
|
|
describe("TECHNICIAN")
|
|
- Can read/update JobOrder (own only)
|
|
- Can read Subscriber, read Inventory (own only)
|
|
- CANNOT manage Payment, Invoice, Report, Ticket
|
|
|
|
describe("CLIENT")
|
|
- Can read Invoice (own), Payment (own), Subscriber (own)
|
|
- Can create Ticket, read Ticket (own)
|
|
- CANNOT manage User, read Report, manage Subscriber
|
|
|
|
describe("Tenant Isolation")
|
|
- Create Tenant A and Tenant B with subscribers, invoices, payments
|
|
- Using Tenant A's context, query subscribers -> returns ONLY Tenant A data
|
|
- Using Tenant B's context, query subscribers -> returns ONLY Tenant B data
|
|
- Cross-query: Tenant A's subscriber ID passed to Tenant B context -> returns null or throws
|
|
- Verify: invoice created in Tenant A is invisible to Tenant B
|
|
- Verify: payment recorded in Tenant A is invisible to Tenant B
|
|
```
|
|
|
|
**Implementation details:**
|
|
- Use `defineAbilityFor` and `definePermissionsFor` directly to test CASL rules
|
|
- Use `withTenantContext` to create tenant-scoped Prisma clients for isolation tests
|
|
- Use real database with actual tenant/user/subscriber records
|
|
- Test at least 5 role combinations with at least 3 subjects each = 15+ assertions
|
|
- Test at least 3 cross-tenant scenarios
|
|
|
|
**Cleanup order:** Follow the most comprehensive pattern (expense report cleanup from 04-04) since we create data across multiple subsystems.
|
|
|
|
Minimum test count: 15+ tests across all describe blocks.
|
|
</action>
|
|
<verify>`npx vitest run src/lib/__tests__/integration/api-rbac.test.ts` — all tests pass</verify>
|
|
<done>All 5 roles tested against all relevant subjects; cross-tenant isolation verified with real data; 15+ tests pass; INFRA-03 satisfied</done>
|
|
</task>
|
|
|
|
</tasks>
|
|
|
|
<verification>
|
|
- `npx vitest run src/lib/__tests__/integration/api-rbac.test.ts` — all tests pass
|
|
- Every role's can/cannot boundaries are explicitly tested
|
|
- Two-tenant cross-contamination test proves data isolation
|
|
</verification>
|
|
|
|
<success_criteria>
|
|
- 15+ integration tests covering all 5 roles
|
|
- Unauthorized access assertions prove RBAC enforcement
|
|
- Two-tenant isolation tests prove no cross-contamination
|
|
- INFRA-03 requirement satisfied
|
|
</success_criteria>
|
|
|
|
<output>
|
|
After completion, create `.planning/phases/05-visibility-and-client-portal/05-04-SUMMARY.md`
|
|
</output>
|