While running the backfill against production we found that many
cards had user-corrected values trapped in fieldData with stale
OCR originals in the top-level column (e.g. LaGay: top-level
email "lagayferters@yahoo.com" vs fieldData "lagayfenters@yahoo.com").
The previous "only promote when top-level is empty" rule skipped
these — so the list view, search, and CSV export still showed the
stale OCR data even though the detail view showed the correction.
New rule:
- When fieldData[canonical] is non-empty, promote it to the
top-level column (regardless of whether the top-level column
already has a value). Reasoning: pre-fix, the UI saved
non-core edits only to fieldData, so any non-empty
fieldData[canonical] is the user's most recent value (or
matches the OCR original — harmless either way). Verified
against the prod DB that fieldData never contains
firstName/lastName/name, so there is no risk of reverting
user-edited names.
Also:
- Adds `import "dotenv/config"` so `npx tsx` picks up .env.
- Logs fill-empty vs overwrite counts and a sample of conflicts
(top-level → fieldData) so the dry-run is easy to audit.
Applied against prod: 23 form fields flipped, ~3127 values
promoted across 901 cards, 282 names recomputed. Re-run dry-run
reports 0 remaining changes.
Co-authored-by: Cursor <cursoragent@cursor.com>