Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eacf1e7926 |
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user