NextExpense/README.md
cclohmar e20a484ebc chore: rename binary from receiptnext to app
- Binary output changed from 'receiptnext' to 'app'
- Release assets renamed to app-linux-amd64 / app-linux-arm64
- install.sh, Makefile, README.md updated to reference 'app'
- contrib/receiptnext.service uses /opt/receiptnext/app
- Systemd service updated to ExecStart=/opt/receiptnext/app
2026-05-30 15:53:24 +00:00

7.5 KiB

ReceiptNext — AI-Powered Expense Tracker

A production-ready, mobile-first Progressive Web App (PWA) for expense management with passwordless OTP login, AI receipt extraction (Gemini / OpenAI / Ollama), and CSV/PDF email reporting with receipt images.

Tech Stack: Go 1.23+ · HTMX · SQLite (pure Go) · Google Gemini / OpenAI / Ollama · PWA


🚀 One-Command Install

sudo bash -c "$(curl -fsSL https://git.lohmar.co.uk/cclohmar/ReceiptNext/raw/branch/main/install.sh)"

Or from a local clone:

sudo ./install.sh

The installer will:

  1. Clone the repo to /opt/receiptnext/

  2. Build the binary (pure Go, no CGO, no dependencies)

  3. Ask which AI provider to use:

    1) Google Gemini  (cloud API, needs API key)
    2) OpenAI / Compatible  (OpenAI, Perplexity, Groq, etc.)
    3) Ollama  (local — installs Ollama + qwen3.5:2b automatically)
    
  4. Prompt for SMTP settings (for OTP emails and report delivery)

  5. Create /opt/receiptnext/.env with all configuration

  6. Set up a systemd service that auto-starts on boot

  7. Start ReceiptNext

Result: A fully configured, always-running expense tracker at http://YOUR_SERVER:8080.


🔄 Updating

sudo /opt/receiptnext/install.sh -update

This pulls the latest code, rebuilds the binary, and restarts the service.


📦 Binary Download (manual)

Pre-compiled static binaries are on the Releases page:

# Linux amd64
curl -L -o app https://git.lohmar.co.uk/cclohmar/ReceiptNext/releases/download/v1.0.0/app-linux-amd64
chmod +x app
./app

# Linux arm64 (Raspberry Pi, etc.)
curl -L -o app https://git.lohmar.co.uk/cclohmar/ReceiptNext/releases/download/v1.0.0/app-linux-arm64
chmod +x app
./app

No dependencies, no CGO, no libc. Drop it on any Linux box and run.


🔧 Building from Source

Prerequisites

  • Go 1.23+Download
  • No GCC, no CGO, no cross-compilers needed

Build

git clone https://git.lohmar.co.uk/cclohmar/ReceiptNext.git
cd ReceiptNext

# Build for your current platform
CGO_ENABLED=0 go build -o app .

# Cross-compile for any platform (no extra tools needed!)
CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -o app-linux-arm64 .
CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build -o app-darwin-amd64 .
CGO_ENABLED=0 GOOS=darwin GOARCH=arm64 go build -o app-darwin-arm64 .

The binary is fully static — zero runtime dependencies.


⚙️ Configuration

Configuration is via environment variables in .env. The install script builds this for you interactively.

Variable Required Default Description
PORT No 8080 HTTP server port
BASE_URL No http://localhost:8080 Public URL for email links
AI Provider
AI_PROVIDER No gemini gemini, openai, or ollama
GEMINI_API_KEY For Gemini Google Gemini API key
OPENAI_API_KEY For OpenAI OpenAI-compatible API key
AI_MODEL For OpenAI/Ollama gpt-4o-mini / qwen3.5:2b Model name
AI_BASE_URL For OpenAI/Ollama https://api.openai.com/v1 API endpoint
SMTP
SMTP_HOST See note SMTP server hostname
SMTP_PORT See note 587 SMTP server port
SMTP_USER See note SMTP username
SMTP_PASS See note SMTP password

Note: SMTP is optional without it, OTP codes are logged to the server console for testing. Reports cannot be emailed without SMTP.


🚀 Usage

1. Start the Server

# If installed via systemd:
systemctl start receiptnext

# Or run directly:
./app

2. Open in Browser

Navigate to http://YOUR_SERVER:8080

3. Full Acceptance Flow

1. Enter your email → click "Send Verification Code"
2. Check your inbox (or server log) for the 6-digit OTP
3. Enter OTP → click "Verify Code"
4. Click "+ New" → name your event → set claim currency → enter a conversion sample
5. Click "Open" on the event
6. Tap "📷 Camera" or "📁 Upload" to add a receipt
7. AI extracts amount, merchant, category, date → form is pre-filled
8. Click "Save Expense"
9. Click "Submit Event" → enter recipient email → choose CSV or PDF
10. Report + receipt images ZIP are emailed → event auto-closes
11. Click "Reopen" to add more receipts

📡 API Reference

Public

Method Path Description
GET / Landing page
POST /request-otp Request OTP code
POST /verify-otp Verify OTP and create session
POST /logout Clear session

Protected (requires session)

Method Path Description
GET /dashboard Event list
POST /events Create event
GET /events/{id}/expenses View event + expenses
PUT /events/{id}/reopen Reopen closed event
POST /expenses/upload Upload receipt image/PDF
POST /expenses Save expense
GET /expenses/{id}/edit Get edit form
PUT /expenses/{id} Update expense
POST /events/{id}/file File report (CSV/PDF + images ZIP)

🏗️ Project Structure

/opt/receiptnext/
├── receiptnext              # Compiled binary
├── .env                     # Configuration
├── templates/               # Go HTML templates
├── static/                  # CSS, icons, favicon, service worker
│   ├── css/style.css
│   ├── favicon.svg          # Rx logo
│   ├── manifest.json
│   ├── sw.js
│   └── icons/
├── storage/                 # Uploaded receipt images (runtime)
├── install.sh               # Installer script
├── Makefile                 # Build targets
└── contrib/
    └── receiptnext.service  # Systemd service file

🧩 Features

🔐 Passwordless OTP Authentication

  • Email-based 6-digit code, 5-minute expiry
  • 3 failed attempts → 1-minute cooldown
  • HTTP-only session cookie, 24h TTL

🤖 AI Receipt Extraction

  • Google Gemini (default) — cloud vision API
  • OpenAI-compatible — works with OpenAI, Perplexity, Groq, Together AI, etc.
  • Ollama — local, offline, no API key needed (uses qwen3.5:2b)
  • Supports: JPEG, PNG, WebP, HEIC, PDF (email receipts from Uber, etc.)

💱 Currency Conversion

  • Sample-based: enter a real receipt amount and what you were charged
  • System computes the rate automatically
  • Each expense stores original + converted amount

📧 Email Reporting

  • CSV or PDF report
  • Receipt images bundled as ZIP (expense-{event}-images.zip)
  • Filenames: expense-{event}-report.csv, expense-{event}-report.pdf
  • Item numbers match between report rows and ZIP images

📱 Progressive Web App

  • Installable on mobile home screen
  • Camera capture + gallery upload
  • Dark "Terminal Mint" theme (#0F172A base)
  • Rx favicon in emerald green

🗄️ Database

SQLite, auto-created on first run — 4 tables: users, auth_otps, events, expenses.


🔒 Security

Area Implementation
Sessions crypto/rand tokens, in-memory, 24h TTL
OTP crypto/rand codes, 5min expiry, lockout after 3 failures
Cookies HTTP-only, SameSite=Lax, path-restricted
SQL Parameterized queries everywhere
Uploads Magic byte validation, max 10MB, UUID filenames
Config .env file is chmod 600 — readable only by root

Built with Go, HTMX, SQLite and ❤️