Domains: each monitored domain with its discovered nameservers and last check timestamp
Hostnames: each monitored hostname with per-nameserver DNS records, status, and last check timestamps
Ports: each monitored IP:port with open/closed state, associated hostnames, and last check timestamp
Certificates: each TLS certificate with CN, issuer, expiry, SANs, status, and last check timestamp
Last updated: timestamp of the overall monitoring state
All data is derived from the existing state.GetSnapshot(), consistent with how the dashboard works. No configuration details (webhook URLs, API tokens) are exposed.
## Summary
Enhances the `/api/v1/status` endpoint to return comprehensive monitoring state instead of just `{"status": "ok"}`.
## Changes
The endpoint now returns:
- **Summary counts**: domains, hostnames, ports (total + open), certificates (total + ok + error)
- **Domains**: each monitored domain with its discovered nameservers and last check timestamp
- **Hostnames**: each monitored hostname with per-nameserver DNS records, status, and last check timestamps
- **Ports**: each monitored IP:port with open/closed state, associated hostnames, and last check timestamp
- **Certificates**: each TLS certificate with CN, issuer, expiry, SANs, status, and last check timestamp
- **Last updated**: timestamp of the overall monitoring state
All data is derived from the existing `state.GetSnapshot()`, consistent with how the dashboard works. No configuration details (webhook URLs, API tokens) are exposed.
## Example response structure
```json
{
"status": "ok",
"lastUpdated": "2026-03-10T12:00:00Z",
"counts": {
"domains": 2,
"hostnames": 3,
"ports": 10,
"portsOpen": 8,
"certificates": 4,
"certificatesOk": 3,
"certificatesError": 1
},
"domains": { ... },
"hostnames": { ... },
"ports": { ... },
"certificates": { ... }
}
```
closes https://git.eeqj.de/sneak/dnswatcher/issues/73
The /api/v1/status endpoint previously returned only {"status": "ok"}.
It now returns comprehensive monitoring state including:
- Summary counts (domains, hostnames, ports, certificates with breakdown)
- Full domain state with nameservers and last check timestamps
- Hostname state with per-nameserver DNS records and status
- Port state with open/closed status and associated hostnames
- TLS certificate state with CN, issuer, expiry, SANs, and status
- Last updated timestamp for the overall monitoring state
All data is derived from the existing state snapshot, providing
operational visibility without exposing configuration details
like webhook URLs or API tokens.
Clean, well-implemented enhancement that transforms the /api/v1/status endpoint from a trivial {"status":"ok"} into a comprehensive monitoring state API. Directly addresses issue #73.
What was reviewed
Single file change: internal/handlers/status.go (+200 / -5 lines)
No modifications to Makefile, linter config, CI config, or test assertions
docker build . passes (includes make check: fmt, lint, tests)
Correctness
Data source: Uses h.state.GetSnapshot() — the same snapshot mechanism the dashboard uses. Consistent and correct.
Defensive copying: All slices (nameservers, hostnames, SANs, records) are properly copied before use, preventing mutation of shared state. This is important because GetSnapshot() returns a shallow copy.
Deterministic output: sort.Strings() applied to nameserver and hostname lists for stable JSON responses.
Type safety: Response types are properly defined with clear JSON tags using camelCase naming. The statusResponse struct cleanly separates concerns (counts, domains, hostnames, ports, certificates).
Security
✅ No webhook URLs, API tokens, or notification endpoints exposed
✅Error field from NameserverRecordState and CertificateState is intentionally excluded — only the status field ("ok"/"error") is surfaced, which avoids leaking internal network diagnostics through this unauthenticated endpoint
✅ Mirrors data already visible on the unauthenticated dashboard, but in machine-readable form
Response structure
Well-designed:
Top-level counts summary for quick programmatic checks
Per-entity detail maps keyed by natural identifiers
Consistent lastChecked timestamps on every entity
lastUpdated at the response level for overall state freshness
Backwards-compatible: status: "ok" field preserved
README
The HTTP API table already describes this endpoint as "Current monitoring state" — that description is now accurate. No specific response format is documented for any endpoint in the README, so this is consistent.
Scope
No scope creep. Single file, single purpose, directly addressing the issue requirements.
## ✅ Review: PASS
### Summary
Clean, well-implemented enhancement that transforms the `/api/v1/status` endpoint from a trivial `{"status":"ok"}` into a comprehensive monitoring state API. Directly addresses [issue #73](https://git.eeqj.de/sneak/dnswatcher/issues/73).
### What was reviewed
- Single file change: `internal/handlers/status.go` (+200 / -5 lines)
- No modifications to Makefile, linter config, CI config, or test assertions
- `docker build .` passes (includes `make check`: fmt, lint, tests)
### Correctness
- **Data source**: Uses `h.state.GetSnapshot()` — the same snapshot mechanism the dashboard uses. Consistent and correct.
- **Defensive copying**: All slices (nameservers, hostnames, SANs, records) are properly copied before use, preventing mutation of shared state. This is important because `GetSnapshot()` returns a shallow copy.
- **Deterministic output**: `sort.Strings()` applied to nameserver and hostname lists for stable JSON responses.
- **Type safety**: Response types are properly defined with clear JSON tags using camelCase naming. The `statusResponse` struct cleanly separates concerns (counts, domains, hostnames, ports, certificates).
### Security
- ✅ No webhook URLs, API tokens, or notification endpoints exposed
- ✅ `Error` field from `NameserverRecordState` and `CertificateState` is intentionally excluded — only the `status` field ("ok"/"error") is surfaced, which avoids leaking internal network diagnostics through this unauthenticated endpoint
- ✅ Mirrors data already visible on the unauthenticated dashboard, but in machine-readable form
### Response structure
Well-designed:
- Top-level `counts` summary for quick programmatic checks
- Per-entity detail maps keyed by natural identifiers
- Consistent `lastChecked` timestamps on every entity
- `lastUpdated` at the response level for overall state freshness
- Backwards-compatible: `status: "ok"` field preserved
### README
The HTTP API table already describes this endpoint as "Current monitoring state" — that description is now accurate. No specific response format is documented for any endpoint in the README, so this is consistent.
### Scope
No scope creep. Single file, single purpose, directly addressing the issue requirements.
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.
Summary
Enhances the
/api/v1/statusendpoint to return comprehensive monitoring state instead of just{"status": "ok"}.Changes
The endpoint now returns:
All data is derived from the existing
state.GetSnapshot(), consistent with how the dashboard works. No configuration details (webhook URLs, API tokens) are exposed.Example response structure
closes #73
The /api/v1/status endpoint previously returned only {"status": "ok"}. It now returns comprehensive monitoring state including: - Summary counts (domains, hostnames, ports, certificates with breakdown) - Full domain state with nameservers and last check timestamps - Hostname state with per-nameserver DNS records and status - Port state with open/closed status and associated hostnames - TLS certificate state with CN, issuer, expiry, SANs, and status - Last updated timestamp for the overall monitoring state All data is derived from the existing state snapshot, providing operational visibility without exposing configuration details like webhook URLs or API tokens.✅ Review: PASS
Summary
Clean, well-implemented enhancement that transforms the
/api/v1/statusendpoint from a trivial{"status":"ok"}into a comprehensive monitoring state API. Directly addresses issue #73.What was reviewed
internal/handlers/status.go(+200 / -5 lines)docker build .passes (includesmake check: fmt, lint, tests)Correctness
h.state.GetSnapshot()— the same snapshot mechanism the dashboard uses. Consistent and correct.GetSnapshot()returns a shallow copy.sort.Strings()applied to nameserver and hostname lists for stable JSON responses.statusResponsestruct cleanly separates concerns (counts, domains, hostnames, ports, certificates).Security
Errorfield fromNameserverRecordStateandCertificateStateis intentionally excluded — only thestatusfield ("ok"/"error") is surfaced, which avoids leaking internal network diagnostics through this unauthenticated endpointResponse structure
Well-designed:
countssummary for quick programmatic checkslastCheckedtimestamps on every entitylastUpdatedat the response level for overall state freshnessstatus: "ok"field preservedREADME
The HTTP API table already describes this endpoint as "Current monitoring state" — that description is now accurate. No specific response format is documented for any endpoint in the README, so this is consistent.
Scope
No scope creep. Single file, single purpose, directly addressing the issue requirements.