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 }