docs(05): create phase plan
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>
This commit is contained in:
160
.planning/phases/05-visibility-and-client-portal/05-01-PLAN.md
Normal file
160
.planning/phases/05-visibility-and-client-portal/05-01-PLAN.md
Normal file
@@ -0,0 +1,160 @@
|
||||
---
|
||||
phase: 05-visibility-and-client-portal
|
||||
plan: 01
|
||||
type: execute
|
||||
wave: 1
|
||||
depends_on: []
|
||||
files_modified:
|
||||
- src/lib/services/dashboard-service.ts
|
||||
- src/app/api/dashboard/route.ts
|
||||
- src/lib/__tests__/dashboard-service.test.ts
|
||||
autonomous: true
|
||||
|
||||
must_haves:
|
||||
truths:
|
||||
- "Dashboard returns revenue collected today and this month"
|
||||
- "Dashboard returns overdue subscriber count and total outstanding amount"
|
||||
- "Dashboard returns active/suspended/cancelled subscriber counts"
|
||||
- "Dashboard returns cash flow summary (money in vs money out)"
|
||||
- "Dashboard returns collector summary (today's collections, unverified remittances)"
|
||||
artifacts:
|
||||
- path: "src/lib/services/dashboard-service.ts"
|
||||
provides: "DashboardService with all metric aggregation methods"
|
||||
exports: ["getRevenueMetrics", "getSubscriberMetrics", "getOverdueMetrics", "getCashFlowSummary", "getCollectorSummary", "getDashboardSummary"]
|
||||
- path: "src/app/api/dashboard/route.ts"
|
||||
provides: "GET endpoint returning all dashboard metrics"
|
||||
exports: ["GET"]
|
||||
- path: "src/lib/__tests__/dashboard-service.test.ts"
|
||||
provides: "Integration tests verifying metric accuracy"
|
||||
key_links:
|
||||
- from: "src/lib/services/dashboard-service.ts"
|
||||
to: "prisma"
|
||||
via: "aggregate queries on Payment, Invoice, Subscriber, Collection, Remittance, JournalEntryLine"
|
||||
pattern: "prisma\\.(payment|invoice|subscriber|collection|remittance|journalEntryLine)\\."
|
||||
- from: "src/app/api/dashboard/route.ts"
|
||||
to: "src/lib/services/dashboard-service.ts"
|
||||
via: "import and call getDashboardSummary"
|
||||
pattern: "getDashboardSummary"
|
||||
---
|
||||
|
||||
<objective>
|
||||
Build the DashboardService that aggregates financial and operational metrics for the ISP owner dashboard, plus a GET /api/dashboard endpoint and integration tests.
|
||||
|
||||
Purpose: DASH-01, DASH-02, DASH-03, DASH-04 — the ISP owner's single-page business health overview.
|
||||
Output: DashboardService, API route, passing tests.
|
||||
</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
|
||||
@.planning/phases/05-visibility-and-client-portal/05-CONTEXT.md
|
||||
|
||||
@src/lib/services/financial-report-service.ts
|
||||
@src/lib/services/outstanding-report-service.ts
|
||||
@src/lib/services/collection-report-service.ts
|
||||
@src/lib/services/expense-report-service.ts
|
||||
@src/lib/services/payment-service.ts
|
||||
@src/lib/services/collector-service.ts
|
||||
@src/lib/middleware/authorize.ts
|
||||
@prisma/schema.prisma
|
||||
</context>
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 1: DashboardService with metric aggregation</name>
|
||||
<files>src/lib/services/dashboard-service.ts</files>
|
||||
<action>
|
||||
Create DashboardService with these methods, all accepting a TenantPrismaClient (same pattern as all other services):
|
||||
|
||||
1. **getRevenueMetrics(db, tenantId)** — Revenue collected today and this month (DASH-01):
|
||||
- Query Payment table with status COMPLETED, grouped by date range
|
||||
- `revenueToday`: sum of payments where createdAt is today (midnight to now)
|
||||
- `revenueThisMonth`: sum of payments where createdAt is current month
|
||||
- Return `{ revenueToday: Decimal, revenueThisMonth: Decimal }`
|
||||
|
||||
2. **getOverdueMetrics(db, tenantId)** — Overdue subscriber count and outstanding total (DASH-02):
|
||||
- Query Invoice table for OVERDUE status invoices
|
||||
- Count distinct subscriberIds with overdue invoices
|
||||
- Sum (totalAmount - amountPaid) for all overdue invoices
|
||||
- Return `{ overdueCount: number, totalOutstanding: Decimal }`
|
||||
|
||||
3. **getSubscriberMetrics(db, tenantId)** — Status breakdown (DASH-03):
|
||||
- Query Subscriber table grouped by status
|
||||
- Return `{ active: number, suspended: number, cancelled: number, total: number }`
|
||||
|
||||
4. **getCashFlowSummary(db, tenantId, startDate, endDate)** — Money in vs money out (DASH-04):
|
||||
- Money in: sum of POSTED JE lines where account is revenue-type (4xxx codes) — use debit/credit with normal balance logic, same as FinancialReportService
|
||||
- Money out: sum of POSTED JE lines where account is expense-type (5xxx codes)
|
||||
- Return `{ moneyIn: Decimal, moneyOut: Decimal, netCashFlow: Decimal }`
|
||||
- Default date range: current month
|
||||
|
||||
5. **getCollectorSummary(db, tenantId)** — Today's collections and unverified remittances (from CONTEXT.md):
|
||||
- `collectionsToday`: sum of non-voided Collection amounts where createdAt is today
|
||||
- `unverifiedRemittances`: count of Remittance records with status SUBMITTED (not VERIFIED)
|
||||
- Return `{ collectionsToday: Decimal, unverifiedRemittances: number }`
|
||||
|
||||
6. **getDashboardSummary(db, tenantId)** — Aggregator that calls all five methods above and returns a single object.
|
||||
|
||||
Use Prisma aggregate/groupBy for efficiency. Follow the existing TenantPrismaClient pattern (type as any). Use Decimal from Prisma for all money fields. All date comparisons use UTC.
|
||||
</action>
|
||||
<verify>TypeScript compiles: `npx tsc --noEmit src/lib/services/dashboard-service.ts` (or full project compile)</verify>
|
||||
<done>DashboardService exports all 6 methods with correct return types</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 2: Dashboard API route and integration tests</name>
|
||||
<files>src/app/api/dashboard/route.ts, src/lib/__tests__/dashboard-service.test.ts</files>
|
||||
<action>
|
||||
**API Route (src/app/api/dashboard/route.ts):**
|
||||
- GET handler wrapped with `withPermission("read", "Report")` — ADMIN and OFFICE_STAFF have this permission
|
||||
- Calls getDashboardSummary with tenant-scoped Prisma client
|
||||
- Returns JSON with all metrics
|
||||
- Accepts optional query params: `startDate`, `endDate` for cash flow date range (defaults to current month)
|
||||
- Follow existing route patterns (see any route.ts in src/app/api/)
|
||||
|
||||
**Integration Tests (src/lib/__tests__/dashboard-service.test.ts):**
|
||||
Create tests using vitest with live PostgreSQL (same pattern as all other test files):
|
||||
|
||||
Setup: Create tenant, seed COA, create subscriber, generate invoice, record payment, create collection, create remittance.
|
||||
|
||||
Tests (minimum 6):
|
||||
1. `getRevenueMetrics returns today's revenue` — after recording a payment, revenueToday > 0
|
||||
2. `getOverdueMetrics counts overdue invoices` — create invoice with past due date, verify overdueCount = 1
|
||||
3. `getSubscriberMetrics returns status breakdown` — create active + suspended subscribers, verify counts
|
||||
4. `getCashFlowSummary computes net cash flow` — after payment + expense, verify moneyIn and moneyOut
|
||||
5. `getCollectorSummary returns today's collections` — after collection, verify collectionsToday > 0
|
||||
6. `getDashboardSummary aggregates all metrics` — verify the composite object has all fields
|
||||
|
||||
Cleanup order: follow the most comprehensive cleanup pattern from 04-04 (expense report tests) since dashboard touches payments, invoices, collections, remittances, expenses, and JEs.
|
||||
|
||||
Run tests with: `npx vitest run src/lib/__tests__/dashboard-service.test.ts`
|
||||
</action>
|
||||
<verify>`npx vitest run src/lib/__tests__/dashboard-service.test.ts` — all tests pass</verify>
|
||||
<done>GET /api/dashboard returns all dashboard metrics; 6+ tests pass verifying metric accuracy</done>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<verification>
|
||||
- `npx tsc --noEmit` passes (no type errors)
|
||||
- `npx vitest run src/lib/__tests__/dashboard-service.test.ts` — all tests pass
|
||||
- DashboardService correctly derives all metrics from existing data (no new stored balances)
|
||||
</verification>
|
||||
|
||||
<success_criteria>
|
||||
- DashboardService aggregates revenue, overdue, subscriber status, cash flow, and collector metrics
|
||||
- GET /api/dashboard returns the composite dashboard object
|
||||
- All integration tests pass, verifying metric accuracy against seeded data
|
||||
- DASH-01, DASH-02, DASH-03, DASH-04 requirements satisfied
|
||||
</success_criteria>
|
||||
|
||||
<output>
|
||||
After completion, create `.planning/phases/05-visibility-and-client-portal/05-01-SUMMARY.md`
|
||||
</output>
|
||||
Reference in New Issue
Block a user