Deep-dive case study
Turn a pile of tax PDFs into a reviewable preparation workspace.
Tax preparation starts long before a filing screen. This workspace turns uploaded paperwork and earlier returns into a clear working record: what each document is, which values it appears to contain, and what a reviewer still needs to check.
It keeps the irreversible step with a person. The software prepares, separates, compares, and surfaces gaps so the human handling the filing can move faster with better context.
At a glance
A preparation desk, not an auto-filing machine.
16
serverless route modules
Small hosted backend routes support the dashboard workflow, each with a bounded job.
9
years of return history
Historical folders cover 2017 through 2025, giving the workflow a useful starting point for comparison.
4 / 15 MB
document upload ceilings
Individual source documents stop at 4 MB; a complete imported return can be up to 15 MB.
300 sec.
maximum dashboard run time
The serverless dashboard is configured to allow up to 300 seconds for a request to finish.
The problem
The information is there, but it is buried in documents.
A tax-preparation process may begin with statements, notices, accounting reports, and a long PDF from an earlier filing. Before anyone can make a sound decision, someone has to identify each document, collect the values that matter, and understand how the old return was assembled.
That is repetitive work, but it is not trivial work. A reviewer needs enough context to question a value, correct it, and see what it affects without treating an AI response as the final word.
This project organizes the preparation layer. It does not replace tax judgment or submit a return.
What this changes for the person preparing the filing
Instead of reading every PDF from the beginning each time, the reviewer gets a structured starting point: documents grouped by purpose, working facts to inspect, and a list of areas that appear incomplete.
How it works
A path from raw PDFs to a focused review queue.
The dashboard uses serverless routes to keep each stage bounded and inspectable. The sequence below is the primary dashboard workflow.
A statement, form, or a whole prior-year return goes in.
The system works out what the document is and which year it belongs to.
A bundled return is cut into its individual forms by page range.
Each form is read on its own, so values are pulled from a small document.
Every value carries a confidence score and waits for a person.
Last year's filing is checked against this year's paperwork.
Blank official forms are fetched and attached to what is needed.
The walkthrough
Five moments that make a document set usable.
Bring in this year's paperwork
A person uploads a source document. The dashboard identifies its kind, category, likely year, and a short summary before asking AI to pull out visible facts.
Each individual source-document upload is capped at 4 MB. The original bytes are held with the dashboard document record while processing finishes.
Hold facts for review
Each extracted value is stored with a label, source snippet, confidence score, and review state. A reviewer can confirm, dismiss, or edit the value before using it as working information.
Facts start as pending_review. The other available states are confirmed and dismissed; an edited value is also marked as overridden.
Unbundle an earlier return
A complete historical PDF is uploaded with a year, a personal or business label, and an entity label. AI identifies where the individual forms start and end.
Imported return files are capped at 15 MB. The child form records point to their parent return instead of copying the original PDF again.
Read one form at a time
The system makes a smaller in-memory PDF for each identified page range, then extracts facts from that one form. This keeps the review unit understandable instead of treating a long return as one document.
Page-level extraction retries up to three times, with 0-, 3-, and 10-second waits. A completed parent is processed; a return with failed children is partial.
Compare the old filing with current paperwork
The workspace looks at the forms in one selected earlier return alongside current source-document facts. It then describes each likely filing as ready, partial, missing, or not applicable.
This is a document-readiness aid, not a tax calculation, rules engine, or filing decision. It can also suggest an additional filing for review.
The practical payoff
The work moves from an unstructured reading task toward a repeatable review process. Each stage leaves the next person something concrete to inspect rather than an undocumented AI conclusion.
Review extracted values
Let the reviewer see the values before they become working information.
Facts carry their own review state and model-provided confidence score. That makes the system useful as a prioritization tool without pretending that a score settles the question.
The record can be manually confirmed, dismissed, or edited. A separate AI review pass is also available, but it is still another source of suggested changes rather than an accuracy guarantee.
Confidence is visible, not a verdict
A model-provided confidence score gives the reviewer a reason to look closely. It does not prove a value is right, and no minimum score automatically blocks a fact.
A second pass can challenge the first
The dashboard can request a separate AI review pass that compares the existing facts with the document and may propose corrections or new facts.
People can change the record
A reviewer can confirm, dismiss, or edit individual facts. An edit marks the fact as overridden so the working record shows that it changed.
Bulk confirmation stays honest
Confirm All is a bulk state change. It marks every non-dismissed fact for one document as confirmed; it does not validate values against the PDF or enforce a confidence threshold.
The fact record and the important limit of Confirm Allshow
A dashboard fact includes a document ID, flexible field key, label, JSON value, value type, optional subject, confidence, source snippet, extraction or review source, review status, overridden flag, and timestamps. Unlike the local draft engine, dashboard field keys are open-ended rather than one closed list of types.
Confirm All changes every non-dismissed fact on one document to confirmed. If none remains pending, it marks that document review as confirmed. It does not compare values back to the file and it does not apply a confidence threshold, so it is not a validation step.
Separate a bundled earlier return
Make a long PDF understandable one form at a time.
Historical returns often arrive as one file. The workspace asks AI to identify every form boundary, then creates a child record that points to the matching page range inside the imported return.
Each child form is extracted from a newly copied in-memory PDF. That lets the reviewer work with a clear form-sized unit while retaining the link back to its place in the parent return.
The exact page-range behaviorshow
Return splitting requires the model to assign every page to a section. For a child document, pdf-lib copies the inclusive saved range, converting the one-indexed range to the zero-indexed indexes the library expects, then sends that mini-PDF to AI for extraction.
Facts are attributable to the child document and its stored page range, not to a precise page number. The dashboard fact table does not include a per-fact page-number field. Also, a child-document download returns the full parent PDF, not the child-only range.
What the current filing still needs
Compare current paperwork with the shape of an earlier filing.
The required-filings analysis considers the child forms in a selected earlier return, top-level facts from current source documents, and selected prior-year summary facts. It gives each candidate a readiness state: ready, partial, missing, or not applicable.
The result is a preparation checklist for human judgment. It is not a statement that a filing is required, complete, or correct.
ready
The available working facts appear to support the candidate filing.
partial
Some relevant paperwork or values appear to be present, but not all.
missing
The analysis found a candidate filing without the supporting current paperwork it expected.
not_applicable
The candidate does not appear applicable from the facts included in that analysis.
How filing readiness is produced, and where it is limitedshow
The dashboard sends bounded prior-return fields and current source-document facts to a text-only OpenAI call, then persists the returned statuses in required_filings. It may also suggest new filings. Context is truncated to limit prompt size.
Although the API allows a selected return ID, the dashboard client does not provide one and the server defaults to the first matching full prior return. Filing rows are deleted and recreated by tax year, without an entity identifier. This is partial multi-entity support, not safe independent filing management for multiple entities.
Accounting reports: a deliberately narrow assist
Treat a report as supporting evidence, not as a live feed.
Business preparation can include accounting reports alongside tax documents. The local draft engine accepts uploaded profit-and-loss reports, balance sheets, and .qbo files read as text, then recognizes those uploads as business documents.
Its extraction is intentionally small: gross receipts, net income, cash, and retained earnings. These are working facts for review, not a synchronization of a bookkeeping system.
What the local extractor recognizes
Profit-and-loss report
Recognized as a business document; may yield gross receipts and net income.
Balance sheet
Recognized as a business document; may yield cash and retained earnings.
.qbo file
Accepted as UTF-8 text by the local extractor, without a dedicated QBO or OFX parser.
Human correction
The reviewer can add context and correct the working values before any filing work continues.
The practical boundary
Upload reports when they help the person preparing the return. Do not assume that the workspace is connected to a bookkeeping platform or that it can reconcile report values against another system.
Built-in operating limits
Make the work bounded before asking a reviewer to trust it.
The constraints below make the dashboard behavior easier to understand. They are engineering limits, not promises about the quality of tax advice or the completeness of a filing.
4 MB
Source-document limit
Standalone uploads have a clear ceiling before classification and extraction begin.
15 MB
Historical-return limit
A full prior return can be imported only within this file-size ceiling.
10 MB
Fetched-template limit
The template fetcher rejects a PDF-like file larger than this cap.
0 / 3 / 10
Retry waits in seconds
Only child-form page extraction retries, for at most three attempts in total.
What was done by hand, not by software
Keep the high-stakes step human-led.
Two parts were deliberately human-and-AI-in-the-loop. First, a person brought accounting-report data into the preparation work and corrected it where needed. Second, a person navigated a commercial tax-filing product to actually file.
That is a considered judgment, not a missing feature. Filing taxes is irreversible and high-stakes, so the software should make the person fast and well-prepared rather than take the driver's seat.
Accounting reports
Useful input, brought in with judgment.
The local engine accepts uploaded profit-and-loss reports, balance sheets, and .qbo files read as text. It recognizes them as business documents and pattern-extracts only gross receipts, net income, cash, and retained earnings.
Commercial filing product
The person makes and submits the filing.
No code in this project submits an e-filed return to a tax authority or provider. The workspace stops at preparation and review, leaving the final navigation and filing action with the human operator.
How the pieces fit together
One dashboard story, with an earlier local draft engine beside it.
The repository shows an evolving codebase. The dashboard is the primary story here because the React UI calls its serverless routes; a separate local engine remains useful technical context.
Vercel serverless dashboard + Neon Postgres
Document workspace
Keeps an upload, its classification, processing status, review information, and extracted facts together for a reviewer.
OpenAI Responses API
AI reading tasks
Uses different prompts for classification, extraction, review, historical-return splitting, and filing-readiness analysis.
pdf-lib 1.17
Page-range handling
Creates a smaller PDF for each historical child form so the form can be read separately from its parent return.
12 maintained source URLs
Template collection
Can fetch a PDF that looks like a form template and attach it to a matching filing for reference.
Express 4 + SQLite + Poppler
Earlier local draft engine
Separately supports local document handling, deterministic text extraction, draft calculations, and worksheets.
TypeScript 5.8 + React 19 + Vite 6
Typed user interface
Presents the dashboard workflow as a single place to upload, inspect, split, review, and compare documents.
Two overlapping implementations are checked inshow
The repository contains two partially overlapping systems rather than one unified runtime. The primary dashboard path uses Vercel serverless handlers, Neon Postgres, PDF bytes stored in Postgres, and direct OpenAI Responses API calls. The React dashboard calls these routes. It uses gpt-4o by default for source classification and extraction, gpt-5-mini for review, and gpt-4o-mini for return splitting and filing-readiness analysis.
A separate local Express and SQLite draft engine encrypts raw local document blobs with AES-256-GCM, runs deterministic extraction through Poppler tooling, has 24 deterministic fact types, and includes a hard-coded 2025 calculator. It also has 18 hard-coded document requirements and a static registry with 9 official-form entries. Those local capabilities should not be attributed to the deployed dashboard as though they were one implementation.
Boundaries that matter
Useful preparation work needs clear limits.
Tax judgment remains a human responsibility
The workspace organizes documents and highlights what appears to be missing. It does not establish that a return is complete, correct, current, or suitable for filing.
Forms are collected, not completed
The dashboard can download PDF-like form templates from mapped or user-provided HTTPS URLs, but it does not fill them. The roadmap marks true form filling as not started.
A single-operator internal tool
This was an internal workspace, not a multi-tenant product. The reviewed routes show no application-level authentication or authorization checks, so the deployed dashboard should not be described as access-controlled.
Third-party AI processing is part of the workflow
The dashboard sends uploaded PDF bytes to the OpenAI Responses API for document reading. That fact matters whenever sensitive documents are considered.
A practical rule for sensitive work
Use the workspace to prepare a better human review, not to hide uncertainty. When the consequence is a filing, a person should have enough evidence and control to decide what happens next.
Storage and template limits, stated preciselyshow
On the dashboard path, raw uploaded PDF bytes are stored in a Neon Postgres BYTEA column; child forms reference their parent bytes. The reviewed code has no application-level authentication or authorization, and no application-level dashboard encryption was found. The local engine encrypts only its original raw document blob, not its SQLite database or generated local artifacts.
The template fetcher follows mapped URLs from 12 sources on IRS, Maryland, and Texas domains or a user-provided HTTPS URL. It accepts a PDF-like response up to 10 MB, but it does not inspect contents to prove a template is blank, official, current, or the right revision. It is a downloader, not a form parser, filler, or filing mechanism.
What this means for the work
Preparation gets structure. The final decision stays visible.
- A legible queue of documents, extracted working facts, and review states instead of scattered PDFs.
- A way to turn one bundled earlier return into the forms that made it up, with each form tied to its page range.
- A focused view of filings that the current paperwork appears to support, partially support, or still leave missing.
- A human-driven path for high-stakes judgment and filing, with the software doing the preparation work around it.
This case study describes a neutral tax-preparation workspace for personal and business returns. All interface illustrations use placeholder data and do not represent a real taxpayer, business, employer, institution, or amount.
Plain-language glossary
Every technical term used on this page, explained without jargon.
- AES-256-GCM
- A strong encryption method used for local raw document blobs in the separate draft engine.
- Confidence score
- A model-provided estimate that helps prioritize human review, not a proof of correctness.
- Fact
- One normalized value extracted from a document, such as a labeled field and its working value.
- Neon Postgres
- The hosted PostgreSQL database used by the deployed dashboard implementation.
- OpenAI Responses API
- The AI service the dashboard calls to classify, extract, review, split, and compare documents.
- Page range
- The inclusive span of pages within an imported full return that belongs to one identified form.
- pdf-lib
- A JavaScript PDF library used here to copy a child form page range into a smaller temporary PDF.
- pending_review
- The initial dashboard fact state, meaning a fact awaits review or another explicit state change.
- Serverless route
- A small hosted backend endpoint that runs for a request rather than as a continually running server.
- Template
- A downloaded PDF-like form reference; collection does not prove it is blank, current, official, or correct.
- Vercel
- The hosting platform used for the dashboard serverless routes and their configured maximum duration.
Build the preparation layer first
Need a human-led workflow that makes complex documents easier to act on?
AK Internet Consulting designs reviewable AI-assisted systems that help people prepare high-stakes work without taking the decision away from them.