No description
  • TypeScript 87.8%
  • PLpgSQL 11.3%
  • JavaScript 0.9%
Find a file
2026-06-23 22:14:27 +02:00
.vscode Initial commit 2026-06-05 21:49:06 +02:00
assets feat: build QuickFIN bookkeeping mockup 2026-06-06 00:10:05 +02:00
scripts Initial commit 2026-06-05 21:49:06 +02:00
src Merge pull request 'Allocate board manual add/change + iOS-style receipt delete button' (#18) from chore/cleanup into main 2026-06-23 22:14:27 +02:00
supabase feat: configurable tax model, per-line Vorsteuer booking, admin tax config 2026-06-23 20:14:32 +02:00
.gitignore chore: stop tracking .claude/settings.json 2026-06-16 15:31:32 +01:00
AGENTS.md Initial commit 2026-06-05 21:49:06 +02:00
app.json feat: receipt booking pipeline, AI grouping, accountant admin board 2026-06-23 01:49:40 +02:00
CLAUDE.md feat: receipt booking pipeline, AI grouping, accountant admin board 2026-06-23 01:49:40 +02:00
eslint.config.js feat: build QuickFIN bookkeeping mockup 2026-06-06 00:10:05 +02:00
LICENSE Initial commit 2026-06-05 21:49:06 +02:00
package-lock.json feat: receipt booking pipeline, AI grouping, accountant admin board 2026-06-23 01:49:40 +02:00
package.json refactor: cloud-only receipt readout, drop on-device tiers 2026-06-23 20:37:21 +02:00
README.md refactor: cloud-only receipt readout, drop on-device tiers 2026-06-23 20:37:21 +02:00
tsconfig.json feat: receipt booking pipeline, AI grouping, accountant admin board 2026-06-23 01:49:40 +02:00

quickfin

A React Native / Expo app for German SMB accounting, backed by Supabase (Postgres + auth). Each user's data is row-level-security-scoped to their account. Scan a receipt, let cloud OCR read it out, and the deterministic booking engine maps each line to an account; bank transactions are reconciled against receipts.

Prerequisites

  • Node.js + npm

  • A dev build for native features (npx expo run:ios / run:android) — the document scanner and Face ID don't run in Expo Go or web.

  • A .env file (gitignored) with your Supabase project credentials:

    EXPO_PUBLIC_SUPABASE_URL=...
    EXPO_PUBLIC_SUPABASE_ANON_KEY=...
    

    src/lib/supabase.ts throws on launch if either is missing.

Get started

npm install
npx expo start          # dev server (Expo Go / dev client)
npx expo run:ios        # build + run on iOS simulator/device
npx expo run:android    # build + run on Android emulator/device
npx expo start --web    # run in the browser

Cloud receipt extraction additionally needs the extract-receipt and assign-groups Supabase Edge Functions deployed (they call Claude server-side with your API key).

Scripts

npx expo lint           # ESLint (eslint-config-expo)
npx tsc --noEmit        # type-check
npm run test:booking    # booking-engine spec tests (tsx harness)

Architecture

quickfin uses Expo Router file-based routing; all source lives under src/ (path alias @/src/).

  • Auth & routingsrc/app/_layout.tsx gates on the Supabase session. New signups go through a 4-step onboarding wizard (onboarding.tsx); the five main tabs (home, transactions, receipts, cashier, account) live in src/app/(tabs)/.
  • Data layer — the Zustand store (src/store/useStore.ts) is a local cache that writes through to Supabase: mutations update local state optimistically, then persist via src/lib/db.ts (the only module that talks to PostgREST). Data slices are also cached to AsyncStorage so the app renders instantly on launch, then refreshes via hydrate().
  • Receipt ↔ transaction linking — an n:m relationship kept in sync locally and in Postgres (receipt_transaction_links). A receipt moves open → reconciled → booked/error.
  • Receipt extraction & booking (src/lib/booking/, src/lib/ocr/) — the document scanner captures the receipt, cloud OCR (Claude vision via a Supabase Edge Function) reads it out, and a deterministic engine harmonizes the read-out against printed totals and maps each line to a category → account. Same input ⇒ same booking; all money is integer cents.
  • Theme & i18n — design tokens in src/theme/tokens.ts (never hard-code colors/spacing); UI locale toggles de/en via useT(), but number/date formatting always stays German.

See CLAUDE.md for the full architecture guide (data flow, the booking pipeline, onboarding, biometric lock, and conventions).

Schema

Postgres schema lives in supabase/migrations/*.sql. supabase/apply_all.sql is a generated concatenation for applying everything to a fresh database in one shot (regenerate it — don't hand-edit).