- Replace pdf2pic/GraphicsMagick with pdfjs-dist + @napi-rs/canvas for
Vercel-compatible PDF rasterization
- Replace MinIO with Supabase Storage (S3-compatible); rename minio.ts
to storage.ts and update all imports
- Replace in-memory job queue with Upstash QStash; upload route now
persists files to storage before enqueuing, /api/jobs/process handles
the QStash callback
- Convert email watcher from persistent IMAP connection to stateless
scanInbox() polled by Vercel Cron every 2 minutes
- Add FTP watcher (basic-ftp) with cron polling for scanner integration
via Dreamhost FTP drop directory
- Add FTP config fields to AppSettings schema
- Remove folder watcher (chokidar), standalone output, Docker-only code
- Update next.config.ts, middleware, instrumentation for serverless
- Add vercel.json with cron schedules for email and FTP polling
- Add migration scripts for database (pg_dump/restore) and storage
(S3-to-S3 copy) with verification
Made-with: Cursor
- Add User model synced from Authentik headers with admin/reviewer/viewer roles
- Add assignment fields (assignedToId, assignedById, reviewedById, etc.) to ResponseCard
- Add userId tracking to ActivityLog and Notification models
- Create auth.ts with getOrCreateUser() and role mapping from Authentik groups
- Create /api/users endpoint and /api/cards/assign batch assignment endpoint
- Gate card mutations behind role checks (viewers read-only, reviewers edit assigned only)
- Gate Monday.com push behind reviewStatus=reviewed instead of ocr_complete
- Add "My Cards" stat card, Assigned To filter, and assignment columns to table
- Add Assign button with user picker to batch selection toolbar (admin only)
- Update card detail: assignment banner, Mark Complete button, prev/next nav, reassign
- Make all field components accept readOnly prop for role-based editing
- Gate settings page behind admin role
- Add userId to stats API for per-user card counts
- Expose dbUser and role through UserProfileProvider context
Made-with: Cursor
- Add firstTimeGuestDate and salvationDate (DateTime?) to Prisma schema
- Auto-compute dates during OCR: find previous Sunday from card createdAt
when visitType indicates first/second time guest or nextStep includes
Baptism
- Add editable date inputs on card detail page in Workflow section
- Add to Monday.com mappable fields in settings for column mapping
- Add table columns (hidden by default) for both date fields
- Handle full ISO datetime strings in Monday.com date parser
- Apply same logic during reprocessing
Made-with: Cursor
Card-level reprocessing only re-OCRs existing images. When the old
page count bug caused survey pages to never be extracted, those images
don't exist to reprocess.
New /api/cards/recover-survey endpoint:
- Finds all cards missing frontImagePath (survey side)
- Locates their source PDFs in MinIO via the ProcessingJob
- Re-extracts the correct survey page for each card
- Stores the image and runs OCR to fill in survey data
- Processes sequentially with rate-limit delays
Settings page shows amber banner when missing backs are detected
with a one-click "Recover Missing Backs" button.
Made-with: Cursor
Rate limiting:
- Retry with exponential backoff (5s, 10s, 20s, 40s) on rate limit errors
- Reduce concurrent OCR jobs from 2 to 1
- Add 2s delay between AI calls within a card (response vs survey side)
- Add 3s delay between cards in a multi-page PDF
- Add 3s delay between jobs in the processing queue
Batch reprocess:
- New /api/cards/reprocess-batch endpoint processes cards sequentially
with delays to respect rate limits
- Reprocess button added to selection toolbar on dashboard
Made-with: Cursor
- Add followUp, notes, serviceTime, planningCenter, iSaidYesBookSent,
ftGuestLetterSent fields to ResponseCard to match Monday.com board
- Expand column mapper from 8 fields to all 32 ResponseCard fields with
friendly labels matching the Easter Survey spreadsheet columns
- Add Workflow & Tracking section on card detail page for the new fields
- Fix pre-existing Buffer type error in images API route
Made-with: Cursor
The presigned URLs pointed to a private IP unreachable from the browser.
The image route now streams bytes directly and the card API returns
proxy paths matching the dashboard's existing approach.
Made-with: Cursor
- Bidirectional Monday.com integration with column mapping and file uploads
- Generic webhook system with HMAC-SHA256 signing and configurable events
- Field-level activity log with diff tracking on card detail page
- Persistent notification center with unread badge in header
- Event dispatcher wired into OCR pipeline, card edits, exports, and deletes
- New Prisma models: ActivityLog, Notification; new fields on AppSettings and ResponseCard
- Settings UI with full Monday.com and webhook configuration panels
Made-with: Cursor
The Reprocess button and dropdown item were only visible for cards
with ocrStatus "error". Now they appear for any card that isn't
currently processing, so users can re-run OCR on completed cards too
(e.g. after changing AI settings).
Made-with: Cursor