fix: correct 4 factual inaccuracies in README
All checks were successful
check / check (push) Successful in 1m2s

- Fix webhook route: /hooks/<uuid> → /webhook/{uuid} (matches routes.go)
- Fix CGO claims: acknowledge mattn/go-sqlite3 transitive dep requires CGO at build time
- Fix database architecture: distinguish current single-DB from planned Phase 2 per-webhook split
- Fix static file descriptions: Bootstrap CSS/jQuery JS → actual style.css and app.js
This commit is contained in:
clawbot
2026-03-01 10:22:08 -08:00
parent 87ff336013
commit 1e8becc4bd

View File

@@ -150,8 +150,10 @@ It uses:
lifecycle management lifecycle management
- **[go-chi](https://github.com/go-chi/chi)** for HTTP routing - **[go-chi](https://github.com/go-chi/chi)** for HTTP routing
- **[GORM](https://gorm.io)** for database access with - **[GORM](https://gorm.io)** for database access with
**[modernc.org/sqlite](https://pkg.go.dev/modernc.org/sqlite)** (pure **[modernc.org/sqlite](https://pkg.go.dev/modernc.org/sqlite)** as
Go, no CGO) as the storage backend the runtime SQLite driver. Note: `gorm.io/driver/sqlite` transitively
depends on `mattn/go-sqlite3`, which requires CGO at build time (see
[Docker](#docker) section)
- **[slog](https://pkg.go.dev/log/slog)** (stdlib) for structured - **[slog](https://pkg.go.dev/log/slog)** (stdlib) for structured
logging with TTY detection (text for dev, JSON for prod) logging with TTY detection (text for dev, JSON for prod)
- **[gorilla/sessions](https://github.com/gorilla/sessions)** for - **[gorilla/sessions](https://github.com/gorilla/sessions)** for
@@ -198,7 +200,7 @@ tier** (event ingestion, delivery, and logging).
┌─────────────────────────────────────────────────────────────┐ ┌─────────────────────────────────────────────────────────────┐
│ EVENT TIER │ │ EVENT TIER │
(per-webhook dedicated database) (planned: per-webhook dedicated database) │
│ │ │ │
│ ┌──────────┐ ┌──────────┐ ┌─────────────────┐ │ │ ┌──────────┐ ┌──────────┐ ┌─────────────────┐ │
│ │ Event │──1:N──│ Delivery │──1:N──│ DeliveryResult │ │ │ │ Event │──1:N──│ Delivery │──1:N──│ DeliveryResult │ │
@@ -254,7 +256,7 @@ the full request and creates an Event.
| -------------- | ------- | ----------- | | -------------- | ------- | ----------- |
| `id` | UUID | Primary key | | `id` | UUID | Primary key |
| `processor_id` | UUID | Foreign key → Webhook | | `processor_id` | UUID | Foreign key → Webhook |
| `path` | string | Unique URL path (UUID-based, e.g. `/hooks/<uuid>`) | | `path` | string | Unique URL path (UUID-based, e.g. `/webhook/{uuid}`) |
| `description` | string | Optional description | | `description` | string | Optional description |
| `active` | boolean | Whether this entrypoint accepts events (default: true) | | `active` | boolean | Whether this entrypoint accepts events (default: true) |
@@ -387,12 +389,21 @@ All entities include these fields from `BaseModel`:
### Database Architecture ### Database Architecture
webhooker uses **separate SQLite database files** rather than a single #### Current Implementation
monolithic database. This is a deliberate architectural choice.
#### Main Application Database webhooker currently uses a **single SQLite database** for all data —
application configuration, user accounts, and (once implemented) event
storage. The database connection is managed by GORM with a single
connection string configured via `DBURL`. On first startup the database
is auto-migrated and an `admin` user is created.
A single SQLite file stores all application-level data: #### Planned: Per-Webhook Event Databases (Phase 2)
In a future phase (see TODO Phase 2 below), webhooker will split into
**separate SQLite database files**: a main application database for
configuration data and per-webhook databases for event storage.
**Main Application Database** — will store:
- **Users** — accounts and Argon2id password hashes - **Users** — accounts and Argon2id password hashes
- **Webhooks** (Processors) — webhook configurations - **Webhooks** (Processors) — webhook configurations
@@ -400,18 +411,14 @@ A single SQLite file stores all application-level data:
- **Targets** — delivery destination configurations - **Targets** — delivery destination configurations
- **APIKeys** — programmatic access credentials - **APIKeys** — programmatic access credentials
This database is small, low-write, and contains the configuration that **Per-Webhook Event Databases** — each webhook will get its own
defines how the application behaves. It is backed up as a single file. dedicated SQLite file containing:
#### Per-Webhook Event Databases
Each webhook gets its own dedicated SQLite database file containing:
- **Events** — captured incoming webhook payloads - **Events** — captured incoming webhook payloads
- **Deliveries** — event-to-target pairings and their status - **Deliveries** — event-to-target pairings and their status
- **DeliveryResults** — individual delivery attempt logs - **DeliveryResults** — individual delivery attempt logs
This separation provides: This planned separation will provide:
- **Isolation** — a high-volume webhook won't cause lock contention or - **Isolation** — a high-volume webhook won't cause lock contention or
WAL bloat affecting the main application or other webhooks. WAL bloat affecting the main application or other webhooks.
@@ -421,22 +428,23 @@ This separation provides:
- **Clean deletion** — removing a webhook and all its history is as - **Clean deletion** — removing a webhook and all its history is as
simple as deleting one file. simple as deleting one file.
- **Per-webhook retention** — the `retention_days` field on each webhook - **Per-webhook retention** — the `retention_days` field on each webhook
controls automatic cleanup of old events in that webhook's database will control automatic cleanup of old events in that webhook's
only. database only.
- **Performance** — each webhook's database has its own WAL, its own - **Performance** — each webhook's database will have its own WAL, its
page cache, and its own lock, so concurrent event ingestion across own page cache, and its own lock, so concurrent event ingestion across
webhooks never contends. webhooks won't contend.
All databases use the pure-Go SQLite driver The database uses the
([modernc.org/sqlite](https://pkg.go.dev/modernc.org/sqlite)) — no CGO [modernc.org/sqlite](https://pkg.go.dev/modernc.org/sqlite) driver at
required. runtime, though CGO is required at build time due to the transitive
`mattn/go-sqlite3` dependency from `gorm.io/driver/sqlite`.
### Request Flow ### Request Flow
``` ```
External Service External Service
│ POST /hooks/<uuid> │ POST /webhook/{uuid}
┌─────────────┐ ┌──────────────┐ ┌──────────────┐ ┌─────────────┐ ┌──────────────┐ ┌──────────────┐
│ chi Router │────►│ Middleware │────►│ Webhook │ │ chi Router │────►│ Middleware │────►│ Webhook │
@@ -484,7 +492,7 @@ against a misbehaving sender).
| `GET` | `/` | Web UI index page (server-rendered) | | `GET` | `/` | Web UI index page (server-rendered) |
| `GET` | `/.well-known/healthcheck` | Health check (JSON: status, uptime, version) | | `GET` | `/.well-known/healthcheck` | Health check (JSON: status, uptime, version) |
| `GET` | `/s/*` | Static file serving (embedded CSS, JS) | | `GET` | `/s/*` | Static file serving (embedded CSS, JS) |
| `ANY` | `/hooks/<uuid>` | Webhook receiver endpoint (POST only; others return 405) | | `ANY` | `/webhook/{uuid}` | Webhook receiver endpoint (accepts all methods) |
#### Authentication Endpoints #### Authentication Endpoints
@@ -579,8 +587,8 @@ webhooker/
├── pkg/config/ # Reusable multi-environment config library ├── pkg/config/ # Reusable multi-environment config library
├── static/ ├── static/
│ ├── static.go # //go:embed directive │ ├── static.go # //go:embed directive
│ ├── css/ # Bootstrap CSS │ ├── css/style.css # Custom stylesheet (system font stack, card effects, layout)
│ └── js/ # Bootstrap + jQuery JS │ └── js/app.js # Client-side JavaScript (minimal bootstrap)
├── templates/ # Go HTML templates (base, index, login, etc.) ├── templates/ # Go HTML templates (base, index, login, etc.)
├── configs/ ├── configs/
│ └── config.yaml.example # Example configuration file │ └── config.yaml.example # Example configuration file
@@ -662,7 +670,7 @@ linted, tested, and compiled.
## TODO ## TODO
### Phase 1: Core Webhook Engine ### Phase 1: Core Webhook Engine
- [ ] Implement webhook reception and event storage at `/hooks/<uuid>` - [ ] Implement webhook reception and event storage at `/webhook/{uuid}`
- [ ] Build event processing and target delivery engine - [ ] Build event processing and target delivery engine
- [ ] Implement HTTP target type (fire-and-forget POST) - [ ] Implement HTTP target type (fire-and-forget POST)
- [ ] Implement retry target type (exponential backoff) - [ ] Implement retry target type (exponential backoff)