No description
Find a file
Randall Stillwell 11773a2ad2 Self-heal stale email verification banner
The banner was wired off session.user.isEmailVerified, which lives on
the JWT cookie. If a user verified their email in another tab or was
auto-verified by the invite flow after an existing session was issued,
the token kept saying unverified until sign-out, so the banner hung
around indefinitely.

- Add GET /api/auth/verify-email/status, a tiny authenticated endpoint
  that returns the authoritative emailVerified state straight from the
  DB.
- Banner now fetches that on mount and only renders if the DB agrees
  the user is unverified. If the DB says verified but the cookie is
  stale, we call useSession().update() to refresh the JWT so the rest
  of the app sees the correct state on the next render.

Made-with: Cursor
2026-04-19 10:53:36 -05:00
prisma Add change password to profile, persist all profile fields to DB 2026-04-17 15:35:24 -05:00
public Add OG/Twitter sharing metadata and screenshot for all marketing pages 2026-04-16 20:34:26 -05:00
scripts Migrate Echo Life Church data, add invite acceptance for existing users 2026-04-17 08:15:31 -05:00
src Self-heal stale email verification banner 2026-04-19 10:53:36 -05:00
.dockerignore Build Echo OCR app: full-stack response card scanner 2026-03-10 07:17:45 -05:00
.env.example Replace hardcoded echoocr.com fallbacks with resolved site URL 2026-04-19 10:12:44 -05:00
.gitignore Migrate to Vercel + Supabase + Upstash production stack 2026-04-15 23:51:44 -05:00
components.json feat: initial commit 2026-03-09 15:31:45 -05:00
docker-compose.yml Build Echo OCR app: full-stack response card scanner 2026-03-10 07:17:45 -05:00
Dockerfile Lower build memory ceiling to 1024MB and clean npm cache in deps layer 2026-04-07 23:14:09 -05:00
eslint.config.mjs Initial commit from Create Next App 2026-03-09 15:31:21 -05:00
next.config.ts Add SFTP support: replace FTP-only TLS toggle with protocol selector 2026-04-17 15:12:54 -05:00
package-lock.json Add SFTP support: replace FTP-only TLS toggle with protocol selector 2026-04-17 15:12:54 -05:00
package.json Add SFTP support: replace FTP-only TLS toggle with protocol selector 2026-04-17 15:12:54 -05:00
postcss.config.mjs Initial commit from Create Next App 2026-03-09 15:31:21 -05:00
prisma.config.ts Build Echo OCR app: full-stack response card scanner 2026-03-10 07:17:45 -05:00
README.md Build Echo OCR app: full-stack response card scanner 2026-03-10 07:17:45 -05:00
start.sh Remove --skip-generate flag from prisma db push 2026-03-10 14:03:20 -05:00
tsconfig.json Initial commit from Create Next App 2026-03-09 15:31:21 -05:00
vercel.json Migrate to Vercel + Supabase + Upstash production stack 2026-04-15 23:51:44 -05:00

Echo OCR

OCR-powered response card scanner and management tool for Echo Life Church.

Scans front/back of paper response cards (PDF or images), extracts structured data using a local Ollama vision model, stores results in PostgreSQL, and serves them through a modern filterable table UI.

Stack

  • Next.js 15 (App Router) + Tailwind CSS v4 + shadcn/ui
  • TanStack Table for data tables with filtering, sorting, pagination
  • Prisma + PostgreSQL for data storage
  • Ollama (local LLM) for OCR via vision models (LLaVA 7B recommended)
  • MinIO (S3-compatible) for PDF/image storage
  • Docker for deployment via Coolify

Local Development

Prerequisites

  • Node.js 18+
  • Docker + Docker Compose (for PostgreSQL + MinIO)
  • Ollama running locally with a vision model (ollama pull llava:7b)
  • GraphicsMagick (brew install graphicsmagick) for PDF-to-image conversion

Setup

# Install dependencies
npm install

# Start local PostgreSQL + MinIO
docker compose up -d postgres minio

# Create MinIO bucket (visit http://localhost:9001, login minioadmin/minioadmin)

# Push database schema
npm run db:push

# Start dev server
npm run dev

Open http://localhost:3000.

Environment Variables

Copy .env.example to .env and configure:

cp .env.example .env

Deployment (Coolify)

See the deployment section in the project plan for step-by-step Coolify setup instructions including PostgreSQL, MinIO bucket creation, Ollama configuration, and Traefik routing.

API Endpoints

Method Path Description
GET /api/cards List cards (filters, pagination, search)
POST /api/cards Create a card
GET /api/cards/[id] Get card with presigned image URLs
PUT /api/cards/[id] Update card fields
DELETE /api/cards/[id] Delete card and images
POST /api/cards/[id]/export Mark card as exported
POST /api/upload Upload PDF/images for OCR
GET /api/jobs List processing jobs
GET /api/stats Card count statistics
GET/PUT /api/settings App settings
POST /api/watch Start/stop folder monitoring
GET /api/images/[...path] Proxy images from MinIO