The Investors/Prospects distinction is now derived live from the canonical
grid (contact_grid_signals -> committed/pipeline_stage), not the mechanically
set contact_type column:
- Desktop Contacts: drop the Investors/Prospects tabs + TYPE badge; show a
derived Status (existing-LP badge + pipeline stage chip).
- Dashboard: repoint Total LPs / Prospects onto fundraising_investors entities
(committed>0 vs $0, graveyard + blank-row placeholder excluded); fix a
total_contacts soft-delete leak.
- Stop reading/writing contact_type across the create/update/import/sync paths.
The column is left inert in place; a physical drop is deferred to a later
signed-off table-rebuild migration (SQLite no-drop-column; contacts is
FK-referenced) -- same retire-then-drop path lp_profiles took.
The fundraising grid + email capture is the canonical system of record. lp_profiles
was a superseded single-fund model with no reachable create/edit path, and the LP
Tracker page was already orphaned (no nav entry + a redirect bouncing it to the grid).
- Remove /api/lp-profiles* endpoints + handlers, the unused lp-breakdown report,
the contact-dossier LP section, the demo-seed LP block, and (frontend) the
LPTrackerPage component + its lp-tracker->fundraising-grid redirect.
- Dashboard "Total Committed" now sums fundraising_investors.total_invested
(graveyarded investors excluded) instead of the orphaned lp_profiles table, which
read ~$0. "Total Funded" dropped: the grid tracks commitments, not a funded amount,
and the frontend never rendered it.
- Leave the empty lp_profiles table/index, the contact-delete soft-delete cascade,
and the --reset-all-data clear in place (never-hard-delete).
- Tests: add test_dashboard_report.py; update test_soft_delete_reads.py. 21/21 green.