Initial MVP commit
All checks were successful
ci/woodpecker/push/build-image Pipeline was successful

This commit is contained in:
2026-03-17 08:35:16 -05:00
parent 8c092c2247
commit 27817f9e43
29 changed files with 1890 additions and 1 deletions

View File

@@ -0,0 +1,84 @@
package observations
import (
"context"
"fmt"
"time"
"gitea.maximumdirect.net/ejr/weatherapi/internal/application/units"
"gitea.maximumdirect.net/ejr/weatherapi/internal/core/ports"
)
type Service struct {
repo ports.ObservationRepository
converter units.Converter
window time.Duration
}
func NewService(repo ports.ObservationRepository, converter units.Converter, window time.Duration) *Service {
return &Service{repo: repo, converter: converter, window: window}
}
type CurrentResponse struct {
Summary SummaryResponse `json:"summary"`
Conditions []ConditionResponse `json:"conditions"`
PrecipitationEvents []string `json:"precipitationEvents"`
}
type SummaryResponse struct {
TemperatureF *float64 `json:"temperatureF"`
ApparentTemperatureF *float64 `json:"apparentTemperatureF"`
WindowMinutes int `json:"windowMinutes"`
}
type ConditionResponse struct {
StationID *string `json:"stationId"`
ObservedAt time.Time `json:"observedAt"`
TemperatureF *float64 `json:"temperatureF"`
TextDescription *string `json:"textDescription"`
ProviderRawDescription *string `json:"providerRawDescription"`
ConditionText *string `json:"conditionText"`
}
func (s *Service) GetCurrent(ctx context.Context) (CurrentResponse, error) {
if s == nil {
return CurrentResponse{}, fmt.Errorf("observations service is nil")
}
summary, err := s.repo.GetCurrentSummary(ctx, s.window)
if err != nil {
return CurrentResponse{}, err
}
conditionsMetric, err := s.repo.ListCurrentConditions(ctx, s.window)
if err != nil {
return CurrentResponse{}, err
}
precip, err := s.repo.ListCurrentPrecipitationEvents(ctx, s.window)
if err != nil {
return CurrentResponse{}, err
}
conditions := make([]ConditionResponse, 0, len(conditionsMetric))
for _, c := range conditionsMetric {
conditions = append(conditions, ConditionResponse{
StationID: c.StationID,
ObservedAt: c.ObservedAt,
TemperatureF: s.converter.TemperatureCToOutput(c.TemperatureC),
TextDescription: c.TextDescription,
ProviderRawDescription: c.ProviderRawDescription,
ConditionText: c.ConditionText,
})
}
return CurrentResponse{
Summary: SummaryResponse{
TemperatureF: s.converter.TemperatureCToOutput(summary.TemperatureC),
ApparentTemperatureF: s.converter.TemperatureCToOutput(summary.ApparentTemperatureC),
WindowMinutes: int(s.window / time.Minute),
},
Conditions: conditions,
PrecipitationEvents: precip,
}, nil
}