feat: add an address filter to unibox search that matches either side of the exchange (from_addr OR to_addr) so the compose history panel can show every conversation with a contact, exposed as ?address= on GET /unibox, with a GIN index on to_addr (migration 000071) mirroring the existing from_addr index

This commit is contained in:
Matthew Meszaros
2026-07-19 07:27:23 +02:00
parent 4a9ae5514b
commit 666a137cd8
5 changed files with 27 additions and 1 deletions
+6
View File
@@ -75,6 +75,12 @@ func (h *Handler) GetUniboxIncoming(c *gin.Context) {
params.Sender = &from
}
// Address filter: conversations with this person in either direction
// (they sent it or we sent it to them). Powers the compose history panel.
if address := c.Query("address"); address != "" {
params.Address = &address
}
// Parse subject filter
if subject := c.Query("subject"); subject != "" {
params.Subject = &subject
@@ -0,0 +1 @@
DROP INDEX IF EXISTS idx_unibox_emails_to;
@@ -0,0 +1,4 @@
-- Compose needs "conversations with this address" lookups that match either
-- side of the exchange. from_addr already has a GIN index; mirror it on
-- to_addr so the address filter and mailbox-affinity scoring stay indexed.
CREATE INDEX IF NOT EXISTS idx_unibox_emails_to ON public.unibox_emails USING gin (to_addr);
+5 -1
View File
@@ -156,7 +156,11 @@ type MailSearchResult struct {
}
type MailSearchParams struct {
Sender *string
Sender *string
// Address matches either side of the exchange (from_addr OR to_addr),
// giving "every conversation with this person" regardless of direction.
// Substring match on the raw header entries, like Sender.
Address *string
Unseen *bool
Subject *string
Since *time.Time
+11
View File
@@ -415,6 +415,17 @@ func (r *uniboxRepository) Search(ctx context.Context, orgID, userID uuid.UUID,
argPos++
}
if params.Address != nil && *params.Address != "" {
// Either direction: the contact as sender OR as recipient, so the
// result is the full back-and-forth with that address.
inner += fmt.Sprintf(` AND EXISTS (
SELECT 1 FROM unnest(ue.from_addr || ue.to_addr) AS f(addr)
WHERE f.addr ILIKE '%%' || $%d || '%%'
)`, argPos)
args = append(args, *params.Address)
argPos++
}
if len(params.EmailAccountIDs) > 0 {
inner += fmt.Sprintf(` AND ue.email_id = ANY($%d)`, argPos)
args = append(args, params.EmailAccountIDs)