Device-test round 2: 4 in-app fixes + Matrix intake cleanup (v0.1.0:99)
Grant's real-phone testing surfaced seven items; this lands six (the seventh, in-app camera card intake, is planned in docs/handoffs/in-app-card-intake-plan.md). CRM half — ships in the s9pk (v0.1.0:99): - Intake fuzzy match no longer over-indexes on generic firm words. _name_similarity now compares DISTINCTIVE tokens only (generic descriptors — "Investment Group", "Capital", "Family Office" — stripped via _GENERIC_ORG_WORDS) for both the difflib ratio and the Jaccard, so "Fortitude Investment Group" stops surfacing Aether/Russell while "Aether Capital" still surfaces "Aether Investment Group". +2 regression cases. - Mobile grid "Last contact"/staleness sort is reversible. SortSheet gains opt-in dir/onToggleDir; other surfaces (Contacts/Pipeline) are untouched. - Mobile "Edit investor" prefills a contact's saved email. GET /api/fundraising/state heals a blank grid pill email from the linked classic contact (fundraising_contacts.contact_id -> contacts.email), fill-only, by pill order then name; the next one-row save persists it. +test_grid_email_heal.py. - Mobile quick-log pencil icon renders. iOS collapses a sole, centered, attribute-only -sized flex-child <svg>; .quicklog-btn svg now gets explicit CSS width/height + flex:none (the pattern the working bottom-tab/sort-pill icons use). The v97 fix only changed color. Matrix intake bot — ships on the Spark (bot-only, NOT the s9pk): - Approve/reject now redacts the whole intake thread (card + ack + main-timeline nudge + the user's own photo/note), mirroring the email-review room; redact_thread takes the room as an arg and matches replies by m.thread OR m.in_reply_to (so the nudge clears). No more in-Matrix confirmation after a commit (the thread vanishing is the ack). Needs the bot to hold a redact/moderator power level in the intake room. - New one-time backend/matrix_intake/redact_intake.py clears the room's pre-existing backlog (dry-run default; --apply). Tests 42/42 green; frontend render-smoke green. Frontend fixes are inspection + render -smoke verified (on-device confirm pending); the bot redaction is live-smoke only.
This commit is contained in:
@@ -69,6 +69,26 @@ Spark). See *Fuzzy matching* below. Tests green (27/27 backend + the offline bot
|
||||
A bare `yes`/`no` typed **top-level** (not in the thread) while a proposal is pending gets a
|
||||
"reply in the thread" redirect (`store.any_pending()` guard in `handle_intake`), not a
|
||||
misparsed new intake.
|
||||
5. **On a conclusive decision (approve or reject) the whole thread is redacted** (Grant, 2026-06-20)
|
||||
— exactly like the email-review room. `handle_reply`/`handle_disambiguation` call
|
||||
`redact_thread(intake_room, root)` instead of posting a `✅`/`🗑️` confirmation: it clears the
|
||||
bot's card + `📇 Reading…` ack + the main-timeline **nudge** + **the user's own note/photo** (the
|
||||
thread root). The thread vanishing is the acknowledgment; a confirmation reply would just keep it
|
||||
alive. Only conclusive decisions clear — an `edit`/NL-revise keeps the thread (still pending), and
|
||||
a commit **failure** posts a `⚠️` and restores the proposal (no redact, so the user can retry).
|
||||
`redact_thread` now takes the **room** as its first arg and matches replies by `m.thread`
|
||||
event_id **or** `m.in_reply_to` event_id (so the un-threaded nudge clears too). **Prerequisite:
|
||||
the bot needs a `redact`/moderator power level in the intake room** to clear the *humans'*
|
||||
messages (its own need none) — without it the user's note/photo lingers (best-effort, no error).
|
||||
Same Element caveat as email: turn OFF "show removed messages" so the placeholders disappear.
|
||||
**Trade-off:** there's no longer an in-Matrix confirmation of *what* was logged after a successful
|
||||
commit (the record is in the CRM) — by design, matching the email room; revisit if wanted.
|
||||
**Retroactive backfill:** `backend/matrix_intake/redact_intake.py` (dry-run default; `--apply`)
|
||||
clears the room's pre-existing backlog. The intake room keeps **no durable pending state** (the
|
||||
proposal store is in-memory, lost on restart), so every message in it is stale after a restart and
|
||||
safe to redact — it clears **every** `m.room.message` (text + card images), bot's and humans'
|
||||
alike. Run on the Spark: `docker compose run --rm matrix-intake python -u
|
||||
backend/matrix_intake/redact_intake.py [--apply]`.
|
||||
|
||||
## Business-card capture (M3 — image intake)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user