mirror of
https://github.com/koala73/worldmonitor.git
synced 2026-04-25 17:14:57 +02:00
* docs: restructure documentation into focused, navigable pages (#docs-reorg) Break the 4096-line documentation.mdx monolith into 13 focused pages organized by feature area. Reorganize Mintlify navigation from 5 generic groups into 7 feature-based groups. Move Orbital Surveillance from Infrastructure to Map Layers where it belongs. - Extract: signal-intelligence, features, overview, hotspots, CII, geographic-convergence, strategic-risk, infrastructure-cascade, military-tracking, maritime-intelligence, natural-disasters, contributing, getting-started - Append to: architecture.mdx (9 sections), ai-intelligence.mdx (3 sections) - Fix legacy .md links in map-engine.mdx, maps-and-geocoding.mdx - Slim documentation.mdx to an 80-line index/hub page - Eliminate duplicate content that caused repeated headings * fix(docs): remove duplicate H1 headings from all Mintlify pages Mintlify auto-renders the frontmatter `title` as an H1, so having `# Title` in the body creates a doubled heading on every page. Remove the redundant H1 (and repeated description lines) from all 31 .mdx files.
213 lines
6.7 KiB
Plaintext
213 lines
6.7 KiB
Plaintext
---
|
|
title: "Health Endpoints"
|
|
description: "World Monitor exposes two health endpoints for monitoring data pipeline integrity. Both run on the Vercel Edge Runtime and query Redis (Upstash) to assess system state."
|
|
---
|
|
|
|
## `/api/health`
|
|
|
|
Primary health endpoint. Checks all Redis-backed data keys and seed freshness metadata in a single pipeline call.
|
|
|
|
**Authentication:** None required. Open to all origins (`Access-Control-Allow-Origin: *`).
|
|
|
|
**HTTP Method:** `GET`
|
|
|
|
### Query Parameters
|
|
|
|
| Parameter | Values | Description |
|
|
|-----------|--------|-------------|
|
|
| `compact` | `1` | Omit per-key details; only return keys with problems |
|
|
|
|
### Response Status Codes
|
|
|
|
| HTTP Status | Overall Status | Meaning |
|
|
|-------------|---------------|---------|
|
|
| `200` | `HEALTHY` | All checks OK, no warnings |
|
|
| `200` | `WARNING` | Some keys stale or on-demand keys empty, but no critical failures |
|
|
| `503` | `DEGRADED` | 1-3 bootstrap keys empty |
|
|
| `503` | `UNHEALTHY` | 4+ bootstrap keys empty |
|
|
| `503` | `REDIS_DOWN` | Could not connect to Redis |
|
|
|
|
### Response Body
|
|
|
|
```json
|
|
{
|
|
"status": "HEALTHY | WARNING | DEGRADED | UNHEALTHY | REDIS_DOWN",
|
|
"summary": {
|
|
"total": 57,
|
|
"ok": 52,
|
|
"warn": 5,
|
|
"crit": 0
|
|
},
|
|
"checkedAt": "2026-03-11T14:00:00.000Z",
|
|
"checks": {
|
|
"earthquakes": {
|
|
"status": "OK",
|
|
"records": 142,
|
|
"seedAgeMin": 8,
|
|
"maxStaleMin": 30
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
With `?compact=1`, the `checks` object is replaced by `problems` containing only non-OK keys.
|
|
|
|
### Key Classifications
|
|
|
|
Keys are grouped into three tiers that determine alert severity:
|
|
|
|
| Tier | Severity when empty | Description |
|
|
|------|-------------------|-------------|
|
|
| **Bootstrap** | CRIT | Seeded data required at startup. Empty means the dashboard is missing critical data |
|
|
| **Standalone** | CRIT (seeded) / WARN (on-demand) | Populated by seed loops or RPC handlers. On-demand keys are expected to be empty until first request |
|
|
| **On-demand** | WARN | Populated lazily by RPC calls. Empty is normal if nobody has requested the data yet |
|
|
|
|
### Per-Key Statuses
|
|
|
|
| Status | Severity | Meaning |
|
|
|--------|----------|---------|
|
|
| `OK` | Green | Data present, seed fresh |
|
|
| `OK_CASCADE` | Green | Key empty but a sibling in the cascade group has data (e.g., theater posture fallback chain) |
|
|
| `STALE_SEED` | Warn | Data present but `seed-meta` age exceeds `maxStaleMin` |
|
|
| `EMPTY_ON_DEMAND` | Warn | On-demand key has no data yet |
|
|
| `EMPTY` | Crit | Bootstrap or standalone key has no data |
|
|
| `EMPTY_DATA` | Crit | Key exists but contains zero records |
|
|
|
|
### Cascade Groups
|
|
|
|
Some keys use fallback chains. If any sibling has data, empty siblings report `OK_CASCADE`:
|
|
|
|
- **Theater Posture:** `theaterPostureLive` -> `theaterPosture` (stale) -> `theaterPostureBackup`
|
|
- **Military Flights:** `militaryFlights` -> `militaryFlightsStale`
|
|
|
|
### Staleness Thresholds (maxStaleMin)
|
|
|
|
Selected thresholds from `SEED_META`:
|
|
|
|
| Domain | Max Stale (min) | Notes |
|
|
|--------|----------------|-------|
|
|
| Market quotes, crypto, sectors | 30 | High-frequency relay loops |
|
|
| Earthquakes, unrest, insights | 30 | Critical event data |
|
|
| Predictions | 15 | Polymarket, fast-moving |
|
|
| Military flights | 15 | Near-real-time tracking |
|
|
| Flight delays (FAA) | 60 | Airport delay snapshots |
|
|
| Wildfires, climate anomalies | 120 | Slower-moving natural events |
|
|
| Cyber threats | 480 | APT data updated less frequently |
|
|
| BIS data, World Bank, minerals | 2880-10080 | Institutional data, weekly/monthly updates |
|
|
|
|
### Example Requests
|
|
|
|
```bash
|
|
# Full health check
|
|
curl -s https://api.worldmonitor.app/api/health | jq .
|
|
|
|
# Compact (problems only)
|
|
curl -s "https://api.worldmonitor.app/api/health?compact=1" | jq .
|
|
|
|
# UptimeRobot / monitoring: check HTTP status code
|
|
curl -o /dev/null -s -w "%{http_code}" https://api.worldmonitor.app/api/health
|
|
# Returns 200 (healthy/warning) or 503 (degraded/unhealthy)
|
|
```
|
|
|
|
## `/api/seed-health`
|
|
|
|
Focused endpoint for seed loop freshness. Checks only `seed-meta:*` keys without fetching actual data payloads.
|
|
|
|
**Authentication:** Requires valid API key or allowed origin.
|
|
|
|
**HTTP Method:** `GET`
|
|
|
|
### Response Status Codes
|
|
|
|
| HTTP Status | Overall Status | Meaning |
|
|
|-------------|---------------|---------|
|
|
| `200` | `healthy` | All seed loops reporting on time |
|
|
| `200` | `warning` | Some seeds stale (age > 2x interval) |
|
|
| `200` | `degraded` | Some seeds missing entirely |
|
|
| `401` | - | Invalid or missing API key |
|
|
| `503` | - | Redis unavailable |
|
|
|
|
### Response Body
|
|
|
|
```json
|
|
{
|
|
"overall": "healthy | warning | degraded",
|
|
"checkedAt": 1710158400000,
|
|
"seeds": {
|
|
"seismology:earthquakes": {
|
|
"status": "ok",
|
|
"fetchedAt": 1710158100000,
|
|
"recordCount": 142,
|
|
"sourceVersion": null,
|
|
"ageMinutes": 5,
|
|
"stale": false
|
|
},
|
|
"market:stocks": {
|
|
"status": "stale",
|
|
"fetchedAt": 1710150000000,
|
|
"recordCount": 85,
|
|
"sourceVersion": null,
|
|
"ageMinutes": 140,
|
|
"stale": true
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### Staleness Logic
|
|
|
|
A seed is considered stale when its age exceeds **2x the configured interval**. This accounts for normal jitter in cron/relay timing.
|
|
|
|
| Domain | Interval (min) | Stale After (min) |
|
|
|--------|---------------|-------------------|
|
|
| Predictions, military flights | 8 | 16 |
|
|
| Market quotes, earthquakes, unrest | 15 | 30 |
|
|
| ETF flows, stablecoins, chokepoints | 30 | 60 |
|
|
| Service statuses, spending, wildfires | 60 | 120 |
|
|
| Shipping rates, satellites | 90-120 | 180-240 |
|
|
| GPS jamming, displacement | 360 | 720 |
|
|
| Iran events, UCDP | 210-5040 | 420-10080 |
|
|
|
|
### Example Request
|
|
|
|
```bash
|
|
curl -s https://api.worldmonitor.app/api/seed-health \
|
|
-H "Origin: https://worldmonitor.app" | jq .
|
|
```
|
|
|
|
## Integration with Monitoring Tools
|
|
|
|
### UptimeRobot
|
|
|
|
Use `/api/health` as the monitor URL. UptimeRobot checks HTTP status:
|
|
|
|
- `200` = up
|
|
- `503` = down
|
|
|
|
For keyword monitoring, check for `"status":"HEALTHY"` in the response body.
|
|
|
|
### Custom Alerting
|
|
|
|
Parse the JSON response to build granular alerts:
|
|
|
|
```bash
|
|
# Alert on any critical keys
|
|
STATUS=$(curl -s "https://api.worldmonitor.app/api/health?compact=1")
|
|
CRIT=$(echo "$STATUS" | jq '.summary.crit')
|
|
if [ "$CRIT" -gt 0 ]; then
|
|
echo "CRITICAL: $CRIT data keys empty"
|
|
echo "$STATUS" | jq '.problems'
|
|
fi
|
|
```
|
|
|
|
## Differences Between Endpoints
|
|
|
|
| Aspect | `/api/health` | `/api/seed-health` |
|
|
|--------|--------------|-------------------|
|
|
| **Scope** | Data keys + seed metadata | Seed metadata only |
|
|
| **Auth** | None (public) | API key or allowed origin |
|
|
| **Data fetched** | Full Redis values (to count records) | Only `seed-meta:*` keys |
|
|
| **HTTP 503** | Yes (DEGRADED/UNHEALTHY) | No (always 200 unless Redis down) |
|
|
| **Best for** | Uptime monitoring, dashboard health | Debugging seed loop issues |
|
|
| **Response size** | Larger (57+ keys with record counts) | Smaller (42 seed domains) |
|