Skip to content

Repository files navigation

Compasso

A finance tracking app that parses bank PDF ledgers, categorizes transactions with smart suggestions, and displays data in an interactive dashboard.

Features

  • Privacy-first: All data stays local in a SQLite database
  • Multi-user support: User authentication with secure session management
  • Multi-workspace: Organize finances into separate workspaces with role-based access (owner, editor, viewer)
  • Collaboration: Invite users to workspaces via username or email
  • Multilingual: English and Portuguese UI with user locale preference
  • Password reset: Reset your password via email
  • Workspace backup/restore: Export and import workspace data
  • Error handling: Structured error codes, session expiry detection, React error boundaries
  • PDF parsing: Extract transactions from Novo Banco and CGD monthly statements (extensible to other banks)
  • Smart categorization: Pattern-based category suggestions with user-defined categories
  • Dashboard: View data by year, month, and category with charts
  • Financial reports: Annual and monthly reports with visualizations
  • Recurring detection: Automatic detection and management of recurring transactions
  • Bank-agnostic architecture: Support for multiple banks with bank-specific patterns

Tech Stack

  • Frontend: React + TypeScript + Vite + react-i18next
  • UI: Tailwind CSS + Recharts
  • Backend: Node.js + Express
  • Database: SQLite (better-sqlite3)
  • PDF Parsing: pdfjs-dist

Project Structure

compasso/
├── apps/
│ ├── web/ # React frontend
│ └── api/ # Node.js backend
├── packages/
│ └── shared/ # Shared types & constants
├── data/ # SQLite database (gitignored)
└── uploads/ # Temporary PDF uploads (gitignored)

Getting Started

Prerequisites

  • Node.js 22+
  • npm 10+

Installation

# Install dependencies
npm install
# Build shared package
npm run build -w @compasso/shared

Development

# Run both frontend and backend in development mode
npm run dev

Environment Variables

Create a .env file in the root or apps/api directory:

# Server configuration
PORT=5181
HOST=127.0.0.1
NODE_ENV=development
# CORS configuration (comma-separated origins for production)
ALLOWED_ORIGINS=http://localhost:5180,http://127.0.0.1:5180
# Database path (optional, defaults to ./data)
DATABASE_PATH=./data
# Cookie security (defaults to true in production, set to false for HTTP-only deployments)# SECURE_COOKIES=false# Email — optional, used for password reset emails (see below)# Option 1: SMTP (any provider)
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_SECURE=false
SMTP_USER=user@gmail.com
SMTP_PASS=app-password
SMTP_FROM=noreply@yourdomain.com
# Option 2: Resend
RESEND_API_KEY=re_xxxxxxxxxxxx
EMAIL_FROM=noreply@compasso.app

Email Service (Optional)

Password reset emails require an email transport. Without configuration the app runs normally but password reset will not send emails. Configure one of the following options:

Option 1: SMTP (any provider)

Works with Gmail, Mailgun, SES, self-hosted, or any SMTP server.

SMTP_HOST=smtp.gmail.com
SMTP_PORT=587 # defaults to 587
SMTP_SECURE=false # true for port 465
SMTP_USER=user@gmail.com
SMTP_PASS=app-password
SMTP_FROM=noreply@yourdomain.com

SMTP_FROM defaults to noreply@compasso.app if not set.

Option 2: Resend

Uses the Resend REST API.

  1. Create an account at resend.com
  2. Generate an API key from the dashboard
  3. Verify a sending domain (or use the sandbox domain for development)
  4. Set the environment variables:
RESEND_API_KEY=re_xxxxxxxxxxxx
EMAIL_FROM=noreply@yourdomain.com

EMAIL_FROM defaults to noreply@compasso.app if not set.

If both are configured, SMTP takes priority.

Production Build

npm run build

Docker

The Docker image is automatically built and pushed to GitHub Container Registry on every push to main (after CI passes). The container runs as a non-root user (node) for security.

# Run with the pre-built image
docker compose up -d
# Pull the latest image (e.g., after a new release)
docker compose pull && docker compose up -d

To build locally instead:

docker build -t compasso .
docker run -d -p 5181:5181 -v ./data:/data compasso

Environment variables are read from a .env file in the project root.

Self-hosted (Synology, NAS, etc.)

For HTTP-only deployments without a reverse proxy, set SECURE_COOKIES=false in your environment — otherwise session cookies won't be sent by the browser:

environment:
- SECURE_COOKIES=false
- ALLOWED_ORIGINS=http://YOUR_IP:5181

Auto-updates with Watchtower

If you run Watchtower, it will automatically detect new image pushes and update the running container:

services:
watchtower:
image: containrrr/watchtowervolumes:
- /var/run/docker.sock:/var/run/docker.sockenvironment:
- WATCHTOWER_POLL_INTERVAL=3600
- WATCHTOWER_CLEANUP=truerestart: unless-stopped

For private repositories, authenticate Docker with GHCR first:

echo"YOUR_GITHUB_PAT"| docker login ghcr.io -u YOUR_USERNAME --password-stdin

Usage

  1. Create an account: Register a new user account on the login page
  2. Create a workspace: Set up a workspace for your finances (one is created by default)
  3. Upload a statement: Go to the Upload page and select your bank, then drag & drop a PDF statement
  4. Review transactions: Review the parsed transactions and adjust categories as needed
  5. View dashboard: See your financial overview with charts and statistics
  6. Manage categories: Add custom categories and patterns for auto-categorization
  7. View reports: Access annual and monthly financial reports
  8. Track recurring: View and manage detected recurring transaction patterns

Supported Banks

  • Novo Banco (Portugal) - "Extrato Integrado" PDF format
  • CGD (Caixa Geral de Depósitos) (Portugal)

Adding Support for New Banks

The project uses a registry pattern — 4 files need to be touched:

  1. Create parser data in apps/api/src/parsers/<bank-slug>-data.ts (exports config, patterns)
  2. Create parser in apps/api/src/parsers/<bank-slug>.ts (imports data, exports BankParserDefinition with parse function)
  3. Register data in apps/api/src/parsers/registry.ts (1 import + 1 array entry)
  4. Write tests in apps/api/src/parsers/<bank-slug>.test.ts

See .github/BANK_PARSER_GUIDE.md for the full contributor guide.

API Endpoints

Authentication

MethodEndpointDescription
POST/api/auth/registerCreate new user account
POST/api/auth/loginAuthenticate user
POST/api/auth/logoutEnd user session
GET/api/auth/meGet current user info
PUT/api/auth/profileUpdate user profile
PUT/api/auth/passwordChange password
POST/api/auth/forgot-passwordRequest password reset email
POST/api/auth/reset-passwordReset password with token

Workspaces

MethodEndpointDescription
GET/api/workspacesList user's workspaces
POST/api/workspacesCreate workspace
GET/api/workspaces/:idGet workspace details
PUT/api/workspaces/:idUpdate workspace
DELETE/api/workspaces/:idDelete workspace

Members & Invitations

MethodEndpointDescription
GET/api/workspaces/:id/membersList workspace members
PUT/api/workspaces/:id/members/:userIdChange member role
DELETE/api/workspaces/:id/members/:userIdRemove member
POST/api/workspaces/:id/invitationsInvite user to workspace
GET/api/workspaces/:id/invitationsList pending invitations
GET/api/invitationsMy pending invitations
POST/api/invitations/:id/acceptAccept invitation
POST/api/invitations/:id/declineDecline invitation

Dashboard & Reports

MethodEndpointDescription
GET/api/dashboardDashboard summary data
GET/api/dashboard/yearsAvailable years with data
GET/api/reports/yearlyAnnual financial report
GET/api/reports/category-trendsCategory trends report
GET/api/reports/yearsList available report years

Transactions

MethodEndpointDescription
GET/api/transactionsList transactions (with filters)
GET/api/transactions/exportExport transactions as CSV
POST/api/transactions/confirmSave parsed transactions
PUT/api/transactions/:idUpdate transaction category
DELETE/api/transactions/:idDelete transaction

Upload & Ledgers

MethodEndpointDescription
POST/api/uploadUpload and parse PDF
GET/api/upload/banksList supported banks
GET/api/upload/ledgersList uploaded ledgers
DELETE/api/upload/ledgers/:idDelete ledger

Categories

MethodEndpointDescription
GET/api/categoriesList categories
POST/api/categoriesCreate category
GET/api/categories/:idGet category with patterns
PUT/api/categories/:idUpdate category
DELETE/api/categories/:idDelete category
POST/api/categories/:id/patternsAdd pattern to category
POST/api/categories/:id/patterns/quickCreate quick pattern
DELETE/api/categories/:id/patterns/:patternIdDelete pattern
GET/api/categories/patterns/existsCheck if pattern exists

Recurring Patterns

MethodEndpointDescription
GET/api/recurringList recurring patterns
POST/api/recurring/detectDetect recurring patterns
PUT/api/recurring/:idToggle pattern active status
GET/api/recurring/:id/transactionsList pattern transactions
DELETE/api/recurring/:idDelete recurring pattern

Backup

MethodEndpointDescription
GET/api/backup/exportExport workspace data
POST/api/backup/importImport workspace data

Health

MethodEndpointDescription
GET/api/healthHealth check

Testing

# Run all tests
npm test# Run tests with coverage
npm test -- --coverage

Tests use Vitest and cover parsers, services, middleware, and error handling.

License

MIT

About

A finance tracking app that parses bank PDF ledgers, categorizes transactions with smart suggestions, and displays data in an interactive dashboard.

Resources

Stars

11 stars

Watchers

1 watching

Forks

Releases

Sponsor this project

Packages

Contributors

Languages