docs(05-06): complete tenant isolation and CASL subjects gap closure plan
Tasks completed: 2/2 - Add 6 missing models to tenant scoping (28 total) - Add Collection and Remittance CASL subjects, update 8 routes SUMMARY: .planning/phases/05-visibility-and-client-portal/05-06-SUMMARY.md Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -5,14 +5,14 @@
|
|||||||
See: .planning/PROJECT.md (updated 2026-03-04)
|
See: .planning/PROJECT.md (updated 2026-03-04)
|
||||||
|
|
||||||
**Core value:** ISP owners can see exactly where their money is — who owes what, what's been collected, what's been spent, and what the business actually looks like financially — in real time.
|
**Core value:** ISP owners can see exactly where their money is — who owes what, what's been collected, what's been spent, and what the business actually looks like financially — in real time.
|
||||||
**Current focus:** All 5 phases complete. Gap closure plans (05-07) done. Milestone v1.0 audit-ready.
|
**Current focus:** All 5 phases complete. Gap closure plans (05-06, 05-07) done. Milestone v1.0 audit-ready.
|
||||||
|
|
||||||
## Current Position
|
## Current Position
|
||||||
|
|
||||||
Phase: 5 of 5 (Visibility and Client Portal)
|
Phase: 5 of 5 (Visibility and Client Portal)
|
||||||
Plan: 7 of 7 in phase 5 (30/30 total complete, including gap closure plans 05-06, 05-07)
|
Plan: 7 of 7 in phase 5 (30/30 total complete, including gap closure plans 05-06, 05-07)
|
||||||
Status: All phases complete. All plans done: 05-01 through 05-07.
|
Status: All phases complete. All plans done: 05-01 through 05-07.
|
||||||
Last activity: 2026-03-05 — Completed 05-07 gap closure (E2E inventory/expense/portal tests + Phase 2 VERIFICATION fix)
|
Last activity: 2026-03-05 — Completed 05-06 gap closure (tenant isolation for 6 models + Collection/Remittance CASL subjects)
|
||||||
|
|
||||||
Progress: [██████████████████████████████] 100% (30/30 plans across all phases)
|
Progress: [██████████████████████████████] 100% (30/30 plans across all phases)
|
||||||
|
|
||||||
@@ -62,6 +62,8 @@ Recent decisions affecting current work:
|
|||||||
- [05-04]: Two-tenant isolation verified with real DB records — cross-tenant queries return null/empty
|
- [05-04]: Two-tenant isolation verified with real DB records — cross-tenant queries return null/empty
|
||||||
- [05-05]: E2E tests exercise services directly (not HTTP) — 16 tests across 3 critical workflows
|
- [05-05]: E2E tests exercise services directly (not HTTP) — 16 tests across 3 critical workflows
|
||||||
- [05-05]: Trial balance verified balanced (debits === credits > 0) after each workflow
|
- [05-05]: Trial balance verified balanced (debits === credits > 0) after each workflow
|
||||||
|
- [05-06]: 6 missing models (expense, expenseCategory, inventoryItem, stockMovement, vendor, ticketComment) added to tenant scoping — TENANT_SCOPED_MODELS now 28 entries
|
||||||
|
- [05-06]: Collection and Remittance added as dedicated CASL subjects — routes no longer borrow Subscriber subject
|
||||||
- [05-07]: E2E coverage extended to 21 tests across 5 workflows (added inventory/expense + portal ticket)
|
- [05-07]: E2E coverage extended to 21 tests across 5 workflows (added inventory/expense + portal ticket)
|
||||||
- [05-07]: Phase 2 VERIFICATION.md corrected from gaps_found (4/5) to passed (5/5) — billing DRAFT-to-SENT fix validated
|
- [05-07]: Phase 2 VERIFICATION.md corrected from gaps_found (4/5) to passed (5/5) — billing DRAFT-to-SENT fix validated
|
||||||
|
|
||||||
@@ -76,6 +78,6 @@ None.
|
|||||||
|
|
||||||
## Session Continuity
|
## Session Continuity
|
||||||
|
|
||||||
Last session: 2026-03-05T10:27:00Z
|
Last session: 2026-03-05T10:29:00Z
|
||||||
Stopped at: Completed 05-07-PLAN.md (gap closure: E2E tests + Phase 2 VERIFICATION fix)
|
Stopped at: Completed 05-06-PLAN.md (gap closure: tenant isolation + CASL subjects)
|
||||||
Resume file: None
|
Resume file: None
|
||||||
|
|||||||
@@ -0,0 +1,112 @@
|
|||||||
|
---
|
||||||
|
phase: 05-visibility-and-client-portal
|
||||||
|
plan: 06
|
||||||
|
subsystem: api, auth, database
|
||||||
|
tags: [prisma, casl, tenant-isolation, rbac, multi-tenancy, security]
|
||||||
|
|
||||||
|
# Dependency graph
|
||||||
|
requires:
|
||||||
|
- phase: 01-foundation
|
||||||
|
provides: Prisma tenant scoping pattern (withTenantContext)
|
||||||
|
- phase: 03-operational-modules
|
||||||
|
provides: Collection, remittance, expense, inventory, vendor models
|
||||||
|
- phase: 05-04
|
||||||
|
provides: RBAC integration tests verifying permission enforcement
|
||||||
|
provides:
|
||||||
|
- Complete tenant isolation for all 28 tenant-scoped models
|
||||||
|
- Dedicated Collection and Remittance CASL subjects with role-based permissions
|
||||||
|
affects: [all future phases using expense/inventory/vendor/ticketComment queries]
|
||||||
|
|
||||||
|
# Tech tracking
|
||||||
|
tech-stack:
|
||||||
|
added: []
|
||||||
|
patterns:
|
||||||
|
- "All tenant-scoped models must have $extends query blocks in prisma-tenant.ts"
|
||||||
|
- "Each domain entity gets its own CASL subject (not borrowed from Subscriber)"
|
||||||
|
|
||||||
|
key-files:
|
||||||
|
created: []
|
||||||
|
modified:
|
||||||
|
- src/lib/prisma-tenant.ts
|
||||||
|
- src/lib/casl/types.ts
|
||||||
|
- src/lib/casl/permissions.ts
|
||||||
|
- src/app/api/collections/route.ts
|
||||||
|
- src/app/api/collections/[id]/route.ts
|
||||||
|
- src/app/api/collections/[id]/void/route.ts
|
||||||
|
- src/app/api/remittances/route.ts
|
||||||
|
- src/app/api/remittances/[id]/verify/route.ts
|
||||||
|
- src/app/api/reports/collections/route.ts
|
||||||
|
|
||||||
|
key-decisions:
|
||||||
|
- "6 missing models use simple tenantId injection (no tenant relation stripping needed)"
|
||||||
|
- "Collection/Remittance subjects added to OFFICE_STAFF (manage) and COLLECTOR (create/read)"
|
||||||
|
|
||||||
|
patterns-established:
|
||||||
|
- "Every tenant-scoped Prisma model requires 14 query method overrides in $extends"
|
||||||
|
- "CASL subjects must match domain entities 1:1 for precise permission control"
|
||||||
|
|
||||||
|
# Metrics
|
||||||
|
duration: 7min
|
||||||
|
completed: 2026-03-05
|
||||||
|
---
|
||||||
|
|
||||||
|
# Phase 5 Plan 6: Gap Closure - Tenant Isolation and CASL Subjects Summary
|
||||||
|
|
||||||
|
**Closed P0 tenant isolation gap for 6 models (expense, expenseCategory, inventoryItem, stockMovement, vendor, ticketComment) and replaced borrowed Subscriber CASL subject with dedicated Collection/Remittance subjects across 8 route files**
|
||||||
|
|
||||||
|
## Performance
|
||||||
|
|
||||||
|
- **Duration:** 7 min
|
||||||
|
- **Started:** 2026-03-05T10:22:11Z
|
||||||
|
- **Completed:** 2026-03-05T10:29:00Z
|
||||||
|
- **Tasks:** 2
|
||||||
|
- **Files modified:** 9
|
||||||
|
|
||||||
|
## Accomplishments
|
||||||
|
- TENANT_SCOPED_MODELS expanded from 22 to 28 entries with complete $extends query blocks
|
||||||
|
- Collection and Remittance added as first-class CASL subjects with proper role assignments
|
||||||
|
- All 8 collection/remittance route handlers now use semantically correct permission subjects
|
||||||
|
- All 533 existing tests continue to pass
|
||||||
|
|
||||||
|
## Task Commits
|
||||||
|
|
||||||
|
Each task was committed atomically:
|
||||||
|
|
||||||
|
1. **Task 1: Add 6 missing models to tenant scoping** - `b462120` (fix)
|
||||||
|
2. **Task 2: Add Collection and Remittance CASL subjects and update routes** - `a59a246` (fix)
|
||||||
|
|
||||||
|
## Files Created/Modified
|
||||||
|
- `src/lib/prisma-tenant.ts` - Added 6 models to TENANT_SCOPED_MODELS array and 6 complete $extends query blocks (577 lines)
|
||||||
|
- `src/lib/casl/types.ts` - Added Collection and Remittance to AppSubjects union
|
||||||
|
- `src/lib/casl/permissions.ts` - Added Collection/Remittance rules for OFFICE_STAFF and COLLECTOR roles
|
||||||
|
- `src/app/api/collections/route.ts` - Switched from Subscriber to Collection subject
|
||||||
|
- `src/app/api/collections/[id]/route.ts` - Switched from Subscriber to Collection subject
|
||||||
|
- `src/app/api/collections/[id]/void/route.ts` - Switched from Subscriber to Collection subject
|
||||||
|
- `src/app/api/remittances/route.ts` - Switched from Subscriber to Remittance subject
|
||||||
|
- `src/app/api/remittances/[id]/verify/route.ts` - Switched from Subscriber to Remittance subject
|
||||||
|
- `src/app/api/reports/collections/route.ts` - Switched from Subscriber to Collection subject
|
||||||
|
|
||||||
|
## Decisions Made
|
||||||
|
- Used the simpler create pattern (direct tenantId injection without tenant relation stripping) for all 6 new models since none have a `tenant` Prisma relation field
|
||||||
|
- Granted COLLECTOR create+read (not manage) for Collection/Remittance to maintain principle of least privilege
|
||||||
|
|
||||||
|
## Deviations from Plan
|
||||||
|
|
||||||
|
None - plan executed exactly as written.
|
||||||
|
|
||||||
|
## Issues Encountered
|
||||||
|
|
||||||
|
None.
|
||||||
|
|
||||||
|
## User Setup Required
|
||||||
|
|
||||||
|
None - no external service configuration required.
|
||||||
|
|
||||||
|
## Next Phase Readiness
|
||||||
|
- Tenant isolation is now complete across all 28 models
|
||||||
|
- Permission model is semantically accurate for all route handlers
|
||||||
|
- Ready for plan 05-07 (remaining gap closure items)
|
||||||
|
|
||||||
|
---
|
||||||
|
*Phase: 05-visibility-and-client-portal*
|
||||||
|
*Completed: 2026-03-05*
|
||||||
Reference in New Issue
Block a user