Accept contact.phone in the fundraising contact upsert (server half of card phone)
_upsert_contact_from_fundraising now reads contact.phone and writes contacts.phone on both the insert and update paths, so a phone captured from a business card persists on the canonical contact record. Phone stays contact-level (not a grid pill field), matching how the team edits it. Validated by test_grid_add_investor.py. This is the SERVER half of business-card phone capture, staged for the next s9pk (version bump + build + install). The bot's phone extraction/card/payload lands in the same deploy, so phone never shows on a card before the box can store it. NOT yet built or installed to the box.
This commit is contained in:
+7
-4
@@ -825,6 +825,7 @@ def _upsert_contact_from_fundraising(conn, investor_name, contact, actor_user_id
|
|||||||
country = str(contact.get('country') or '').strip()
|
country = str(contact.get('country') or '').strip()
|
||||||
location_query = str(contact.get('location_query') or '').strip()
|
location_query = str(contact.get('location_query') or '').strip()
|
||||||
linkedin_url = str(contact.get('linkedin_url') or '').strip()
|
linkedin_url = str(contact.get('linkedin_url') or '').strip()
|
||||||
|
phone = str(contact.get('phone') or '').strip()
|
||||||
if not full_name and not email:
|
if not full_name and not email:
|
||||||
return None
|
return None
|
||||||
first_name, last_name = _split_full_name(full_name)
|
first_name, last_name = _split_full_name(full_name)
|
||||||
@@ -869,20 +870,21 @@ def _upsert_contact_from_fundraising(conn, investor_name, contact, actor_user_id
|
|||||||
next_country = country or str(existing['country'] or '')
|
next_country = country or str(existing['country'] or '')
|
||||||
next_location_query = location_query or str(existing['location_query'] or '')
|
next_location_query = location_query or str(existing['location_query'] or '')
|
||||||
next_linkedin = linkedin_url or str(existing['linkedin_url'] or '')
|
next_linkedin = linkedin_url or str(existing['linkedin_url'] or '')
|
||||||
|
next_phone = phone or str(existing['phone'] or '')
|
||||||
next_org = org_id or existing['organization_id']
|
next_org = org_id or existing['organization_id']
|
||||||
conn.execute("""
|
conn.execute("""
|
||||||
UPDATE contacts
|
UPDATE contacts
|
||||||
SET first_name = ?, last_name = ?, email = ?, title = ?,
|
SET first_name = ?, last_name = ?, email = ?, title = ?,
|
||||||
organization_id = ?, source = ?, contact_type = 'investor', city = ?, state = ?, country = ?, location_query = ?, linkedin_url = ?, updated_at = ?
|
organization_id = ?, source = ?, contact_type = 'investor', city = ?, state = ?, country = ?, location_query = ?, linkedin_url = ?, phone = ?, updated_at = ?
|
||||||
WHERE id = ?
|
WHERE id = ?
|
||||||
""", (next_first, next_last, next_email, next_title, next_org, next_source, next_city, next_state, next_country, next_location_query, next_linkedin, now(), existing['id']))
|
""", (next_first, next_last, next_email, next_title, next_org, next_source, next_city, next_state, next_country, next_location_query, next_linkedin, next_phone, now(), existing['id']))
|
||||||
return existing['id']
|
return existing['id']
|
||||||
|
|
||||||
contact_id = generate_id()
|
contact_id = generate_id()
|
||||||
conn.execute("""
|
conn.execute("""
|
||||||
INSERT INTO contacts (
|
INSERT INTO contacts (
|
||||||
id, first_name, last_name, email, title, organization_id, source, contact_type, status, city, state, country, location_query, linkedin_url, created_by, updated_at
|
id, first_name, last_name, email, title, organization_id, source, contact_type, status, city, state, country, location_query, linkedin_url, phone, created_by, updated_at
|
||||||
) VALUES (?, ?, ?, ?, ?, ?, ?, 'investor', 'active', ?, ?, ?, ?, ?, ?, ?)
|
) VALUES (?, ?, ?, ?, ?, ?, ?, 'investor', 'active', ?, ?, ?, ?, ?, ?, ?, ?)
|
||||||
""", (
|
""", (
|
||||||
contact_id,
|
contact_id,
|
||||||
first_name or 'Unknown',
|
first_name or 'Unknown',
|
||||||
@@ -896,6 +898,7 @@ def _upsert_contact_from_fundraising(conn, investor_name, contact, actor_user_id
|
|||||||
country,
|
country,
|
||||||
location_query,
|
location_query,
|
||||||
linkedin_url,
|
linkedin_url,
|
||||||
|
phone,
|
||||||
actor_user_id,
|
actor_user_id,
|
||||||
now()
|
now()
|
||||||
))
|
))
|
||||||
|
|||||||
@@ -161,6 +161,27 @@ def main():
|
|||||||
f"reminder linked to the new investor (got id={rem.get('investor_id')!r}, "
|
f"reminder linked to the new investor (got id={rem.get('investor_id')!r}, "
|
||||||
f"name={rem.get('investor_name')!r})")
|
f"name={rem.get('investor_name')!r})")
|
||||||
|
|
||||||
|
# ── card-intake contact fields land on the canonical contact (phone/city/linkedin) ──
|
||||||
|
# The Matrix card flow sends these on the contact dict; the upsert must persist them.
|
||||||
|
print("\n[contact fields: phone + city + linkedin persist on the contact]")
|
||||||
|
st, d = _req(port, "POST", "/api/fundraising/log-communication", token, {
|
||||||
|
"investor_name": "MARA Holdings", "create_investor_if_missing": True,
|
||||||
|
"contact": {"name": "Doug Mellinger", "email": "doug@mara.example",
|
||||||
|
"phone": "1.914.456.2146", "city": "New York",
|
||||||
|
"linkedin_url": "linkedin.com/in/dougmellinger"},
|
||||||
|
"type": "note", "body": "from a business card", "append_note": True,
|
||||||
|
})
|
||||||
|
check(st == 201, f"create with contact fields -> 201 (got {st})")
|
||||||
|
c = _db()
|
||||||
|
crow = c.execute("SELECT phone, city, linkedin_url FROM contacts WHERE lower(email) = ?",
|
||||||
|
("doug@mara.example",)).fetchone()
|
||||||
|
c.close()
|
||||||
|
check(crow is not None, "contact row exists")
|
||||||
|
check(bool(crow) and crow[0] == "1.914.456.2146", f"phone persisted (got {crow[0] if crow else None!r})")
|
||||||
|
check(bool(crow) and crow[1] == "New York", f"city persisted (got {crow[1] if crow else None!r})")
|
||||||
|
check(bool(crow) and crow[2] == "linkedin.com/in/dougmellinger",
|
||||||
|
f"linkedin persisted (got {crow[2] if crow else None!r})")
|
||||||
|
|
||||||
# ── unknown source_row_id is refused (guard) ──
|
# ── unknown source_row_id is refused (guard) ──
|
||||||
print("\n[guard: reminder on an unknown source_row_id -> 404]")
|
print("\n[guard: reminder on an unknown source_row_id -> 404]")
|
||||||
st, _ = _req(port, "POST", "/api/reminders", token, {
|
st, _ = _req(port, "POST", "/api/reminders", token, {
|
||||||
|
|||||||
Reference in New Issue
Block a user