Files
bookhoard/internal/router/router.go
T
john-okeefe 6784c25b2e refactor: complete router package migration
Major refactoring milestone - migrate all routes from main.go to internal/router/ package:

## Changes

### cmd/server/main.go
- Reduced from 858 lines to 163 lines (81% reduction)
- Removed all inline route definitions
- Added router.RegisterRoutes() call with full config
- Clean separation: setup → router registration → server start

### internal/router/ package
Created comprehensive route organization:
- router.go: Main router setup and JWT middleware
- auth.go: Authentication routes (login, register, profile, etc.)
- library.go: Library management routes
- device.go: Device registration and management
- sync.go: KOReader/Kobo sync + book matching + WebSocket
- media.go: Media download, shelves, bulk operations
- conflicts.go: Conflict resolution routes
- analytics.go: Analytics API routes
- queue.go: Sync queue management
- opds.go: OPDS feed routes
- frontend.go: SSR pages (/login, /admin, /dashboard, etc.)
- docs.go: Documentation routes
- helpers.go: Template rendering helpers

## Verification
 All 26 guideline checks pass
 Code compiles successfully
 Zero API behavior changes (100% compatible)
 Follows Go standard project layout

## Breaking Changes
None - API compatibility fully maintained
2026-02-06 11:49:28 -05:00

89 lines
2.6 KiB
Go

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