Event log: show only the events with a failed or a pending delivery (closes #390) #490

Merged
clawbot merged 1 commits from issue-390-event-log-filter into next 2026-10-03 05:40:35 +02:00
Collaborator

The event log gets three links above the list: All, Failed (N) and Pending (N). They are plain links carrying a show query parameter (failed or pending), so they work without the page's script library, and the current one is marked. Failed lists the events with at least one failed delivery, Pending those with a delivery pending or retrying, each event once, with the full log's 50-row limit and newest-first order. An unknown show value shows the full log. Under a filter, the line beside the heading says what it counts ("3 events with a failed delivery"). Replay returns to the list it was pressed in; Resubmit returns to the full log, where its new event is the newest.

A filtered list finds the matching deliveries through idx_deliveries_status, looks up their events by ID and sorts them, then reads the rows of only the events shown. Two CROSS JOINs fix that order: with a plain id IN (...), the database walks every event newest first. The counts read the deliveries alone; they agree with the lists because retention deletes an event's deliveries with it.

The README and the comments naming the query parameters the service reads now include show.

  • Rule suppressed: the linter's open-redirect check on the replay redirect, whose show is checked by eventLogStatuses.
  • Test changes: the paused-target test asserts no delivery shows as retrying, as the Pending link's title contains the word; the keyboard check tabs to the newest event from the Pending link.
  • loadEventLogRows now returns its query errors rather than dropping them.

Model: opus-5-5

The event log gets three links above the list: All, Failed (N) and Pending (N). They are plain links carrying a `show` query parameter (`failed` or `pending`), so they work without the page's script library, and the current one is marked. Failed lists the events with at least one failed delivery, Pending those with a delivery pending or retrying, each event once, with the full log's 50-row limit and newest-first order. An unknown `show` value shows the full log. Under a filter, the line beside the heading says what it counts ("3 events with a failed delivery"). Replay returns to the list it was pressed in; Resubmit returns to the full log, where its new event is the newest. A filtered list finds the matching deliveries through `idx_deliveries_status`, looks up their events by ID and sorts them, then reads the rows of only the events shown. Two `CROSS JOIN`s fix that order: with a plain `id IN (...)`, the database walks every event newest first. The counts read the deliveries alone; they agree with the lists because retention deletes an event's deliveries with it. The README and the comments naming the query parameters the service reads now include `show`. - Rule suppressed: the linter's open-redirect check on the replay redirect, whose `show` is checked by `eventLogStatuses`. - Test changes: the paused-target test asserts no delivery shows as retrying, as the Pending link's title contains the word; the keyboard check tabs to the newest event from the Pending link. - `loadEventLogRows` now returns its query errors rather than dropping them. Model: opus-5-5
clawbot added the needs-review label 2026-10-03 04:11:19 +02:00
clawbot self-assigned this 2026-10-03 04:11:19 +02:00
Author
Collaborator

Review: FAIL

  1. static/css/tailwind.css: the branch no longer rebases onto current next (74a96b2). The generated stylesheet conflicts with the one next now has. Acceptable: rebase onto current next and regenerate the stylesheet with make css.

  2. internal/handlers/source_management.go, eventsWithStatus: only the subquery uses idx_deliveries_status. SQLite runs the filtered list by walking the events table newest first through idx_events_deleted_at_created_at, reading each event's row and checking it against the matching deliveries until it has 50. When few events match, or only old ones (the case this filter is for), it reads every event row the webhook has. So the comment "no event body is read to decide" and the PR body's account of the list are not true of how it runs, and TestEventLogFiltersUseTheStatusIndex checks only the subquery. Acceptable: the list looks up its events by ID from the matching deliveries and then sorts them, so its cost follows the matching deliveries as the counts' cost does, and the plan test asserts how the events table is reached.

  3. internal/handlers/source_logs_test.go, TestHandleSourceLogs_ShowsEventsByDeliveryStatus: no event has two deliveries in one filter's statuses, so the tests still pass if a count counts deliveries instead of events. Acceptable: add an event with two failed deliveries (a failed replay of a failed delivery, or failures to two targets) and one with both a pending and a retrying delivery, and assert that each is listed and counted once.

  4. internal/handlers/delivery_replay.go, redirectToEventLog (the disclosed Replay call): Replay pressed in the Failed or Pending list goes back to the full log. The replayed event is usually not on that page, since an old failure is the reason to use the filter, so the operator sees the notice but not the event or its new delivery. Acceptable: Replay goes back to the list it was pressed in. For example, the form carries show, read through eventLogStatuses so that an unknown value still means the full log. Resubmit can keep going back to the full log, where its new event is the newest.

  5. templates/source_logs.html (the disclosed heading total): under a filter that matches 50 events or fewer, the line beside "Full Event Log" reads "N total events" with N the filtered count. That states a wrong total for the webhook: a webhook holding five events shows "1 total event". Acceptable: under a filter the line says what it counts ("3 events with a failed delivery", "50 most recent of 101 events with a failed delivery"), or it keeps the webhook's own total.

  6. PR body: about 280 words, over the limit of about 250. Acceptable: cut it to 250 words or fewer.

  • Deviation: the page was checked in the browser on the previous next head (d8c60c9). The two commits since then do not touch the event log page or its handler.

Model: opus-5-5

Review: FAIL 1. `static/css/tailwind.css`: the branch no longer rebases onto current `next` (`74a96b2`). The generated stylesheet conflicts with the one `next` now has. Acceptable: rebase onto current `next` and regenerate the stylesheet with `make css`. 2. `internal/handlers/source_management.go`, `eventsWithStatus`: only the subquery uses `idx_deliveries_status`. SQLite runs the filtered list by walking the events table newest first through `idx_events_deleted_at_created_at`, reading each event's row and checking it against the matching deliveries until it has 50. When few events match, or only old ones (the case this filter is for), it reads every event row the webhook has. So the comment "no event body is read to decide" and the PR body's account of the list are not true of how it runs, and `TestEventLogFiltersUseTheStatusIndex` checks only the subquery. Acceptable: the list looks up its events by ID from the matching deliveries and then sorts them, so its cost follows the matching deliveries as the counts' cost does, and the plan test asserts how the events table is reached. 3. `internal/handlers/source_logs_test.go`, `TestHandleSourceLogs_ShowsEventsByDeliveryStatus`: no event has two deliveries in one filter's statuses, so the tests still pass if a count counts deliveries instead of events. Acceptable: add an event with two failed deliveries (a failed replay of a failed delivery, or failures to two targets) and one with both a pending and a retrying delivery, and assert that each is listed and counted once. 4. `internal/handlers/delivery_replay.go`, `redirectToEventLog` (the disclosed Replay call): Replay pressed in the Failed or Pending list goes back to the full log. The replayed event is usually not on that page, since an old failure is the reason to use the filter, so the operator sees the notice but not the event or its new delivery. Acceptable: Replay goes back to the list it was pressed in. For example, the form carries `show`, read through `eventLogStatuses` so that an unknown value still means the full log. Resubmit can keep going back to the full log, where its new event is the newest. 5. `templates/source_logs.html` (the disclosed heading total): under a filter that matches 50 events or fewer, the line beside "Full Event Log" reads "N total events" with N the filtered count. That states a wrong total for the webhook: a webhook holding five events shows "1 total event". Acceptable: under a filter the line says what it counts ("3 events with a failed delivery", "50 most recent of 101 events with a failed delivery"), or it keeps the webhook's own total. 6. PR body: about 280 words, over the limit of about 250. Acceptable: cut it to 250 words or fewer. - Deviation: the page was checked in the browser on the previous `next` head (`d8c60c9`). The two commits since then do not touch the event log page or its handler. Model: opus-5-5
clawbot added needs-rework and removed needs-review labels 2026-10-03 04:37:19 +02:00
clawbot force-pushed issue-390-event-log-filter from ae2ce55575 to 4b59194c81 2026-10-03 04:55:34 +02:00 Compare
clawbot added needs-review and removed needs-rework labels 2026-10-03 04:56:05 +02:00
Author
Collaborator

Rework pushed.

  1. Rebased onto current next; static/css/tailwind.css regenerated with make css.
  2. The filtered list takes the matching deliveries' distinct event IDs through idx_deliveries_status, looks each event up by ID and sorts them to keep the 50 newest; CROSS JOINs fix that order. The plan test asserts both reaches into the events table are lookups by ID; the code comment and PR body now say this.
  3. Added an event whose delivery and its replay both failed, and one with a pending and a retrying delivery; each is asserted listed and counted once.
  4. The Replay form carries show, read through eventLogStatuses; Resubmit still returns to the full log.
  5. Under a filter the line says what it counts: "2 events with a failed delivery", "50 most recent of 51 events with a failed delivery".
  6. Left for merge, as directed.
  • Judgement call: a second join reads the rows of only the events kept, so no other matching event's body is read.
  • Rule suppressed: gosec's open-redirect check on the replay redirect, as the login redirect already does.

Model: opus-5-5

Rework pushed. 1. Rebased onto current `next`; `static/css/tailwind.css` regenerated with `make css`. 2. The filtered list takes the matching deliveries' distinct event IDs through `idx_deliveries_status`, looks each event up by ID and sorts them to keep the 50 newest; `CROSS JOIN`s fix that order. The plan test asserts both reaches into the events table are lookups by ID; the code comment and PR body now say this. 3. Added an event whose delivery and its replay both failed, and one with a pending and a retrying delivery; each is asserted listed and counted once. 4. The Replay form carries `show`, read through `eventLogStatuses`; Resubmit still returns to the full log. 5. Under a filter the line says what it counts: "2 events with a failed delivery", "50 most recent of 51 events with a failed delivery". 6. Left for merge, as directed. - Judgement call: a second join reads the rows of only the events kept, so no other matching event's body is read. - Rule suppressed: gosec's open-redirect check on the replay redirect, as the login redirect already does. Model: opus-5-5
Author
Collaborator

Review: FAIL (needs-rebase)

  1. README.md, the paragraph in the logging section that lists the only query parameters the service reads: the branch no longer rebases onto current next (b9ec91c). That commit, for #399, renamed "the login page's next" there to "the sign-in page's next", and this PR rewrites the same lines to add show. Acceptable: rebase onto current next and keep both changes ("the sign-in page's next, the page to return to, notice, which names the line a page shows after an action, and the event log's show, which picks the events it lists"), then run make fmt.

This is the only finding.

  • Deviation: the rest of the change was checked on current next with that paragraph resolved locally as above; nothing else conflicts.

Model: opus-5-5

Review: FAIL (needs-rebase) 1. `README.md`, the paragraph in the logging section that lists the only query parameters the service reads: the branch no longer rebases onto current `next` (`b9ec91c`). That commit, for https://git.eeqj.de/sneak/webhooker/issues/399, renamed "the login page's `next`" there to "the sign-in page's `next`", and this PR rewrites the same lines to add `show`. Acceptable: rebase onto current `next` and keep both changes ("the sign-in page's `next`, the page to return to, `notice`, which names the line a page shows after an action, and the event log's `show`, which picks the events it lists"), then run `make fmt`. This is the only finding. - Deviation: the rest of the change was checked on current `next` with that paragraph resolved locally as above; nothing else conflicts. Model: opus-5-5
clawbot added needs-rebase and removed needs-review labels 2026-10-03 05:23:21 +02:00
clawbot added 1 commit 2026-10-03 05:28:16 +02:00
The event log gains three links above the list: All, Failed (N) and
Pending (N), carried in a `show` query parameter; any other value shows
every event. Failed lists the events with a failed delivery, Pending
those with one pending or retrying, each once, under the full list's
50-row limit and order. A filtered list finds the matching deliveries
through `idx_deliveries_status`, looks up their events by ID and sorts
them, and reads the rows of only the events shown; its counts read the
deliveries alone. The line beside the heading says what a filter
counts, and Replay returns to the list it was pressed in. The README
and the comments naming the query parameters the service reads include
`show`.

Model: opus-5-5
clawbot force-pushed issue-390-event-log-filter from 4b59194c81 to 48ecfaab34 2026-10-03 05:28:16 +02:00 Compare
clawbot added needs-review and removed needs-rebase labels 2026-10-03 05:28:20 +02:00
Author
Collaborator

Rebased onto current next.

  1. README.md, the paragraph listing the query parameters the service reads: kept both changes, as the review's Acceptable line gives it ("the sign-in page's next, the page to return to, notice, which names the line a page shows after an action, and the event log's show, which picks the events it lists").
  2. README.md route table: the event's own page keeps the entrypoint and request headers from #489, and the event log row keeps show.
  3. internal/handlers/source_management.go, loadEventLogRows: the filtered list keeps this PR's query and passes both cut lengths the event log's columns now take (request headers and body), as #489 does.
  4. static/css/tailwind.css regenerated with make css.
  • Judgement call: the code comments in internal/middleware/middleware.go and internal/server/sentry.go still say "the login page's next", as they do on next; #399 renamed only the README there.

Model: opus-5-5

Rebased onto current `next`. 1. `README.md`, the paragraph listing the query parameters the service reads: kept both changes, as the review's Acceptable line gives it ("the sign-in page's `next`, the page to return to, `notice`, which names the line a page shows after an action, and the event log's `show`, which picks the events it lists"). 2. `README.md` route table: the event's own page keeps the entrypoint and request headers from https://git.eeqj.de/sneak/webhooker/pulls/489, and the event log row keeps `show`. 3. `internal/handlers/source_management.go`, `loadEventLogRows`: the filtered list keeps this PR's query and passes both cut lengths the event log's columns now take (request headers and body), as https://git.eeqj.de/sneak/webhooker/pulls/489 does. 4. `static/css/tailwind.css` regenerated with `make css`. - Judgement call: the code comments in `internal/middleware/middleware.go` and `internal/server/sentry.go` still say "the login page's `next`", as they do on `next`; https://git.eeqj.de/sneak/webhooker/issues/399 renamed only the README there. Model: opus-5-5
Author
Collaborator

Re-gate passed on current next.

Model: opus-5-5

Re-gate passed on current `next`. Model: opus-5-5
clawbot merged commit 7e779f7fce into next 2026-10-03 05:40:35 +02:00
clawbot deleted branch issue-390-event-log-filter 2026-10-03 05:40:35 +02:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/webhooker#490