Part 5 of 7 · Tax doc collector series ~5 min read

How a finished file reaches the preparer

The Patel file just went complete — all four documents received. The preparer gets a ping: “Patel file is ready for review.” There’s a link to the status board. What happens when they open it? The honest answer is “it depends on what the documents actually are.” This post walks through the three things the preparer can do on a complete file — accept, reject one item, reopen — and how the file, the chase state, and the audit trail all stay in sync.

Key takeaways

  • Three actions per review: accept (file to done), reject one item (fresh request for just that item), reopen (add a forgotten item back).
  • Each action updates the file via the Sheets API and writes an audit row.
  • A rejected item drops back to waiting and the client gets a request for that one document only.
  • Nothing is marked final until a human has looked at every document.
  • The status board and its action buttons are backed by Function URLs.

Three actions on review

Three actions on a complete file A diagram showing one input on the left flowing through a status board, then branching into three action paths. Far left: a "Complete file on the board" box showing a typical review view — client name, the checklist with every item received, a thumbnail per uploaded document — with three button placeholders below: Accept, Reject item, Reopen. The preparer taps one button per item or for the whole file. The middle column shows the three branches. Branch one, Accept: confirms each received document is the right one; on confirm, a Function URL Lambda marks every item accepted, sets the file status to done via the Sheets API, stops all chasing, and writes a done event to the audit trail. Branch two, Reject item: the preparer picks one document that's wrong — a blurry photo, last year's W-2, the wrong account — adds a short note, and saves; the Function URL Lambda drops that one item back to waiting, sends the client a fresh request for just that document with the note, and leaves the rest of the file untouched. Branch three, Reopen: the preparer realizes the checklist was missing something — the client mentioned a new rental — and adds an item back; the file leaves done and re-enters the chase cadence for the new item only. The right side shows the convergence: every action writes a row to the td-audit DynamoDB table with timestamp, client id, action, by-user, and a before-and-after snapshot. A note at the bottom: nothing is marked final until a human has looked at every document — the collector only ever proposed the match. Complete file checklist, thumbnails [Accept] [Reject item] [Reopen] Action 1 Accept • Confirm each document is the right one • Sheets API sets file done • All chasing stops Action 2 Reject item • Pick the wrong document, add a short note • Item drops to waiting; fresh request for it only Action 3 Reopen • Add a forgotten item back to the checklist • File leaves done, chases the new item Audit trail DynamoDB td-audit timestamp · client_id action · by-user before / after Nothing is marked final until a human has looked at every document — the collector only proposed.
Fig 5. Three actions per review, three different effects. Accept moves the file to done. Reject one item sends the client a fresh request for just that document. Reopen adds a forgotten item back. Every action writes to the audit trail.

Action 1: accept (the most common)

The preparer opens the Patel file on the status board. They see the four checklist items, each marked received, pending review, with a thumbnail and a one-line note from the collector (“looks like a W-2”). They glance at each — the W-2 is the W-2, the mortgage statement is the right year, the childcare receipt has the provider’s name on it, the refund letter is the state one. They tap Accept all.

The tap submits to a Function URL Lambda. Two things happen, in order. First, the Sheets API updates the row: every item moves from received to accepted, and the file status becomes done, with today’s date and the reviewing user in the reviewed_by column. Second, an action: accepted row is written to td-audit with the user, timestamp, and the file snapshot. From this point the tracker treats the file as done — no more chasing, no more reminders. The preparer can now start the return with every document in one place.

Action 2: reject one item (the targeted re-ask)

Sometimes a document is the right kind but the wrong one. The W-2 is from last year. The mortgage statement is for the wrong property. The receipt is a blurry photo with the amount cut off. The collector correctly recognized the kind of document, but only a human can tell it’s not the one needed for this return.

The preparer taps Reject on that one item, picks a reason from a short list or types a note (“this is your 2024 W-2, we need 2025”), and saves. The Function URL Lambda drops just that item back to waiting, leaves every other accepted item alone, and sends the client a fresh request — but only for the one document, with the preparer’s note included so the client knows exactly what was wrong. The file leaves done and re-enters the chase cadence for that single item; when the client re-uploads, it goes through the Part 3 check flow again and comes back for review. The rest of the file never moves.

This is the action that makes the whole system honest. Without it, “complete” would mean “the client sent four files,” not “the preparer has four usable documents.” Reject-one-item keeps the gap between those two small and closes it with a request the client can actually act on.

Action 3: reopen (the forgotten item)

Sometimes the checklist itself was wrong. The client mentioned on a call that they bought a rental property in November — which means they now owe a closing statement nobody added to the checklist. The file went complete against a checklist that was missing an item.

Reopen lets the preparer add an item back. They pick from the rules-doc list of document types (or type a custom one), and save. The Function URL Lambda adds the item in waiting, sets the file status back from done to collecting, and the file re-enters the chase cadence — but only for the new item. The client gets a request for that one document. Everything already accepted stays accepted. Reopen is the escape hatch for “we asked for the wrong list” that doesn’t force the preparer to start the file over.

Every action is logged, every action is reversible

The td-audit table records every accept, reject, and reopen with the user who took the action, the timestamp, and a snapshot of the file before and after. If a file gets accepted by mistake (wrong client, fat-fingered button), a preparer can run an “undo last action” through a small admin command that reads the previous-state snapshot and restores the row. The undo is itself an audit row, so the trail stays clean. This matters most a year later, when a question about a client’s return comes up and the only memory anyone has is the trail: who collected what, who reviewed it, and when.

And it’s worth saying once more, plainly: the collector never decided a file was finished. It recognized document types and checked boxes; a person accepted every one. The machine did the chasing and the filing; the human kept the judgment.

Next post: the cost breakdown. The whole pipeline above runs in coffee-money territory at small-practice volume; Part 6 explains exactly where the dollars go and why the chase tick is nearly free.

All posts