The Problem
Small businesses and freelancers need a local‑only way to import bank PDFs, tag transactions, and view financial health without sending sensitive data to third‑party SaaS platforms. Existing tools either require cloud storage or lack programmable parsing for Portuguese‑language statements.
What This Does
compasso provides a self‑hosted web app that ingests PDF ledgers (Novo Banco, CGD) via the upload endpoints in apps/api/src/routes/upload.ts. Parsed rows are stored in a SQLite file managed by apps/api/src/db/database.ts. The front‑end in apps/web/src/App.tsx renders a dashboard (pages/Dashboard.tsx) with charts from Recharts and lets users create workspaces, categories, and recurring‑transaction patterns. Core business logic lives in services such as apps/api/src/services/transactionService.ts, workspaceService.ts, and recurringDetector.ts, while shared type definitions are in packages/shared/src/types.ts.
How It Is Wired
- Server start –
apps/api/src/index.tscreates an Express app, registers middleware (middleware/auth.ts,middleware/rateLimiter.ts) and mounts the router fromapps/api/src/routes/index.ts. - Routing – The router forwards requests to concrete route files (e.g.,
routes/transactions.ts,routes/categories.ts). Each route calls a service function; for example,POST /transactionsinvokescreateTransactionintransactionService.ts. - Database hub – All services that persist data call
getDatabase(called from 67 places) defined indb/database.ts. This file is the most connected module (Ca = 33) and therefore the blast‑radius for any change. - Error handling – Errors are constructed via helpers in
apps/api/src/errors.ts(badRequest,unauthorized, etc.). This hub (Ca = 32) centralises HTTP‑status mapping. - Workspace logic –
workspaceService.ts(imports only two other modules,Ca = 19) orchestrates creation, deletion, and role checks; it is the second‑largest stable hub. - Auth flow –
authService.tsperforms password hashing (hashPassword) and session ID generation (generateSessionId). These functions perform cryptographic work and write to the DB. - Front‑end boot –
apps/web/src/main.tsxrenders<App />. The protected route component (ProtectedRouteinApp.tsx) checks authentication viauseAuth(callsfetchApi→ API client). API calls funnel throughapps/web/src/services/api/client.ts, which wrapsfetchApi(called from 44 places). - Utility spread – Helpers like
formatCurrency(called from 4 UI components) andcn(class‑name utility) are widely used but low‑complexity.
No circular imports were detected, and the internal call graph shows 500 resolved call edges. The most frequently invoked functions (getDatabase, fetchApi, badRequest) indicate where stability matters most.
How To Use It
# Clone the repo
git clone https://github.com/moses-y/compasso
cd compasso
# Install all npm dependencies (root and workspaces)
npm install
# Build the shared package (required before dev)
npm run build -w @compasso/shared
# Start both services in development mode (see package.json scripts)
npm run dev
- Configuration – Copy
.env.exampleto.env(orapps/api/.env) and set at leastPORT,ALLOWED_ORIGINS, andDATABASE_PATH. For password‑reset emails, addRESEND_API_KEYandEMAIL_FROMas documented. - Running – Backend listens on
http://localhost:5181; front‑end is served athttp://localhost:5180. The Docker compose file (docker-compose.yml) offers an alternative containerised launch (docker compose up -d).
Real‑World Use
A freelancer runs the app on a personal laptop. After registering, they create a “Consulting” workspace, upload a monthly PDF from Novo Banco, and let the parser auto‑categorise expenses. The dashboard shows a “Recurring” chart that flags a monthly software subscription, prompting the user to set a recurring pattern for future alerts.
Code Health & Issues
- MEDIUM – GITHUB_TOKEN permissions –
.github/workflows/ci.ymllacks explicitpermissions; addcontents: read. - MEDIUM – Dependabot – No dependabot config; add
.github/dependabot.ymlfor npm and GitHub‑Actions. - MEDIUM – Docker base image –
Dockerfileuses mutablenode:20-alpine; pin to a digest. - MEDIUM – Dependency scan – CI does not run a vulnerability review; integrate
dependency-review-actionorosv-scanner. - MEDIUM – Checkout persist‑credentials – Set
persist-credentials: falseon the checkout step. - MEDIUM – Non‑root user – Add a
USERdirective to the Dockerfile. - LOW – Job timeout – Define
timeout-minutesfor each CI job to avoid runaway builds.
Additional observations: 35 test files exist, CI is present, and a LICENSE is included. No secrets were detected in the repo. Several dependencies lag several major versions (e.g., react-dropzone, better-sqlite3), which could affect future compatibility.
The Bottom Line
compasso delivers a complete local finance‑tracking stack with clear separation between API, UI, and shared types. The architecture is sound but hinges on a few high‑traffic hub modules (database.ts, errors.ts, workspaceService.ts); keeping these stable is essential. The project is ready for internal use, though updating out‑of‑date dependencies and tightening CI security would improve maintainability. Suitable for teams that require on‑premise financial data handling with minimal external exposure.