Merged SCHEMA.md into API.md and made some tweaks to ensure consistency with the underlying domain model.
All checks were successful
ci/woodpecker/push/build-image Pipeline was successful

This commit is contained in:
2026-02-07 19:36:50 -06:00
parent 190420e908
commit cff8c5f593
2 changed files with 45 additions and 224 deletions

103
API.md
View File

@@ -47,36 +47,22 @@ Each payload is described below using the JSON field names as the contract.
---
## Shared conventions
## Shared Conventions
### Optional fields
Most non-identity measurements are optional. Optional fields are omitted when unknown (i.e., not present).
### Units
Canonical payloads are normalized to metric units:
- Temperature: `*C` (Celsius)
- Wind speed/gust: `*Kmh` (kilometers/hour)
- Pressure: `*Pa` (Pascals)
- Visibility / distance / elevation: `*Meters` (meters)
- Precipitation amount / snowfall depth: `*Mm` (millimeters)
- Humidity / cloud cover / PoP: `*Percent` (0100)
### Float rounding
For readability and stability, weatherfeeder rounds floating-point values in canonical payloads to
**2 digits after the decimal** during normalization finalization.
### WMO condition codes
`conditionCode` uses the WMO weather interpretation code vocabulary.
- Type: integer
- Unknown/unmappable: `-1`
Downstream consumers should treat unknown codes as “unknown conditions” rather than failing decoding.
- Timestamps are JSON strings in RFC3339Nano format.
- Optional fields are omitted when unknown (`omitempty` behavior).
- Numeric measurements are normalized to metric units:
- `*C` = Celsius
- `*Kmh` = kilometers/hour
- `*Pa` = Pascals
- `*Meters` = meters
- `*Mm` = millimeters
- `*Percent` = percent (0-100)
- `conditionCode` is a WMO weather interpretation code (`int`).
- Unknown/unmappable is `-1`.
- Downstream consumers should treat unknown codes as “unknown conditions” rather than failing decoding.
- For readability and stability, weatherfeeder rounds floating-point values in canonical payloads to
**4 digits after the decimal** during normalization.
---
@@ -88,31 +74,31 @@ A `WeatherObservation` represents a point-in-time observation for a station/loca
### Fields
| Field | Type | Required | Units / Notes |
| Field | Type | Required | Notes |
|---|---:|:---:|---|
| `stationId` | string | no | Provider station/location identifier |
| `stationName` | string | no | Human name, if available |
| `timestamp` | string (timestamp) | yes | Observation time |
| `conditionCode` | int | yes | WMO code (`-1` for unknown) |
| `conditionText` | string | no | Canonical short text (often derived from WMO code) |
| `isDay` | bool | no | Day/night hint when available |
| `providerRawDescription` | string | no | Provider-specific evidence text |
| `textDescription` | string | no | Legacy/transitional human text |
| `stationName` | string | no | Human station name |
| `timestamp` | timestamp string | yes | Observation timestamp |
| `conditionCode` | int | yes | WMO code (`-1` unknown) |
| `conditionText` | string | no | Canonical short condition text |
| `isDay` | bool | no | Day/night hint |
| `providerRawDescription` | string | no | Provider-specific evidence text |
| `textDescription` | string | no | Legacy/transitional text description |
| `iconUrl` | string | no | Legacy/transitional icon URL |
| `temperatureC` | number | no | °C |
| `dewpointC` | number | no | °C |
| `windDirectionDegrees` | number | no | Degrees (meteorological) |
| `temperatureC` | number | no | Celsius |
| `dewpointC` | number | no | Celsius |
| `windDirectionDegrees` | number | no | Degrees |
| `windSpeedKmh` | number | no | km/h |
| `windGustKmh` | number | no | km/h |
| `barometricPressurePa` | number | no | Pa |
| `seaLevelPressurePa` | number | no | Pa |
| `visibilityMeters` | number | no | meters |
| `relativeHumidityPercent` | number | no | percent (0100) |
| `apparentTemperatureC` | number | no | °C |
| `elevationMeters` | number | no | meters |
| `rawMessage` | string | no | Provider raw message (e.g. METAR), if available |
| `presentWeather` | array | no | Provider-specific structured fragments |
| `cloudLayers` | array | no | Cloud layers (base + amount) |
| `barometricPressurePa` | number | no | Pascals |
| `seaLevelPressurePa` | number | no | Pascals |
| `visibilityMeters` | number | no | Meters |
| `relativeHumidityPercent` | number | no | Percent |
| `apparentTemperatureC` | number | no | Celsius |
| `elevationMeters` | number | no | Meters |
| `rawMessage` | string | no | Provider raw message (for example METAR) |
| `presentWeather` | array | no | Provider-specific structured weather fragments |
| `cloudLayers` | array | no | Cloud layer details |
### Nested: `cloudLayers[]`
@@ -156,7 +142,7 @@ A `WeatherForecastRun` is a single issued forecast snapshot for a location and a
| `locationName` | string | no | Human name, if available |
| `issuedAt` | string (timestamp) | yes | When this run was generated/issued |
| `updatedAt` | string (timestamp) | no | Optional later update time |
| `product` | string | yes | `"hourly"`, `"narrative"`, or `"daily"` |
| `product` | string | yes | One of `hourly`, `narrative`, `daily` |
| `latitude` | number | no | Degrees |
| `longitude` | number | no | Degrees |
| `elevationMeters` | number | no | meters |
@@ -220,14 +206,15 @@ A run may contain zero, one, or many alerts.
| Field | Type | Required | Notes |
|---|---:|:---:|---|
| `id` | string | yes | Provider-stable identifier (often a URL/URI) |
| `event` | string | no | Classification |
| `headline` | string | no | Short headline |
| `severity` | string | no | e.g. Extreme/Severe/Moderate/Minor/Unknown |
| `urgency` | string | no | e.g. Immediate/Expected/Future/Past/Unknown |
| `certainty` | string | no | e.g. Observed/Likely/Possible/Unlikely/Unknown |
| `status` | string | no | e.g. Actual/Exercise/Test/System/Unknown |
| `messageType` | string | no | e.g. Alert/Update/Cancel |
| `category` | string | no | e.g. Met/Geo/Safety/... |
| `event` | string | no | Classification/event label |
| `headline` | string | no | Alert headline |
| `severity` | string | no | Example: Extreme/Severe/Moderate/Minor/Unknown |
| `urgency` | string | no | Example: Immediate/Expected/Future/Past/Unknown |
| `certainty` | string | no | Example: Observed/Likely/Possible/Unlikely/Unknown |
| `status` | string | no | Example: Actual/Exercise/Test/System/Unknown |
| `messageType` | string | no | Example: Alert/Update/Cancel |
| `category` | string | no | Example: Met/Geo/Safety/Rescue/Fire/Health/Env/Transport/Infra/CBRNE/Other |
| `response` | string | no | Example: Shelter/Evacuate/Prepare/Execute/Avoid/Monitor/Assess/AllClear/None |
| `response` | string | no | e.g. Shelter/Evacuate/Prepare/... |
| `description` | string | no | Narrative |
| `instruction` | string | no | What to do |