refactor(providers): centralize provider-specific parsing and invariants
- Introduce internal/providers/nws with shared timestamp parsing used by both NWS sources and normalizers - Migrate NWS observation source + normalizer to use the shared provider helper for consistent RFC3339/RFC3339Nano handling - Introduce internal/providers/openweather with a shared URL invariant helper enforcing units=metric - Remove duplicated OpenWeather URL validation logic from the observation source - Align provider layering: move provider “contract/quirk” logic out of normalizers and into internal/providers - Update normalizer and standards documentation to clearly distinguish: provider helpers (internal/providers) vs canonical mapping logic (internal/normalizers) This refactor reduces duplication between sources and normalizers, clarifies layering boundaries, and establishes a scalable pattern for future forecast and alert implementations.
This commit is contained in:
@@ -1,19 +0,0 @@
|
||||
// FILE: ./internal/normalizers/openmeteo/common.go
|
||||
package openmeteo
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
openmeteo "gitea.maximumdirect.net/ejr/weatherfeeder/internal/providers/openmeteo"
|
||||
)
|
||||
|
||||
// parseOpenMeteoTime parses Open-Meteo timestamps.
|
||||
//
|
||||
// The actual parsing logic lives in internal/providers/openmeteo so both the
|
||||
// source (envelope EffectiveAt / event ID) and normalizer (canonical payload)
|
||||
// can share identical timestamp behavior.
|
||||
//
|
||||
// We keep this thin wrapper to avoid churn in the normalizer package.
|
||||
func parseOpenMeteoTime(s string, tz string, utcOffsetSeconds int) (time.Time, error) {
|
||||
return openmeteo.ParseTime(s, tz, utcOffsetSeconds)
|
||||
}
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"gitea.maximumdirect.net/ejr/feedkit/event"
|
||||
"gitea.maximumdirect.net/ejr/weatherfeeder/internal/model"
|
||||
normcommon "gitea.maximumdirect.net/ejr/weatherfeeder/internal/normalizers/common"
|
||||
omcommon "gitea.maximumdirect.net/ejr/weatherfeeder/internal/providers/openmeteo"
|
||||
"gitea.maximumdirect.net/ejr/weatherfeeder/internal/standards"
|
||||
)
|
||||
|
||||
@@ -54,7 +55,7 @@ func buildObservation(parsed omResponse) (model.WeatherObservation, time.Time, e
|
||||
// Parse current.time.
|
||||
var ts time.Time
|
||||
if s := strings.TrimSpace(parsed.Current.Time); s != "" {
|
||||
t, err := parseOpenMeteoTime(s, parsed.Timezone, parsed.UTCOffsetSeconds)
|
||||
t, err := omcommon.ParseTime(s, parsed.Timezone, parsed.UTCOffsetSeconds)
|
||||
if err != nil {
|
||||
return model.WeatherObservation{}, time.Time{}, fmt.Errorf("parse time %q: %w", s, err)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user