Commit Graph
2 Commits
Author SHA1 Message Date
Claude 0062edbec3 fix(readiness): /api/ready svarade 200 med en död motor i produktion
CI (SIAX Cloud) / integration (push) Skipped
masterplan-lock / check (push) Successful in 6s
CI (SIAX Cloud) / security (push) Successful in 15s
masterplan-lock / check (pull_request) Successful in 4s
Security Scan (SIAX Cloud) / security (push) Successful in 27s
CI (SIAX Cloud) / security (pull_request) Successful in 23s
Security Scan (SIAX Cloud) / security (pull_request) Successful in 24s
CI (SIAX Cloud) / quality (push) Successful in 45s
CI (SIAX Cloud) / integration (pull_request) Successful in 31s
CI (SIAX Cloud) / quality (pull_request) Successful in 40s
Mätt live 2026-09-25 mot produktionsdeployen (0pt.app / api.0pt.app,
container shxd6lepxuxfsjsp0ath3z1g-172514162615 på server6, uppe 17,9 h,
Docker-status "healthy" hela tiden):

    GET /api/health -> HTTP/1.1 200 OK
      {"ok":false,"service":"0pt-web","db":"ok","queue":"not_configured",
       "engine":"error","stripe":"not_configured",
       "detail":{"engine":"This operation was aborted"}}

    GET /api/ready  -> HTTP/1.1 200 OK
      {"ready":true,"service":"0pt-web","db":"ok","engine":"error",...}

ENGINE_URL pekade på http://0pt-engine:8000. Mätt inifrån containern:
`getent hosts 0pt-engine` ger ingen post, och det finns ingen sådan
container på någon av server5-11. Ett direktanrop mot motorn misslyckas
efter ~5 s (DNS). Datamotorn — 0pt:s hela produkt — var alltså BORTA, och
samtliga signaler ovanför den var gröna: Docker healthy, /api/health 200,
/api/ready 200.

`ok:false` i en 200-kropp är ingen signal. Ingenting i kedjan läser
kroppar; allt läser statuskoder och exitkoder.

isReady skilde tidigare bara på "db ok". Den skillnad som saknades är inte
konfigurerad-vs-ej-konfigurerad utan FRÅNVARANDE-vs-TRASIG:

  * not_configured / not_integrated -> fortsatt ready. 0pt är byggt för att
    kunna köra utan motor, Stripe och kö (se .env.example).
  * error -> INTE ready. Statusen "error" betyder att någon medvetet
    konfigurerade beroendet och att en riktig round trip mot det just
    misslyckades. Det är inte längre en valfri integration.

Ändrar ingenting i driften i dag: container-HEALTHCHECK pekar på
/api/health (liveness) och Dockerfilen säger uttryckligen att en
readiness-probe inte ska peka dit. Den här ändringen gör bara att den
ärliga ytan faktiskt blir ärlig, så en yttre övervakning kan använda den.

Regressionstest tillagt; verifierat att det FALLER mot den gamla isReady
(1 failed | 18 passed) och passerar mot den nya (24 passed över
health-checks/ready/health).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-25 13:34:42 +02:00
admin a88ad04867 fix(health): report real per-dependency status instead of hardcoded ok:true
CI (SIAX Cloud) / security (push) Successful in 21s
Security Scan (SIAX Cloud) / security (push) Successful in 21s
CI (SIAX Cloud) / quality (push) Successful in 41s
CI (SIAX Cloud) / security (pull_request) Successful in 22s
Security Scan (SIAX Cloud) / security (pull_request) Successful in 21s
CI (SIAX Cloud) / quality (pull_request) Successful in 41s
BACKLOG P0-3: /api/health only ever checked *presence* of DATABASE_URL/
REDIS_URL and always returned ok:true regardless of whether anything was
reachable -- ARCHITECTURE.md's own words, "an uptime monitor watching HTTP
200 would show green for a dying instance".

lib/health-checks.ts adds real dependency probes:
  - db: a live `select 1` round trip (not just DATABASE_URL presence)
  - engine: a real HTTP call to the FastAPI engine's own GET /health
  - stripe: Stripe's documented lightweight balance.retrieve() liveness call
  - queue: honestly reports "not_integrated" when REDIS_URL is set but
    unused -- no Redis client is wired anywhere in this repo, so reporting
    "ok" would fabricate a check that doesn't exist

/api/health stays a liveness check (always 200 while the process can
respond; the body's `ok` field is the honest signal). New GET /api/ready
fails closed with 503 when the load-bearing dependency (db) isn't both
configured and reachable -- the "no /ready route" gap.

contracts/openapi.yaml, docs/architecture/ARCHITECTURE.md, and docs/slo.md
updated to match. 17 new unit tests (dependency-injected fakes, no real
network/DB) + 5 route-level tests.
2026-08-11 13:49:23 +02:00