Shared HTTP envelope
Both stacks agree on this wire shape. Class internals stay in api/ or app/.
Reserved, not implemented on live health and version. WP-00 adds ApiEnvelope when the first write endpoint lands.
Shape
{ data, status, message, errors }
data is the resource or list. errors is empty on success.
Paths
Canonical paths live in health.afia.app.common.EndpointUri. Flutter copies them into ApiConfig. Host is AFIA_API_BASE_URL (default http://127.0.0.1:8080).
Session
After WP-01 verify, the client sends the opaque session token on later requests. Header name lands with WP-01 unless a later ADR replaces OTP. Do not invent a second auth protocol here.
Errors
Validation failures return field errors in errors. Unauthorized and forbidden stay distinct. A patient write to diagnostics results is forbidden.