Checks whether an exporter's commercial invoice and packing list actually agree — quantity, unit, HS code, invoice number, date, and product description — before the shipment gets filed with customs. Built for Indian exporters across any commodity — garments, agri produce, seafood, textiles, spices, and beyond — where a small export office fills out a dozen documents by hand per shipment and a typo (invoice says 480 units, packing list says 475) can hold a container at port. The extraction and comparison logic doesn't assume any one product category; the six sample shipments bundled with this repo span garments, coffee, seafood, textiles, rice, and spices to prove it.
ClearFile never files anything and never auto-corrects a document. It flags disagreements for a person to review, remembers how each exporter phrases things so it gets faster over time, and screens the shipper name against the US forced-labor entity watchlist — all in one photo-in, verdict-out flow that works from a phone.
- Document capture — photograph or upload a commercial invoice and packing list. Google Cloud Vision reads photos; PDFs are read directly from their text layer. A blurry or blank capture is rejected on the spot instead of failing later.
- Field extraction — DeepSeek pulls the seven fields that matter (quantity, unit, HS code, invoice number, date, description, shipper) out of the raw text.
- Comparison — numbers and codes are compared exactly in code (with unit-of-measure synonyms normalized, e.g. "PCS" = "units"); the product description is compared for meaning, not exact wording, via an LLM call.
- Per-exporter memory — every wording judgment and field pattern is stored per exporter in Supabase, so the second shipment from the same exporter resolves faster and more consistently than the first. A human correction permanently overrides the model's judgment.
- Compliance screening — the shipper name is checked against the US DHS UFLPA Entity List (forced-labor watchlist, ~186 entities, via OpenSanctions' public mirror) using name-similarity matching. Always "needs review," never an automatic block.
- Audit trail — every checked shipment exports as a PDF with the full field-by-field comparison and compliance result, for the exporter's own records.
- Session history — the Compare tab keeps every shipment checked this session as a revisitable card, not just the last one.
- Admin view — a read-only, no-login dashboard of flag rates and the most common reasons for a flag, across every exporter.
Every live dependency (Vision OCR, embeddings) degrades to a local, dependency-free fallback if its API is unavailable — the Learning Log and comparison logic still work with zero network access beyond the two required LLM calls.
- Run it (see Running it below) and open the app. You'll land on the check screen with two document slots: Invoice and Packing List.
- Add both documents, either slot first:
- Camera opens your device camera to photograph a physical document.
- Upload accepts a PDF or image already on your device.
- Each document is validated the moment it's added — an unreadable or mostly-blank capture is rejected immediately with a message telling you to retake it, instead of silently passing through and failing later.
- No documents on hand? Click "Load sample shipment" at the bottom to instantly load a working example (Meridian Apparel Exports, #8471) and see the full flow without uploading anything. The
public/*-invoice.pdf/public/*-packing-list.pdffiles bundled in this repo are six more real, filled-in Indian-exporter shipment pairs you can upload yourself through the actual capture flow — see Sample documents below for what each one demonstrates. - Click "Check documents." ClearFile extracts every field from both documents and compares them field by field — this reuses the extraction already done during validation, so nothing is read twice.
- Read the result. Matching fields are shown plainly; disagreeing or unclear fields are flagged with a plain-language reason ("Quantity doesn't match: invoice says 620 PCS, packing list says 600 PCS"). Nothing is auto-corrected — you decide what's actually wrong.
- Correct a flag if the model got it wrong. Marking a flagged field as actually-fine teaches ClearFile that exporter's phrasing permanently, so the same non-issue won't get flagged again on their next shipment.
- Export the audit PDF from the result screen for the exporter's own paper trail — full field comparison plus the compliance screening result, ready to file alongside the shipment.
- Revisit past checks any time from the Compare tab — every shipment checked this session appears as a card; click one to see its full detail view again.
- Check overall patterns from the Admin tab — a read-only dashboard of flag rates and the most common flag reasons across every exporter checked so far. Settings shows which live services (Vision OCR, DeepSeek, Supabase, embeddings) are actually connected versus running on local fallback.
Six ready-to-use invoice/packing-list pairs live in public/, each a real Indian exporter shipment. Five deliberately carry one mismatch each so you can see every kind of flag; the sixth is fully clean:
| Shipment | Exporter | What's wrong |
|---|---|---|
meridian-apparel-* |
Meridian Apparel Exports (Tirupur, TN) | Quantity mismatch — 620 PCS vs 600 PCS |
coorg-estates-coffee-* |
Coorg Estates Coffee Exports (Madikeri, KA) | HS code mismatch — 0901.11 vs 0901.21 |
godavari-marine-* |
Godavari Marine Exports Pvt Ltd (Kakinada, AP) | Date mismatch |
sarvodaya-textile-* |
Sarvodaya Textile Mills (Surat, GJ) | Unit mismatch — ROLLS vs CARTONS |
amrit-basmati-* |
Amrit Basmati Exports (Karnal, HR) | Invoice number mismatch (transposed digits) |
malabar-spice-* |
Malabar Spice Traders (Kochi, KL) | Clean — every field agrees |
Upload any pair through the real Camera/Upload flow to see ClearFile catch it live.
npm install
npm run devOpen http://localhost:3000. Without any environment variables set, ClearFile still runs — every live dependency degrades to a local fallback, so you can go through the whole flow (including the sample documents above) with zero setup.
Copy .env.example to .env.local and fill in what you have:
| Variable | Enables | Without it |
|---|---|---|
DEEPSEEK_API_KEY |
Field extraction and description-matching | Required. There's no local fallback for this one — without it, every field comes back unreadable and documents get rejected at validation regardless of quality. |
GOOGLE_CLOUD_VISION_API_KEY |
Vision OCR for photographed documents | Optional. Falls back to an offline Tesseract OCR bundled in the repo. PDFs are unaffected either way (read from their text layer directly). |
SUPABASE_URL / SUPABASE_SERVICE_ROLE_KEY |
Per-exporter Learning Log, admin dashboard | Optional. App works stateless — no history, no memory. |
AI_GATEWAY_API_KEY |
Real embeddings for near-duplicate description matching | Optional. Falls back to a local, dependency-free hash embedding. |
lib/supabase/schema.sql has the full schema if you want to stand up your own Supabase project.
The repo includes a render.yaml blueprint, so Render can pick up the build/start commands automatically:
- Push this repo to GitHub (already done if you're reading this from there).
- In the Render dashboard, click New → Blueprint and point it at this repo. Render reads
render.yamland creates a Node web service withnpm install && npm run buildas the build command andnpm run startas the start command. - Fill in whichever environment variables you have under the service's Environment tab — all of them are optional (see the table above); the app runs on local fallbacks for whatever's missing.
- Deploy. Render assigns the port itself via
PORT, whichnext startreads automatically — no extra config needed.
No persistent disk is required — the only stateful pieces are Supabase (external) and per-browser localStorage (client-side).
Next.js 16 (App Router, Turbopack) · TypeScript · Tailwind v4 · Supabase (Postgres + pgvector) · DeepSeek · Google Cloud Vision (with a Tesseract.js/WASM offline fallback) · Vercel AI Gateway embeddings (with a local fallback) · jsPDF for audit exports.