Communications tab: show matched investors only (v0.1.0:81)

The email-activity panel surfaced every captured message, including cold/
unknown-sender email with no investor association. Gate query_email_activity
on EXISTS(email_investor_links) so the panel shows only email tied to a known
investor/contact. Capture is unchanged — unmatched email is still stored
(metadata-only) and will appear automatically if its sender is later added as
an investor; this is a read-side filter only.

Graveyard investors are unaffected (their email has a link), so they remain
visible/searchable as an audit surface, hidden only from the filter picker.
This commit is contained in:
Keysat
2026-06-16 15:43:30 -05:00
parent def7c9ea6a
commit 6563a7811e
6 changed files with 52 additions and 16 deletions
+5
View File
@@ -89,6 +89,11 @@ the manual-log path). Backed by **`GET /api/email/activity`** (`routes.py:_h_act
query). Filters: `investor_id`, `account_id` (mailbox), `direction` (`inbound`/`outbound`),
`q` (free-text over subject/snippet/from). Non-obvious semantics to preserve:
- **Matched-only:** the panel surfaces ONLY email that links to a known
investor/contact (`query_email_activity` gates on `EXISTS email_investor_links`).
Capture still stores unmatched cold/unknown-sender email (metadata only, see "match-only
full storage"), but it is never shown here — the Communications tab is the
investor-relationship view, not the raw mailbox.
- **Soft-delete lives on the per-mailbox sighting**, not the email: `emails` has no
`deleted_at`. An email is "live" iff it has a sighting with `email_account_messages.
deleted_at IS NULL` — the query gates on `EXISTS(... deleted_at IS NULL)`. (Investor