feat(activity): search/filter on both Activity-tab panes
CI / lint (push) Successful in 4s
CI / frontend-build (push) Successful in 21s
CI / backend-lint-and-test (push) Successful in 39s
CI / integration (push) Successful in 3m17s

Recent failures gains a client-side search over the already-loaded 24h
rows (task/queue/target/error), shown as a filtered/total count alongside
the existing error-type chips. All recent activity gains a debounced
server-side task-name search (new `task` ILIKE param on /runs) so it
spans the full history, not just the loaded page. LIKE wildcards are
escaped so task names' literal underscores match literally.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-06-10 11:34:42 -04:00
parent 14c244bd3d
commit 70d4017cf6
4 changed files with 80 additions and 7 deletions
+19
View File
@@ -182,6 +182,25 @@ async def test_runs_filter_by_status(client, _seed_runs):
assert len(body["runs"]) == 2 # i=3, i=4
@pytest.mark.asyncio
async def test_runs_filter_by_task_substring(client, _seed_runs):
# Case-insensitive substring across the full task_name.
resp = await client.get("/api/system/activity/runs?task=FAKE")
body = await resp.get_json()
assert len(body["runs"]) == 5
assert all("fake" in r["task_name"] for r in body["runs"])
@pytest.mark.asyncio
async def test_runs_filter_by_task_escapes_underscore(client, _seed_runs):
# The literal "_" in "task_3" must match one row, not act as a
# single-char wildcard matching every task_N.
resp = await client.get("/api/system/activity/runs?task=task_3")
body = await resp.get_json()
assert len(body["runs"]) == 1
assert body["runs"][0]["task_name"].endswith("task_3")
@pytest.mark.asyncio
async def test_runs_keyset_cursor(client, _seed_runs):
page1 = await (await client.get("/api/system/activity/runs?limit=2")).get_json()