Grid/contacts unification step 1: real contact_id link + grid as front door (v0.1.0:52)
Structural fix for the duplicate-people class of bug: instead of matching a grid contact "pill" to a contacts row heuristically by name/email (which drifted and caused the 1406 double-count), link them by id. Backend: - Migration 0004: fundraising_contacts.contact_id (additive, nullable, logical FK to contacts(id)) + index. Paired down migration. - sync_fundraising_relational now stores the id that _upsert_contact_from_fundraising already returns, so every grid contact carries its contacts-table id. - _backfill_grid_contact_ids: one-time, idempotent backfill on startup (re-runs the grid sync once if any row lacks contact_id), so existing data links immediately. - entity_resolution: grid pass prefers the explicit contact_id link (match_kind 'grid_link') over heuristic email / name+investor, guarded by a PRAGMA check so older DBs without the column still work. Frontend: - Fundraising grid "+ Row" -> "+ Investor" (clear, single investor entry point). - Contacts page: the "+ Add Contact" trigger is replaced by a pointer to the grid; the page is now a read/search/edit view (ContactDetailPanel still edits all fields). New people are added from the grid. No contact data is removed. Tests: backend/ingest/test_entity_resolution.py extended (explicit-link case, 11/11) and a new backend/test_grid_contact_link.py integration test (init_db applies 0004, sync populates contact_id to the right contact, re-sync is idempotent). py_compile + frontend html.parser clean. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+2
-2
@@ -3534,7 +3534,7 @@
|
||||
value={search}
|
||||
onChange={(e) => setSearch(e.target.value)}
|
||||
/>
|
||||
<button onClick={() => setShowForm(true)}>+ Add Contact</button>
|
||||
<span style={{ fontSize: '12px', color: '#8a93a6', alignSelf: 'center' }}>New people are added from the Fundraising Grid; click anyone here to view or edit.</span>
|
||||
</div>
|
||||
|
||||
{loading ? (
|
||||
@@ -7126,7 +7126,7 @@
|
||||
<option value="">All Leads</option>
|
||||
{teamMembers.map((m) => <option key={m} value={m}>{m}</option>)}
|
||||
</select>
|
||||
<button onClick={addRow}>+ Row</button>
|
||||
<button onClick={addRow}>+ Investor</button>
|
||||
<button className="button-secondary" onClick={() => setShowViewModal(true)}>+ Save View</button>
|
||||
<button className="button-secondary" onClick={toggleRowDensity}>{rowDensity === 'compact' ? 'Expand Rows' : 'Compact Rows'}</button>
|
||||
<button className="button-secondary" onClick={() => setShowColumnVisibilityModal(true)}>Columns</button>
|
||||
|
||||
Reference in New Issue
Block a user