Files
webhooker/TODO.md
T
clawbot c8efbd41d4
check / check (push) Waiting to run
Drop Completed Steps from TODO.md; the tracker is the record (closes #112)
Every issue branch added an entry to the same list, so each branch
conflicted with `next` as soon as another one landed. The tracker already
records what is done, in more detail than the list did.

The Workflow section now says the tracker is that record, in place of the
rule that issue branches leave this file alone. Status points to the 1.0.0
milestone for what is open, and Next Step says @sneak tags `v1.0.0` after
running webhooker in limited production. In Future Steps, each item that
overlaps with what webhooker already does now says what exists and what is
still missing, and the delivery status and retry UI item is gone because the
event log, replay and resubmit cover it.

Model: opus-5-5
2026-10-13 07:18:48 +02:00

3.4 KiB

Workflow

One issue per unit of work, one branch and one PR per issue:

  • ensure a tracked issue exists with a definition of done
  • branch from next (never from main)
  • do the work; open a PR based on next (never on main)
  • pass an independent review, then the manager squash-merges into next
  • push; nothing stays local-only

next is the branch for the next milestone and must stay green and mergeable to main without notice. One next -> main PR accumulates the milestone; releases are cut from main separately.

The tracker (https://git.eeqj.de/sneak/webhooker/issues) is the record of what is done and what is under way. This file keeps no list of either.

Status

What is still open for 1.0.0 is in its milestone (https://git.eeqj.de/sneak/webhooker/milestone/9). v1.0.0 is not tagged, and only @sneak tags it.

Delivery is at-least-once by design, not by accident: a send whose result row does not land is attempted again, so a receiver can see a duplicate. That is deliberate — the alternative is a silent lost delivery — and the README says so under Rationale. It is not a defect to re-file.

Next Step

@sneak runs webhooker in limited production, then tags v1.0.0. Merging next into main is a separate act from tagging and waits on neither of those: next is kept mergeable at all times, which is the point of the branch.

Future Steps

  • Per-webhook rate limits, set in the web UI and enforced in the receiver handler, on top of the receiver's existing limits, which RECEIVER_RATE_LIMIT sets for the whole server (see Rate Limiting in the README)
  • API key authentication for programmatic access (the APIKey model exists, but nothing creates a key and no middleware checks one)
  • REST API v1
    • CRUD for webhooks, entrypoints, targets
    • event viewing and filtering endpoints
    • event redelivery endpoint
    • OpenAPI specification
  • Analytics in the web UI: response times summarised per webhook or per target, and figures for all webhooks together. The webhook page already shows event, delivery and failure counts and failure percentages, the target list counts each target's deliveries, the event log and each event's page show every attempt's duration, and /metrics carries server-wide counts and delivery durations
  • A remember-me option at login. Every session already survives a browser restart: it lasts up to 7 days, and ends sooner after SESSION_IDLE_TIMEOUT (default 24 hours) without activity
  • Password reset flow for a forgotten password over the web. The authenticated password change flow already landed, and a lost password is recoverable from the console with webhooker resetpw (#208)
  • Later, nice to have
    • email delivery target type
    • SNS and S3 delivery targets
    • data transformations (e.g. a configurable Slack message format; the Slack target sends one fixed format today)
    • JSONL file delivery with periodic S3 upload (the database target already archives events to SQLite files, rotated hourly, daily or monthly if set, and the webhook page offers them as one gzipped JSON download)
    • webhook event search, and filtering beyond the event log's failed and pending views
    • multi-user with role-based access control (each webhook already belongs to one account, but there is only the account made at first boot and no way to add another)