Phase 04: 5 plans in 2 waves - Wave 1: 04-01 (inventory event-ledger), 04-03 (expense tracking), 04-05 (financial reports) — parallel - Wave 2: 04-02 (asset management), 04-04 (expense reports + audit trail) — sequential - Ready for execution Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
8.0 KiB
phase, plan, type, wave, depends_on, files_modified, autonomous, must_haves
| phase | plan | type | wave | depends_on | files_modified | autonomous | must_haves | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 04-inventory-expenses-and-financial-reports | 04 | execute | 2 |
|
|
true |
|
Purpose: Gives ISP owners spending visibility (where money goes) and auditors the ability to trace any ledger entry to its origin. ACCT-08 (audit trail) applies to ALL journal entries, not just expense ones. Output: ExpenseReportService, AuditTrailService, report API routes, tests.
<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>
@.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md @.planning/phases/04-inventory-expenses-and-financial-reports/04-CONTEXT.md @.planning/phases/04-inventory-expenses-and-financial-reports/04-03-SUMMARY.md @prisma/schema.prisma @src/lib/accounting/journal-entry-service.ts @src/lib/services/expense-service.ts Task 1: ExpenseReportService and AuditTrailService src/lib/services/expense-report-service.ts src/lib/services/audit-trail-service.ts src/app/api/reports/expenses/route.ts src/app/api/reports/expenses/by-vendor/route.ts src/app/api/accounting/journal-entries/[id]/audit/route.ts **ExpenseReportService** (`src/lib/services/expense-report-service.ts`): Static class:-
getExpensesByCategory(tenantPrisma, { startDate, endDate }):- Query POSTED expenses grouped by categoryId within date range
- Return: array of { categoryId, categoryName, totalAmount (Decimal), expenseCount (number) }
- Order by totalAmount DESC
-
getExpensesByVendor(tenantPrisma, { startDate, endDate, vendorId? }):- Query POSTED expenses grouped by vendorId within date range
- Optional vendorId filter for single-vendor detail
- Return: array of { vendorId, vendorName, totalAmount, expenseCount }
- Include a "No Vendor" bucket for expenses without vendorId
- Order by totalAmount DESC
-
getExpenseSummary(tenantPrisma, { startDate, endDate }):- Return combined report: { totalExpenses (Decimal), byCategory: [...], byVendor: [...], expenseCount }
- Calls the two methods above and computes grand total
AuditTrailService (src/lib/services/audit-trail-service.ts):
Static class:
-
getJournalEntryAudit(tenantPrisma, entryId):- Fetch JE with include: createdBy (select id, email, firstName, lastName), approvedBy, lines with account details
- Return: { entryNumber, date, description, source, status, referenceType, referenceId, createdBy: {name, email}, createdAt, approvedBy?: {name, email}, approvedAt?, lines: [{account code+name, debit, credit}] }
- This provides ACCT-08: who created it, when, what source transaction
-
getAuditTrailForEntity(tenantPrisma, { referenceType, referenceId }):- Fetch all JEs where referenceType and referenceId match
- Returns array of JE audit records — enables "show all journal entries for this invoice" or "for this payment"
- Includes reversing entries (where reversesEntryId links to matching JEs)
API Routes:
GET /api/reports/expenses— expense summary by category. Query: startDate, endDate. ADMIN only.GET /api/reports/expenses/by-vendor— expense summary by vendor. Query: startDate, endDate, vendorId?. ADMIN only.GET /api/accounting/journal-entries/[id]/audit— full audit trail for a JE. ADMIN, OFFICE_STAFF.
All routes use withPermission() HOF. API route files exist and export correct HTTP methods ExpenseReportService provides category and vendor expense reports; AuditTrailService links every JE to its creator and source transaction
Task 2: Tests for expense reports and audit trail src/lib/__tests__/expense-report-service.test.ts **Setup:** createTenant, create admin user, create 2 vendors, create expenses across 3 categories (use 2 different expense categories from the 9 seeded defaults + 1 custom category). Create expenses linked to different vendors. Ensure expenses are POSTED (so JEs exist).Test cases:
- Expense report by category — returns correct totals per category for date range
- Expense report by category excludes DRAFT/VOIDED expenses (only POSTED counted)
- Expense report by vendor — returns correct totals per vendor
- Expense report by vendor includes "No Vendor" bucket for unlinked expenses
- Expense summary — combines category and vendor views with grand total
- Date range filtering works (expenses outside range excluded)
- JE audit trail — fetch audit for a posted expense's JE: shows createdBy user, source=SYSTEM, referenceType="Expense", referenceId=expense.id
- Audit trail for entity — fetch all JEs for an expense (original + void reversal if voided)
- JE audit trail on a payment JE (from Phase 2) — verify referenceType="Payment" is correctly returned (proves ACCT-08 works across all JE sources, not just expenses)
Cleanup order: expenses -> vendors -> expenseCategories (custom only) -> journalEntryLines -> null reversesEntryId -> journalEntries -> invoiceLines -> invoices -> subscribers -> servicePlans -> accountingPeriods -> accounts -> ticketCategories -> expenseCategories (system) -> users -> tenant npx jest expense-report-service --verbose passes all tests Expense reports correctly aggregate by category/vendor with date filtering. Audit trail shows creator, timestamp, and source reference for any JE. All tests pass.
- `npx jest expense-report-service --verbose` — all tests pass - Expense report by category shows correct totals - Expense report by vendor shows correct totals - JE audit trail includes who/when/source for all JE types (not just expenses)<success_criteria>
- Admin can generate expense reports by category and vendor for any date range
- Reports show totals and counts, excluding non-POSTED expenses
- Every journal entry (Invoice, Payment, Expense, Collection, Remittance, StockMovement) has traceable audit trail
- All tests pass </success_criteria>