Files
netwatch/backend
clawbot 4a7bdf8f61
All checks were successful
check / check (push) Successful in 26s
chore: root .editorconfig and hardened .gitignore (closes #15)
Three root-level dotfiles diverged from the org models. Two are fixed
here; the third is deferred for a reason spelled out below.

Move backend/.editorconfig to the repo root. The file is byte-identical
to the org model, so this is a pure relocation with no content change.
It carries root = true, which one level down was actively harmful: it
stopped editors walking further up, leaving the entire frontend
(src/, index.html, vite.config.js, nginx.conf, script/) with no
indentation settings at all. At the root the same file covers the whole
tree, backend included, so the subdirectory copy is redundant.

Replace .gitignore with the org model verbatim, then re-append the two
repo-specific entries the model does not carry: dist/ (Vite output) and
*.log. This adds the OS entry Thumbs.db, the entire Editors section
(*.swp, *.swo, *~, *.bak, .idea/, .vscode/, *.sublime-*), and the
Environment / secrets section (.env, .env.*, *.pem, *.key).

The secrets section is the substantive part. The backend loads .env via
godotenv and only backend/.gitignore ignored it, so a .env at the repo
root was untracked but unignored -- one git add -A away from being
committed. Policy allows no exceptions there.

Not done here: excluding .git from .dockerignore. Both images read git
metadata at build time. Dockerfile.backend has an explicit
COPY .git /repo/.git feeding git describe in backend/Makefile, and the
frontend Dockerfile's make check runs vite, whose config calls
git rev-parse at config-eval time. Ignoring .git breaks both builds
outright rather than degrading them, and decoupling them from git
metadata belongs to the Dockerfile rework in #17. Deferred deliberately,
not overlooked; tracked separately so it is not lost.

No tracked file becomes ignored by the new patterns: git ls-files
differs only by the .editorconfig relocation, and check-ignore over the
full tracked set matches nothing.
2026-08-09 04:59:24 +00:00
..

netwatch-server is an MIT-licensed Go HTTP backend by @sneak that receives telemetry reports from the NetWatch SPA and persists them as zstd-compressed JSONL files on disk.

Getting Started

# Build and run locally
make run

# Run tests, lint, and format check
make check

# Docker
docker build -t netwatch-server .
docker run -p 8080:8080 netwatch-server

Rationale

The NetWatch frontend collects latency measurements from the browser but has no way to persist or aggregate them. This backend provides a minimal POST /api/v1/reports endpoint that buffers incoming reports in memory and flushes them to compressed files on disk for later analysis.

Design

The server is structured as an fx-wired Go application under cmd/netwatch-server/. Internal packages in internal/ follow standard Go project layout:

  • config: Loads configuration from environment variables and config files via Viper.
  • handlers: HTTP request handlers for the API (health check, report ingestion).
  • reportbuf: In-memory buffer that accumulates JSONL report lines and flushes to zstd-compressed files when the buffer reaches 10 MiB or every 60 seconds.
  • server: Chi-based HTTP server with middleware wiring and route registration.
  • healthcheck, middleware, logger, globals: Supporting infrastructure.

Configuration

Variable Default Description
PORT 8080 HTTP listen port
DATA_DIR ./data/reports Directory for compressed reports
DEBUG false Enable debug logging

Report storage

Reports are written as reports-<timestamp>.jsonl.zst files in DATA_DIR. Each file contains one JSON object per line, compressed with zstd. Files are created with O_EXCL to prevent overwrites.

TODO

  • Add integration test that POSTs a report and verifies the compressed output
  • Add report decompression/query endpoint
  • Add metrics (Prometheus) for buffer size, flush count, report count
  • Add retention policy to prune old report files

License

MIT. See LICENSE.

Author

@sneak