Sprint 2 of autonomous trainer day 2026-05-05. Mistral-implemented through ICM workspace ship-info-aggregator (bootstrapped backend + BDD before hitting price limit at stage 02), Claude-completed for frontend + Playwright + verifier + PR. Backend: - GET /api/info aggregator returning version, commit_short, build_date, uptime_seconds, cache_enabled, healthz_status (single round trip) - Optional cache via existing cache service (X-Cache: HIT/MISS) - BDD scenario @critical covers happy path + version regex; cache scenario kept under @skip @bdd-deferred until BDD harness gains a cache-enabled mode Frontend: - AppFooterView (dumb) + AppFooter (smart wrapper, useFetch) following the HealthDashboard / HealthDashboardView pattern - layouts/default.vue auto-applied via NuxtLayout in app.vue - humaniseUptime helper in utils/ - Playwright tests use route.fulfill mocking (decoupled from dev-proxy infra), assert visible AND content (PR #32 lesson) Docs: - documentation/API.md /api/info entry with schema and rationale - ADR-0026 documents composite endpoint vs separate calls choice Verifier verdict (skill-driven, audit at stage 04): APPROVE_WITH_NITS. Nits: handleInfo is 51 lines (could split into builder + emitter); X-Cache: DISABLED could improve ops clarity. Out-of-scope follow-up: existing tests/e2e/health.spec.ts happy path hits the same dev-proxy infra issue as my footer happy path before mocking. Same fix (server: false + route.fulfill) would apply.
47 lines
1.2 KiB
Go
47 lines
1.2 KiB
Go
package steps
|
|
|
|
import (
|
|
"dance-lessons-coach/pkg/bdd/testserver"
|
|
)
|
|
|
|
// HealthSteps holds health-related step definitions
|
|
type HealthSteps struct {
|
|
client *testserver.Client
|
|
scenarioKey string // Track current scenario for state isolation
|
|
}
|
|
|
|
func NewHealthSteps(client *testserver.Client) *HealthSteps {
|
|
return &HealthSteps{client: client}
|
|
}
|
|
|
|
// SetScenarioKey sets the current scenario key for state isolation
|
|
func (s *HealthSteps) SetScenarioKey(key string) {
|
|
s.scenarioKey = key
|
|
}
|
|
|
|
// Health-related steps
|
|
func (s *HealthSteps) iRequestTheHealthEndpoint() error {
|
|
return s.client.Request("GET", "/api/health", nil)
|
|
}
|
|
|
|
func (s *HealthSteps) iRequestTheHealthzEndpoint() error {
|
|
return s.client.Request("GET", "/api/healthz", nil)
|
|
}
|
|
|
|
func (s *HealthSteps) iRequestTheInfoEndpoint() error {
|
|
return s.client.Request("GET", "/api/info", nil)
|
|
}
|
|
|
|
func (s *HealthSteps) iRequestTheInfoEndpointAgain() error {
|
|
return s.client.Request("GET", "/api/info", nil)
|
|
}
|
|
|
|
func (s *HealthSteps) theServerIsRunning() error {
|
|
// Actually verify the server is running by checking the readiness endpoint
|
|
return s.client.Request("GET", "/api/ready", nil)
|
|
}
|
|
|
|
func (s *HealthSteps) theServerIsRunningWithCacheEnabled() error {
|
|
return s.client.Request("GET", "/api/ready", nil)
|
|
}
|