feat(api): implement saved filters backend service and handlers
Add complete backend implementation for saved filters CRUD operations with proper service layer architecture and RESTful API endpoints. Service Layer (internal/services/filters.go): - NewFiltersService() constructor following project patterns - GetSavedFilters(): Retrieve all filters for user + resource type - CreateSavedFilter(): Create filter with duplicate name validation - UpdateSavedFilter(): Update filter with ownership verification - DeleteSavedFilter(): Delete filter with user scoping Business Logic: - Filter name uniqueness enforced per user + resource type - User ownership validation on all operations (JWT user_id) - JSONB marshaling/unmarshaling for flexible filter storage - Proper error wrapping with context messages Handler Layer (internal/handlers/filters.go): - NewFiltersHandler() constructor (receives db.Queries) - GetSavedFilters: GET /api/saved-filters?resource_type=X - CreateSavedFilter: POST /api/saved-filters - UpdateSavedFilter: PUT /api/saved-filters/:id - DeleteSavedFilter: DELETE /api/saved-filters/:id Content Negotiation: - Supports both JSON (API clients) and HTML (HTMX) responses - wantsHTML() helper checks Accept header - HX-Redirect header for HTMX form submissions - Proper status codes (200, 201, 204, 400, 401, 404, 409) Router Configuration: - registerFiltersRoutes() function in internal/router/filters.go - JWT middleware protection on all endpoints - RESTful route structure: /api/saved-filters - Registered in main router.go RegisterRoutes() function - Added FiltersHandler to router.Config struct Test Infrastructure: - Added FiltersHandler to test server setup (test_helpers_test.go) - FiltersHandler initialized in setupTestServer() function - Router.Config includes FiltersHandler for integration tests Code Quality: - Follows PROJECT_GUIDELINES.md service layer patterns - Uses database models (not custom domain models) - JSONB returned as []byte (matches collections pattern) - All errors wrapped with context using fmt.Errorf - Handlers create services internally (not dependency injection) Part of: Saved Filters Implementation (Phase 2: Backend) Related: #saved-filters-feature
This commit is contained in:
@@ -466,6 +466,7 @@ func setupTestServer(t *testing.T) *TestServerSetup {
|
||||
services.WorkerInstance = worker
|
||||
jobsHandler := handlers.NewJobsHandler(queries, worker)
|
||||
collectionHandler := handlers.NewCollectionHandler(queries, libraryService, connManager)
|
||||
filtersHandler := handlers.NewFiltersHandler(queries)
|
||||
dashboardService := services.NewDashboardService(queries)
|
||||
dashboardHandler := handlers.NewDashboardHandler(queries)
|
||||
mediaHandler := handlers.NewMediaHandler(queries, libraryService, worker)
|
||||
@@ -514,6 +515,7 @@ func setupTestServer(t *testing.T) *TestServerSetup {
|
||||
QueueHandler: queueHandler,
|
||||
SystemSettingsHandler: systemSettingsHandler,
|
||||
CollectionHandler: collectionHandler,
|
||||
FiltersHandler: filtersHandler,
|
||||
DashboardHandler: dashboardHandler,
|
||||
DashboardService: dashboardService,
|
||||
OPDSHandler: opdsHandler,
|
||||
|
||||
Reference in New Issue
Block a user