Paperless: The Invoice Workflow Around the Model
The first version of Paperless was easy to pitch: upload an invoice, let Gemini read it, and put the result in a table. That description is accurate, but it hides the part that made the project worth building.
An invoice is not a document someone wants summarized. It is a record that changes what a business believes it owes. A wrong vendor, total, due date, or line item is not an awkward chatbot response; it is bad data in an accounting workflow.
So the central decision was not to make extraction look automatic. It was to make the extracted result useful without pretending it was authoritative.
The model stops at a draft
Paperless extracts the fields a person would otherwise type: vendor, invoice number, dates, category, line items, and totals. When a value is not present, the workflow leaves it blank rather than filling the gap with a plausible guess.
Every result comes back as a draft. The user reviews it, corrects what is wrong, and approves it before the invoice moves into the rest of the workflow. That extra step is the product boundary. The model can reduce data entry; it does not silently become the bookkeeper.
The dashboard is built around that boundary. Outstanding and overdue amounts, paid invoices, and the approval queue are useful only if a person can tell which records are still provisional. CSV export and filtering are not especially glamorous features, but they make the result easier to inspect outside the app.
Multi-page documents made the pipeline less magical
Multi-page PDFs are split into individual pages, sent through extraction, and merged back into one invoice. That creates more work for the application, especially when line items or totals cross page boundaries. It also gives the system a smaller unit to process and a clearer place to inspect when an extraction is wrong.
This is the kind of tradeoff that disappears in a feature description. “AI reads PDFs” sounds like one operation. In a real workflow, it is a series of decisions about document shape, partial results, merging, and review. The model is only one stage.
Vendor links changed the trust boundary
The most consequential feature was not dark mode or another dashboard number. It was the vendor submission link.
The link lets a vendor upload an invoice without creating an account. That removes friction from the person who has the document, but it also turns a private dashboard into an intake surface exposed to someone else’s browser. The link is token-based, can be toggled off, and can optionally expire. Those controls are not decoration; they are the minimum lifecycle around an unauthenticated upload.
The invoice still has to land in the right account, pass input validation, and remain a draft. Supabase Row Level Security isolates each user’s records at the database layer. The workflow is therefore doing two jobs at once: making it easier to receive a document and refusing to treat receipt as approval.
Demo mode is still a real system
Paperless has a demo path so someone can try the extraction flow without signing up. The demo is deliberately limited, and the API has rate limiting and upload validation around it. That is a small product surface, but it has the same problem as the main one: an anonymous user can supply the input, while the application still has to protect its resources and keep the result understandable.
The lesson was not that every small app needs enterprise machinery. It was that a “demo” is still an operational mode with different identity, abuse, and data-retention assumptions. Naming those assumptions early made the rest of the application easier to reason about.
What the project actually proves
Paperless does not prove that invoice processing can be fully automated. It proves something narrower and more useful: a model can take the repetitive first pass if the surrounding system makes uncertainty visible and gives a person a clear point of control.
The stack is ordinary—Next.js, Supabase for authentication, storage, and database access, Gemini for document extraction, and Tailwind for the interface. The interesting part is the handoff between them. Files become structured data; structured data becomes a draft; a review turns the draft into a record; a tokenized link brings an outside participant into that path without giving them a dashboard.
If I continued the project, I would work on email ingestion and approval workflows before adding more model capability. The unresolved problem is not whether the model can produce more fields. It is how a team decides who is allowed to trust and approve the fields it produces.