Files
breakpilot-compliance/breakpilot-compliance-sdk/services/api-gateway/main.go
Benjamin Boenisch 4435e7ea0a Initial commit: breakpilot-compliance - Compliance SDK Platform
Services: Admin-Compliance, Backend-Compliance,
AI-Compliance-SDK, Consent-SDK, Developer-Portal,
PCA-Platform, DSMS

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-11 23:47:28 +01:00

189 lines
5.1 KiB
Go

// 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")
}