Refresh internal state and adapter documentation
This commit is contained in:
@@ -1,101 +1,69 @@
|
||||
# Weather Data Internals
|
||||
|
||||
This document describes Weather API ingestion into `weatherdata.Bundle`.
|
||||
`internal/weatherdata` owns the normalized, wire-independent weather bundle
|
||||
that passes from collection through rendering and persistence. The Weather API
|
||||
adapter translates provider responses into these types; its request, response,
|
||||
and availability contract is documented in the
|
||||
[Weather API integration guide](../integrations/weatherapi.md).
|
||||
|
||||
## Purpose
|
||||
## Bundle contract
|
||||
|
||||
`internal/adapters/weatherapi` fetches normalized weather data from the
|
||||
configured Weather API and assembles the bundle consumed by forecast derivation
|
||||
and module builders. Module builders expose normalized current conditions and
|
||||
weather story context when those sources are available.
|
||||
`Bundle` has a collection timestamp (`FetchedAt`), source provenance
|
||||
(`Sources`), and collection-level warnings (`Warnings`). Its product fields are
|
||||
optional so an allowed missing source can be represented without manufacturing
|
||||
weather data.
|
||||
|
||||
## Inputs And Outputs
|
||||
| Field | Normalized product |
|
||||
| --- | --- |
|
||||
| `Observation` | Station observation |
|
||||
| `Current` | Current conditions |
|
||||
| `Hourly` | Hourly forecast periods |
|
||||
| `Narrative` | Narrative forecast |
|
||||
| `Alerts` | Active-alert check, including an explicitly empty result |
|
||||
| `Discussion` | Forecast discussion and its time-range sections |
|
||||
| `Daily` | Daily forecast periods when supplied |
|
||||
| `WeatherStory` | Latest weather story |
|
||||
| `SPCConvectiveOutlooks` | Convective outlook run, discussions, and GeoJSON geometry |
|
||||
|
||||
Inputs:
|
||||
The bundle carries values rather than provider request details. Consumers use
|
||||
it to construct report facts and data packages; they should not infer a
|
||||
provider endpoint or retry policy from the normalized types. See
|
||||
[collection](collect.md) for assembly and
|
||||
[report templates](../templates.md) for the values exposed to authors.
|
||||
|
||||
- `config.Config` with Weather API URL, timeout, format, units, timezone,
|
||||
precision, and missing-source policy
|
||||
- HTTP responses using the Weather API `data` envelope
|
||||
## Source provenance
|
||||
|
||||
Outputs:
|
||||
Every checked source is represented by a `Source` entry. The record identifies
|
||||
the source (`Name`), request location and query (`Endpoint`, `Query`), fetch
|
||||
time, provider issue and update times when available, a SHA-256 digest of the
|
||||
source data, and whether the source was unavailable (`Missing`). Its warnings
|
||||
stay with that source in addition to the bundle-level warning list.
|
||||
|
||||
- `weatherdata.Bundle` with observation, current conditions, hourly forecast,
|
||||
narrative forecast, active alerts, discussion, latest weather story, source
|
||||
records, source warnings, and typed SPC convective outlook data when that
|
||||
optional source is available
|
||||
- optional saved bundle JSON through app fetch helpers
|
||||
An empty product can be meaningful checked data. For example, an explicit
|
||||
empty alerts result is not missing and retains its source hash. A source is
|
||||
marked missing only when the adapter's missing-source policy treats the
|
||||
response or parsing failure as unavailable. The policy itself belongs to the
|
||||
[configuration reference](../config.md).
|
||||
|
||||
## Boundaries
|
||||
## Warning semantics
|
||||
|
||||
- The adapter owns HTTP calls, response-envelope handling, source hashing, and
|
||||
decoding into internal bundle types.
|
||||
- It does not derive dayparts, resolve report periods, build module values, compare
|
||||
snapshots, write report state, or invoke Scriptorium.
|
||||
`SourceWarning` has a source name, stable code, severity, explanatory message,
|
||||
endpoint, and `CompletenessImpact`. When collection proceeds with a warning,
|
||||
the same warning appears in `Source.Warnings` and `Bundle.Warnings` so both
|
||||
local provenance and whole-run consumers see it. A policy that treats a missing
|
||||
source as an error returns no partial bundle.
|
||||
|
||||
## Config Fields Used
|
||||
Warnings describe data completeness, not rendering or delivery failures.
|
||||
Those failures are recorded by the application and state layers; see
|
||||
[application orchestration](app-orchestration.md) and [state internals](state.md).
|
||||
|
||||
- `weather_api.base_url`
|
||||
- `weather_api.timeout`
|
||||
- `weather_api.format`
|
||||
- `weather_api.units`
|
||||
- `weather_api.timezone`
|
||||
- `weather_api.precision`
|
||||
- `missing_source.default`
|
||||
- `missing_source.sources`
|
||||
## Boundaries and verification
|
||||
|
||||
## External Adapters Used
|
||||
This package defines data shapes and has no HTTP client, configuration loader,
|
||||
filesystem access, or template behavior. Focused tests cover the normalized
|
||||
types and the Weather API adapter verifies translation into them:
|
||||
|
||||
- Weather API HTTP service
|
||||
|
||||
See [Weather API integration](../integrations/weatherapi.md) for the external
|
||||
contract used by this project.
|
||||
|
||||
## State Or Manifest Behavior
|
||||
|
||||
The adapter records source name, endpoint, query, fetch time, source timestamps
|
||||
when available, SHA-256 hash over compact raw `data` JSON, missing status, and
|
||||
source warnings. Successful `data: null` responses from `/alerts/active`
|
||||
represent a checked empty active-alert list, not a missing source. Successful
|
||||
non-null `/outlooks/convective` responses with empty outlook and discussion
|
||||
arrays represent checked empty outlook data.
|
||||
`app.FetchAndSaveBundle` can write bundle JSON atomically for inspection.
|
||||
|
||||
SPC convective outlook data is stored on
|
||||
`weatherdata.Bundle.SPCConvectiveOutlooks`. The collected run keeps upstream
|
||||
run metadata, location identifiers, ordered outlook records, discussion
|
||||
records, and each outlook's raw GeoJSON geometry. Source provenance for this
|
||||
payload uses the `spc_convective_outlooks` source name, endpoint
|
||||
`/outlooks/convective`, the query sent by the adapter, timestamps, and a hash
|
||||
of the raw `data` object.
|
||||
|
||||
## Skip And Resume Behavior
|
||||
|
||||
No resume behavior. Optional missing or malformed sources may be omitted,
|
||||
warned, or treated as errors according to missing-source policy. Hourly forecast
|
||||
data is required and cannot be skipped.
|
||||
|
||||
## Failure Behavior
|
||||
|
||||
- Missing or invalid `weather_api.base_url` prevents client construction.
|
||||
- HTTP errors, response read failures, and envelope decode failures include
|
||||
endpoint context.
|
||||
- Missing hourly data or hourly forecasts with no periods fail bundle fetch.
|
||||
- Optional sources follow missing-source policy.
|
||||
- Explicit `data: null` from `/alerts/active` produces an empty, non-missing
|
||||
alert run.
|
||||
- Explicit `data: null` from `/outlooks/convective` follows optional
|
||||
missing-source policy.
|
||||
|
||||
## Tests
|
||||
|
||||
Inspect:
|
||||
|
||||
- `internal/adapters/weatherapi/client_test.go`
|
||||
- `internal/app/app_test.go`
|
||||
|
||||
## Invariants
|
||||
|
||||
- Weather facts come from normalized source data.
|
||||
- Full hourly and narrative products are fetched; Go owns report-period
|
||||
selection.
|
||||
- Source provenance and warnings remain inspectable downstream.
|
||||
```sh
|
||||
go test ./internal/weatherdata
|
||||
go test ./internal/adapters/weatherapi
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user