feat(api): hosts/{id} enrichment — liveness + compliance summary (16/16 ACs)#428
Merged
Conversation
…16 ACs)
Extends api-hosts to v1.1.0 by enriching GET /hosts/{id} with the
two highest-value per-host views from Slice B: live reachability
state and compliance roll-up. List endpoint (GET /hosts) unchanged
to keep bulk-read cost flat.
Spec (api-hosts 1.0.0 -> 1.1.0)
New constraints:
C-05 GET /hosts/{id} response MUST include liveness sub-object
(populated when host_liveness has a row, null otherwise).
C-06 GET /hosts/{id} response MUST include compliance_summary
with passing, failing, skipped, error, total counts.
Empty rule_state -> all zeros, never null or error.
New ACs:
AC-13 liveness populated when probed.
AC-14 liveness null when never probed.
AC-15 compliance_summary counts correct on mixed rule_state.
AC-16 compliance_summary all zeros on empty rule_state.
OpenAPI schema additions
HostLiveness mirrors host_liveness columns + the
reachability_status enum.
HostComplianceSummary five typed counters.
HostDetailResponse {host: HostResponse, liveness: HostLiveness?,
compliance_summary: HostComplianceSummary}.
GET /hosts/{id} response switched from HostResponse to
HostDetailResponse. PATCH/POST/DELETE responses unchanged.
Implementation
- internal/server/hosts_enrichment.go: two helpers behind the
handler.
loadHostLiveness LEFT-JOIN-style read; returns (nil,
nil) when no row exists so the
handler can encode liveness=null.
loadHostComplianceSummary FILTER aggregate over
host_rule_state; always returns a
struct (zeros on empty).
- internal/server/hosts_handlers.go: GetHostByID now fans out
to the two helpers after the host fetch and wraps everything
in HostDetailResponse.
- internal/server/api_hosts_test.go: existing AC-08 + AC-10 tests
updated to decode the new {host: {...}} envelope shape.
- internal/server/api_hosts_enrichment_test.go: four new tests
covering AC-13/14/15/16 against a real Postgres fixture.
Verification
go vet ./... clean
go test -race -count=1 PASS (5.3s with Postgres)
specter parse PASS (api-hosts@1.1.0)
specter check PASS
specter coverage api-hosts 16/16 (100%)
Spec: app/specs/api/hosts.spec.yaml
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Extends `api-hosts` to v1.1.0. `GET /api/v1/hosts/{id}` now returns the host plus the two highest-value per-host views from Slice B: live reachability state and compliance roll-up.
`GET /api/v1/hosts` (list) is intentionally unchanged — keeps bulk-read cost flat. Enrichment is detail-only.
Spec changes (api-hosts 1.0.0 → 1.1.0)
New constraints:
New ACs:
OpenAPI shape
New schemas: `HostLiveness`, `HostComplianceSummary`, `HostDetailResponse`.
```json
{
"host": { ...HostResponse... },
"liveness": { "reachability_status": "reachable", "last_probe_at": "...", ... } | null,
"compliance_summary": { "passing": 2, "failing": 3, "skipped": 1, "error": 1, "total": 7 }
}
```
Verification
```
go vet ./... clean
go test -race -count=1 PASS (5.3s with Postgres)
specter parse PASS (api-hosts@1.1.0)
specter check PASS
specter coverage api-hosts 16/16 (100%)
```
Test plan