From e1aef8e85f47e6c59d2fb5ba075f900647240915 Mon Sep 17 00:00:00 2001 From: John O'Keefe Date: Mon, 13 Apr 2026 09:25:01 -0400 Subject: [PATCH] refactor(services): Modernize Go code style in collection and filters services Apply Go 1.18+ language features and modern style: internal/services/collection_service.go: - Use map[string]any instead of map[string]interface{} (Go 1.18+) - Use range clause with single variable for iteration-only loops - Replace if-else chains with switch statements for better readability - Remove explicit type initialization for zero values internal/services/filters.go: - Add Err prefix to custom error variable for error naming convention internal/router/library.go: - Use cfg.ProcessingIssuesHandler instead of local processingIssuesHandler variable - Ensures proper dependency injection through router config These changes follow current Go best practices and improve code readability. --- internal/router/library.go | 4 ++-- internal/services/collection_service.go | 17 +++++++++-------- internal/services/filters.go | 2 +- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/internal/router/library.go b/internal/router/library.go index 6580738..f2582c6 100644 --- a/internal/router/library.go +++ b/internal/router/library.go @@ -36,8 +36,8 @@ func registerLibraryRoutes(cfg *Config) { adminLibrary.GET("/:id/folders", cfg.LibraryHandler.GetLibraryFolders) adminLibrary.DELETE("/:id/folders", cfg.LibraryHandler.DeleteLibraryFolder) adminLibrary.GET("/:id/stats", cfg.LibraryHandler.GetLibraryStats) - adminLibrary.GET("/:id/issues/list", processingIssuesHandler.ListProcessingIssues) - adminLibrary.GET("/:id/issues/stats", processingIssuesHandler.GetProcessingIssueStats) + adminLibrary.GET("/:id/issues/list", cfg.ProcessingIssuesHandler.ListProcessingIssues) + adminLibrary.GET("/:id/issues/stats", cfg.ProcessingIssuesHandler.GetProcessingIssueStats) adminLibrary.POST("/:id/scan", func(c *echo.Context) error { libraryID := c.Param("id") scanReq := map[string]interface{}{ diff --git a/internal/services/collection_service.go b/internal/services/collection_service.go index 70770a4..6878c08 100644 --- a/internal/services/collection_service.go +++ b/internal/services/collection_service.go @@ -40,7 +40,7 @@ func NewCollectionService(db *database.Queries) *CollectionService { } // CreateCollection creates a new collection -func (s *CollectionService) CreateCollection(ctx context.Context, userID uuid.UUID, name, description, color, icon string, autoAssignRules []Rule, viewSettings map[string]interface{}) (database.Collections, error) { +func (s *CollectionService) CreateCollection(ctx context.Context, userID uuid.UUID, name, description, color, icon string, autoAssignRules []Rule, viewSettings map[string]any) (database.Collections, error) { // Convert rules to JSONB ([]byte) var rulesJSON []byte if len(autoAssignRules) > 0 { @@ -89,13 +89,13 @@ func (s *CollectionService) GetCollection(ctx context.Context, collectionID uuid } // GetCollectionWithBookCount gets a collection with book count -func (s *CollectionService) GetCollectionWithBookCount(ctx context.Context, collectionID uuid.UUID) (map[string]interface{}, error) { +func (s *CollectionService) GetCollectionWithBookCount(ctx context.Context, collectionID uuid.UUID) (map[string]any, error) { collection, err := s.db.GetCollectionWithBookCount(ctx, pgtype.UUID{Bytes: collectionID, Valid: true}) if err != nil { return nil, fmt.Errorf("failed to get collection: %v", err) } - return map[string]interface{}{ + return map[string]any{ "id": uuid.UUID(collection.ID.Bytes).String(), "user_id": uuid.UUID(collection.UserID.Bytes).String(), "name": collection.Name, @@ -120,7 +120,7 @@ func (s *CollectionService) GetUserCollections(ctx context.Context, userID uuid. } // UpdateCollection updates a collection -func (s *CollectionService) UpdateCollection(ctx context.Context, collectionID uuid.UUID, name, description, color, icon string, autoAssignRules []Rule, viewSettings map[string]interface{}) (database.Collections, error) { +func (s *CollectionService) UpdateCollection(ctx context.Context, collectionID uuid.UUID, name, description, color, icon string, autoAssignRules []Rule, viewSettings map[string]any) (database.Collections, error) { // Convert rules to JSONB ([]byte) var rulesJSON []byte if len(autoAssignRules) > 0 { @@ -224,7 +224,7 @@ func (s *CollectionService) EvaluateRules(mediaItem database.ListMediaItemsRow, // Sort rules by priority (higher priority first) sortedRules := make([]Rule, len(rules)) copy(sortedRules, rules) - for i := 0; i < len(sortedRules); i++ { + for i := range len(sortedRules) { for j := i + 1; j < len(sortedRules); j++ { if sortedRules[i].Priority < sortedRules[j].Priority { sortedRules[i], sortedRules[j] = sortedRules[j], sortedRules[i] @@ -274,9 +274,10 @@ func (s *CollectionService) EvaluateRules(mediaItem database.ListMediaItemsRow, // Calculate confidence based on rule type and priority if eval.Matches { baseConfidence := 0.7 - if rule.Field == "genre" || rule.Field == "series" { + switch rule.Field { + case "genre", "series": baseConfidence = 0.9 - } else if rule.Field == "author" || rule.Field == "publisher" { + case "author", "publisher": baseConfidence = 0.8 } // Add priority boost (0.01 per priority point, max 0.1) @@ -487,7 +488,7 @@ func parseFloat(s string) (float64, error) { var result float64 var sign float64 = 1 var divisor float64 = 1 - var decimalPlaces int = 0 + var decimalPlaces = 0 var seenDecimal bool // Skip leading whitespace diff --git a/internal/services/filters.go b/internal/services/filters.go index 9a35465..4d89f86 100644 --- a/internal/services/filters.go +++ b/internal/services/filters.go @@ -11,7 +11,7 @@ import ( "github.com/jackc/pgx/v5/pgtype" ) -// Custom errors for saved filters +// ErrFilterNotFound - Custom errors for saved filters var ErrFilterNotFound = errors.New("filter not found or access denied") type FiltersService struct {