SlowBooks Pro
Windows·Mac·Linux용 무료 회계 소프트웨어, 급여·재고·무제한 청구·다중 사용자 서버 에디션 포함, 클라우드·구독 없음
아직 감지된 업데이트가 없습니다. GitHub 릴리스가 나오면 여기에 보입니다.
개인 계정의 공개 저장소 소유자는 GitHub로 로그인해 운영자를 확인하고 소개를 직접 관리할 수 있습니다. 관리자 승인은 필요하지 않습니다.
로그인한 뒤 확인 파일을 만들어 이 저장소의 기본 브랜치에 30분 안에 커밋해 주세요. 다른 브랜치나 포크의 파일은 인정하지 않습니다. 파일을 올린 뒤 아래에서 확인하면 관리자 승인 없이 관리할 수 있습니다. 자격을 유지하려면 파일을 남겨 두세요.
로그인이 필요하면 로그인 화면으로 이동합니다. 로그인 후 이곳으로 돌아와 원하는 확인 버튼을 다시 눌러 주세요.
프로젝트 폴더에서 /nomorevibe verify를 실행하면 소유권을 확인하고 소개를 직접 관리할 수 있습니다.
1분 만에 확인하기메이커가 쓴 소개는 위의 한 줄이 전부입니다. 더 자세한 내용은 저장소 README에서 읽을 수 있습니다. 저장소 README ↗
README 전체를 불러오는 중입니다.
README 전문 보기 ↗Split bills. Settle up. Call it quits.
Quits is a free, mobile-first bill-splitting web app for Indian students, built as the course project for Applied Data Science & AI at IISc. It was built with spec-driven development: SPEC.md states what to build, and PLAN.md records how it was built and the evidence for every acceptance criterion.
gemini-3.5-flash-lite).| Part | Choice |
|---|---|
| App | Next.js 16 (App Router, TypeScript), Tailwind CSS 4 with design tokens for both themes, Inter self-hosted via next/font, on Vercel |
| Data | Supabase Postgres. RLS is on for every table with no policies. The database is used only from server code with the secret key, so the browser never talks to Supabase. |
| AI | Gemini structured JSON output (receipts and type-to-add), called only from the server. Receipt images are never stored. |
| Exchange rates | Frankfurter v2 (/v2/rate/{BASE}/{QUOTE}?date=), cached in fx_rates |
| Core logic | Pure, unit-tested modules in lib/: money, splits, simplify, receipt, nlparse, currency, upi, share, csv, recurring, demo-seed, recent-groups, stats, theme, avatar, category-style |
| Writes | Each multi-table write is one Postgres function, so it is atomic. The functions re-check that every id belongs to the group and that payers = splits = total. |
npm install
cp .env.example .env.local # then fill in the values (never commit .env.local)
npm run db:push # applies supabase/migrations to your database
npm run dev # http://localhost:3000
Environment variables (names only):
| Name | Where | Notes |
|---|---|---|
SUPABASE_URL | .env.local, Vercel | |
SUPABASE_SECRET_KEY | .env.local, Vercel | secret |
GEMINI_API_KEY | .env.local, Vercel | secret |
GEMINI_MODEL | .env.local, Vercel | gemini-3.5-flash-lite |
SUPABASE_DB_URL | .env.local only | Session pooler connection string (IPv4), for migrations and DB tests |
SCAN_LIMIT_PER_GROUP, SCAN_LIMIT_PER_APP | optional | daily receipt scans per group (default 30) and AI calls for the whole app (default 300) |
NL_LIMIT_PER_GROUP | optional | daily type-to-add calls per group (default 50) |
APP_URL | GitHub repository variable | used by the daily keep-alive workflow |
Deploy: push to main, and Vercel builds and deploys it. GitHub Actions does two things:
ci.yml runs lint, typecheck and unit tests on every push;keepalive.yml calls /api/health daily so the free Supabase project doesn't pause.npm run lint && npm run typecheck
npm test # unit tests (Vitest): 162 tests
npm run test:db # DB integration tests (24); needs SUPABASE_DB_URL, skipped otherwise
npm run test:db:clean # removes leftover "__test__" groups
npm run build
npm run eval # receipt eval on eval/receipts (see eval/README.md)
npm run eval:nl # type-to-add eval on eval/nl (see eval/nl/README.md)
Both evals call Gemini. Every run is kept, never overwritten, and each run's report says what changed since the previous one and which results are not blind. The results are on the About page.
Receipt eval (eval/REPORT.md): n = 5, small sample (one receipt moves a per-receipt rate by 20 points). Five real receipts with ground truth checked by hand against the paper bills. The main result is run 3:
| Overall | When answered | |
|---|---|---|
| Answer rate (read within 25 s) | 80% (4 of 5) | — |
| Item F1 | 45.2% | 100% |
| Total accuracy | 80% | 100% |
| Reconciliation (items + tax + charges = total ± ₹1) | 80% | 100% |
Run 3 is not blind for r01 and r04: run 2 revealed two prompt gaps there, which were fixed. The low overall F1 comes from one receipt that timed out (all 34 of its items count as missed), not from misreads.
Type-to-add eval (eval/nl/REPORT.md): n = 30, small sample. Twenty sentences were written by Claude and ten by the human, all reviewed by the human; seven are deliberately ambiguous. The main result is run 3:
| Overall | When answered | |
|---|---|---|
| Answer rate (within 20 s) | 80% (24 of 30) | — |
| Amount | 76.7% | 95.8% |
| Exact match | 76.7% | 95.8% |
The 6 unanswered sentences were Gemini "high demand" errors (HTTP 503) or timeouts, not wrong answers.
The eval/synthetic/ run only smoke-tests the script.
Tested on a Samsung phone against the deployed app, 2026-10-16:
| Path | GPay | PhonePe | Paytm |
|---|---|---|---|
upi://pay link from a website ("Pay via UPI app") | blocked: misleading "exceeded bank limit" error at ₹1 | blocked | blocked |
| QR shown on a laptop, scanned by the phone | works: payee and ₹1.00 filled in | — | — |
| QR screenshot scanned from the gallery | works | — | — |
As a result, settle-up is QR-first (SPEC v0.5, D-18). The link is kept only as a best-effort option, labelled "May be blocked by some UPI apps". The 2026-10-19 production check confirmed the QR also scans in the dark theme: on screen, full screen and from the saved image.
58 of 60 acceptance criteria pass, all with evidence in PLAN.md → "AC status": unit and DB tests, headless-browser checks, and live checks on production and on an Android phone. The two failures are Should-level accuracy targets:
| AC | Target | Result (n is small) | Why |
|---|---|---|---|
| AC-25 (Should) | receipt item F1 ≥ 0.80 and reconciliation ≥ 0.70 | F1 0.452, reconciliation 0.80 (run 3, n = 5) | One receipt timed out at 25 s, so all 34 of its items count as missed. When answered: F1 1.00, reconciliation 1.00. |
| AC-52 (Should) | type-to-add amount ≥ 95% and exact match ≥ 80% | 76.7% and 76.7% (run 3, n = 30) | Six sentences got no answer (Gemini 503 or timeouts). When answered: amount and exact match 95.8%. |
Both are reported as measured. Fixes driven by the evals are labelled in the reports, and the next run is marked not blind:
Nothing was tuned just to raise a score.
| File | What it is |
|---|---|
| SPEC.md | The specification, v1.7: goals and users, constraints, data model and interfaces, 73 requirements in EARS form (49 Must, 24 Should), 60 pass/fail acceptance criteria, deliverables, non-goals, risks, decisions D-1 to D-41, and a changelog from v0.1 to v1.7. When the code and the spec disagreed, the spec was changed first and logged. |
| PLAN.md | The build plan: phases 1–12 with tasks mapped to requirements and ACs (AUTO / HUMAN), the build log, SPEC change proposals, and the AC status table, with evidence for every criterion. |
| eval/README.md, eval/nl/README.md | How the two evaluations work, their ground-truth rules, and every kept run (REPORT*.md, results*.json). |
AGENTS.md, .claude/settings.json | Instructions and settings for the coding agent (Claude Code). |