Cases in depth

Files route by identifier: a matching identifier joins the existing case, otherwise a new case is atomically created. Extraction never overwrites your manual edits, and every case carries a read-time activity timeline.

Updated 6 min read
Diagram of two documents flying along dotted arcs into a single dossier folder whose tab carries a padlock seal, with a third document queued behind a gate
Fig. 01Same identifier, same case. The padlock is the workspace's identifier lock: at most one case may claim a value, so every later file with that identifier files itself into the winner.

How files route to cases

Every case has a top-level Identifier. The workspace enforces uniqueness: at most one case per (workspace, identifier value) pair, backed by an atomic Firestore lock. Every ingestion channel (Gmail, Drive, manual upload) runs the same routing:

  1. Identifier extracted, lock found → file attaches to the existing case.
  2. Identifier extracted, no lock → atomically claim the lock, create a new case, attach the file.
  3. No identifier surfaced → create a new case with an auto-generated ID, attach the file.

The atomic claim makes step 2 race-safe: two parallel ingests of one identifier can't produce two cases (one wins the lock, the other attaches to it).

Auto-promote: a case created without an identifier (manual placeholder or no-identifier ingest) auto-promotes the moment a later extraction surfaces a clean value. If that value is already claimed, the promote is skipped and the auto ID stays, so resolve the collision by editing either case's identifier.

Rename: open the case, choose Edit case (header menu), change the Case ID field at the top of the edit form, then click Save changes. The rename atomically releases the old lock and claims the new one. If another case owns the new value, a prompt appears: Merge folds this case into that one (files move, this case deleted), or Rename uses the next free variant (e.g. E-9 (2)). Cancel keeps you editing.

What happens when a second file arrives

Extraction runs on that one new file against its matched template; results write to case.data field by field. There's no cross-file diffing. The write rules:

  • Latest extraction wins per field: the newest value replaces the prior one. No "longer string wins," no similarity check.
  • Empty extractions can't blank populated fields: null/undefined/empty for a field that already has a value is skipped, and the previous value stays.
  • Manual edits are sticky. Any pencil-edit (or chat-agent correction) is recorded as an _overrides entry. Every re-extraction, automatic or manual, skips overridden fields, so the product never silently undoes a worker's correction. Confirm protection via the ↺ reset button that appears on the row (and the row's history popover): an extracted field is override-protected exactly when that reset button is present. To hand a field back to extraction, click that ↺ reset button: the value stays for now, the next extraction may update it.
  • Dates normalize at write time to US MM/DD/YYYY; free text like "TBD" falls through unchanged.
  • Batch (repeating-row) fields write as a whole: the latest array replaces the previous one. No row-level concatenation; to accumulate line items across invoices, use a separate case or merge by hand.
A merge in action
Old fileVendor='Acme Supply', Due=2026-04-01
New fileVendor='Acme Supply Co.', Due=2026-04-15
After re-extractionVendor='Acme Supply Co.' (overwritten), Due=2026-04-15 (overwritten)

To force a re-extraction without losing edits: expand the file row in the case detail's Documents section and use the quick re-extract (↻) icon, or Update case (saves your inputs and re-reads the file when the run is stale, no new document) or Autofill (extract and generate) on the template's item. Override-protected fields stay; everything else takes the new values.

Consolidating two cases

Auto-detected (primary). When an orphan case (no readable identifier) holds a document carrying the real ID, run an ID-capturing template on it (any template with an identifier field configured to extract the case ID from the document). If the extracted ID belongs to another case, a merge banner appears at the top of the orphan case detail: "This document's ID [X] belongs to an existing case. Merge this case's documents into [X] and delete this one?" Click Merge: the orphan's files re-attach to the matching case (normal upload path, so the rules above re-apply) and the orphan is deleted, and you land on the survivor. If the ID is unclaimed, the orphan simply auto-promotes (no banner).

Manual (fallback). When neither case carries a shared extractable ID:

1Download the stray file2Open the surviving case3Edit case4Upload the fileDelete the duplicate case

In Edit case (the duplicate's menu, after downloading the stray file via the Download button in its preview), the Upload File section takes a Source File plus its File Category (which routes it to the right templates); click Upload to Case. Then delete the duplicate via Delete case from its menu; the confirm dialog warns deletion is permanent, so move everything you need first. The survivor re-extracts the uploaded file like any other arrival, so the merge rules above apply.

The activity timeline

Each case has a chronological timeline (most recent first), derived at read time from several Firestore sources (case notes, form submissions, PDF generations, file store, template runs, the dataHistory map, override/hidden audit markers, and the activity subcollection), not one canonical collection. That's why some entries can be deleted by a worker, others can only be soft-reverted, and editing a note rewrites the source rather than creating a new event. Entry types: Notes, added by workers in the single-editor composer (no tabs): free text, an optional event date, and paperclip attachments (images, PDFs, other media); edited notes show an Edited badge and keep an edit history so earlier text, attachments, or event date can be reviewed. Form submissions capture a client's template answers from the portal or a shared form link (workers don't fill forms from this composer). Generations preserve the template, output file, and a snapshot of the input values used. Signed documents read "Signed · N electronic signatures", save the stamped PDF to the case's Files, and keep an immutable signing record (who signed, when, the consent agreed to, and tamper-evident hashes of the file): an electronic signature, not a notarized or legally-binding one. Template runs can show field-level diffs when the same template runs more than once. System events cover file ingested, field updated, case created, collaborator added/removed, mailbox move (e.g. "Moved to Confirmations by automation: Confirmation of Award"), and a general catch-all.

Dates and calendar: entries land on their creation day; a note with an event date lands on that date instead, useful for follow-ups, calls, site visits, due dates, or reminders. Click a date for View in calendar (the in-app Calendar view) or Download .ics (a standard calendar file you open in Google, Apple, or Outlook); the Calendar view also has a bulk Export .ics that bundles every date showing under the current filters. The product does not push events to Google Calendar over the API. Copy distinguishes staff from clients: "Riley was assigned to this case" vs "client@example.com was given client access to this case".

Category visibility: entries referencing a file carry that file's category; any entry whose category a viewer can't see is hidden, enforced at the data layer, not UI-only. A restricted viewer still sees the case exists, just not activity about files they can't access. If a collaborator says an entry is missing, check its file category first.

Delete and restore: notes you manage can be deleted (if a note was tied to structured case changes, you may be asked whether to undo those too). System entries use soft-revert: the original is struck-through and an audit row appears ("Riley deleted activity: File ingested"); restoring adds another ("Riley restored activity: File ingested"). The original is never physically removed. To add a note, scroll to the Activity section, type in the composer, optionally attach via the paperclip or set an event date with the calendar icon, then click Add Note.

We use cookies to keep you signed in and improve the product. See our Cookie Policy.
Manage preferences