Multi-tenant SaaS backend for subscription management with double-entry bookkeeping and deferred revenue recognition.
Each tenant (company) manages its own customers, plans, subscriptions, invoices, and payments — fully isolated.
| Layer | Technology |
|---|---|
| Framework | NestJS (Node.js + TypeScript) |
| Database | PostgreSQL (Neon.tech serverless) |
| ORM | Prisma |
| Auth | JWT (Passport + bcrypt) |
| API Docs | Swagger UI (auto-opens on /) |
| Deploy | Vercel (serverless) |
| License | MIT |
All tenants share the same database with row-level isolation via tenantId on every table. Every query is filtered by the tenant extracted from the JWT token. This approach is cost-effective for SaaS and scales well with Neon.tech's serverless PostgreSQL.
Every financial transaction creates balanced journal entries (SUM(debit) = SUM(credit)). Three automated journal entry types:
| Event | Debit | Credit |
|---|---|---|
| Invoice Created | Accounts Receivable | Deferred Revenue |
| Payment Received | Cash | Accounts Receivable |
| Revenue Recognized | Deferred Revenue | Subscription Revenue |
Both invoice generation and revenue recognition are idempotent — safe to call multiple times without creating duplicates.
| Group | Endpoint | Method | Description |
|---|---|---|---|
| Auth | /api/auth/register |
POST | Register tenant + admin user |
| Auth | /api/auth/login |
POST | Login, get JWT |
| Plans | /api/plans |
CRUD | Manage subscription plans |
| Customers | /api/customers |
CRUD | Manage customers |
| Subscriptions | /api/subscriptions |
POST/GET | Create & list subscriptions |
| Subscriptions | /api/subscriptions/:id/cancel |
PATCH | Cancel subscription |
| Billing | /api/billing/generate-invoices |
POST | Generate monthly invoices |
| Billing | /api/invoices |
GET | List invoices |
| Payments | /api/payments |
POST/GET | Record payments |
| Accounting | /api/accounts |
GET | Chart of accounts |
| Accounting | /api/accounts/:id/ledger |
GET | Account ledger |
| Accounting | /api/journal-entries |
GET | All journal entries |
| Accounting | /api/accounting/recognize-revenue |
POST | Recognize deferred revenue |
| Reports | /api/reports/income-statement |
GET | Income statement |
| Reports | /api/reports/balance-sheet |
GET | Balance sheet |
- Node.js 18+
- PostgreSQL (or Neon.tech free tier)
# 1. Clone
git clone https://github.com/your-username/mosanada-saas.git
cd mosanada-saas
# 2. Install
npm install
# 3. Configure environment
cp .env.example .env
# Edit .env with your DATABASE_URL and JWT_SECRET
# 4. Generate Prisma client
npx prisma generate
# 5. Run migrations
npx prisma migrate dev --name init
# 6. Start development server
npm run start:dev
# 7. Open Swagger UI
# Visit http://localhost:3000 (redirects to /api/docs)- Register → POST
/api/auth/register - Authorize → Click "Authorize" in Swagger, paste JWT
- Create Plan ($500/mo) → POST
/api/plans - Create Customer → POST
/api/customers - Create Subscription → POST
/api/subscriptions - Generate Invoices → POST
/api/billing/generate-invoices(1 invoice, $500) - Verify → Balance Sheet: AR=$500, Deferred=$500
- Record Payment → POST
/api/payments - Verify → Balance Sheet: Cash=$500, AR=$0
- Recognize Revenue → POST
/api/accounting/recognize-revenue - Verify → Income Statement: Revenue=$500, Balance Sheet balances ✅
- Register 2nd Tenant → Verify data isolation
- Create a Neon.tech free PostgreSQL database
- Push code to GitHub
- Import project in Vercel
- Set environment variables:
DATABASE_URL,JWT_SECRET - Build command:
npx prisma generate && npm run build - Add postbuild script for migrations
MIT — open source, use freely.