This issue tracks possible improvements found during a codebase review. It is a backlog item, not a decision to implement everything now.
Current checks pass:
go test -race ./...
golangci-lint run
- Coverage: ~80.7%
Suggested order by impact:
-
Debug endpoints exposure
/debug/pprof/* and /debug/vars are currently enabled by default.
- For this small template project, this may be acceptable as-is.
- If this template is used in production, consider documenting the tradeoff or making debug routes opt-in.
-
Avoid leaking panic details to clients
recovery currently returns the panic value in the 500 response.
- Prefer a generic client response like
internal server error while keeping the full error and stack in logs.
-
Add stronger server timeouts
ReadHeaderTimeout is set.
- Consider adding
ReadTimeout, WriteTimeout, and IdleTimeout as safer defaults.
-
Preserve http.ErrAbortHandler behavior
recovery currently swallows http.ErrAbortHandler.
- Better to re-panic it so
net/http can abort the connection as intended.
-
Fix responseRecorder correctness
- Empty successful responses are logged with status
0 instead of 200.
- Multiple
WriteHeader calls can overwrite the first status.
- Byte count should track actual written bytes, not only
len(b).
-
Emit access logs for panic responses
- Current middleware order can skip access logs when a panic happens.
- Consider changing middleware order or using a deferred access log.
-
Run Docker image as non-root
- Add
USER 65532:65532 or similar in the runtime image.
-
Avoid global logger mutation
slog.SetDefault changes process-wide state.
- Prefer creating a logger and passing it explicitly.
-
Align Docker image names
Makefile: ghcr.io/raeperd/kickstart
- GitHub Actions:
ghcr.io/${{ github.repository }}
- Pick one name to avoid confusion.
-
Improve test robustness
- Avoid free-port-then-close race in
TestMain.
- Fail explicitly if readiness check never succeeds.
- Close response bodies in all readiness-loop paths.
-
Dockerfile polish
- Use
AS instead of as.
- Prefer
ENTRYPOINT ["/bin/app"].
- Add
.dockerignore for app, coverage.txt, and temporary files.
This issue tracks possible improvements found during a codebase review. It is a backlog item, not a decision to implement everything now.
Current checks pass:
go test -race ./...golangci-lint runSuggested order by impact:
Debug endpoints exposure
/debug/pprof/*and/debug/varsare currently enabled by default.Avoid leaking panic details to clients
recoverycurrently returns the panic value in the 500 response.internal server errorwhile keeping the full error and stack in logs.Add stronger server timeouts
ReadHeaderTimeoutis set.ReadTimeout,WriteTimeout, andIdleTimeoutas safer defaults.Preserve
http.ErrAbortHandlerbehaviorrecoverycurrently swallowshttp.ErrAbortHandler.net/httpcan abort the connection as intended.Fix
responseRecordercorrectness0instead of200.WriteHeadercalls can overwrite the first status.len(b).Emit access logs for panic responses
Run Docker image as non-root
USER 65532:65532or similar in the runtime image.Avoid global logger mutation
slog.SetDefaultchanges process-wide state.Align Docker image names
Makefile:ghcr.io/raeperd/kickstartghcr.io/${{ github.repository }}Improve test robustness
TestMain.Dockerfile polish
ASinstead ofas.ENTRYPOINT ["/bin/app"]..dockerignoreforapp,coverage.txt, and temporary files.