trackit / backend /README.md
devZenaight's picture
npm run dev
479f206
|
Raw
History Blame Contribute Delete
3.44 kB

Slip Scanner Backend (FastAPI)

FastAPI service exposing a /scan endpoint to process receipt images:

  • Validates Supabase user via Authorization: Bearer
  • Detects edges and crops the receipt (OpenCV, perspective transform)
  • Performs OCR via Hugging Face Inference API (TrOCR)
  • Uploads the cropped image to Supabase Storage
  • Inserts a row into the slips table with extracted metadata

Prerequisites

  • Python 3.11+
  • Supabase project with Storage and Postgres
  • Hugging Face account and API token

Environment Variables

Create a .env file in backend/ with:

SUPABASE_URL=... SUPABASE_ANON_KEY=... SUPABASE_SERVICE_ROLE_KEY=... SUPABASE_STORAGE_BUCKET=slips

HUGGINGFACE_API_TOKEN=... HF_OCR_MODEL=microsoft/trocr-base-printed

FRONTEND_CORS_ORIGIN=http://localhost:3000

Notes:

  • Use the Service Role key server-side only. Never expose it to the frontend.
  • If you prefer signed URLs, adjust upload_bytes_to_supabase_storage accordingly and do not make the bucket public.

Install & Run (Windows PowerShell)

cd backend python -m venv .venv . .venv\Scripts\Activate.ps1 pip install -r requirements.txt uvicorn backend.main:app --reload --host 0.0.0.0 --port 8000

API

Health

GET http://localhost:8000/health

Scan

POST http://localhost:8000/scan Authorization: Bearer Content-Type: multipart/form-data file=@/path/to/receipt.jpg

cURL example:

curl -X POST http://localhost:8000/scan
-H "Authorization: Bearer $SUPABASE_JWT"
-F "file=@receipt.jpg"

Response: { "ok": true, "slip": { "id": "...", "user_id": "...", "image_url": "https://...", "amount": 250.0, "category": "Food", "raw_text": "...", "created_at": "2025-09-15T10:00:00Z", "crop_confidence": 0.8 } }

Supabase Setup

Storage Bucket (public or signed)

  • Create bucket slips.
  • For public previews, enable public read on the bucket or a specific folder per user. Alternatively, keep private and generate signed URLs server-side.

Table

Create table slips (adjust types as desired):

create table if not exists public.slips ( id uuid primary key default gen_random_uuid(), user_id uuid not null, image_path text not null, image_url text, raw_text text, amount numeric, category text, crop_confidence real, created_at timestamptz not null default now() );

alter table public.slips enable row level security;

RLS policies (only owner reads/writes their slips):

create policy "slips select own" on public.slips for select using (auth.uid() = user_id);

create policy "slips insert own" on public.slips for insert with check (auth.uid() = user_id);

create policy "slips update own" on public.slips for update using (auth.uid() = user_id);

Frontend Config

In Next.js .env.local:

NEXT_PUBLIC_API_URL=http://localhost:8000 NEXT_PUBLIC_SUPABASE_URL=... NEXT_PUBLIC_SUPABASE_ANON_KEY=...

From the client, include the Supabase session JWT as the Authorization header when calling /scan.

Design Notes (rules.md alignment)

  • Mobile-first UX is handled in the Next.js app; backend is stateless and fast.
  • No sensitive keys in frontend; backend uses Service Role for Storage/DB.
  • Performance: edge detection and OCR happen server-side; images are resized and optimized.
  • Security: RLS ensures users only see their own slips; Storage access can be scoped.

Dev Tips