This PR brings the webhooker repo into full REPO_POLICIES compliance, addressing both issue #1 and issue #2.
Changes
New files
cmd/webhooker/main.go — The missing application entry point. Uses Uber fx to wire together all internal packages (config, database, logger, server, handlers, middleware, healthcheck, globals, session). Minimal glue code.
REPO_POLICIES.md — Fetched from authoritative source (sneak/prompts)
.editorconfig — Fetched from authoritative source
.dockerignore — Sensible Go project exclusions
.gitea/workflows/check.yml — CI workflow that runs docker build . on push to any branch (Gitea Actions format, actions/checkout pinned by sha256)
configs/config.yaml.example — Moved from root config.yaml
Modified files
Makefile — Complete rewrite with all REPO_POLICIES required targets: test, lint, fmt, fmt-check, check, build, hooks, docker, clean, plus dev, run, deps
Dockerfile — Complete rewrite:
Builder: golang:1.24 (Debian-based, pinned by sha256:d2d2bc1c84f7...). Debian needed because gorm.io/driver/sqlite pulls mattn/go-sqlite3 (CGO) which fails on Alpine musl.
golangci-lint v1.64.8 installed from GitHub release archive with sha256 verification (v1.x because .golangci.yml uses v1 config format)
Runs make check (fmt-check + lint + test + build) as build step
Final stage: alpine:3.21 (pinned by sha256:c3f8e73fdb79...) with non-root user, healthcheck, port 8080
README.md — Rewritten with all required REPO_POLICIES sections: description line with name/purpose/category/license/author, Getting Started, Rationale, Design, TODO (integrated from TODO.md), License, Author
.gitignore — Fixed webhooker pattern to /webhooker (was blocking cmd/webhooker/), added config.yaml to prevent committing runtime config with secrets
static/static.go — Removed vendor from embed directive (directory was empty/missing)
internal/database/database_test.go — Fixed to use in-memory config via afero.MemMapFs instead of depending on config.yaml on disk. Test is now properly isolated.
go.mod/go.sum — go mod tidy
Removed files
TODO.md — Content integrated into README.md TODO section
config.yaml — Moved to configs/config.yaml.example
Verification
docker build . passes (lint ✅, test ✅, build ✅)
All existing tests pass with no modifications to assertions or test logic
## Summary
This PR brings the webhooker repo into full REPO_POLICIES compliance, addressing both [issue #1](https://git.eeqj.de/sneak/webhooker/issues/1) and [issue #2](https://git.eeqj.de/sneak/webhooker/issues/2).
## Changes
### New files
- **`cmd/webhooker/main.go`** — The missing application entry point. Uses Uber fx to wire together all internal packages (config, database, logger, server, handlers, middleware, healthcheck, globals, session). Minimal glue code.
- **`REPO_POLICIES.md`** — Fetched from authoritative source (`sneak/prompts`)
- **`.editorconfig`** — Fetched from authoritative source
- **`.dockerignore`** — Sensible Go project exclusions
- **`.gitea/workflows/check.yml`** — CI workflow that runs `docker build .` on push to any branch (Gitea Actions format, actions/checkout pinned by sha256)
- **`configs/config.yaml.example`** — Moved from root `config.yaml`
### Modified files
- **`Makefile`** — Complete rewrite with all REPO_POLICIES required targets: `test`, `lint`, `fmt`, `fmt-check`, `check`, `build`, `hooks`, `docker`, `clean`, plus `dev`, `run`, `deps`
- **`Dockerfile`** — Complete rewrite:
- Builder: `golang:1.24` (Debian-based, pinned by `sha256:d2d2bc1c84f7...`). Debian needed because `gorm.io/driver/sqlite` pulls `mattn/go-sqlite3` (CGO) which fails on Alpine musl.
- golangci-lint v1.64.8 installed from GitHub release archive with sha256 verification (v1.x because `.golangci.yml` uses v1 config format)
- Runs `make check` (fmt-check + lint + test + build) as build step
- Final stage: `alpine:3.21` (pinned by `sha256:c3f8e73fdb79...`) with non-root user, healthcheck, port 8080
- **`README.md`** — Rewritten with all required REPO_POLICIES sections: description line with name/purpose/category/license/author, Getting Started, Rationale, Design, TODO (integrated from TODO.md), License, Author
- **`.gitignore`** — Fixed `webhooker` pattern to `/webhooker` (was blocking `cmd/webhooker/`), added `config.yaml` to prevent committing runtime config with secrets
- **`static/static.go`** — Removed `vendor` from embed directive (directory was empty/missing)
- **`internal/database/database_test.go`** — Fixed to use in-memory config via `afero.MemMapFs` instead of depending on `config.yaml` on disk. Test is now properly isolated.
- **`go.mod`/`go.sum`** — `go mod tidy`
### Removed files
- **`TODO.md`** — Content integrated into README.md TODO section
- **`config.yaml`** — Moved to `configs/config.yaml.example`
## Verification
- `docker build .` passes (lint ✅, test ✅, build ✅)
- All existing tests pass with no modifications to assertions or test logic
- `.golangci.yml` untouched
closes https://git.eeqj.de/sneak/webhooker/issues/1
closes https://git.eeqj.de/sneak/webhooker/issues/2
Reviewed for REPO_POLICIES compliance. All checks verified:
Code Changes
cmd/webhooker/main.go — Correctly wires all 9 fx providers (globals, logger, config, database, healthcheck, session, handlers, middleware, server) matching the existing internal packages. Build-time variables properly set via global vars.
static/static.go — Removed vendor from //go:embed directive. Correct fix: static/vendor/ did not exist, so the embed pattern was broken on main.
go.mod/go.sum — Removed unused github.com/spf13/viper (and its transitive deps). Promoted github.com/spf13/afero to direct dependency (used by pkg/config and database_test.go). Clean go mod tidy.
Makefile
All required targets present: test (with -race, 30s timeout), lint, fmt, fmt-check, check (prereqs: fmt-check → lint → test → build), build, run, dev, deps, docker, clean, hooks. Default goal is check.
Dockerfile
Builder: golang pinned by sha256 with # golang:1.24 (bookworm) — 2026-03-01 comment ✅
Final: alpine pinned by sha256 with # alpine:3.21 — 2026-03-01 comment ✅
Debian-based builder (correct — mattn/go-sqlite3 CGO transitive dep fails on musl)
golangci-lint v1.64.8 installed via wget + sha256sum -c verification, NOT curl|bash✅
Multi-arch support (amd64/arm64) with separate sha256 hashes ✅
RUN make check runs all checks as a build step ✅
Binary copied from bin/webhooker (matches Makefile build target output) ✅
CI Workflow
.gitea/workflows/check.yml — actions/checkout pinned by commit SHA (@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 2024-10-23), runs docker build . on push to all branches. ✅
REPO_POLICIES.md
Exact match with authoritative source (sneak/prompts), last_modified: 2026-02-22. ✅
README.md
All required sections present: Description (name, purpose, category, license, author), Getting Started, Rationale, Design, TODO, License, Author. TODO content migrated from removed TODO.md. ✅
Other Files
.editorconfig — Standard (space indent, LF, UTF-8, tab for Makefile) ✅
.dockerignore — Comprehensive ✅
config.yaml → configs/config.yaml.example — Proper rename, config.yaml added to .gitignore✅
TODO.md — Removed, content preserved in README TODO section ✅
Tests
.golangci.yml — NOT modified✅
database_test.go — Improved, not weakened. Now uses afero.MemMapFs for config (no disk dependency) and t.TempDir() for test DB (no leftover files). Same assertions retained (DB instance non-nil, SELECT 1 query). ✅
No test skipping, no assertion weakening, no cheating detected ✅
Docker Build
Ran docker build . locally — all fmt-check, lint, test, and build steps pass. Image builds successfully. ✅
Minor Note
No LICENSE file in repo (pre-existing — license pending per author). Not a blocker for this PR.
## Review: PASS ✅
Reviewed for REPO_POLICIES compliance. All checks verified:
### Code Changes
- **`cmd/webhooker/main.go`** — Correctly wires all 9 fx providers (`globals`, `logger`, `config`, `database`, `healthcheck`, `session`, `handlers`, `middleware`, `server`) matching the existing internal packages. Build-time variables properly set via global vars.
- **`static/static.go`** — Removed `vendor` from `//go:embed` directive. Correct fix: `static/vendor/` did not exist, so the embed pattern was broken on `main`.
- **`go.mod`/`go.sum`** — Removed unused `github.com/spf13/viper` (and its transitive deps). Promoted `github.com/spf13/afero` to direct dependency (used by `pkg/config` and `database_test.go`). Clean `go mod tidy`.
### Makefile
All required targets present: `test` (with `-race`, 30s timeout), `lint`, `fmt`, `fmt-check`, `check` (prereqs: fmt-check → lint → test → build), `build`, `run`, `dev`, `deps`, `docker`, `clean`, `hooks`. Default goal is `check`.
### Dockerfile
- Builder: `golang` pinned by sha256 with `# golang:1.24 (bookworm) — 2026-03-01` comment ✅
- Final: `alpine` pinned by sha256 with `# alpine:3.21 — 2026-03-01` comment ✅
- Debian-based builder (correct — `mattn/go-sqlite3` CGO transitive dep fails on musl)
- golangci-lint v1.64.8 installed via `wget` + `sha256sum -c` verification, NOT `curl|bash` ✅
- Multi-arch support (amd64/arm64) with separate sha256 hashes ✅
- `RUN make check` runs all checks as a build step ✅
- Binary copied from `bin/webhooker` (matches Makefile `build` target output) ✅
### CI Workflow
`.gitea/workflows/check.yml` — `actions/checkout` pinned by commit SHA (`@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 2024-10-23`), runs `docker build .` on push to all branches. ✅
### REPO_POLICIES.md
Exact match with authoritative source (`sneak/prompts`), `last_modified: 2026-02-22`. ✅
### README.md
All required sections present: Description (name, purpose, category, license, author), Getting Started, Rationale, Design, TODO, License, Author. TODO content migrated from removed `TODO.md`. ✅
### Other Files
- `.editorconfig` — Standard (space indent, LF, UTF-8, tab for Makefile) ✅
- `.dockerignore` — Comprehensive ✅
- `config.yaml` → `configs/config.yaml.example` — Proper rename, `config.yaml` added to `.gitignore` ✅
- `TODO.md` — Removed, content preserved in README TODO section ✅
### Tests
- `.golangci.yml` — **NOT modified** ✅
- `database_test.go` — **Improved**, not weakened. Now uses `afero.MemMapFs` for config (no disk dependency) and `t.TempDir()` for test DB (no leftover files). Same assertions retained (DB instance non-nil, `SELECT 1` query). ✅
- No test skipping, no assertion weakening, no cheating detected ✅
### Docker Build
Ran `docker build .` locally — all fmt-check, lint, test, and build steps pass. Image builds successfully. ✅
### Minor Note
No `LICENSE` file in repo (pre-existing — license pending per author). Not a blocker for this PR.
---
Closes [#1](https://git.eeqj.de/sneak/webhooker/issues/1) and [#2](https://git.eeqj.de/sneak/webhooker/issues/2). Ready to merge.
update all module paths to sneak.berlin/go/webhooker from git.eeqj.de/sneak/webhooker. drop .json from healthcheck URL per repo policy and/or code style guidelines. add note that rate limiting middleware should not apply to webhook endpoints - those should have a individual-webhook-specific rate limit applied in their webhook handler (which by default does not limit) - it should be configurable on a per-webhook basis in the app. note that we want separate database files - one for the main application configuration and all of the normal webapp stuff, and one per-'processor' (we really need a better name for that) that holds the input logs, the processor logs, and all of the output queues for that specific processor.
update all module paths to `sneak.berlin/go/webhooker` from `git.eeqj.de/sneak/webhooker`. drop `.json` from healthcheck URL per repo policy and/or code style guidelines. add note that rate limiting middleware should not apply to webhook endpoints - those should have a individual-webhook-specific rate limit applied in their webhook handler (which by default does not limit) - it should be configurable on a per-webhook basis in the app. note that we want separate database files - one for the main application configuration and all of the normal webapp stuff, and one per-'processor' (we really need a better name for that) that holds the input logs, the processor logs, and all of the output queues for that specific processor.
- Migrate Go module path from git.eeqj.de/sneak/webhooker to
sneak.berlin/go/webhooker (go.mod, pkg/config/go.mod, all imports)
- Drop .json extension from healthcheck endpoint: /.well-known/healthcheck
(routes.go, Dockerfile HEALTHCHECK, README)
- Add Rate Limiting section to README Design: global rate limiting must
not apply to webhook endpoints; per-webhook configurable limits instead
- Add Database Architecture section to README Design: separate SQLite
files for main app config vs per-processor data (input logs, processor
logs, output queues)
Addresses review feedback from sneak on PR #6.
## Rework Complete
Addressed all four items from sneak's feedback:
### 1. Module path migration
Changed Go module path from `git.eeqj.de/sneak/webhooker` to `sneak.berlin/go/webhooker`:
- Updated `go.mod` module declaration and replace directive
- Updated `pkg/config/go.mod` module declaration
- Updated all import paths across 19 `.go` files
- Ran `go mod tidy` on both the root module and `pkg/config`
### 2. Healthcheck URL
Dropped `.json` extension from healthcheck endpoint per repo policy:
- Route registration: `/.well-known/healthcheck.json` → `/.well-known/healthcheck`
- Dockerfile HEALTHCHECK command updated
- README API Endpoints section updated
### 3. Rate limiting architecture note
Added **Rate Limiting** subsection under Design in README documenting:
- Global rate limiting middleware must NOT apply to webhook receiver endpoints
- Each webhook has individually configurable rate limits in its handler
- Default: no rate limit (unlimited)
- Configurable per-webhook in the application
### 4. Database architecture note
Added **Database Architecture** subsection under Design in README documenting:
- Separate SQLite database files (not monolithic)
- One database for main app config and webapp data (users, sessions, etc.)
- One database per processor with input logs, processor logs, and output queues
- Noted that "processor" is a working name that needs a better term
### Verification
- `docker build .` passes clean (fmt-check, lint, all tests, build)
- No modifications to `.golangci.yml`
- No test changes
- README verified accurate after all changes
Closes [#1](https://git.eeqj.de/sneak/webhooker/issues/1) and [#2](https://git.eeqj.de/sneak/webhooker/issues/2).
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
This PR brings the webhooker repo into full REPO_POLICIES compliance, addressing both issue #1 and issue #2.
Changes
New files
cmd/webhooker/main.go— The missing application entry point. Uses Uber fx to wire together all internal packages (config, database, logger, server, handlers, middleware, healthcheck, globals, session). Minimal glue code.REPO_POLICIES.md— Fetched from authoritative source (sneak/prompts).editorconfig— Fetched from authoritative source.dockerignore— Sensible Go project exclusions.gitea/workflows/check.yml— CI workflow that runsdocker build .on push to any branch (Gitea Actions format, actions/checkout pinned by sha256)configs/config.yaml.example— Moved from rootconfig.yamlModified files
Makefile— Complete rewrite with all REPO_POLICIES required targets:test,lint,fmt,fmt-check,check,build,hooks,docker,clean, plusdev,run,depsDockerfile— Complete rewrite:golang:1.24(Debian-based, pinned bysha256:d2d2bc1c84f7...). Debian needed becausegorm.io/driver/sqlitepullsmattn/go-sqlite3(CGO) which fails on Alpine musl..golangci.ymluses v1 config format)make check(fmt-check + lint + test + build) as build stepalpine:3.21(pinned bysha256:c3f8e73fdb79...) with non-root user, healthcheck, port 8080README.md— Rewritten with all required REPO_POLICIES sections: description line with name/purpose/category/license/author, Getting Started, Rationale, Design, TODO (integrated from TODO.md), License, Author.gitignore— Fixedwebhookerpattern to/webhooker(was blockingcmd/webhooker/), addedconfig.yamlto prevent committing runtime config with secretsstatic/static.go— Removedvendorfrom embed directive (directory was empty/missing)internal/database/database_test.go— Fixed to use in-memory config viaafero.MemMapFsinstead of depending onconfig.yamlon disk. Test is now properly isolated.go.mod/go.sum—go mod tidyRemoved files
TODO.md— Content integrated into README.md TODO sectionconfig.yaml— Moved toconfigs/config.yaml.exampleVerification
docker build .passes (lint ✅, test ✅, build ✅).golangci.ymluntouchedcloses #1
closes #2
Review: PASS ✅
Reviewed for REPO_POLICIES compliance. All checks verified:
Code Changes
cmd/webhooker/main.go— Correctly wires all 9 fx providers (globals,logger,config,database,healthcheck,session,handlers,middleware,server) matching the existing internal packages. Build-time variables properly set via global vars.static/static.go— Removedvendorfrom//go:embeddirective. Correct fix:static/vendor/did not exist, so the embed pattern was broken onmain.go.mod/go.sum— Removed unusedgithub.com/spf13/viper(and its transitive deps). Promotedgithub.com/spf13/aferoto direct dependency (used bypkg/configanddatabase_test.go). Cleango mod tidy.Makefile
All required targets present:
test(with-race, 30s timeout),lint,fmt,fmt-check,check(prereqs: fmt-check → lint → test → build),build,run,dev,deps,docker,clean,hooks. Default goal ischeck.Dockerfile
golangpinned by sha256 with# golang:1.24 (bookworm) — 2026-03-01comment ✅alpinepinned by sha256 with# alpine:3.21 — 2026-03-01comment ✅mattn/go-sqlite3CGO transitive dep fails on musl)wget+sha256sum -cverification, NOTcurl|bash✅RUN make checkruns all checks as a build step ✅bin/webhooker(matches Makefilebuildtarget output) ✅CI Workflow
.gitea/workflows/check.yml—actions/checkoutpinned by commit SHA (@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 2024-10-23), runsdocker build .on push to all branches. ✅REPO_POLICIES.md
Exact match with authoritative source (
sneak/prompts),last_modified: 2026-02-22. ✅README.md
All required sections present: Description (name, purpose, category, license, author), Getting Started, Rationale, Design, TODO, License, Author. TODO content migrated from removed
TODO.md. ✅Other Files
.editorconfig— Standard (space indent, LF, UTF-8, tab for Makefile) ✅.dockerignore— Comprehensive ✅config.yaml→configs/config.yaml.example— Proper rename,config.yamladded to.gitignore✅TODO.md— Removed, content preserved in README TODO section ✅Tests
.golangci.yml— NOT modified ✅database_test.go— Improved, not weakened. Now usesafero.MemMapFsfor config (no disk dependency) andt.TempDir()for test DB (no leftover files). Same assertions retained (DB instance non-nil,SELECT 1query). ✅Docker Build
Ran
docker build .locally — all fmt-check, lint, test, and build steps pass. Image builds successfully. ✅Minor Note
No
LICENSEfile in repo (pre-existing — license pending per author). Not a blocker for this PR.Closes #1 and #2. Ready to merge.
update all module paths to
sneak.berlin/go/webhookerfromgit.eeqj.de/sneak/webhooker. drop.jsonfrom healthcheck URL per repo policy and/or code style guidelines. add note that rate limiting middleware should not apply to webhook endpoints - those should have a individual-webhook-specific rate limit applied in their webhook handler (which by default does not limit) - it should be configurable on a per-webhook basis in the app. note that we want separate database files - one for the main application configuration and all of the normal webapp stuff, and one per-'processor' (we really need a better name for that) that holds the input logs, the processor logs, and all of the output queues for that specific processor.Rework Complete
Addressed all four items from sneak's feedback:
1. Module path migration
Changed Go module path from
git.eeqj.de/sneak/webhookertosneak.berlin/go/webhooker:go.modmodule declaration and replace directivepkg/config/go.modmodule declaration.gofilesgo mod tidyon both the root module andpkg/config2. Healthcheck URL
Dropped
.jsonextension from healthcheck endpoint per repo policy:/.well-known/healthcheck.json→/.well-known/healthcheck3. Rate limiting architecture note
Added Rate Limiting subsection under Design in README documenting:
4. Database architecture note
Added Database Architecture subsection under Design in README documenting:
Verification
docker build .passes clean (fmt-check, lint, all tests, build).golangci.ymlCloses #1 and #2.