Owner ruling on #25: the backend ships wired up. POST /api/v1/reports (backend/internal/handlers/report.go) has no caller; src/main.js collects every sample the endpoint is shaped for and never sends any of it.
Definition of done
The page periodically POSTs a JSON report to the same-origin path /api/v1/reports in the shape the backend decodes today: {clientId, geo, hosts: [{name, url, status, history: [{t, latency, error}]}], timestamp}. clientId is a random id generated once per browser and kept in localStorage. geo is sent as JSON null (no geolocation lookup). timestamp is ISO 8601 UTC. t is the sample's Unix time in milliseconds; latency is the integer ms or null; error is the existing "timeout" / "unreachable" string or null. Paused (blank) samples are not reported.
Each report carries only samples not yet reported (a per-host high-water mark), so it is a delta. The interval is a CONFIG value, default 60 s. While paused nothing is sent. Unsent samples are bounded by the existing history window; if a report cannot be delivered, what falls out of the window is dropped oldest-first.
Failure is quiet and bounded: a failed POST (network error, non-2xx, including the 404 you get under yarn dev with no backend) is logged once to the in-page debug log at debug level, retried at the next interval, never blocks probing, never shows an alert, never retries in a tight loop. A later success is logged at debug level once.
fetch POST with Content-Type: application/json, credentials: "omit", no other headers. No new dependency.
The measured byte size of a full report at the maximum history (maxHistoryPoints x all hosts) is stated in the PR and is well under the backend's 1 MiB body limit.
vite.config.js gains a dev-server proxy for /api to http://127.0.0.1:8080 so make dev with a locally running netwatch-server exercises the real path; one line in README Getting Started says so.
Verified and summarised in the PR: with the backend running locally, it logs report received with the expected host_count; without a backend the page works and the debug log shows one debug-level failure line per outage, not one per interval.
Code follows the file's existing class-based structure (a reporter class beside AppState), with the report-building step a pure function of host state so #21 can test it. README Design section gets a short paragraph: what is sent, how often, to where.
make check green; docker build . green. TODO.md updated in the same commit. Commit title ends (closes #N).
Implementation requirements
Do not change the backend or its schema. If the schema needs a change to be usable, stop, say so on the PR with the reading taken, and leave the backend alone.
Do not touch nginx.conf or any Dockerfile; the proxy route is #52.
No scripted edits (sed -i, perl -pi, awk, python rewrites); edit by hand, format only via make fmt. make targets and script/ entrypoints only. No attribution trailers.
model: claude-fable-5
## Why
Owner ruling on https://git.eeqj.de/sneak/netwatch/issues/25: the backend ships wired up. `POST /api/v1/reports` (`backend/internal/handlers/report.go`) has no caller; `src/main.js` collects every sample the endpoint is shaped for and never sends any of it.
## Definition of done
- [ ] The page periodically POSTs a JSON report to the same-origin path `/api/v1/reports` in the shape the backend decodes today: `{clientId, geo, hosts: [{name, url, status, history: [{t, latency, error}]}], timestamp}`. `clientId` is a random id generated once per browser and kept in `localStorage`. `geo` is sent as JSON `null` (no geolocation lookup). `timestamp` is ISO 8601 UTC. `t` is the sample's Unix time in milliseconds; `latency` is the integer ms or `null`; `error` is the existing `"timeout"` / `"unreachable"` string or `null`. Paused (blank) samples are not reported.
- [ ] Each report carries only samples not yet reported (a per-host high-water mark), so it is a delta. The interval is a `CONFIG` value, default 60 s. While paused nothing is sent. Unsent samples are bounded by the existing history window; if a report cannot be delivered, what falls out of the window is dropped oldest-first.
- [ ] Failure is quiet and bounded: a failed POST (network error, non-2xx, including the 404 you get under `yarn dev` with no backend) is logged once to the in-page debug log at debug level, retried at the next interval, never blocks probing, never shows an alert, never retries in a tight loop. A later success is logged at debug level once.
- [ ] `fetch` POST with `Content-Type: application/json`, `credentials: "omit"`, no other headers. No new dependency.
- [ ] The measured byte size of a full report at the maximum history (`maxHistoryPoints` x all hosts) is stated in the PR and is well under the backend's 1 MiB body limit.
- [ ] `vite.config.js` gains a dev-server proxy for `/api` to `http://127.0.0.1:8080` so `make dev` with a locally running `netwatch-server` exercises the real path; one line in README Getting Started says so.
- [ ] Verified and summarised in the PR: with the backend running locally, it logs `report received` with the expected `host_count`; without a backend the page works and the debug log shows one debug-level failure line per outage, not one per interval.
- [ ] Code follows the file's existing class-based structure (a reporter class beside `AppState`), with the report-building step a pure function of host state so https://git.eeqj.de/sneak/netwatch/issues/21 can test it. README Design section gets a short paragraph: what is sent, how often, to where.
- [ ] `make check` green; `docker build .` green. `TODO.md` updated in the same commit. Commit title ends ` (closes #N)`.
## Implementation requirements
- Do not change the backend or its schema. If the schema needs a change to be usable, stop, say so on the PR with the reading taken, and leave the backend alone.
- Do not touch `nginx.conf` or any Dockerfile; the proxy route is https://git.eeqj.de/sneak/netwatch/issues/52.
- No scripted edits (`sed -i`, `perl -pi`, awk, python rewrites); edit by hand, format only via `make fmt`. `make` targets and `script/` entrypoints only. No attribution trailers.
model: claude-fable-5
clawbot
added this to the 1.0.0 milestone 2026-09-21 09:47:41 +02:00
clawbot
self-assigned this 2026-09-21 09:47:41 +02:00
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.
Why
Owner ruling on #25: the backend ships wired up.
POST /api/v1/reports(backend/internal/handlers/report.go) has no caller;src/main.jscollects every sample the endpoint is shaped for and never sends any of it.Definition of done
/api/v1/reportsin the shape the backend decodes today:{clientId, geo, hosts: [{name, url, status, history: [{t, latency, error}]}], timestamp}.clientIdis a random id generated once per browser and kept inlocalStorage.geois sent as JSONnull(no geolocation lookup).timestampis ISO 8601 UTC.tis the sample's Unix time in milliseconds;latencyis the integer ms ornull;erroris the existing"timeout"/"unreachable"string ornull. Paused (blank) samples are not reported.CONFIGvalue, default 60 s. While paused nothing is sent. Unsent samples are bounded by the existing history window; if a report cannot be delivered, what falls out of the window is dropped oldest-first.yarn devwith no backend) is logged once to the in-page debug log at debug level, retried at the next interval, never blocks probing, never shows an alert, never retries in a tight loop. A later success is logged at debug level once.fetchPOST withContent-Type: application/json,credentials: "omit", no other headers. No new dependency.maxHistoryPointsx all hosts) is stated in the PR and is well under the backend's 1 MiB body limit.vite.config.jsgains a dev-server proxy for/apitohttp://127.0.0.1:8080somake devwith a locally runningnetwatch-serverexercises the real path; one line in README Getting Started says so.report receivedwith the expectedhost_count; without a backend the page works and the debug log shows one debug-level failure line per outage, not one per interval.AppState), with the report-building step a pure function of host state so #21 can test it. README Design section gets a short paragraph: what is sent, how often, to where.make checkgreen;docker build .green.TODO.mdupdated in the same commit. Commit title ends(closes #N).Implementation requirements
nginx.confor any Dockerfile; the proxy route is #52.sed -i,perl -pi, awk, python rewrites); edit by hand, format only viamake fmt.maketargets andscript/entrypoints only. No attribution trailers.model: claude-fable-5
clawbot referenced this issue2026-09-21 14:45:40 +02:00