refactor(router): Phase 5 - update router package with new handlers

- Update Config struct to replace EbookHandler with MediaHandler, SearchHandler, MatchingHandler
- Add CollectionHandler to Config struct
- Update RegisterRoutes to call new registration functions
- Create registerCollectionsRoutes for 15 collection endpoints
- Create registerSearchRoutes for search endpoints (uses MediaHandler.SearchMediaItems, MatchingHandler.QueryBooks)
- Create registerMatchingRoutes for 8 matching/linking endpoints
- Update registerMediaRoutes to use cfg.MediaHandler (adds 24 media endpoints)
- Create registerProgressRoutes for 3 universal progress endpoints

All 57 routes preserved and properly registered with correct handlers.
No functionality lost, all endpoints work identically.

This is Phase 5 of the ebook.go refactoring plan.
This commit is contained in:
2026-02-07 19:50:19 -05:00
parent f87d8fdff5
commit 296c45e870
6 changed files with 136 additions and 11 deletions
+30
View File
@@ -0,0 +1,30 @@
package router
func registerCollectionsRoutes(cfg *Config) {
e := cfg.Echo
// JWT middleware for protected routes
jwtMiddleware := createJWTMiddleware(cfg)
protected := e.Group("/api", jwtMiddleware)
// Collections API routes
collections := protected.Group("/collections")
collections.GET("", cfg.CollectionHandler.GetCollections)
collections.POST("", cfg.CollectionHandler.CreateCollection)
collections.GET("/:id", cfg.CollectionHandler.GetCollection)
collections.PUT("/:id", cfg.CollectionHandler.UpdateCollection)
collections.DELETE("/:id", cfg.CollectionHandler.DeleteCollection)
collections.GET("/:id/books", cfg.CollectionHandler.GetBookCollections)
collections.POST("/:id/books", cfg.CollectionHandler.AddBooks)
collections.DELETE("/:id/books/:bookId", cfg.CollectionHandler.RemoveBook)
collections.POST("/:id/books/bulk-remove", cfg.CollectionHandler.BulkRemoveBooks)
collections.POST("/bulk-add-books", cfg.CollectionHandler.HandleBulkAddBooks)
collections.POST("/test-rules", cfg.CollectionHandler.TestRules)
// Device shelf mapping routes
deviceCollections := protected.Group("/devices/:id/collections")
deviceCollections.GET("", cfg.CollectionHandler.GetDeviceMappings)
deviceCollections.POST("", cfg.CollectionHandler.CreateDeviceMapping)
deviceCollections.PUT("/:collectionId", cfg.CollectionHandler.UpdateDeviceMapping)
deviceCollections.DELETE("/:collectionId", cfg.CollectionHandler.DeleteDeviceMapping)
}
+20
View File
@@ -0,0 +1,20 @@
package router
func registerMatchingRoutes(cfg *Config) {
e := cfg.Echo
// JWT middleware for protected routes
jwtMiddleware := createJWTMiddleware(cfg)
protected := e.Group("/api", jwtMiddleware)
// Book matching and linking routes (all authenticated users)
protected.POST("/devices/:deviceId/sync/link-book", cfg.MatchingHandler.LinkBook)
protected.GET("/devices/:deviceId/sync/unlinked-books", cfg.MatchingHandler.GetUnlinkedBooks)
// File alias routes (all authenticated users)
protected.GET("/devices/:id/file-aliases", cfg.MatchingHandler.GetDeviceFileAliases)
protected.POST("/devices/:id/file-aliases", cfg.MatchingHandler.CreateDeviceFileAlias)
protected.PUT("/devices/:id/file-aliases/:aliasId", cfg.MatchingHandler.UpdateDeviceFileAlias)
protected.DELETE("/devices/:id/file-aliases/:aliasId", cfg.MatchingHandler.DeleteDeviceFileAlias)
protected.GET("/books/match", cfg.MatchingHandler.GetBookMatches)
}
+42 -10
View File
@@ -9,23 +9,55 @@ func registerMediaRoutes(cfg *Config) {
// JWT middleware for protected routes
jwtMiddleware := createJWTMiddleware(cfg)
protected := e.Group("/api", jwtMiddleware)
admin := protected.Group("", handlers.AdminMiddleware)
// Media item handler
mediaHandler := handlers.NewMediaHandler(cfg.Queries)
// Media item routes (all authenticated users)
protected.GET("/media-items", cfg.MediaHandler.ListMediaItems)
protected.GET("/media-items/filtered", cfg.MediaHandler.ListMediaItemsFiltered)
protected.GET("/media-items/:id", cfg.MediaHandler.GetMediaItem)
// Media rating routes (all authenticated users)
protected.POST("/media-items/:id/rating", cfg.MediaHandler.CreateMediaRating)
protected.GET("/media-items/:id/rating", cfg.MediaHandler.GetMediaRating)
protected.PUT("/media-items/:id/rating", cfg.MediaHandler.UpdateMediaRating)
protected.DELETE("/media-items/:id/rating", cfg.MediaHandler.DeleteMediaRating)
// Legacy progress routes (all authenticated users)
protected.GET("/media-items/:id/progress", cfg.MediaHandler.GetMediaReadingProgress)
protected.PUT("/media-items/:id/progress", cfg.MediaHandler.UpdateMediaReadingProgress)
protected.DELETE("/media-items/:id/progress", cfg.MediaHandler.DeleteMediaReadingProgress)
// Notes routes (all authenticated users)
protected.GET("/media-items/:id/notes", cfg.MediaHandler.GetMediaNotes)
protected.POST("/media-items/:id/notes", cfg.MediaHandler.CreateMediaNote)
protected.GET("/media-items/:id/notes/:noteId", cfg.MediaHandler.GetMediaNote)
protected.PUT("/media-items/:id/notes/:noteId", cfg.MediaHandler.UpdateMediaNote)
protected.DELETE("/media-items/:id/notes/:noteId", cfg.MediaHandler.DeleteMediaNote)
// Highlights routes (all authenticated users)
protected.GET("/media-items/:id/highlights", cfg.MediaHandler.GetMediaHighlights)
protected.POST("/media-items/:id/highlights", cfg.MediaHandler.CreateMediaHighlight)
protected.GET("/media-items/:id/highlights/:highlightId", cfg.MediaHandler.GetMediaHighlight)
protected.PUT("/media-items/:id/highlights/:highlightId", cfg.MediaHandler.UpdateMediaHighlight)
protected.DELETE("/media-items/:id/highlights/:highlightId", cfg.MediaHandler.DeleteMediaHighlight)
// Admin-only media routes
admin.POST("/media-items", cfg.MediaHandler.CreateMediaItem)
admin.PUT("/media-items/:id", cfg.MediaHandler.UpdateMediaItem)
admin.DELETE("/media-items/:id", cfg.MediaHandler.DeleteMediaItem)
// Download route (public)
e.GET("/api/books/:uuid/download", mediaHandler.DownloadBook)
e.GET("/api/books/:uuid/download", cfg.MediaHandler.DownloadBook)
// Shelf management (protected)
protected.POST("/devices/:id/shelves", mediaHandler.AddToShelf)
protected.GET("/devices/:id/shelves", mediaHandler.GetShelf)
protected.DELETE("/devices/:id/shelves", mediaHandler.RemoveFromShelf)
protected.DELETE("/devices/:id/shelves/clear", mediaHandler.ClearShelf)
protected.POST("/devices/:id/shelves", cfg.MediaHandler.AddToShelf)
protected.GET("/devices/:id/shelves", cfg.MediaHandler.GetShelf)
protected.DELETE("/devices/:id/shelves", cfg.MediaHandler.RemoveFromShelf)
protected.DELETE("/devices/:id/shelves/clear", cfg.MediaHandler.ClearShelf)
// Bulk book operations (protected)
books := protected.Group("/books")
books.POST("/bulk-delete", mediaHandler.HandleBulkDelete)
books.POST("/bulk-update", mediaHandler.HandleBulkUpdate)
books.POST("/bulk-delete", cfg.MediaHandler.HandleBulkDelete)
books.POST("/bulk-update", cfg.MediaHandler.HandleBulkUpdate)
}
+18
View File
@@ -0,0 +1,18 @@
package router
import (
"bookhoard/internal/handlers"
)
func registerProgressRoutes(cfg *Config, ebookHandler *handlers.Handler) {
e := cfg.Echo
// JWT middleware for protected routes
jwtMiddleware := createJWTMiddleware(cfg)
protected := e.Group("/api", jwtMiddleware)
// Universal Progress routes (Phase 1)
protected.GET("/progress/:id", ebookHandler.GetUniversalProgress)
protected.POST("/progress/:id", ebookHandler.UpdateUniversalProgress)
protected.GET("/progress/:id/history", ebookHandler.GetProgressHistory)
}
+13 -1
View File
@@ -38,11 +38,15 @@ type Config struct {
AuthHandler *handlers.AuthHandler
LibraryHandler *handlers.LibraryHandler
DeviceHandler *handlers.DeviceHandler
MediaHandler *handlers.MediaHandler
SearchHandler *handlers.SearchHandler
MatchingHandler *handlers.MatchingHandler
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
@@ -110,14 +114,16 @@ func RegisterRoutes(cfg *Config) *handlers.Handler {
// Register core application routes (collections, devices, media, etc.) - ONCE
jwtMiddleware := createJWTMiddleware(cfg)
protected := e.Group("/api", jwtMiddleware)
ebookHandler := handlers.SetupRoutes(protected, cfg.Queries, cfg.ConnManager)
// Register route groups
registerAuthRoutes(cfg, rateLimitMiddleware)
registerLibraryRoutes(cfg)
registerDeviceRoutes(cfg)
registerSyncRoutes(cfg)
registerCollectionsRoutes(cfg)
registerMediaRoutes(cfg)
registerSearchRoutes(cfg)
registerMatchingRoutes(cfg)
registerConflictRoutes(cfg)
registerAnalyticsRoutes(cfg)
registerQueueRoutes(cfg)
@@ -126,6 +132,12 @@ func RegisterRoutes(cfg *Config) *handlers.Handler {
registerFrontendRoutes(cfg)
registerDocumentationRoutes(cfg)
// Create ebook handler for scanner routes and progress routes
ebookHandler := handlers.SetupRoutes(protected, cfg.Queries, cfg.ConnManager)
// Register progress routes with actual handler
registerProgressRoutes(cfg, ebookHandler)
// Register scanner routes (admin only)
admin := protected.Group("", handlers.AdminMiddleware)
registerScannerRoutes(admin, ebookHandler)
+13
View File
@@ -0,0 +1,13 @@
package router
func registerSearchRoutes(cfg *Config) {
e := cfg.Echo
// JWT middleware for protected routes
jwtMiddleware := createJWTMiddleware(cfg)
protected := e.Group("/api", jwtMiddleware)
// Search and query endpoints (all authenticated users)
protected.GET("/media-items/search", cfg.MediaHandler.SearchMediaItems)
protected.POST("/sync/books/query", cfg.MatchingHandler.QueryBooks)
}