feat: add pr, repo, pr_title chat search filters (#25569)

Relates to CODAGT-432

Adds three new search filters to the chat list endpoint (`GET
/api/experimental/chats/`):

- `pr:<number>` - exact PR number match
- `repo:<owner/repo>` - substring match against git remote origin or URL
- `pr_title:<text>` - case-insensitive PR title substring match

Includes SQL filter clauses (EXISTS against `chat_diff_statuses`),
parser with validation, handler wiring, unit tests, swagger annotation
update, and a new search syntax documentation page.

> 🤖 Generated with [Coder Agents](https://coder.com/agents)
This commit is contained in:
Cian Johnston
2026-05-22 13:58:07 +01:00
committed by GitHub
parent 5deab9f721
commit 15ada66e14
12 changed files with 286 additions and 12 deletions
+41 -2
View File
@@ -7638,6 +7638,39 @@ WHERE
)
ELSE true
END
-- Filter by PR number (exact match on chat's diff status).
AND CASE
WHEN $11::int != 0 THEN EXISTS (
SELECT 1
FROM chat_diff_statuses cds
WHERE cds.chat_id = chats_expanded.id
AND cds.pr_number = $11
)
ELSE true
END
-- Filter by repository (substring match on remote origin or PR URL).
AND CASE
WHEN $12::text != '' THEN EXISTS (
SELECT 1
FROM chat_diff_statuses cds
WHERE cds.chat_id = chats_expanded.id
AND (
cds.git_remote_origin ILIKE '%' || $12 || '%'
OR cds.url ILIKE '%' || $12 || '%'
)
)
ELSE true
END
-- Filter by pull request title (case-insensitive substring).
AND CASE
WHEN $13::text != '' THEN EXISTS (
SELECT 1
FROM chat_diff_statuses cds
WHERE cds.chat_id = chats_expanded.id
AND cds.pull_request_title ILIKE '%' || $13 || '%'
)
ELSE true
END
-- Paginate over root chats only. Children are fetched
-- separately via GetChildChatsByParentIDs and embedded under
-- each parent. Other callers that need the full set should
@@ -7654,11 +7687,11 @@ ORDER BY
-chats_expanded.pin_order DESC,
chats_expanded.updated_at DESC,
chats_expanded.id DESC
OFFSET $11
OFFSET $14
LIMIT
-- The chat list is unbounded and expected to grow large.
-- Default to 50 to prevent accidental excessively large queries.
COALESCE(NULLIF($12 :: int, 0), 50)
COALESCE(NULLIF($15 :: int, 0), 50)
`
type GetChatsParams struct {
@@ -7672,6 +7705,9 @@ type GetChatsParams struct {
TitleQuery string `db:"title_query" json:"title_query"`
HasUnread sql.NullBool `db:"has_unread" json:"has_unread"`
PullRequestStatuses []string `db:"pull_request_statuses" json:"pull_request_statuses"`
PrNumber int32 `db:"pr_number" json:"pr_number"`
RepoQuery string `db:"repo_query" json:"repo_query"`
PrTitleQuery string `db:"pr_title_query" json:"pr_title_query"`
OffsetOpt int32 `db:"offset_opt" json:"offset_opt"`
LimitOpt int32 `db:"limit_opt" json:"limit_opt"`
}
@@ -7693,6 +7729,9 @@ func (q *sqlQuerier) GetChats(ctx context.Context, arg GetChatsParams) ([]GetCha
arg.TitleQuery,
arg.HasUnread,
pq.Array(arg.PullRequestStatuses),
arg.PrNumber,
arg.RepoQuery,
arg.PrTitleQuery,
arg.OffsetOpt,
arg.LimitOpt,
)