// BreakPilot Compliance SDK - API Gateway // // Main entry point for the API Gateway service. // Handles authentication, rate limiting, and request routing. package main import ( "context" "log" "net/http" "os" "os/signal" "syscall" "time" "github.com/breakpilot/compliance-sdk/services/api-gateway/internal/api" "github.com/breakpilot/compliance-sdk/services/api-gateway/internal/config" "github.com/breakpilot/compliance-sdk/services/api-gateway/internal/middleware" "github.com/gin-gonic/gin" "go.uber.org/zap" ) func main() { // Initialize logger logger, _ := zap.NewProduction() defer logger.Sync() // Load configuration cfg, err := config.Load() if err != nil { logger.Fatal("Failed to load configuration", zap.Error(err)) } // Set Gin mode if cfg.Environment == "production" { gin.SetMode(gin.ReleaseMode) } // Initialize router router := gin.New() // Global middleware router.Use(gin.Recovery()) router.Use(middleware.Logger(logger)) router.Use(middleware.CORS()) router.Use(middleware.RequestID()) // Health check (no auth required) router.GET("/health", func(c *gin.Context) { c.JSON(http.StatusOK, gin.H{ "status": "healthy", "service": "api-gateway", "version": cfg.Version, }) }) // API v1 routes v1 := router.Group("/api/v1") { // Public routes (rate limited) v1.Use(middleware.RateLimiter(cfg.RateLimit)) // Auth routes auth := v1.Group("/auth") { auth.POST("/token", api.GetToken) auth.POST("/refresh", api.RefreshToken) } // Protected routes protected := v1.Group("") protected.Use(middleware.Auth(cfg.JWTSecret)) protected.Use(middleware.TenantIsolation()) { // State management protected.GET("/state/:tenantId", api.GetState) protected.POST("/state/save", api.SaveState) protected.POST("/state/reset", api.ResetState) // DSGVO dsgvo := protected.Group("/dsgvo") { dsgvo.POST("/consent", api.RecordConsent) dsgvo.GET("/consent/:userId", api.GetConsents) dsgvo.DELETE("/consent/:consentId", api.RevokeConsent) dsgvo.POST("/dsr", api.SubmitDSR) dsgvo.GET("/dsr", api.ListDSRRequests) dsgvo.PUT("/dsr/:requestId", api.UpdateDSRStatus) dsgvo.GET("/vvt", api.GetProcessingActivities) dsgvo.POST("/vvt", api.CreateProcessingActivity) dsgvo.PUT("/vvt/:activityId", api.UpdateProcessingActivity) dsgvo.DELETE("/vvt/:activityId", api.DeleteProcessingActivity) dsgvo.GET("/tom", api.GetTOMs) dsgvo.POST("/tom", api.CreateTOM) dsgvo.PUT("/tom/:tomId", api.UpdateTOM) dsgvo.DELETE("/tom/:tomId", api.DeleteTOM) dsgvo.GET("/dsfa", api.GetDSFAs) dsgvo.POST("/dsfa", api.CreateDSFA) dsgvo.PUT("/dsfa/:dsfaId", api.UpdateDSFA) dsgvo.GET("/retention", api.GetRetentionPolicies) dsgvo.POST("/retention", api.CreateRetentionPolicy) dsgvo.PUT("/retention/:policyId", api.UpdateRetentionPolicy) dsgvo.DELETE("/retention/:policyId", api.DeleteRetentionPolicy) } // Compliance compliance := protected.Group("/compliance") { compliance.GET("/controls", api.GetControls) compliance.POST("/controls", api.CreateControl) compliance.PUT("/controls/:controlId", api.UpdateControl) compliance.DELETE("/controls/:controlId", api.DeleteControl) compliance.GET("/evidence", api.GetEvidence) compliance.POST("/evidence", api.UploadEvidence) compliance.PUT("/evidence/:evidenceId", api.UpdateEvidence) compliance.DELETE("/evidence/:evidenceId", api.DeleteEvidence) compliance.GET("/obligations", api.GetObligations) compliance.POST("/assessment", api.RunAssessment) compliance.GET("/export/pdf", api.ExportPDF) compliance.GET("/export/docx", api.ExportDOCX) } // RAG rag := protected.Group("/rag") { rag.POST("/search", api.SearchRAG) rag.POST("/ask", api.AskRAG) rag.GET("/regulations", api.GetRegulations) rag.POST("/documents", api.UploadDocument) } // SBOM & Security security := protected.Group("/security") { security.POST("/sbom/generate", api.GenerateSBOM) security.GET("/sbom/components", api.GetSBOMComponents) security.GET("/sbom/export/:format", api.ExportSBOM) security.POST("/scan", api.StartSecurityScan) security.GET("/findings", api.GetSecurityFindings) security.GET("/recommendations", api.GetRecommendations) security.GET("/reports", api.GetSecurityReports) } } } // Create HTTP server srv := &http.Server{ Addr: ":" + cfg.Port, Handler: router, ReadTimeout: 15 * time.Second, WriteTimeout: 15 * time.Second, IdleTimeout: 60 * time.Second, } // Start server in goroutine go func() { logger.Info("Starting API Gateway", zap.String("port", cfg.Port)) if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed { logger.Fatal("Failed to start server", zap.Error(err)) } }() // Graceful shutdown quit := make(chan os.Signal, 1) signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM) <-quit logger.Info("Shutting down server...") ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() if err := srv.Shutdown(ctx); err != nil { logger.Fatal("Server forced to shutdown", zap.Error(err)) } logger.Info("Server exited") }