Files
webhooker/TODO.md
T
sneak 370fad06fc
check / check (push) Waiting to run
Rewrite TODO.md sentence by sentence
Rewritten from scratch against the code on next; the sections and
their contents are kept.

Model: fable-5-1
2026-10-25 05:18:45 +00:00

3.6 KiB

Workflow

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

  • make sure a tracked issue exists with a definition of done
  • branch from next, never from main
  • do the work and push the branch
  • open a PR with base next, never main
  • pass an independent review
  • the repository manager squash-merges it into next

The repository manager is the role that merges each issue's PR into next. Nothing stays local-only: every commit is pushed.

next is the branch for the next milestone. It must stay green and mergeable into main at all times. A milestone's work reaches main through one PR from next. The owner, @sneak, merges that PR. Cutting a release from main is a separate step after that.

The tracker (https://git.eeqj.de/sneak/webhooker/issues) records 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. Only @sneak tags it.

Delivery is at least once by design. When webhooker cannot record the outcome of a delivery, it sends that delivery again. The target can then receive the same event twice. The alternative is a lost delivery that nothing reports. The README says so. Such a duplicate 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. It waits on neither the production run nor the tag.

Future Steps

  • Per-webhook rate limits, set in the web UI and enforced at the entrypoint. Today RECEIVER_RATE_LIMIT is the only rate-limit setting. It is how many requests per minute one client address may send to one entrypoint. The same address is also capped at ten times that across all entrypoints together.
  • API key authentication for programmatic access. The APIKey model and its api_keys table exist. Nothing creates a key and nothing checks one.
  • REST API v1. /api/v1 is mounted with no routes today.
    • CRUD for webhooks, entrypoints and 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. Today the webhook page shows event, delivery and failure counts and failure percentages. The target list counts each target's deliveries. The event log shows every attempt's duration. /metrics carries server-wide counts and delivery durations.
  • A remember-me option at login. Today every session survives a browser restart. It lasts up to 7 days. It ends sooner after SESSION_IDLE_TIMEOUT (default 24 hours) without use.
  • Password reset over the web for a forgotten password. Today a signed-in user can change their password. A lost password is reset from the command line with webhooker resetpw (#208).
  • Later, nice to have
    • email delivery target type
    • SNS and S3 delivery targets
    • data transformations, such as a configurable Slack message format. The Slack target sends one fixed format today.
    • JSONL file delivery with periodic S3 upload. Today an archive target writes events to SQLite files. An archive target can rotate those files hourly, daily or monthly. 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. Today each webhook belongs to one account. Only the account made at first boot exists. There is no way to add another.