| 02-subscriber-and-billing-core |
01 |
database |
| prisma |
| postgresql |
| accounting |
| double-entry |
| chart-of-accounts |
| multi-tenancy |
|
| phase |
provides |
| 01-foundation |
Tenant model, User model, createTenant(), withTenantContext(), withPermission() HOF |
|
|
| Account Prisma model with tenant scoping, code/name/accountType/normalBalance/parentId |
| AccountingPeriod Prisma model with year/month/status/closedAt/closedById |
| ISP_CHART_OF_ACCOUNTS |
| 28-account definition covering all 5 accounting types |
|
| seedChartOfAccounts(tx, tenantId) |
| auto-provisions COA inside Prisma transaction |
|
| createTenant() now provisions full COA atomically with tenant+user creation |
| closePeriod, getOpenPeriod, isDateInClosedPeriod functions |
| GET /api/accounting/accounts — list COA for authenticated tenant |
| GET /api/accounting/periods — list accounting periods |
| POST /api/accounting/periods/[id]/close — close a period |
|
| 02-02-journal-entry-service (posts to Account records created here; enforces closed periods) |
| 02-03-invoice-billing (uses Subscription Revenue 4010, Accounts Receivable 1100) |
| 02-04-payment-collection (uses Cash accounts 1010/1020, credits AR) |
| All future phases that touch financial data |
|
| added |
patterns |
|
|
| COA auto-provisioning in Prisma $transaction — atomic tenant+user+COA creation |
| Zero mutable balance fields — all balances derived from journal entry sums |
| On-demand period creation via getOpenPeriod() — periods created at first use |
| TxClient pattern — seed functions accept transaction client, not full PrismaClient |
| withTenantContext() extended with account and accountingPeriod query blocks |
|
|
| created |
modified |
| prisma/migrations/20260304144656_add_accounting_models/migration.sql |
| src/lib/accounting/chart-of-accounts.ts |
| src/lib/accounting/accounting-period.ts |
| src/lib/accounting/seed-coa.ts |
| src/app/api/accounting/accounts/route.ts |
| src/app/api/accounting/periods/route.ts |
| src/app/api/accounting/periods/[id]/close/route.ts |
| src/lib/__tests__/accounting-coa.test.ts |
|
| prisma/schema.prisma |
| src/lib/prisma-tenant.ts |
| src/lib/tenant.ts |
|
|
| 28 accounts in ISP COA — 5 parent headers (1000/2000/3000/4000/5000) + 23 leaf accounts |
| Subscriber Credits (1150) is contra-asset with CREDIT normal balance — reduces AR |
| seedChartOfAccounts receives Prisma tx client (not full PrismaClient) — works inside $transaction |
| Periods created on-demand via getOpenPeriod() — not pre-seeded at tenant creation |
| closedPeriods back-reference added on User model for Prisma relation integrity |
| close route uses closure pattern (withPermission wrapping inside POST fn) for param access |
|
| Accounting isolation: zero mutable balance fields — enforced at model level (no balanceColumn exists) |
| COA seeding: ISP_CHART_OF_ACCOUNTS array ordered parents-before-children for correct parentId resolution |
|
7min |
2026-03-04 |