package httpapi import ( "net/http" "os" "time" "github.com/gin-contrib/cors" "github.com/gin-gonic/gin" "go.uber.org/zap" "productier/apps/backend/internal/authsession" "productier/apps/backend/internal/filestorage" "productier/apps/backend/internal/mailruntime" "productier/apps/backend/internal/store" ) func getEnvOrDefault(key, fallback string) string { if value := os.Getenv(key); value != "" { return value } return fallback } type OAuthConfig struct { GoogleClientID string GoogleClientSecret string GoogleRedirectURI string SlackClientID string SlackClientSecret string SlackRedirectURI string } type Server struct { engine *gin.Engine mode string store store.Store authClient *authsession.Client mail *mailruntime.Service files filestorage.Storage metrics *requestMetrics metricsToken string config OAuthConfig } func NewServer( dataStore store.Store, authClient *authsession.Client, mailService *mailruntime.Service, fileStorage filestorage.Storage, mode string, corsAllowOrigins []string, metricsToken string, logger *zap.Logger, ) *Server { engine := gin.New() metrics := newRequestMetrics() engine.Use(gin.Recovery()) engine.Use(requestMetricsMiddleware(metrics)) engine.Use(requestLogMiddleware(logger)) engine.Use(requestIDMiddleware()) engine.Use(cors.New(cors.Config{ AllowOrigins: corsAllowOrigins, AllowMethods: []string{http.MethodGet, http.MethodPost, http.MethodPatch, http.MethodDelete, http.MethodOptions}, AllowHeaders: []string{"Origin", "Content-Type", "Authorization", "Cookie"}, ExposeHeaders: []string{"Content-Length", "X-Request-Id"}, AllowCredentials: true, MaxAge: 12 * time.Hour, })) server := &Server{ engine: engine, mode: mode, store: dataStore, authClient: authClient, mail: mailService, files: fileStorage, metrics: metrics, metricsToken: metricsToken, config: OAuthConfig{ GoogleClientID: getEnvOrDefault("GOOGLE_CLIENT_ID", ""), GoogleClientSecret: getEnvOrDefault("GOOGLE_CLIENT_SECRET", ""), GoogleRedirectURI: getEnvOrDefault("GOOGLE_REDIRECT_URI", "http://localhost:8080/v1/oauth/google-calendar/callback"), SlackClientID: getEnvOrDefault("SLACK_CLIENT_ID", ""), SlackClientSecret: getEnvOrDefault("SLACK_CLIENT_SECRET", ""), SlackRedirectURI: getEnvOrDefault("SLACK_REDIRECT_URI", "http://localhost:8080/v1/oauth/slack/callback"), }, } server.registerRoutes() return server } func (s *Server) Engine() *gin.Engine { return s.engine }