lead claims: outreach v1, decided by Mike
Who picked a lead up and when, so nothing sits waiting unnoticed. No outcomes, no end states, nothing on join_leads changes: the lead stays the record of what the family said and the claim is only who has it. One row per claim in lead_claims; the current claim is the latest unreleased. Taking over is release then claim, never a silent overwrite: 409 names the holder. The holder or an owner may release. Every claim and release lands in the action log; the summary carries an unclaimed count. tests/smoke_admin.py 112 -> 122.
This commit is contained in:
@@ -301,6 +301,28 @@ check("kind prefix filter and limit", all(e["kind"].startswith("nearby.") for e
|
||||
check("history is admin and above, and not scopable on a key", "history:read" in I.CAPS["admin"]
|
||||
and "history:read" not in I.CAPS["leader"] and "history:read" in I.KEY_UNSCOPABLE)
|
||||
|
||||
print("\nlead claims")
|
||||
lid = S.record_lead({"parent_name": "Claim Test", "email": "claim@example.test", "interested_in": "Pack 73"}) if hasattr(S, "record_lead") else None
|
||||
if lid is None:
|
||||
con = S.connect(); lid = "lead-claim-test"
|
||||
con.execute("INSERT INTO join_leads (id, submitted_at, recorded_at, parent_name, email, payload) VALUES (?,?,?,?,?,?)",
|
||||
(lid, I._now(), I._now(), "Claim Test", "claim@example.test", "{}")); con.commit(); con.close()
|
||||
check("unclaimed count sees it", S.unclaimed_count() >= 1 and S.summary()["unclaimed"] >= 1)
|
||||
c = S.claim_lead(lid, "p-a", "a@example.test")
|
||||
check("claim recorded and listed on the lead", c["email"] == "a@example.test" and S.get_lead(lid)["claim"]["email"] == "a@example.test"
|
||||
and [r for r in S.list_leads(limit=500) if r["id"] == lid][0]["claim"]["email"] == "a@example.test")
|
||||
raises("claiming again yourself", 409, S.ClaimRejected, S.claim_lead, lid, "p-a", "a@example.test")
|
||||
raises("someone else cannot take it over silently", 409, S.ClaimRejected, S.claim_lead, lid, "p-b", "b@example.test")
|
||||
raises("someone else cannot release it", 403, S.ClaimRejected, S.release_lead, lid, "p-b", "b@example.test")
|
||||
check("an owner can release it", S.release_lead(lid, "p-b", "b@example.test", can_release_any=True)["email"] == "a@example.test"
|
||||
and S.get_lead(lid)["claim"] is None)
|
||||
raises("release when nobody has it", 409, S.ClaimRejected, S.release_lead, lid, "p-a", "a@example.test")
|
||||
S.claim_lead(lid, "p-b", "b@example.test"); S.release_lead(lid, "p-b", "b@example.test")
|
||||
check("history keeps every claim", len(S.get_lead(lid)["claim_history"]) == 2 and all(h["released_at"] for h in S.get_lead(lid)["claim_history"]))
|
||||
check("nothing on the lead itself changed", "status" not in S.get_lead(lid) and "claimed" not in S.get_lead(lid))
|
||||
check("unknown lead is None", S.claim_lead("nope", "p", "e") is None and S.release_lead("nope", "p", "e") is None)
|
||||
con = S.connect(); con.execute("DELETE FROM lead_claims WHERE lead_id=?", (lid,)); con.execute("DELETE FROM join_leads WHERE id=?", (lid,)); con.commit(); con.close()
|
||||
|
||||
print("\napi docs registry")
|
||||
import admin_api as A
|
||||
reg = A.describe_routes()
|
||||
|
||||
Reference in New Issue
Block a user