docs(05-03): complete Portal Ticket Submission and Payment Scaffold plan
Tasks completed: 2/2 - Task 1: TicketComment model and portal ticket service - Task 2: Portal ticket API routes, payment scaffold, and tests SUMMARY: .planning/phases/05-visibility-and-client-portal/05-03-SUMMARY.md Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,118 @@
|
||||
---
|
||||
phase: 05-visibility-and-client-portal
|
||||
plan: 03
|
||||
subsystem: portal
|
||||
tags: [portal, tickets, comments, conversation, payment-scaffold, subscriber]
|
||||
|
||||
# Dependency graph
|
||||
requires:
|
||||
- phase: 03-operational-modules
|
||||
provides: Ticket model, TicketService with createTicket and status transitions
|
||||
- phase: 05-visibility-and-client-portal
|
||||
plan: 02
|
||||
provides: Portal auth (withPortalAuth, subscriberId in session), PortalService
|
||||
provides:
|
||||
- TicketComment model for conversation threads
|
||||
- Portal ticket service (createPortalTicket, listPortalTickets, getPortalTicket, addTicketComment)
|
||||
- ensurePortalUser shadow User pattern for subscriber->User FK bridge
|
||||
- Portal ticket API routes (list, create, detail, comments)
|
||||
- Payment scaffold endpoint with outstanding balance and instructions
|
||||
affects: [05-04 (network monitoring may reference tickets), 05-05 (e2e tests)]
|
||||
|
||||
# Tech tracking
|
||||
tech-stack:
|
||||
added: []
|
||||
patterns:
|
||||
- "ensurePortalUser shadow User for subscriber->User FK bridge"
|
||||
- "TicketComment append-only conversation thread on tickets"
|
||||
- "Payment scaffold returning balance + instructions (gateway deferred to v2)"
|
||||
|
||||
key-files:
|
||||
created:
|
||||
- prisma/schema.prisma (TicketComment model, paymentInstructions field)
|
||||
- src/lib/services/portal-ticket-service.ts
|
||||
- src/app/api/portal/tickets/route.ts
|
||||
- src/app/api/portal/tickets/[id]/route.ts
|
||||
- src/app/api/portal/tickets/[id]/comments/route.ts
|
||||
- src/app/api/portal/payments/coming-soon/route.ts
|
||||
- src/lib/__tests__/portal-ticket-service.test.ts
|
||||
modified:
|
||||
- prisma/schema.prisma
|
||||
|
||||
key-decisions:
|
||||
- "ensurePortalUser creates shadow User with CLIENT role and portal-{accountNumber}@portal.local email -- bridges Subscriber auth to User FK on Ticket.createdById"
|
||||
- "Portal tickets use source=SUBSCRIBER (not PORTAL) -- TicketSource enum has STAFF/SUBSCRIBER, SUBSCRIBER is semantically correct"
|
||||
- "TicketComment is append-only (no edits/deletes) -- conversation integrity preserved"
|
||||
- "Closed tickets reject new comments -- enforced at service layer"
|
||||
- "Payment scaffold computes outstanding balance in JS from SENT/PARTIAL/OVERDUE invoices -- same pattern as other derived aggregations"
|
||||
|
||||
patterns-established:
|
||||
- "Shadow User pattern: portal subscribers get lazy-created User records for FK constraints"
|
||||
- "Ticket conversation threads via TicketComment with chronological ordering"
|
||||
|
||||
# Metrics
|
||||
duration: 5min
|
||||
completed: 2026-03-05
|
||||
---
|
||||
|
||||
# Phase 05 Plan 03: Portal Ticket Submission and Payment Scaffold Summary
|
||||
|
||||
**Subscriber portal ticket creation with conversation threads, shadow User FK bridge, and payment coming-soon endpoint with outstanding balance -- 6 tests passing**
|
||||
|
||||
## Performance
|
||||
|
||||
- **Duration:** 5 min
|
||||
- **Started:** 2026-03-05T09:30:50Z
|
||||
- **Completed:** 2026-03-05T09:35:36Z
|
||||
- **Tasks:** 2
|
||||
- **Files modified:** 8
|
||||
|
||||
## Accomplishments
|
||||
- Subscribers can create support tickets from the portal (source=SUBSCRIBER)
|
||||
- Conversation threads on tickets via TicketComment model (append-only, chronological)
|
||||
- Shadow User pattern bridges Subscriber auth to User FK on Ticket.createdById
|
||||
- Portal tickets visible in staff ticket queue (cross-system verified)
|
||||
- Closed tickets reject new comments
|
||||
- Payment scaffold returns outstanding balance and configurable payment instructions
|
||||
|
||||
## Task Commits
|
||||
|
||||
Each task was committed atomically:
|
||||
|
||||
1. **Task 1: TicketComment model and portal ticket service** - `2d5b9ca` (feat)
|
||||
2. **Task 2: Portal ticket API routes, payment scaffold, and tests** - `3f44f5c` (feat)
|
||||
|
||||
## Files Created/Modified
|
||||
- `prisma/schema.prisma` - Added TicketComment model, paymentInstructions on TenantSettings, ticketComments relation on User
|
||||
- `src/lib/services/portal-ticket-service.ts` - Portal ticket service with ensurePortalUser, createPortalTicket, listPortalTickets, getPortalTicket, addTicketComment
|
||||
- `src/app/api/portal/tickets/route.ts` - GET (list) and POST (create) for portal tickets
|
||||
- `src/app/api/portal/tickets/[id]/route.ts` - GET ticket detail with conversation thread
|
||||
- `src/app/api/portal/tickets/[id]/comments/route.ts` - GET (list) and POST (add) ticket comments
|
||||
- `src/app/api/portal/payments/coming-soon/route.ts` - GET outstanding balance and payment instructions
|
||||
- `src/lib/__tests__/portal-ticket-service.test.ts` - 6 integration tests
|
||||
|
||||
## Decisions Made
|
||||
- **Shadow User pattern:** Portal subscribers authenticate as Subscriber (not User), but Ticket.createdById requires User.id. ensurePortalUser() lazily creates a User with CLIENT role and email `portal-{accountNumber}@portal.local` to bridge this gap.
|
||||
- **SUBSCRIBER source (not PORTAL):** The TicketSource enum has STAFF and SUBSCRIBER. Used SUBSCRIBER which is semantically correct for portal-submitted tickets.
|
||||
- **Append-only comments:** TicketComment has no updatedAt -- comments cannot be edited or deleted, preserving conversation integrity.
|
||||
- **Closed ticket comment rejection:** Enforced at service layer -- addTicketComment checks ticket.status !== CLOSED before creating comment.
|
||||
- **Outstanding balance in JS:** Payment scaffold computes balance from SENT/PARTIAL/OVERDUE invoices in JavaScript, consistent with the derived-aggregation pattern used throughout the project.
|
||||
|
||||
## Deviations from Plan
|
||||
|
||||
None -- plan executed exactly as written.
|
||||
|
||||
## Issues Encountered
|
||||
None.
|
||||
|
||||
## User Setup Required
|
||||
None - no external service configuration required.
|
||||
|
||||
## Next Phase Readiness
|
||||
- PORT-03 (ticket submission) and PORT-05 (online payment scaffold) requirements satisfied
|
||||
- Portal now has: auth, account view, invoices, payments, tickets, and payment scaffold
|
||||
- Ready for 05-04 (network monitoring) and 05-05 (e2e tests)
|
||||
|
||||
---
|
||||
*Phase: 05-visibility-and-client-portal*
|
||||
*Completed: 2026-03-05*
|
||||
Reference in New Issue
Block a user