Desktop app for collecting invoices for tax declaration preparation.
Deductions helps people in Germany collect invoices and receipts to save money through income tax deductions.
You may know that certain expenses can lower your taxable income, but the supporting documents are often scattered across email inboxes, online shops, PDFs, photos, local folders, and paper receipts.
Does this sound familiar?
- You postpone collecting them until close to the tax deadline.
- You have to remember what was purchased and why it was tax relevant.
- You search for missing invoices and receipts under time pressure.
- Even if a tax consultant files the return, you still have to collect all the documents, which is time-consuming.
- You lose money by missing items or not filing your tax return at all.
The app transforms this task from a late, stressful, memory-based activity into an automated, AI-assisted, money-saving process.
The app is not a full tax declaration assistant. Use one of the existing services for that. Its job is to reduce the manual burden of finding, collecting, classifying, explaining, and exporting invoices relevant to deductions. Simply create a neat handover package for tax consultants or your own tax declaration, and start saving money.
Prerequisites:
- Node.js and npm.
- A local clone of this repository.
Install dependencies:
npm installStart the app in development:
npm startAI-assisted document processing uses a local LM Studio server. Before starting
Deductions, load gemma-4-e4b-it-mlx in LM Studio and start its local server.
With no additional configuration, npm start uses this model at
http://localhost:1234/v1.
To use another model, load that model in LM Studio and override the default for the command you run:
DEDUCTIONS_AI_MODEL_ID=your-model-id npm startRun the standard checks during development:
npm test
npm run lint
npx tsc --noEmitPackage the Electron app locally:
npm run packageRun end-to-end tests:
npm run test:e2eThe end-to-end test command packages the app first through pretest:e2e.
SQLite schema is defined in TypeScript at app/main/data/schema.ts.
Drizzle Kit generates migration files into app/main/data/drizzle.
Generate migrations with:
npm run db:generateThis uses drizzle.config.ts, which points Drizzle Kit at the schema file and migration output folder.
Generated migration artifacts should be committed as-is:
app/main/data/drizzle/*.sqlapp/main/data/drizzle/meta/_journal.jsonapp/main/data/drizzle/meta/*_snapshot.json
Do not hand-edit generated migration files unless a migration genuinely needs custom SQL. If custom SQL is needed, document why in the migration review.
To manually create the initial migration with the current naming convention from an empty migration folder:
npx drizzle-kit generate \
--dialect sqlite \
--schema ./app/main/data/schema.ts \
--out ./app/main/data/drizzle \
--name initial \
--prefix indexAfter generating migrations, run:
npx tsc --noEmit
npm test
npm run lint