fix(backend): report ingest correctness — propagate storage failure, 413 on oversize, global body cap (closes #23)
check / check (push) Successful in 1m10s

A buffer failure on POST /api/v1/reports now returns 500 instead of a
false `ok`, so clients can retry. An over-limit body returns 413
(errors.As on `*http.MaxBytesError`); malformed JSON stays 400. A
MaxBodyBytes middleware (1 MiB) caps every route, rejecting an
oversized Content-Length up front and capping the read otherwise; a
route group can only lower that limit. The raw geo blob is no longer
logged, only its length; client_id, timestamp and decode error text
are length-bounded before logging. A decodeJSON handler helper is
added. Panic recovery routes the stack through slog as structured
JSON. Storage failure uses 500: a full buffer or write error is
server-side and retryable.

Model: opus-5-5
This commit is contained in:
2026-09-28 17:29:08 +00:00
parent 7a1ee6e5a8
commit 1f9e192001
11 changed files with 584 additions and 33 deletions
+8
View File
@@ -23,6 +23,14 @@ latest run passes.
# Completed Steps
- 2026-09-28: report ingest correctness (issue #23): a storage failure now
returns 500 instead of a false `ok`; oversize bodies return 413 (distinguished
from malformed JSON, which stays 400); a `MaxBodyBytes` middleware caps every
route, not just the report route; the raw attacker-controlled `geo` blob is no
longer logged (only its length), and `client_id`, `timestamp` and decode error
text are length-bounded before logging; a `decodeJSON` handler helper was
added; and panic recovery now routes the stack through slog instead of chi's
plain-text stderr
- 2026-09-21: shutdown lifecycle correctness. The process now shuts down through
fx instead of `os.Exit`, so every component's `OnStop` runs and buffered
reports are flushed to disk on `SIGTERM` — previously a full flush window of