audit the whole app for stupid cases of missing functionality or basic things like this (like the stats panel at the top that i requested).
What is wrong:
Target edit page (templates/target_edit.html; applyTargetEdit in internal/handlers/target_edit.go, which calls buildTargetConfig in internal/handlers/source_management.go). Any rejected save answers with a bare text page, for example "Invalid timeout: timeout is out of range: at most 300 seconds". Causes include an empty name, a timeout over 300, a refused header, a refused destination and a bad archive expiry. The form is gone, every change typed into it is lost, and there is no link back. The page already has an error slot (renderTargetEdit takes a message), but these paths do not use it.
Webhook edit page (templates/source_edit.html, applyWebhookEdit). A rejected save shows its error in the form, but the form comes back with the stored name, description and retention. In the audit, a description typed alongside an empty name was lost.
#370 covers the same problem in the add-target form, and #373 covers it on the new-webhook page. This issue covers the two edit pages.
Definition of done:
A rejected save on the target edit page renders the edit form again, with the error shown above it and every submitted value kept: name, URL, headers, timeout, retries and expiry. The status code is the same as today.
A rejected save on the webhook edit page keeps the submitted name, description and retention.
Neither edit path answers a validation failure with plain text any more.
Tests: for each target type, a rejected edit renders the form with the error and the submitted values; the same for the webhook edit form.
PRIORITY: from the owner's audit request of 1 October (#377), in the tier of #367 to #376.
Model: opus-5-5
Owner's request, https://git.eeqj.de/sneak/webhooker/issues/377 (chat, 2026-10-01):
> audit the whole app for stupid cases of missing functionality or basic things like this (like the stats panel at the top that i requested).
What is wrong:
- **Target edit page** (`templates/target_edit.html`; `applyTargetEdit` in `internal/handlers/target_edit.go`, which calls `buildTargetConfig` in `internal/handlers/source_management.go`). Any rejected save answers with a bare text page, for example "Invalid timeout: timeout is out of range: at most 300 seconds". Causes include an empty name, a timeout over 300, a refused header, a refused destination and a bad archive expiry. The form is gone, every change typed into it is lost, and there is no link back. The page already has an error slot (`renderTargetEdit` takes a message), but these paths do not use it.
- **Webhook edit page** (`templates/source_edit.html`, `applyWebhookEdit`). A rejected save shows its error in the form, but the form comes back with the stored name, description and retention. In the audit, a description typed alongside an empty name was lost.
https://git.eeqj.de/sneak/webhooker/issues/370 covers the same problem in the add-target form, and https://git.eeqj.de/sneak/webhooker/issues/373 covers it on the new-webhook page. This issue covers the two edit pages.
Definition of done:
- A rejected save on the target edit page renders the edit form again, with the error shown above it and every submitted value kept: name, URL, headers, timeout, retries and expiry. The status code is the same as today.
- A rejected save on the webhook edit page keeps the submitted name, description and retention.
- Neither edit path answers a validation failure with plain text any more.
- Tests: for each target type, a rejected edit renders the form with the error and the submitted values; the same for the webhook edit form.
PRIORITY: from the owner's audit request of 1 October (https://git.eeqj.de/sneak/webhooker/issues/377), in the tier of https://git.eeqj.de/sneak/webhooker/issues/367 to https://git.eeqj.de/sneak/webhooker/issues/376.
Model: opus-5-5
clawbot
self-assigned this 2026-10-01 22:04:46 +02:00
Target edit page: every validation failure in applyTargetEdit (an empty name, a timeout out of range, a refused header or destination, a bad expiry) renders the edit form again through renderTargetEdit's existing error slot, with the error above the form and every submitted value kept, and the same status code as today. Validation returns its message instead of writing the response, as the add flow does since #463; an encoding or database failure stays a logged 500.
Webhook edit page: a rejected save keeps the submitted name, description and retention in the form.
Neither edit path answers a validation failure with plain text.
Tests: for each target type, a rejected edit renders the form with the error and the submitted values; the same for the webhook edit form.
Model: opus-5-5
Plan.
- **Target edit page:** every validation failure in `applyTargetEdit` (an empty name, a timeout out of range, a refused header or destination, a bad expiry) renders the edit form again through `renderTargetEdit`'s existing error slot, with the error above the form and every submitted value kept, and the same status code as today. Validation returns its message instead of writing the response, as the add flow does since https://git.eeqj.de/sneak/webhooker/pulls/463; an encoding or database failure stays a logged 500.
- **Webhook edit page:** a rejected save keeps the submitted name, description and retention in the form.
- Neither edit path answers a validation failure with plain text.
- Tests: for each target type, a rejected edit renders the form with the error and the submitted values; the same for the webhook edit form.
Model: opus-5-5
Done in #474. A refused save on the target edit page now shows the edit form again with the reason above it and every value submitted, with the same status codes as before. A refused save on the webhook edit page keeps the submitted name, description and retention. Target edits are now checked by the same validation as new targets, from #463, so there is no second copy. The browser test now also covers a refused save on both edit pages.
Judgement call: the 409 on the target edit page, when an archive file already has the new name, also comes back in the form, as it already did on the webhook edit page.
Model: opus-5-5
Done in https://git.eeqj.de/sneak/webhooker/pulls/474. A refused save on the target edit page now shows the edit form again with the reason above it and every value submitted, with the same status codes as before. A refused save on the webhook edit page keeps the submitted name, description and retention. Target edits are now checked by the same validation as new targets, from https://git.eeqj.de/sneak/webhooker/pulls/463, so there is no second copy. The browser test now also covers a refused save on both edit pages.
- Judgement call: the 409 on the target edit page, when an archive file already has the new name, also comes back in the form, as it already did on the webhook edit page.
Model: opus-5-5
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Owner's request, #377 (chat, 2026-10-01):
What is wrong:
templates/target_edit.html;applyTargetEditininternal/handlers/target_edit.go, which callsbuildTargetConfigininternal/handlers/source_management.go). Any rejected save answers with a bare text page, for example "Invalid timeout: timeout is out of range: at most 300 seconds". Causes include an empty name, a timeout over 300, a refused header, a refused destination and a bad archive expiry. The form is gone, every change typed into it is lost, and there is no link back. The page already has an error slot (renderTargetEdittakes a message), but these paths do not use it.templates/source_edit.html,applyWebhookEdit). A rejected save shows its error in the form, but the form comes back with the stored name, description and retention. In the audit, a description typed alongside an empty name was lost.#370 covers the same problem in the add-target form, and #373 covers it on the new-webhook page. This issue covers the two edit pages.
Definition of done:
PRIORITY: from the owner's audit request of 1 October (#377), in the tier of #367 to #376.
Model: opus-5-5
Plan.
applyTargetEdit(an empty name, a timeout out of range, a refused header or destination, a bad expiry) renders the edit form again throughrenderTargetEdit's existing error slot, with the error above the form and every submitted value kept, and the same status code as today. Validation returns its message instead of writing the response, as the add flow does since #463; an encoding or database failure stays a logged 500.Model: opus-5-5
Done in #474. A refused save on the target edit page now shows the edit form again with the reason above it and every value submitted, with the same status codes as before. A refused save on the webhook edit page keeps the submitted name, description and retention. Target edits are now checked by the same validation as new targets, from #463, so there is no second copy. The browser test now also covers a refused save on both edit pages.
Model: opus-5-5