Rewrite TODO.md sentence by sentence
check / check (push) Waiting to run

Rewritten from scratch against the code on next; the sections and
their contents are kept.

Model: fable-5-1
This commit is contained in:
2026-10-25 02:24:03 +00:00
parent 54b643044f
commit 11c8b6b851
+40 -44
View File
@@ -1,72 +1,68 @@
# Workflow # Workflow
One issue per unit of work, one branch and one PR per issue: One issue per unit of work, and one branch and one PR per issue:
- ensure a tracked issue exists with a definition of done - make sure a tracked issue exists with a definition of done
- branch from `next` (never from `main`) - branch from `next`, never from `main`
- do the work; open a PR based on `next` (never on `main`) - do the work, then open a PR with base `next`, never `main`
- pass an independent review, then the manager squash-merges into `next` - pass an independent review; the manager then squash-merges into `next`
- push; nothing stays local-only - push; nothing stays local-only
`next` is the branch for the next milestone and must stay green and mergeable to `next` is the branch for the next milestone. It must stay green and mergeable
`main` without notice. One `next` -> `main` PR accumulates the milestone; into `main` at all times. One PR from `next` into `main` accumulates the
releases are cut from `main` separately. milestone. Releases are cut from `main` separately.
The tracker (https://git.eeqj.de/sneak/webhooker/issues) is the record of what The tracker (https://git.eeqj.de/sneak/webhooker/issues) records what is done
is done and what is under way. This file keeps no list of either. and what is under way. This file keeps no list of either.
# Status # Status
What is still open for 1.0.0 is in its milestone 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 (https://git.eeqj.de/sneak/webhooker/milestone/9). `v1.0.0` is not tagged. Only
only @sneak tags it. @sneak tags it.
Delivery is at-least-once by design, not by accident: a send whose result row Delivery is at least once by design. A send whose result row does not land is
does not land is attempted again, so a receiver can see a duplicate. That is sent again, so a receiver can see a duplicate. The alternative is a silent lost
deliberate — the alternative is a silent lost delivery — and the README says so delivery. The README says so under How it works. It is not a defect to re-file.
under Rationale. It is not a defect to re-file.
# Next Step # Next Step
@sneak runs webhooker in limited production, then tags `v1.0.0`. Merging `next` @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` into `main` is a separate act from tagging and waits on neither. `next` is kept
is kept mergeable at all times, which is the point of the branch. mergeable at all times; that is the point of the branch.
# Future Steps # Future Steps
- Per-webhook rate limits, set in the web UI and enforced in the receiver - Per-webhook rate limits, set in the web UI and enforced in the receiver. Today
handler, on top of the receiver's existing limits, which `RECEIVER_RATE_LIMIT` `RECEIVER_RATE_LIMIT` sets one limit for every entrypoint on the server.
sets for the whole server (see Rate Limiting in the README) - API key authentication for programmatic access. The `APIKey` table exists, but
- API key authentication for programmatic access (the `APIKey` model exists, but nothing creates a key and nothing checks one.
nothing creates a key and no middleware checks one) - REST API v1. `/api/v1` is mounted with no routes today.
- REST API v1 - CRUD for webhooks, entrypoints and targets
- CRUD for webhooks, entrypoints, targets
- event viewing and filtering endpoints - event viewing and filtering endpoints
- event redelivery endpoint - event redelivery endpoint
- OpenAPI specification - OpenAPI specification
- Analytics in the web UI: response times summarised per webhook or per target, - 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, and figures for all webhooks together. Today the webhook page shows event,
delivery and failure counts and failure percentages, the target list counts 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 each target's deliveries. The event log shows every attempt's duration.
attempt's duration, and `/metrics` carries server-wide counts and delivery `/metrics` carries server-wide counts and delivery durations.
durations - A remember-me option at login. Today every session survives a browser restart.
- A remember-me option at login. Every session already survives a browser It lasts up to 7 days, and ends sooner after `SESSION_IDLE_TIMEOUT` (default
restart: it lasts up to 7 days, and ends sooner after `SESSION_IDLE_TIMEOUT` 24 hours) without use.
(default 24 hours) without activity - Password reset over the web for a forgotten password. Today a signed-in user
- Password reset flow for a forgotten password over the web. The authenticated can change their password, and a lost password is reset from the console with
password _change_ flow already landed, and a lost password is recoverable from `webhooker resetpw` (https://git.eeqj.de/sneak/webhooker/issues/208).
the console with `webhooker resetpw`
(https://git.eeqj.de/sneak/webhooker/issues/208)
- Later, nice to have - Later, nice to have
- email delivery target type - email delivery target type
- SNS and S3 delivery targets - SNS and S3 delivery targets
- data transformations (e.g. a configurable Slack message format; the Slack - data transformations, such as a configurable Slack message format; the
target sends one fixed format today) Slack target sends one fixed format today
- JSONL file delivery with periodic S3 upload (the `database` target already - JSONL file delivery with periodic S3 upload. Today the `database` target
archives events to SQLite files, rotated hourly, daily or monthly if set, archives events to SQLite files, rotated hourly, daily or monthly if set,
and the webhook page offers them as one gzipped JSON download) and the webhook page offers them as one gzipped JSON download.
- webhook event search, and filtering beyond the event log's failed and - webhook event search, and filtering beyond the event log's failed and
pending views pending views
- multi-user with role-based access control (each webhook already belongs to - multi-user with role-based access control. Today each webhook belongs to
one account, but there is only the account made at first boot and no way one account, but only the account made at first boot exists and there is
to add another) no way to add another.