# Flow F7 — Health probe > Trivial flow. Documented for completeness because it is the contract every external orchestrator (Watchtower, docker compose healthcheck, reverse proxy) relies on. ## Description `GET /health` returns `{ "status": "healthy" }` with no auth. Confirms the process is up and the HTTP pipeline is serving — does NOT confirm DB connectivity, JWT validation works, or any feature endpoint is reachable. ## Preconditions - HTTP pipeline is serving (i.e., F6 reached `app.Run()`). ## Sequence Diagram ```mermaid sequenceDiagram autonumber participant Probe as Watchtower / compose / reverse proxy participant Host as 07_host Probe->>Host: GET /health (no Authorization header) Host-->>Probe: 200 OK + { "status": "healthy" } ``` ## Flowchart ```mermaid flowchart LR Start([GET /health]) --> Resp([200 OK + healthy]) ``` ## Data Flow | Step | From | To | Data | Format | |------|------|----|------|--------| | 1 | Probe | `MapGet("/health")` | (no body, no auth) | HTTP GET | | 2 | `MapGet("/health")` | Probe | `{ "status": "healthy" }` | JSON (PascalCase irrelevant — single key) | ## Error Scenarios | Error | Where | Detection | Recovery | |-------|-------|-----------|----------| | Process down | TCP layer | Probe gets `ECONNREFUSED` | Orchestrator restarts container | | Pipeline not yet at `app.Run()` (mid-startup) | TCP layer | TCP connect succeeds but no response | Probe times out; orchestrator typically retries with backoff | ## Performance Expectations | Metric | Target | Notes | |--------|--------|-------| | Latency | <5ms | Pure pipeline execution; no I/O | | Throughput | bounded only by ASP.NET Core's request handling | Not load-tested | ## Future improvement (carry-forward, NOT this Epic) Add a DB ping: ```csharp app.MapGet("/health", async (AppDataConnection db) => { await db.ExecuteAsync("SELECT 1"); return Results.Ok(new { status = "healthy" }); }); ``` This would let `flight-gate` and reverse-proxy checks reflect actual readiness rather than process liveness. Today the migrator runs at startup and crashes the process on DB failure (F6), which is a coarse but workable substitute for one-shot bring-up. In a steady-state running device, a transient DB outage AFTER startup would not be caught by `/health` today.