Files
weatherapi/cmd/weatherapi/main.go
2026-03-20 09:44:53 -05:00

86 lines
2.0 KiB
Go

// main.go wires configuration, dependencies, and HTTP runtime startup.
// Layer: cmd/weatherapi executable composition root.
package main
import (
"context"
"flag"
"fmt"
"log"
"os"
"os/signal"
"strings"
"syscall"
feedapp "gitea.maximumdirect.net/ejr/feedapi/app"
"gitea.maximumdirect.net/ejr/feedapi/config"
"gitea.maximumdirect.net/ejr/feedapi/db"
httpapi "gitea.maximumdirect.net/ejr/weatherapi/internal/adapters/inbound/httpapi"
wfpq "gitea.maximumdirect.net/ejr/weatherapi/internal/adapters/outbound/postgres"
"gitea.maximumdirect.net/ejr/weatherapi/internal/app"
_ "github.com/lib/pq"
)
func main() {
log.SetFlags(log.LstdFlags | log.Lmicroseconds)
cfgPath := flag.String("config", envOrDefault("WEATHERAPI_CONFIG", "config.yml"), "Path to config YAML")
flag.Parse()
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt, syscall.SIGTERM)
defer cancel()
if err := run(ctx, *cfgPath); err != nil {
log.Fatalf("weatherapi failed: %v", err)
}
}
func run(ctx context.Context, cfgPath string) error {
cfg, err := config.Load(cfgPath)
if err != nil {
return fmt.Errorf("load config: %w", err)
}
if len(cfg.Databases) == 0 {
return fmt.Errorf("config.databases requires at least one entry")
}
reg, err := db.OpenAll(cfg.Databases)
if err != nil {
return fmt.Errorf("open databases: %w", err)
}
defer func() {
if cerr := reg.Close(); cerr != nil {
log.Printf("database close error: %v", cerr)
}
}()
primaryName := cfg.Databases[0].Name
primary, err := reg.Get(primaryName)
if err != nil {
return fmt.Errorf("select primary database %q: %w", primaryName, err)
}
repo := wfpq.NewRepository(primary)
svc := app.NewService(repo)
defs := httpapi.Definitions(svc)
a, err := feedapp.New(cfg,
feedapp.WithDBRegistry(reg),
feedapp.WithEndpoints(defs...),
)
if err != nil {
return fmt.Errorf("build app: %w", err)
}
return a.Start(ctx)
}
func envOrDefault(key, fallback string) string {
v := strings.TrimSpace(os.Getenv(key))
if v == "" {
return fallback
}
return v
}