← Back to projects

Personal Document Archive

A private "digital filing cabinet" for personal documents — scan a bill with your phone, let AI suggest what it is, review and archive it, then search and retrieve anything in seconds. Full pipeline: OCR, auto-crop/deskew, AI-powered metadata extraction, full-text search, and reminders.

PythonFastAPISQLAlchemyPostgreSQLRedisMinIOTesseract OCRReactViteTypeScriptTailwind CSSOpenRouterAlembicarqDocker

Every household accumulates the same paper trail: electricity bills, insurance contracts, bank statements, tax letters, receipts that matter for three years then matter again at tax time. The problem was never having the documents — it was finding them later.

Personal Document Archive is a self-hosted web application that replaces a shoebox of paper with a searchable, AI-assisted digital archive. The core loop is simple: take a photo of a document (or upload a file), the system runs OCR, an AI suggests what it is — type, sender, amount, due date, tags — and you review, correct, and archive. Later, you search by any dimension: full-text over the scanned text, by category, sender, date range, or payment status.

The upload experience is designed around the phone camera as the primary input. A multi-page staging area lets you photograph pages one at a time (or pick from your gallery) and submit them as a single document. Uploaded images are automatically edge-detected, deskewed, and contrast-enhanced — a proper document-scanner pipeline — with the original always kept untouched alongside the cleaned version. A combined clean PDF is generated automatically for image-only documents.

OCR runs in the background. Tesseract handles image pages (running against the cleaned-up version when available), and embedded text layers are extracted from PDFs. A background worker powered by arq and Redis processes documents asynchronously, so uploads stay fast regardless of processing time.

AI analysis happens via OpenRouter, with every provider and model abstracted behind an interface that makes swapping to local inference (Ollama) or another provider a config change, not a code change. The AI suggests document type, category, sender, dates, amount with currency, tags, and payment status — but every suggestion is shown to the user for review before it's trusted. Fields that have been confirmed or edited by the user are never silently overwritten by a later AI run. Low-confidence suggestions are visually flagged.

The archive supports real search, not just metadata browsing. Full-text search runs over filenames, sender names, tags, categories, and the full OCR-extracted text of every document. Filtering can be combined across category, tag, sender, document type, payment status, and date range. Results can be grouped by category, sender, month, or document type.

Reminders attach to any document — set a due date for a bill, get a reminder four days before it's due, and mark it done once paid. A global reminders view surfaces everything upcoming across all documents, with overdue items highlighted.

System health is visible at a glance. A dedicated status page checks whether the database, Redis, background worker, object storage, and AI provider are all reachable and configured — essential when several moving parts are involved.

Duplicate detection catches exact byte-for-byte re-uploads at upload time using per-page SHA-256 hashing, surfacing a warning when a document is identical to one already in the archive.

The entire system is designed around a layered architecture with clean abstraction boundaries: storage, OCR, imaging, and AI analysis are all behind abstract interfaces, wired via configuration. This means the stack is deployment-agnostic — containerizable, configurable via environment variables, and ready for self-hosting without lock-in to any particular cloud provider.

All six originally-planned development phases are complete, plus post-MVP improvements including auto-crop/deskew, manual crop correction, duplicate detection, and a system health dashboard.