Commit Graph
10 Commits
Author SHA1 Message Date
clawbot 7a1ee6e5a8 lint: adopt org-standard .golangci.yml and golangci-lint v2.12.2 (closes #14)
check / check (push) Failing after 1s
The old backend/.golangci.yml declared version "2" but used v1 schema
keys, so under v2 it never validated and its thresholds were inert: the
linter ran at defaults. Replace it verbatim with the org-standard file,
repin the Dockerfile.backend lint stage to golangci-lint v2.12.2, and
assert the config's sha256 as the first step of the backend lint target
so it cannot silently drift again -- a local hash check, no network.

The standard config surfaces findings only in the tests: the repeated
IP literals in middleware_test.go become named constants (goconst) and
its request switches to NewRequestWithContext (noctx). reportbuf.go's
gosec suppression gains a plain justification comment. The rest of the
backend, including the fx-based server lifecycle, is already clean.
TODO.md updated.

Model: opus-4-8
2026-09-21 19:30:06 +02:00
clawbot d7cf010e00 fix(server): shut down through fx so buffered reports flush (closes #22)
check / check (push) Successful in 1m11s
The server ran os.Exit at the end of its own goroutine, racing fx's
teardown and sometimes killing the process before reportbuf's OnStop
flushed — silently losing a full flush window of telemetry on every
restart, at exit 0. Shutdown now goes through fx.Shutdowner, so every
OnStop runs in order.

The http.Server is built synchronously in OnStart before the serving
goroutine, so shutdown can no longer race or nil-deref it. A listen
failure exits non-zero via fx.ExitCode(1). reportbuf's OnStop is guarded
by sync.Once. writeTimeout now exceeds the chi per-request budget so that
budget is reachable. Dead startupTime, exitCode, and cancelFunc fields
are gone. A new test asserts a buffered report reaches disk after the
lifecycle stops.

Model: opus-4-8
2026-09-21 18:47:12 +02:00
clawbot 14eb376d79 test: automated responsive-layout harness (closes #13)
check / check (push) Failing after 1s
`make frontend-viewport-test` builds `dist/`, serves it from the same
digest-pinned nginx image and nginx.conf the shipping container uses, and
drives a digest-pinned headless Chrome over CDP. Viewport widths are derived
from the app's own @media breakpoints rather than a list of phone models: each
breakpoint is tested one pixel below, on, and above, plus four anchor
viewports. Assertions are on computed layout — horizontal overflow, off-screen
elements, clipped text, 44x44 tap targets, host-row reflow — not screenshots,
and each check declares the minimum elements it must find so a stale selector
fails instead of passing blind against a page it is not measuring. Kept out of
`make check`: it needs Docker and takes minutes. Proven able to fail before
being trusted.

Model: opus-4-8
2026-09-21 18:29:20 +02:00
clawbot f3895789d2 feat(backend): server hardening: timeouts, security headers, trusted-proxy client IP (closes #19)
check / check (push) Failing after 1s
Add ReadHeaderTimeout and IdleTimeout to the http.Server as named constants beside the existing timeouts. Add a SecurityHeaders middleware (HSTS, a JSON-API CSP of default-src 'none'; frame-ancestors 'none', X-Frame-Options DENY, nosniff, Referrer-Policy, Permissions-Policy), registered before CORS so preflight responses carry it. Resolve the client IP from X-Forwarded-For / X-Real-IP only when the direct peer is in the trusted-proxy allowlist (loopback plus RFC1918 by default, configurable via TRUSTED_PROXIES); an untrusted peer's forwarded headers are ignored. Uses net/netip; no new dependency.

Model: opus-4-8 (implementation and review); claude-fable-5 (merge)
2026-09-21 15:05:25 +02:00
clawbot f7c7f92e27 fix(frontend): meet the 44x44 minimum tap target on every control (closes #43)
check / check (push) Successful in 10s
2026-08-10 16:12:00 +02:00
clawbot 852a11eec2 fix: wrap per-host status line so 320px viewport does not scroll (closes #42)
check / check (push) Has been cancelled
2026-08-10 16:07:28 +02:00
clawbot 25a852d35c build: Dockerfile.backend multistage lint stage (closes #17)
check / check (push) Has been cancelled
2026-08-10 16:04:48 +02:00
clawbot a644efe9ff chore: root .editorconfig and hardened .gitignore (closes #15)
check / check (push) Successful in 45s
2026-08-10 15:47:49 +02:00
sneak e45bc578b2 scripts-to-rule-them-all (#10)
check / check (push) Successful in 21s
Reviewed-on: #10
Co-authored-by: sneak <sneak@sneak.berlin>
Co-committed-by: sneak <sneak@sneak.berlin>
2026-07-07 02:14:16 +02:00
sneak 247a3c33fd TODO (#9)
check / check (push) Successful in 22s
Reviewed-on: #9
2026-07-06 21:20:37 +02:00