Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

14 - QA Checklist (Health Module)

Verification checklist for the Health module. Baseline in 00-shared/10. Items marked with the failure class they catch; every item maps to a source line so tests stay honest to the contract.


1. Contract tests (endpoint)

#CheckExpectationSource
C1All-up request200; data.status: 'ok'; 4 keys in info; error: {}health.controller.spec.ts:21-36, health.controller.ts:31-36
C2Indicator countexactly mongodb, redis, storage, bullmq - no more, no lesshealth.controller.ts:31-36
C3Redis detailinfo.redis.ping === 'PONG' on successredis-health.indicator.ts:12-23
C4BullMQ detailinfo.bullmq.pendingJobs is a 4-element int array in injection order [emails, in-app, webhook-deliver, dlq]bullmq-health.indicator.ts:21-30, queue.constants.ts:2,5,14
C5Version both/api/v1/health and /api/v2/health both 200@Version(['1','2']), health.controller.ts:28
C6Auth bypassrequest without any Authorization header → 200 (not 401/403)@Public(), health.controller.ts:15; guards app.module.ts:129-131
C7Rate cap> 30 req/min → 429rate-limit.constants.ts:4
C8Envelopesuccess body has success/message/data/timestamp/requestIdresponse-envelope.interceptor.ts:47-60
C9No DTOno validation 400 on any query/body (none accepted)health.controller.ts:27-37

2. Failure modes

#ScenarioExpectedGaps to flag
F1Redis down503; data.error.redis.status === 'down' in the result Terminus built; error envelope code: 'INTERNAL_SERVER_ERROR' (503 unmapped in filter)error body does not carry the key - http-exception.filter.ts:56-58
F2Partial - Redis + BullMQ down, Mongo + storage up503; info keeps healthy keys upverify client never blanks healthy cards (13 §4)
F3All four down503; all keys in error-
F4Storage provider throwsindicator catches → HealthCheckError → downstorage-health.indicator.ts:16-26
F5Redis PING returns non-PONGdown (status computed, :15)-
F6Queue unreachable (Redis-backed queues)getJobCounts rejects → HealthCheckError → downbullmq-health.indicator.ts:31-36
F7BullMQ partial queue failurePromise.all fails whole indicator → all-or-nothing; no per-queue down granularityacceptable; document

3. Client behaviours (proposed screen)

#CheckExpectation
G1503 mapped to down-state, not error stateHealthRepository maps error envelope → HealthSnapshot(down); never a red error page (13 §4)
G2Partial failure renderingred only on culprit cards; healthy cards stay green (06 S1 row 3)
G3Stale guardsnapshot > 60 s old renders stale + amber, never fresh-green (07 §4)
G4Poll pause/resumebackgrounded → timer canceled; resume → immediate refetch (13 §2)
G5429 handlingpoll pauses 60 s; retry disabled with countdown (10 I5)
G6In-flight guarddouble-tap Retry issues exactly one request
G7PendingJobs driftdlq > 0 shows amber chip (07 §3)
G8Detail sheetrenders from cache; zero network calls on open (06 S2)

4. Security / leakage

#CheckExpectation
S1No secret leakagepayload carries only statuses + counts; no Redis URLs/credentials, queue connection strings, storage keys
S2Public endpoint abuse30 req/min cap enforced; no auth bypass of other endpoints via @Public() scope creep (health.controller.ts:15 is controller-scoped only)
S3No tenant dataresponse must never contain tenant names/ids; health is global (01 §5)
S4DoS via hanging probecheck has no internal timeout - a hung dependency stalls the request until client/middleware timeout; monitor p99 of /health

5. Load-shedding / performance

#CheckExpectation
L1Probe storm30 concurrent probes → all served within rate window; no queue buildup (each probe runs 4 checks in parallel, health.controller.ts:31-36)
L2Indicator parallelism4 checks run concurrently (Promise batch via HealthCheckService) - total latency ≈ slowest check, not the sum
L3Monitor driftpendingJobs in info is a sum, not per-state; alert thresholds must not be built on it (bullmq-health.indicator.ts:27-29)

6. Planned / forward-looking (flag in tests)

#ItemStatus
P1/health/live + /health/ready route tests(planned) - END_TO_END_USER_FLOWS.md:738-740
P2Disk/memory indicator tests(planned) - not wired
P3Uptime/version fields(planned) - absent from payload
P4Failing-key in 503 body(proposed) - filter change needed (http-exception.filter.ts:56-58)
P5Authenticated admin variant(proposed) - needs health.* permission (permissions.constants.ts:1-97)