Capture phone (office) + mobile (cell) on card intake; ship v0.1.0:98
Completes business-card contact capture. The transcription prompt now labels Phone/Mobile/Fax on separate lines, and the extractor maps an office/main number -> phone and a cell -> mobile, never a fax. Both carry the same digit-in-source integrity rule as email/LinkedIn: a number is kept only if its digits literally appear in the source (or, on revise, the instruction) -- never minted. The proposal card shows Phone + Mobile and they're editable (aliases phone/tel/office, mobile/cell). Server: _upsert_contact_from_fundraising now accepts contact.phone + contact.mobile and writes them to the canonical contact record (contact-level, not grid pills), shipped in s9pk v0.1.0:98. No schema change -- the contacts columns already exist. 41/41 backend suite green + the matrix_intake units; card flow end-to-end is live-smoke.
This commit is contained in:
@@ -233,6 +233,43 @@ def test_revise_linkedin_taken_only_from_instruction():
|
||||
assert r2["contact_title"] == "GP"
|
||||
|
||||
|
||||
def test_phone_and_mobile_kept_when_digits_in_source():
|
||||
# A card transcription separates Phone/Mobile/Fax; the model maps office->phone, cell->mobile.
|
||||
src = ("New investor — from a business card:\nName: Daniel Raupp\nCompany: Fortitude\n"
|
||||
"Phone: 631-474-5610\nFax: 631-474-1806\nCell: 631-922-1195")
|
||||
p = parse.parse_message(
|
||||
src,
|
||||
parse_fn=_stub({"intent": "new_investor", "investor_name": "Fortitude",
|
||||
"contact_name": "Daniel Raupp", "phone": "631-474-5610",
|
||||
"mobile": "631-922-1195"}),
|
||||
)
|
||||
assert p["phone"] == "631-474-5610"
|
||||
assert p["mobile"] == "631-922-1195" # the cell, kept in its printed formatting
|
||||
|
||||
|
||||
def test_fabricated_phone_dropped_when_digits_not_in_source():
|
||||
p = parse.parse_message(
|
||||
"new prospect Gamma Partners, talked to their GP",
|
||||
parse_fn=_stub({"intent": "new_investor", "investor_name": "Gamma Partners",
|
||||
"contact_name": "their GP", "phone": "555-867-5309"}),
|
||||
)
|
||||
assert p["phone"] is None # number not in the source → never minted
|
||||
|
||||
|
||||
def test_revise_phone_taken_only_from_instruction():
|
||||
proposal = {"intent": "new_investor", "investor_name": "Acme", "contact_name": "Jane",
|
||||
"contact_email": None, "contact_title": None, "city": None, "linkedin_url": None,
|
||||
"phone": None, "mobile": None, "note": None, "_source_text": "Acme Jane"}
|
||||
r1 = parse.revise(proposal, "her cell is 917-555-0199",
|
||||
parse_fn=_stub({"mobile": "917-555-0199"}))
|
||||
assert r1["mobile"] == "917-555-0199"
|
||||
# model tries to set a number but the instruction has none → keep existing (None)
|
||||
r2 = parse.revise(proposal, "set her title to GP",
|
||||
parse_fn=_stub({"mobile": "000-000-0000", "contact_title": "GP"}))
|
||||
assert r2["mobile"] is None
|
||||
assert r2["contact_title"] == "GP"
|
||||
|
||||
|
||||
def test_revise_cannot_empty_the_proposal():
|
||||
proposal = {"intent": "new_investor", "investor_name": "Acme", "contact_name": "Jane",
|
||||
"contact_email": None, "contact_title": None, "note": "x", "_source_text": "Acme Jane"}
|
||||
|
||||
Reference in New Issue
Block a user