fix: Restore all files lost during destructive rebase
A previous `git pull --rebase origin main` dropped 177 local commits,
losing 3400+ files across admin-v2, backend, studio-v2, website,
klausur-service, and many other services. The partial restore attempt
(660295e2) only recovered some files.
This commit restores all missing files from pre-rebase ref 98933f5e
while preserving post-rebase additions (night-scheduler, night-mode UI,
NightModeWidget dashboard integration).
Restored features include:
- AI Module Sidebar (FAB), OCR Labeling, OCR Compare
- GPU Dashboard, RAG Pipeline, Magic Help
- Klausur-Korrektur (8 files), Abitur-Archiv (5+ files)
- Companion, Zeugnisse-Crawler, Screen Flow
- Full backend, studio-v2, website, klausur-service
- All compliance SDKs, agent-core, voice-service
- CI/CD configs, documentation, scripts
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
143
billing-service/cmd/server/main.go
Normal file
143
billing-service/cmd/server/main.go
Normal file
@@ -0,0 +1,143 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"github.com/breakpilot/billing-service/internal/config"
|
||||
"github.com/breakpilot/billing-service/internal/database"
|
||||
"github.com/breakpilot/billing-service/internal/handlers"
|
||||
"github.com/breakpilot/billing-service/internal/middleware"
|
||||
"github.com/breakpilot/billing-service/internal/services"
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Load configuration
|
||||
cfg, err := config.Load()
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to load config: %v", err)
|
||||
}
|
||||
|
||||
// Initialize database
|
||||
db, err := database.Connect(cfg.DatabaseURL)
|
||||
if err != nil {
|
||||
log.Fatalf("Failed to connect to database: %v", err)
|
||||
}
|
||||
defer db.Close()
|
||||
|
||||
// Run migrations
|
||||
if err := database.Migrate(db); err != nil {
|
||||
log.Fatalf("Failed to run migrations: %v", err)
|
||||
}
|
||||
|
||||
// Setup Gin router
|
||||
if cfg.Environment == "production" {
|
||||
gin.SetMode(gin.ReleaseMode)
|
||||
}
|
||||
|
||||
router := gin.Default()
|
||||
|
||||
// Global middleware
|
||||
router.Use(middleware.CORS())
|
||||
router.Use(middleware.RequestLogger())
|
||||
router.Use(middleware.RateLimiter())
|
||||
|
||||
// Health check (no auth required)
|
||||
router.GET("/health", func(c *gin.Context) {
|
||||
c.JSON(200, gin.H{
|
||||
"status": "healthy",
|
||||
"service": "billing-service",
|
||||
"version": "1.0.0",
|
||||
})
|
||||
})
|
||||
|
||||
// Initialize services
|
||||
subscriptionService := services.NewSubscriptionService(db)
|
||||
|
||||
// Create Stripe service (mock or real depending on config)
|
||||
var stripeService *services.StripeService
|
||||
if cfg.IsMockMode() {
|
||||
log.Println("Starting in MOCK MODE - Stripe API calls will be simulated")
|
||||
stripeService = services.NewMockStripeService(
|
||||
cfg.BillingSuccessURL,
|
||||
cfg.BillingCancelURL,
|
||||
cfg.TrialPeriodDays,
|
||||
subscriptionService,
|
||||
)
|
||||
} else {
|
||||
stripeService = services.NewStripeService(
|
||||
cfg.StripeSecretKey,
|
||||
cfg.StripeWebhookSecret,
|
||||
cfg.BillingSuccessURL,
|
||||
cfg.BillingCancelURL,
|
||||
cfg.TrialPeriodDays,
|
||||
subscriptionService,
|
||||
)
|
||||
}
|
||||
|
||||
entitlementService := services.NewEntitlementService(db, subscriptionService)
|
||||
usageService := services.NewUsageService(db, entitlementService)
|
||||
|
||||
// Initialize handlers
|
||||
billingHandler := handlers.NewBillingHandler(
|
||||
db,
|
||||
subscriptionService,
|
||||
stripeService,
|
||||
entitlementService,
|
||||
usageService,
|
||||
)
|
||||
webhookHandler := handlers.NewWebhookHandler(
|
||||
db,
|
||||
cfg.StripeWebhookSecret,
|
||||
subscriptionService,
|
||||
entitlementService,
|
||||
)
|
||||
|
||||
// API v1 routes
|
||||
v1 := router.Group("/api/v1/billing")
|
||||
{
|
||||
// Stripe webhook (no auth - uses Stripe signature)
|
||||
v1.POST("/webhook", webhookHandler.HandleStripeWebhook)
|
||||
|
||||
// =============================================
|
||||
// User Endpoints (require JWT auth)
|
||||
// =============================================
|
||||
user := v1.Group("")
|
||||
user.Use(middleware.AuthMiddleware(cfg.JWTSecret))
|
||||
{
|
||||
// Subscription status and management
|
||||
user.GET("/status", billingHandler.GetBillingStatus)
|
||||
user.GET("/plans", billingHandler.GetPlans)
|
||||
user.POST("/trial/start", billingHandler.StartTrial)
|
||||
user.POST("/change-plan", billingHandler.ChangePlan)
|
||||
user.POST("/cancel", billingHandler.CancelSubscription)
|
||||
user.GET("/portal", billingHandler.GetCustomerPortal)
|
||||
}
|
||||
|
||||
// =============================================
|
||||
// Internal Endpoints (service-to-service)
|
||||
// =============================================
|
||||
internal := v1.Group("")
|
||||
internal.Use(middleware.InternalAPIKeyMiddleware(cfg.InternalAPIKey))
|
||||
{
|
||||
// Entitlements
|
||||
internal.GET("/entitlements/:userId", billingHandler.GetEntitlements)
|
||||
internal.GET("/entitlements/check/:userId/:feature", billingHandler.CheckEntitlement)
|
||||
|
||||
// Usage tracking
|
||||
internal.POST("/usage/track", billingHandler.TrackUsage)
|
||||
internal.GET("/usage/check/:userId/:type", billingHandler.CheckUsage)
|
||||
}
|
||||
}
|
||||
|
||||
// Start server
|
||||
port := cfg.Port
|
||||
if port == "" {
|
||||
port = "8083"
|
||||
}
|
||||
|
||||
log.Printf("Starting Billing Service on port %s", port)
|
||||
if err := router.Run(":" + port); err != nil {
|
||||
log.Fatalf("Failed to start server: %v", err)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user