mirror of
https://github.com/koala73/worldmonitor.git
synced 2026-04-25 17:14:57 +02:00
* feat(climate+health):add shared air quality seed and mirrored health/climate RPCs * feat(climate+health):add shared air quality seed and mirrored health/climate RPCs * fix(air-quality): address review findings — TTL, seed-health, FAST_KEYS, shared meta - Raise CACHE_TTL from 3600 to 10800 (3× the 1h cron cadence; gold standard) - Add health:air-quality to api/seed-health.js SEED_DOMAINS so monitoring dashboard tracks freshness - Remove climateAirQuality and healthAirQuality from FAST_KEYS (large station payloads; load in slow batch) - Point climateAirQuality SEED_META to same meta key as healthAirQuality (same seeder run, one source of truth) * fix(bootstrap): move air quality keys to SLOW tier — large station payloads avoid critical-path batch * fix(air-quality): fix malformed OpenAQ URL and remove from bootstrap until panel exists - Drop deprecated first URL attempt (parameters=pm25, order_by=lastUpdated, sort=desc); use correct v3 params (parameters_id=2, sort_order=desc) directly — eliminates guaranteed 4xx retry cycle per page on 20-page crawl - Remove climateAirQuality and healthAirQuality from BOOTSTRAP_CACHE_KEYS, SLOW_KEYS, and BOOTSTRAP_TIERS — no panel consumes these yet; adding thousands of station records to every startup bootstrap is pure payload bloat - Remove normalizeAirQualityPayload helpers from bootstrap.js (no longer called) - Update service wrappers to fetch via RPC directly; re-add bootstrap hydration when a panel actually needs it * fix(air-quality): raise lock TTL to 3600s to cover 20-page crawl worst case 2 OpenAQ calls × 20 pages × (30s timeout × 3 attempts) = 3600s max runtime. Previous 600s TTL allowed concurrent cron runs on any degraded upstream. --------- Co-authored-by: Elie Habib <elie.habib@gmail.com>
190 lines
7.5 KiB
YAML
190 lines
7.5 KiB
YAML
openapi: 3.1.0
|
|
info:
|
|
title: HealthService API
|
|
version: 1.0.0
|
|
paths:
|
|
/api/health/v1/list-disease-outbreaks:
|
|
get:
|
|
tags:
|
|
- HealthService
|
|
summary: ListDiseaseOutbreaks
|
|
description: ListDiseaseOutbreaks returns recent WHO/ProMED disease outbreak alerts.
|
|
operationId: ListDiseaseOutbreaks
|
|
responses:
|
|
"200":
|
|
description: Successful response
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ListDiseaseOutbreaksResponse'
|
|
"400":
|
|
description: Validation error
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ValidationError'
|
|
default:
|
|
description: Error response
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Error'
|
|
/api/health/v1/list-air-quality-alerts:
|
|
get:
|
|
tags:
|
|
- HealthService
|
|
summary: ListAirQualityAlerts
|
|
description: ListAirQualityAlerts returns recent PM2.5 stations with AQI-derived health risk.
|
|
operationId: ListAirQualityAlerts
|
|
responses:
|
|
"200":
|
|
description: Successful response
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ListAirQualityAlertsResponse'
|
|
"400":
|
|
description: Validation error
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/ValidationError'
|
|
default:
|
|
description: Error response
|
|
content:
|
|
application/json:
|
|
schema:
|
|
$ref: '#/components/schemas/Error'
|
|
components:
|
|
schemas:
|
|
Error:
|
|
type: object
|
|
properties:
|
|
message:
|
|
type: string
|
|
description: Error message (e.g., 'user not found', 'database connection failed')
|
|
description: Error is returned when a handler encounters an error. It contains a simple error message that the developer can customize.
|
|
FieldViolation:
|
|
type: object
|
|
properties:
|
|
field:
|
|
type: string
|
|
description: The field path that failed validation (e.g., 'user.email' for nested fields). For header validation, this will be the header name (e.g., 'X-API-Key')
|
|
description:
|
|
type: string
|
|
description: Human-readable description of the validation violation (e.g., 'must be a valid email address', 'required field missing')
|
|
required:
|
|
- field
|
|
- description
|
|
description: FieldViolation describes a single validation error for a specific field.
|
|
ValidationError:
|
|
type: object
|
|
properties:
|
|
violations:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/FieldViolation'
|
|
description: List of validation violations
|
|
required:
|
|
- violations
|
|
description: ValidationError is returned when request validation fails. It contains a list of field violations describing what went wrong.
|
|
ListDiseaseOutbreaksRequest:
|
|
type: object
|
|
ListDiseaseOutbreaksResponse:
|
|
type: object
|
|
properties:
|
|
outbreaks:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/DiseaseOutbreakItem'
|
|
fetchedAt:
|
|
type: integer
|
|
format: int64
|
|
description: 'Warning: Values > 2^53 may lose precision in JavaScript'
|
|
DiseaseOutbreakItem:
|
|
type: object
|
|
properties:
|
|
id:
|
|
type: string
|
|
description: Unique identifier (URL-derived).
|
|
disease:
|
|
type: string
|
|
description: Disease or outbreak name.
|
|
location:
|
|
type: string
|
|
description: Affected country or region.
|
|
countryCode:
|
|
type: string
|
|
description: ISO2 country code when known.
|
|
alertLevel:
|
|
type: string
|
|
description: 'Alert level: "watch" | "warning" | "alert".'
|
|
summary:
|
|
type: string
|
|
description: Short description from the source.
|
|
sourceUrl:
|
|
type: string
|
|
description: Source URL.
|
|
publishedAt:
|
|
type: integer
|
|
format: int64
|
|
description: 'Unix epoch milliseconds when published.. Warning: Values > 2^53 may lose precision in JavaScript'
|
|
sourceName:
|
|
type: string
|
|
description: Source name (e.g., "WHO", "ProMED", "HealthMap").
|
|
lat:
|
|
type: number
|
|
format: double
|
|
description: Precise latitude from source (overrides country centroid on map when non-zero).
|
|
lng:
|
|
type: number
|
|
format: double
|
|
description: Precise longitude from source (overrides country centroid on map when non-zero).
|
|
cases:
|
|
type: integer
|
|
format: int32
|
|
description: Case count if reported by source (0 = unknown).
|
|
description: DiseaseOutbreakItem represents a single disease outbreak event.
|
|
ListAirQualityAlertsRequest:
|
|
type: object
|
|
ListAirQualityAlertsResponse:
|
|
type: object
|
|
properties:
|
|
alerts:
|
|
type: array
|
|
items:
|
|
$ref: '#/components/schemas/AirQualityAlert'
|
|
fetchedAt:
|
|
type: integer
|
|
format: int64
|
|
description: 'Warning: Values > 2^53 may lose precision in JavaScript'
|
|
AirQualityAlert:
|
|
type: object
|
|
properties:
|
|
city:
|
|
type: string
|
|
countryCode:
|
|
type: string
|
|
lat:
|
|
type: number
|
|
format: double
|
|
lng:
|
|
type: number
|
|
format: double
|
|
pm25:
|
|
type: number
|
|
format: double
|
|
aqi:
|
|
type: integer
|
|
format: int32
|
|
riskLevel:
|
|
type: string
|
|
pollutant:
|
|
type: string
|
|
measuredAt:
|
|
type: integer
|
|
format: int64
|
|
description: 'Warning: Values > 2^53 may lose precision in JavaScript'
|
|
source:
|
|
type: string
|