package router import ( "bookhoard/internal/config" "bookhoard/internal/database" "bookhoard/internal/handlers" "bookhoard/internal/middleware" ratelimit "bookhoard/internal/middleware" "bookhoard/internal/sync" "log" "time" "github.com/go-playground/validator/v10" "github.com/labstack/echo/v4" echomiddleware "github.com/labstack/echo/v4/middleware" ) // CustomValidator wraps the go-playground validator type CustomValidator struct { validator *validator.Validate } func (cv *CustomValidator) Validate(i interface{}) error { return cv.validator.Struct(i) } // Config holds all dependencies needed for route registration type Config struct { Echo *echo.Echo Queries *database.Queries Cfg *config.Config DBPool interface{} // pgxpool.Pool interface AuthHandler *handlers.AuthHandler LibraryHandler *handlers.LibraryHandler DeviceHandler *handlers.DeviceHandler KOReaderHandler *handlers.KOReaderHandler WSHandler *handlers.WSHandler ConflictHandler *handlers.ConflictHandler AnalyticsHandler *handlers.AnalyticsHandler QueueHandler *handlers.QueueHandler CollectionHandler *handlers.CollectionHandler OPDSHandler *handlers.OPDSHandler ConnManager *sync.ConnectionManager QueueProcessor *sync.SyncQueueProcessor DeviceAuthMiddleware *middleware.DeviceAuthMiddleware LoginTracker *ratelimit.LoginAttemptTracker } // RegisterRoutes registers all application routes func RegisterRoutes(cfg *Config) { e := cfg.Echo // Set up validator v := validator.New() if err := ratelimit.RegisterPasswordValidation(v); err != nil { log.Fatal("Failed to register password validator:", err) } e.Validator = &CustomValidator{validator: v} // Global middleware e.Use(echomiddleware.Logger()) e.Use(echomiddleware.Recover()) e.Use(echomiddleware.CORS()) e.Use(ratelimit.RequestTracingMiddleware(cfg.Cfg)) // Rate limiter rateLimiterConfig := ratelimit.RateLimiterConfig{ Enabled: cfg.Cfg.RateLimitEnabled, RequestsPerMinute: cfg.Cfg.RequestsPerMinute, CleanupInterval: 5 * time.Minute, } rateLimiter := ratelimit.NewRateLimiter(rateLimiterConfig) rateLimitMiddleware := ratelimit.RateLimiterMiddleware(rateLimiter) // Register route groups registerAuthRoutes(cfg, rateLimitMiddleware) registerLibraryRoutes(cfg) registerDeviceRoutes(cfg) registerSyncRoutes(cfg) registerMediaRoutes(cfg) registerConflictRoutes(cfg) registerAnalyticsRoutes(cfg) registerQueueRoutes(cfg) registerOPDSRoutes(cfg) registerWebSocketRoutes(cfg) registerFrontendRoutes(cfg) registerDocumentationRoutes(cfg) } // Stub functions - will be implemented incrementally func registerSyncRoutes(cfg *Config) { // TODO: Implement in sync.go } func registerMediaRoutes(cfg *Config) { // TODO: Implement in media.go } func registerConflictRoutes(cfg *Config) { // TODO: Implement in conflicts.go } func registerAnalyticsRoutes(cfg *Config) { // TODO: Implement in analytics.go } func registerQueueRoutes(cfg *Config) { // TODO: Implement in queue.go } func registerOPDSRoutes(cfg *Config) { // TODO: Implement in opds.go } func registerWebSocketRoutes(cfg *Config) { // TODO: Implement in websocket.go }