Document convective outlook endpoints
This commit is contained in:
@@ -8,7 +8,8 @@ This document describes the internal HTTP adapter under
|
||||
|
||||
The HTTP adapter turns feedapi route definitions into calls on the application
|
||||
service boundary. It owns route registration, query binding, request validation,
|
||||
forecast day-slice filtering, response envelopes, and template names.
|
||||
forecast day-slice filtering, outlook active/location filter construction,
|
||||
response envelopes, and template names.
|
||||
|
||||
## Inputs and Outputs
|
||||
|
||||
@@ -33,7 +34,8 @@ The adapter may:
|
||||
- bind and validate query parameters;
|
||||
- call the `Service` interface;
|
||||
- choose the presenter function for an endpoint;
|
||||
- filter forecast copies for `/today` and `/tomorrow`.
|
||||
- filter forecast copies for `/today` and `/tomorrow`;
|
||||
- construct outlook active/location filters.
|
||||
|
||||
The adapter must not:
|
||||
|
||||
@@ -59,9 +61,9 @@ declared in endpoint definitions, but `templates.base_dir` is loaded by feedapi.
|
||||
|
||||
## State
|
||||
|
||||
The adapter has no durable state. `forecastNow` is package-level state only to
|
||||
make forecast day filtering testable. Do not add request caches or cross-request
|
||||
mutable state here.
|
||||
The adapter has no durable state. `forecastNow` and `outlookNow` are
|
||||
package-level state only to make time-dependent endpoint tests deterministic.
|
||||
Do not add request caches or cross-request mutable state here.
|
||||
|
||||
## Route Registry
|
||||
|
||||
@@ -71,6 +73,7 @@ mutable state here.
|
||||
- active alerts;
|
||||
- current conditions;
|
||||
- weather stories;
|
||||
- convective outlooks;
|
||||
- forecast discussions;
|
||||
- hourly and narrative forecasts.
|
||||
|
||||
@@ -80,19 +83,25 @@ middleware, and error normalization after definitions are registered.
|
||||
|
||||
## Query Binding
|
||||
|
||||
There are three binder shapes:
|
||||
Binder shapes include:
|
||||
|
||||
- `bindQuery`: `format` and `units`;
|
||||
- `bindPrecisionQuery`: `format`, `units`, and `precision`;
|
||||
- `bindForecastPrecisionQuery`: `format`, `units`, `precision`, and timezone;
|
||||
- `bindTimezoneQuery`: `format`, `units`, and timezone.
|
||||
- outlook binders: `format`, `units`, timezone, and outlook filters.
|
||||
|
||||
All binders use feedapi binding helpers with `RejectUnknown: true`. Supported
|
||||
common query values are lowercased and trimmed before binding where applicable.
|
||||
|
||||
`precision` defaults to `0` and must be between `0` and `2`. Timezone parsing is
|
||||
available only through binders used by forecast, discussion, and weather story
|
||||
routes.
|
||||
available only through binders used by forecast, discussion, weather story, and
|
||||
outlook routes.
|
||||
|
||||
Outlook routes accept `day`, `outlookType`, and, except for
|
||||
`/outlooks/convective/location`, `containsLocation`. The location route always
|
||||
adds `containsLocation=true` after binding and rejects an explicit
|
||||
`containsLocation` query value.
|
||||
|
||||
## Timezone Parsing
|
||||
|
||||
@@ -122,6 +131,19 @@ Filtering behavior:
|
||||
The package variable `forecastNow` exists so endpoint tests can make day-slice
|
||||
behavior deterministic.
|
||||
|
||||
## Outlook Filters
|
||||
|
||||
Outlook route filters are built at the HTTP boundary and passed to the
|
||||
application service:
|
||||
|
||||
- `/outlooks/convective` uses only user-supplied filters;
|
||||
- `/outlooks/convective/active` adds `ActiveAt=outlookNow().UTC()`;
|
||||
- `/outlooks/convective/location` adds the same active timestamp and
|
||||
`ContainsLocation=true`.
|
||||
|
||||
The package variable `outlookNow` exists so endpoint tests can make active and
|
||||
location filtering deterministic.
|
||||
|
||||
## Failure Behavior
|
||||
|
||||
Binder failures become feedapi invalid-parameter responses. Handler service
|
||||
|
||||
@@ -21,8 +21,8 @@ Inputs:
|
||||
|
||||
Outputs:
|
||||
|
||||
- latest observation, forecast, discussion, weather story, alert, and current
|
||||
conditions read models;
|
||||
- latest observation, forecast, discussion, weather story, alert, convective
|
||||
outlook, and current conditions read models;
|
||||
- nil data with nil error when the latest resource does not exist;
|
||||
- contextual errors for query, scan, iteration, and JSON decode failures.
|
||||
|
||||
@@ -89,6 +89,8 @@ successful responses with `data: null`.
|
||||
- `LatestWeatherStoryRun`: latest row from `weather_story_runs`, then child
|
||||
`weather_stories`.
|
||||
- `LatestWeatherStory`: latest individual row from `weather_stories`.
|
||||
- `LatestConvectiveOutlookRun`: latest row from `outlook_runs`, then child
|
||||
`outlooks`.
|
||||
|
||||
Latest parent rows are selected by descending weather timestamp and
|
||||
`event_emitted_at` where that tie-breaker is available in the query.
|
||||
@@ -102,7 +104,8 @@ Child queries preserve stored order:
|
||||
- alert references by `alert_index`, then `reference_index`;
|
||||
- forecast periods by `period_index`;
|
||||
- discussion key messages by `message_index`;
|
||||
- weather stories by `story_index`.
|
||||
- weather stories by `story_index`;
|
||||
- outlooks by `outlook_index`.
|
||||
|
||||
Alert references are attached after both alert and reference rows are loaded.
|
||||
References are grouped by alert index and attached to their corresponding alert.
|
||||
@@ -126,6 +129,10 @@ Observation present-weather rows store raw JSON text. Empty or null text maps
|
||||
to an empty present-weather value. Invalid JSON returns a contextual decode
|
||||
error with the weather index.
|
||||
|
||||
Outlook rows store `geometry_json` as compact GeoJSON text. The repository
|
||||
validates and copies the JSON bytes into `json.RawMessage` without parsing or
|
||||
reserializing the geometry.
|
||||
|
||||
## Failure Behavior
|
||||
|
||||
Repository methods wrap failures with operation context, for example:
|
||||
|
||||
@@ -93,9 +93,9 @@ Latitude and longitude are copied but not rounded by forecast presenters.
|
||||
timezone is supplied. Without a timezone, timestamps are preserved as returned
|
||||
by the repository.
|
||||
|
||||
Timezone conversion is applied by forecast, discussion, and weather story
|
||||
presenters. Observations and current conditions do not currently receive
|
||||
timezone input from their routes.
|
||||
Timezone conversion is applied by forecast, discussion, weather story, and
|
||||
outlook presenters. Observations and current conditions do not currently
|
||||
receive timezone input from their routes.
|
||||
|
||||
## Optional Fields and Copy Semantics
|
||||
|
||||
@@ -118,6 +118,9 @@ response envelope so renderers can produce `data: null`.
|
||||
- Discussions: full or focused payload shapes, section copy, key-message copy,
|
||||
timezone conversion.
|
||||
- Weather stories: run/story copy and timezone conversion.
|
||||
- Convective outlooks: canonical model copy, pointer and geometry copy, and
|
||||
timezone conversion. `units` is accepted by routes but ignored by the
|
||||
presenter because outlook fields are not unit-bearing.
|
||||
|
||||
## Templates
|
||||
|
||||
|
||||
Reference in New Issue
Block a user