Add temporary admin contacts-census diagnostic (v0.1.0:105)
A throwaway, admin-only diagnostic for the deferred contacts <-> fundraising_contacts consolidation: GET /api/admin/contacts-census + a Settings -> Admin "Run census" button report the A/B/C populations (linked / contacts-only / pill-only) plus the communications/opportunities repointing surface. Counts only, no PII -- mirrors backend/scripts/contacts_census.sql so the numbers can be read off the box without a shell. All pieces are tagged TEMPORARY; delete the endpoint + route + button after the census is captured. No schema change. 45/45 tests, render-smoke green.
This commit is contained in:
@@ -2359,6 +2359,8 @@ class CRMHandler(BaseHTTPRequestHandler):
|
||||
return self.handle_get_digest_policy(user)
|
||||
if path == '/api/admin/soft-deleted':
|
||||
return self.handle_list_soft_deleted(user)
|
||||
if path == '/api/admin/contacts-census': # TEMPORARY — remove after the consolidation census
|
||||
return self.handle_contacts_census(user)
|
||||
if path == '/api/fundraising/relational-summary':
|
||||
return self.handle_get_fundraising_relational_summary(user)
|
||||
if path == '/api/fundraising/automations':
|
||||
@@ -4868,6 +4870,39 @@ class CRMHandler(BaseHTTPRequestHandler):
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
# ─── TEMPORARY (v0.1.0:105) — DELETE AFTER the contacts<->fundraising_contacts census ──
|
||||
# A throwaway admin diagnostic for the deferred consolidation (ROADMAP backlog): mirrors
|
||||
# backend/scripts/contacts_census.sql so the A/B/C populations can be read from the box
|
||||
# without shell access. Counts only — no names/PII. Remove this handler + its route + the
|
||||
# Settings "Contacts census" button once the numbers are captured.
|
||||
def handle_contacts_census(self, user):
|
||||
if not require_admin(user):
|
||||
return self.send_error_json("Admin required", 403)
|
||||
conn = get_db()
|
||||
try:
|
||||
def n(sql):
|
||||
return conn.execute(sql).fetchone()[0]
|
||||
no_pill = ("NOT EXISTS (SELECT 1 FROM fundraising_contacts fc WHERE fc.contact_id = c.id)")
|
||||
return self.send_json({"data": {
|
||||
"total_live_contacts": n("SELECT COUNT(*) FROM contacts WHERE deleted_at IS NULL"),
|
||||
"A_linked": n("SELECT COUNT(*) FROM contacts c WHERE c.deleted_at IS NULL "
|
||||
"AND EXISTS (SELECT 1 FROM fundraising_contacts fc WHERE fc.contact_id = c.id)"),
|
||||
"B_contacts_only": n(f"SELECT COUNT(*) FROM contacts c WHERE c.deleted_at IS NULL AND {no_pill}"),
|
||||
"B_investor": n(f"SELECT COUNT(*) FROM contacts c WHERE c.deleted_at IS NULL AND c.contact_type='investor' AND {no_pill}"),
|
||||
"B_prospect": n(f"SELECT COUNT(*) FROM contacts c WHERE c.deleted_at IS NULL AND c.contact_type='prospect' AND {no_pill}"),
|
||||
"B_with_live_communication": n(f"SELECT COUNT(*) FROM contacts c WHERE c.deleted_at IS NULL AND {no_pill} "
|
||||
"AND EXISTS (SELECT 1 FROM communications cm WHERE cm.contact_id=c.id AND cm.deleted_at IS NULL)"),
|
||||
"B_with_live_opportunity": n(f"SELECT COUNT(*) FROM contacts c WHERE c.deleted_at IS NULL AND {no_pill} "
|
||||
"AND EXISTS (SELECT 1 FROM opportunities o WHERE o.contact_id=c.id AND o.deleted_at IS NULL)"),
|
||||
"C_pill_only": n("SELECT COUNT(*) FROM fundraising_contacts WHERE contact_id IS NULL"),
|
||||
"dangling_pills": n("SELECT COUNT(*) FROM fundraising_contacts fc WHERE fc.contact_id IS NOT NULL "
|
||||
"AND NOT EXISTS (SELECT 1 FROM contacts c WHERE c.id=fc.contact_id AND c.deleted_at IS NULL)"),
|
||||
"total_grid_pills": n("SELECT COUNT(*) FROM fundraising_contacts"),
|
||||
"total_grid_rows": n("SELECT COUNT(*) FROM fundraising_investors"),
|
||||
}})
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
def handle_decide_activity_proposal(self, user, proposal_id, decision, body):
|
||||
if not require_admin(user):
|
||||
return self.send_error_json("Admin required", 403)
|
||||
|
||||
Reference in New Issue
Block a user