feat(watched-repos): F5 — watch/unwatch + automatic webhook lifecycle #503
No reviewers
Labels
No labels
area:agents
area:dashboard
area:database
area:design
area:design-review
area:flows
area:infra
area:meta
area:security
area:sessions
area:webhook
area:workdir
security
type:bug
type:chore
type:meta
type:user-story
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
charles/claude-hooks!503
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "dev/486"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Adds
POST/DELETE/PATCH /watched-reposendpoints that register and remove forge webhooks automatically when an operator watches or unwatches a repo.Closes #486
Test plan
POST /watched-reposwith{ owner, name }→ 201, row inwatched_repos, forge webhook created; webhook URL is<public_base_url>/webhooks/<forge_type>.POST /watched-reposwith no active forge → 412.POST /watched-reposfor an already-watched repo → 409.DELETE /watched-repos/:owner/:name→ 204, forge webhook deleted, row removed. 404 from forge still removes the row.PATCH /watched-repos/:owner/:name{ enabled: false }→ 200, forge webhook deactivated.GET /watched-repos→ 200, lists all rows.public_base_urlabsent with OAuth clients configured → startup error.CI green. All 8 ACs verified:
watched_reposschema correct,randomBytes(32).toString("hex")64-char secret, per-forge webhook lifecycle (Forgejo/GitHub/GitLab), idempotency 409, row persists withwebhook_id=nullon forge failure,public_base_urlstartup guard,guardMutatingon all routes, 15 tests covering 412 guards + per-forge round-trips + validation.Nit: DELETE/PATCH apply
checkActiveForge(), so they return 412 if no forge is active — AC says "unwatch rows from any forge they have an OAuth row for." The stated cleanup use case (switching forges) always has an active forge set, so this doesn't block the workflow in practice.b80f02479b83142e117f83142e117f5c4ec3b0675c4ec3b0678318132d038318132d03d2dce5b88cd2dce5b88c437fa6d5f0437fa6d5f01d45db66211d45db66211fdbbabb171fdbbabb172bfa2f6adb