How s-prem-kumar/cashpilot- works
1. Purpose and deployment shape
CashPilot is a personal-finance system combining manual income/expense records with bank-PDF extraction, transaction-to-record mapping, dashboard analytics, and exportable reports. It is a Docker-compose three-tier deployment: Next.js frontend, NestJS API, and PostgreSQL. Persistent volumes retain database data, uploaded PDFs/files, and OCR cache.
• docker-compose.yml
• backend/Dockerfile
• frontend/Dockerfile
2. Entry points and application boundary
The frontend is a Next.js App Router client with middleware-protected authenticated route groups. It calls the NestJS API at /api; authentication uses JWTs in HttpOnly cookies. The backend initializes Nest modules, global validation/security middleware, Prisma, and startup maintenance services.
• frontend/src/app/layout.tsx
• frontend/src/middleware.ts
• backend/src/main.ts
• backend/src/app.module.ts
3. Identity, user data, and protected files
Auth covers signup email OTP verification, login, password reset, JWT revocation through token versions, and rate-limited access. User/profile operations own avatar lifecycle and account deletion. File access is not static: the API streams receipts/avatars only after re-deriving ownership.
• backend/src/auth/auth.service.ts
• backend/src/auth/guards/jwt-auth.guard.ts
• backend/src/user/user.service.ts
• backend/src/files/files.service.ts
External mail delivery is abstracted behind Nodemailer/direct SMTP or optional Resend.
• backend/src/mail/mail.service.ts
• backend/src/config/configuration.ts
4. Ledger and master-data domain
Manual expenses and incomes share a generic record service, differentiated by direction/party semantics. Records reference user-scoped parent categories and categories by ID, plus polymorphic Vendor/Employee parties. Masters are soft-deleted and guarded from deletion when referenced by mapped records; master validation ensures category-parent consistency.
• backend/src/common/records/record.service.ts
• backend/src/expense/expense.controller.ts
• backend/src/income/income.controller.ts
• backend/src/masters/base-master.service.ts
• backend/src/masters/master-lookup.service.ts
The relational source of truth, constraints, cascades, and migrations are Prisma/PostgreSQL.
• backend/prisma/schema.prisma
• backend/src/prisma/prisma.service.ts
5. Bank-statement ingestion pipeline
Statement upload stores PDFs privately, hashes file bytes to reject exact per-user duplicates, and processes synchronously. Text extraction is attempted first; scanned PDFs enter an isolated child-process OCR path. Both produce normalized text for an auto-detecting parser registry, then transaction rows are confidence-gated before persistence.
• backend/src/bank-statement/statement-processor.service.ts
• backend/src/bank-statement/pdf/text-extractor.ts
• backend/src/bank-statement/pdf/ocr-worker.ts
• backend/src/bank-statement/parsers/registry.ts
Dedicated bank parsers delegate row extraction to a generic engine. Ingestion tracks statuses including pending confirmation, processed, review-needed, and failed.
• backend/src/bank-statement/parsers/generic.parser.ts
• backend/src/bank-statement/bank-statement.service.ts
• backend/src/bank-statement/statement-reconcile.service.ts
6. Transaction integrity and reconciliation
Extracted bank transactions are distinct from manual records. Duplicate detection first uses user/reference number and then normalized row fingerprints with count-aware matching; clean imports commit directly, while overlap-bearing uploads pause for preview/confirmation. Statement deletion transactionally cascades bank transactions and mappings but preserves manual records by clearing provenance.
• backend/src/bank-statement/duplicate-detection.service.ts
• backend/src/bank-statement/dedupe-transactions.ts
• backend/src/transaction/bank-transaction.service.ts
A mapping table creates strictly one-to-one links between bank transactions and Income/Expense records. Mapping/remapping is an upsert-like flow; unmapping only removes the link.
• backend/src/mapping/mapping.service.ts
• backend/src/mapping/mapping.controller.ts
7. Read models, reporting, and UI composition
Dashboard aggregation is pushed to PostgreSQL and returns bounded aggregate shapes rather than full transaction histories. Shared ordered categorization rules are implemented in JavaScript and compiled SQL to keep chart/insight classification aligned.
• backend/src/dashboard/dashboard.service.ts
• backend/src/dashboard/dashboard-queries.ts
• backend/src/dashboard/categorize.sql.ts
Reports are backend-filtered, paginated analytical views; the frontend uses config-driven rendering and client-side Excel/PDF export. Primary workflow pages cover dashboard, records, masters, and reports.
• backend/src/reports/reports.service.ts
• frontend/src/lib/reports.ts
• frontend/src/components/reports/report-view.tsx
• frontend/src/app/records/transactions/page.tsx
Components 19
Frontend
- Next.js app · Authenticated App Router interface for finance workflows.
frontend/src/app/layout.tsx - Route middleware · Protects authenticated route groups.
frontend/src/middleware.ts - Workflow pages · Dashboard, records, masters, and reports workflows.
frontend/src/app/records/transactions/page.tsx - Report renderer and export · Config-driven reports with client-side Excel/PDF export.
frontend/src/components/reports/report-view.tsx
NestJS API
- API bootstrap · Initializes Nest modules and global security and validation.
backend/src/main.ts - Auth and identity · JWT-cookie sessions, OTP, resets, revocation, and rate limits.
backend/src/auth/auth.service.ts - Users and protected files · Owns profiles, avatar lifecycle, deletion, and authorized file streaming.
backend/src/files/files.service.ts - Records and masters · Manual income/expense records, categories, and vendor/employee masters.
backend/src/common/records/record.service.ts - Transaction mapping · Maintains one-to-one bank-transaction to manual-record links.
backend/src/mapping/mapping.service.ts - Dashboard analytics · Returns bounded PostgreSQL aggregates with aligned categorization rules.
backend/src/dashboard/dashboard.service.ts - Reports API · Provides filtered, paginated analytical views.
backend/src/reports/reports.service.ts
Statement ingestion
- Statement processor · Privately stores uploads, hashes them, and runs synchronous processing.
backend/src/bank-statement/statement-processor.service.ts - PDF text and OCR · Uses text extraction first, then isolated child-process OCR for scans.
backend/src/bank-statement/pdf/text-extractor.ts - Parser registry · Auto-detects bank format and delegates rows to generic parsing.
backend/src/bank-statement/parsers/registry.ts - Dedupe and confirmation · Fingerprint/reference matching sends overlaps to preview confirmation.
backend/src/bank-statement/duplicate-detection.service.ts
Data and external services
- Prisma data access · Applies relational constraints, migrations, and database access.
backend/src/prisma/prisma.service.ts - PostgreSQL · Source of truth for users, records, statements, transactions, and mappings.
backend/prisma/schema.prisma - Email provider · SMTP/Nodemailer or optional Resend delivery.
backend/src/mail/mail.service.ts
Other components
- Docker Compose · Runs the frontend, API, and PostgreSQL tiers.
docker-compose.yml
Connections 24
- Docker Compose → Next.js app: runs
- Docker Compose → API bootstrap: runs
- Docker Compose → PostgreSQL: runs
- Next.js app → Route middleware: passes through
- Route middleware → Workflow pages: permits authenticated access
- Workflow pages → Report renderer and export: renders reports
- Next.js app → API bootstrap: /api with JWT cookie
- API bootstrap → Auth and identity: routes identity requests
- API bootstrap → Records and masters: routes ledger requests
- API bootstrap → Statement processor: accepts statement uploads
- API bootstrap → Dashboard analytics: serves aggregates
- API bootstrap → Reports API: serves report views
- Auth and identity → Email provider: sends OTP and reset email
- Auth and identity → Prisma data access: persists identity state
- Users and protected files → Prisma data access: authorizes ownership
- Records and masters → Prisma data access: persists records and masters
- Statement processor → PDF text and OCR: extracts normalized text
- PDF text and OCR → Parser registry: provides text
- Parser registry → Dedupe and confirmation: produces transaction rows
- Dedupe and confirmation → Prisma data access: commits or awaits confirmation
- Transaction mapping → Prisma data access: upserts one-to-one links
- Dashboard analytics → Prisma data access: runs aggregate queries
- Reports API → Prisma data access: runs filtered queries
- Prisma data access → PostgreSQL: reads and writes