Author SHA1 Message Date
sneak eacf1e7926 next into main (#556)
check / check (push) Waiting to run
Reviewed-on: #556
2026-10-25 02:52:09 +01:00
+46 -51
View File
@@ -1,77 +1,72 @@
# Workflow # Workflow
One issue per unit of work, and one branch and one PR per issue: One issue per unit of work, one branch and one PR per issue:
- make sure a tracked issue exists with a definition of done - ensure a tracked issue exists with a definition of done
- branch from `next`, never from `main` - branch from `next` (never from `main`)
- do the work and push the branch - do the work; open a PR based on `next` (never on `main`)
- open a PR with base `next`, never `main` - pass an independent review, then the manager squash-merges into `next`
- pass an independent review - push; nothing stays local-only
- the repository manager squash-merges it into `next`
The repository manager is the role that merges each issue's PR into `next`. `next` is the branch for the next milestone and must stay green and mergeable to
Nothing stays local-only: every commit is pushed. `main` without notice. One `next` -> `main` PR accumulates the milestone;
releases are cut from `main` separately.
`next` is the branch for the next milestone. It must stay green and mergeable The tracker (https://git.eeqj.de/sneak/webhooker/issues) is the record of what
into `main` at all times. A milestone's work reaches `main` through one PR from is done and what is under way. This file keeps no list of either.
`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 # 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. Only (https://git.eeqj.de/sneak/webhooker/milestone/9). `v1.0.0` is not tagged, and
@sneak tags it. only @sneak tags it.
Delivery is at least once by design. When webhooker cannot record the outcome of Delivery is at-least-once by design, not by accident: a send whose result row
a delivery, it sends that delivery again. The target can then receive the same does not land is attempted again, so a receiver can see a duplicate. That is
event twice. The alternative is a lost delivery that nothing reports. The README deliberate — the alternative is a silent lost delivery — and the README says so
says so. Such a duplicate 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. It waits on neither the production run nor the into `main` is a separate act from tagging and waits on neither of those: `next`
tag. is kept mergeable at all times, which is the point of the branch.
# Future Steps # Future Steps
- Per-webhook rate limits, set in the web UI and enforced at the entrypoint. - Per-webhook rate limits, set in the web UI and enforced in the receiver
Today `RECEIVER_RATE_LIMIT` is the only rate-limit setting. It is how many handler, on top of the receiver's existing limits, which `RECEIVER_RATE_LIMIT`
requests per minute one client address may send to one entrypoint. The same sets for the whole server (see Rate Limiting in the README)
address is also capped at ten times that across all entrypoints together. - API key authentication for programmatic access (the `APIKey` model exists, but
- API key authentication for programmatic access. The `APIKey` model and its nothing creates a key and no middleware checks one)
`api_keys` table exist. Nothing creates a key and nothing checks one. - REST API v1
- REST API v1. `/api/v1` is mounted with no routes today. - CRUD for webhooks, entrypoints, targets
- CRUD for webhooks, entrypoints and 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. Today the webhook page shows event, and figures for all webhooks together. The webhook page already 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 shows every attempt's duration. each target's deliveries, the event log and each event's page show every
`/metrics` carries server-wide counts and delivery durations. attempt's duration, and `/metrics` carries server-wide counts and delivery
- A remember-me option at login. Today every session survives a browser restart. durations
It lasts up to 7 days. It ends sooner after `SESSION_IDLE_TIMEOUT` (default 24 - A remember-me option at login. Every session already survives a browser
hours) without use. restart: it lasts up to 7 days, and ends sooner after `SESSION_IDLE_TIMEOUT`
- Password reset over the web for a forgotten password. Today a signed-in user (default 24 hours) without activity
can change their password. A lost password is reset from the command line with - Password reset flow for a forgotten password over the web. The authenticated
`webhooker resetpw` (https://git.eeqj.de/sneak/webhooker/issues/208). password _change_ flow already landed, and a lost password is recoverable from
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, such as a configurable Slack message format. The - data transformations (e.g. a configurable Slack message format; the Slack
Slack target sends one fixed format today. target sends one fixed format today)
- JSONL file delivery with periodic S3 upload. Today an archive target - JSONL file delivery with periodic S3 upload (the `database` target already
writes events to SQLite files. An archive target can rotate those files archives events to SQLite files, rotated hourly, daily or monthly if set,
hourly, daily or monthly. The webhook page offers them as one gzipped JSON and the webhook page offers them as one gzipped JSON download)
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. Today each webhook belongs to - multi-user with role-based access control (each webhook already belongs to
one account. Only the account made at first boot exists. There is no way one account, but there is only the account made at first boot and no way
to add another. to add another)