Commit Graph
24 Commits
Author SHA1 Message Date
john-okeefe d61afbef50 test(services): rename test files for MediaScanner
- Rename ebook_scanner_library_type_test.go -> media_scanner_library_type_test.go
- Rename ebook_scanner_comic_test.go -> media_scanner_comic_test.go
- Rename ebook_scanner_hash_test.go -> media_scanner_hash_test.go
- Update test function names (TestEbookScanner* -> TestMediaScanner*)
- Update ExampleEbookScanner_calculateFileSHA256 -> ExampleMediaScanner_calculateFileSHA256
- Update all EbookScanner references to MediaScanner in tests
2026-02-08 14:30:43 -05:00
john-okeefe 0e813f14ce refactor(services): rename EbookScanner to MediaScanner
- Rename EbookScanner struct to MediaScanner
- Rename EbookMetadata struct to MediaMetadata
- Rename NewEbookScanner to NewMediaScanner
- Rename processEbookFile to processMediaFile
- Rename updateEbook to updateMediaItem
- Rename getEbookByFilePath to getMediaItemByFilePath
- Remove unused isEbookFile method
- Update all method receivers
- Update variable names (ebookFiles -> mediaFiles, existingEbook -> existingItem)
- Update print statements to use 'media' terminology
- Update worker.go to use NewMediaScanner
- File renamed: ebook_scanner.go -> media_scanner.go
2026-02-08 14:29:49 -05:00
john-okeefe eb8f83e1b9 feat: update ebook scanner to normalize metadata
Update extractEPUBMetadata:
- Normalize tags for display using NormalizeTags()
- Normalize contributors for display using NormalizeContributors()
- Preserves extracted metadata formatting while ensuring consistency

Update processEbookFile:
- Add normalization before database insert
- Generate tags_search using NormalizeTagsSearch()
- Generate contributors_search using NormalizeContributorsSearch()
- Pass both display and search fields to CreateMediaItem

Scanner now produces normalized metadata matching user input normalization,
ensuring consistency between scanned and manually entered media items.

Relates to Tags & Contributors Migration Phase 7
2026-02-08 11:05:29 -05:00
john-okeefe 516cec5a7f feat: migrate tags and contributors from TEXT to TEXT[] arrays
Convert tags and contributors columns from comma-separated strings to PostgreSQL
TEXT[] arrays for better data normalization and query performance.

Database Changes:
- schema.sql: Change tags/contributors from TEXT to TEXT[]
- schema.sql: Add GIN indexes for fast array searches
- queries.sql: Update search queries to use ANY() operator
- queries.sql: Update fuzzy search with unnest() for arrays

Generated Code (sqlc):
- models.go: Auto-generated with []string types for tags/contributors
- queries.sql.go: Auto-generated with proper array handling

Handler Changes:
- media.go: Update request structs to use []string for tags/contributors
- media.go: Remove pgtype.Text wrapping, use direct array assignment
- media.go: Add tag normalization in CreateMediaItemHandler
- collections.go: Update tags evaluation to join arrays for comparison
- collections.go: Add strings import for Join() function

Service Changes:
- ebook_scanner.go: Update EbookMetadata struct to use []string
- ebook_scanner.go: Remove string Join(), assign arrays directly
- collection_service.go: Update tags rule evaluation to join arrays
- collection_service.go: Add strings import

New Utilities:
- internal/utils/tags.go: Create NormalizeTags(), JoinTags(), SplitTags()
- Normalizes tags by trimming, lowercasing, removing duplicates/empties

API Documentation:
- bruno/media-items/Create Media Item.bru: Update examples to use arrays
- bruno/media-items/Update Media Item.bru: Update examples to use arrays
- Update docs: tags/contributors now array of string

Breaking Change:
- JSON format changes from "tags": "tag1,tag2" to "tags": ["tag1", "tag2"]
- Tests already use array format (no changes needed)

Benefits:
- GIN indexes enable faster array searches
- Normalization prevents data quality issues (case, duplicates)
- Array operations use PostgreSQL native operators (ANY, &&, unnest)
- Better separation of concerns (no string parsing in application)
2026-02-07 22:53:12 -05:00
john-okeefe 42b6fae297 chore(router): remove unused CollectionHandler from config
Remove the CollectionHandler field from router.Config struct and its
initialization in main.go. This field was never used - collections are
registered directly in handlers.SetupRoutes() where a CollectionHandler
is created locally.

Changes:
- Remove CollectionHandler field from internal/router/router.go Config
- Remove CollectionHandler: nil line from cmd/server/main.go

This cleans up dead code from the router refactoring. Collections
continue to work correctly as they are registered in SetupRoutes().

Related: Router refactoring completion
2026-02-07 17:59:06 -05:00
john-okeefe 9238fad8d5 test(scanner): add comprehensive comic metadata extraction tests
Test coverage for multi-format comic archive metadata extraction:

Format-specific tests:
- TestExtractZipMetadata - .cbz (ZIP) with ComicInfo.xml
- TestExtractZipMetadataWithoutComicInfo - Fallback behavior
- TestExtractTarMetadata - .cbt (TAR) archives
- TestExtractTarGzMetadata - .tar.gz (gzipped TAR)

Integration tests:
- TestExtractComicMetadata - Router function tests
- TestIsImageFile - Image detection validation

Helper functions:
- createTestCBZ, createTestCBT, createTestTarGz - Create test archives
- Uses image/png package for valid test images

Tests cover:
- Metadata extraction (title, series, issue, publisher, writer)
- Cover image extraction with format validation
- Fallback behavior when metadata missing
- Error handling for invalid/corrupted archives

All tests use t.TempDir() for automatic cleanup and follow
project testing patterns (table-driven tests, t.Run(), etc).
2026-02-07 17:07:50 -05:00
john-okeefe 1cc9863cb0 feat(scanner): implement library-type-aware scanning
Phase 2 of scanner enhancement plan

Changes:
- Add libraryTypes map[string][]string field to EbookScanner
- Initialize libraryTypes cache in NewEbookScanner
- Build library types cache in SetFolders by querying database
- Replace isEbookFile with isScannableFile for library-aware filtering
- Update ScanFolders and WatchChanges to use isScannableFile

This prevents cross-contamination between library types:
- Epub libraries only scan .epub files
- Comic libraries only scan .cbz/.cbr files
- Manga libraries only scan appropriate formats
- Each library type has configurable allowed extensions

Files are now filtered based on their library's allowed extensions,
ensuring only supported formats are scanned for each library type.
2026-02-07 17:07:32 -05:00
john-okeefe 4bdd08602c test: rename test files to better reflect their purpose
- Rename phase1_integration_test.go to universal_progress_integration_test.go
  (tests universal reading progress feature)
- Rename ebook_scanner_phase2_test.go to ebook_scanner_hash_test.go
  (tests hash calculation and file identification utilities)

These renames make the test suite more maintainable and self-documenting.
2026-02-07 17:06:45 -05:00
john-okeefe 5b9f21a592 Final cleanup: Update remaining comments and variable names
Changes:
- Update comments: "Bookmann UUID" → "Bookhoard UUID"
- Rename sidecar struct field: Bookmann → Bookhoard
- Update type names: SidecarBookmannConfig → SidecarBookhoardConfig
- Fix test database name in queue_test.go
- Fix uppercase env var examples in KOBO_SETUP.md

Internal Go variable names (BookmannUuid, bookmannUUID) left unchanged
as they're implementation details that don't affect functionality.

Part of project rename to Bookhoard.
2026-02-01 16:24:58 -05:00
john-okeefe 00a083b60b Rename backend code references: Bookmann → Bookhoard
Backend changes:
- Update import paths: bookmann/internal → bookhoard/internal
- Rename struct fields: BookmannUUID → BookhoardUUID
- Update handler function names: mapContentIdToBookmannUUID → mapContentIdToBookhoardUUID
- Update HTTP response headers: X-Bookmann-* → X-Bookhoard-*
- Update service and middleware references
- Update main.go imports and references

This is part 2 of the project rename to Bookhoard.
2026-02-01 16:11:54 -05:00
john-okeefe 351c68b0b8 test: add comprehensive test coverage for API endpoints and services 2026-02-01 13:21:34 -05:00
john-okeefe ec5a961f6c feat(conversion): add EPUB to KEPUB conversion service with kepubify
- Install kepubify binary in Dockerfile for on-the-fly conversion
- Add conversion service with caching layer (24hr TTL)
- Support KEPUB downloads through OPDS endpoint
- Cache converted files to reduce processing overhead
- Add environment configuration for cache directory and tool path
2026-02-01 12:15:28 -05:00
john-okeefe 964a4583ab feat(services): Add book matching and collection services
- Add book matching service for intelligent book deduplication
- Add collection service for collection management
- Add test files for book matching and collections
2026-01-31 22:32:28 -05:00
john-okeefe d28002e4cb feat(sync): Add Kobo/Koreader sync and conflict handling
- Add Kobo markup/sync endpoints for bookshelves
- Add Koreader progress sync with SHA-256 support
- Add sync conflict detection and resolution
- Update ebook scanner for better file matching
2026-01-31 22:32:09 -05:00
john-okeefe 2044c1a631 fix: resolve GetLibraryByFolder undefined error
- ebook_scanner.go:293 now compiles successfully
- GetLibraryByFolder method available after database code regeneration
- Scanner service can properly find libraries by folder path

Fixes primary compilation error blocking build
2026-01-30 13:51:52 -05:00
john-okeefe 8f739af285 fix: correct UUID format string issues in logging and tests
- Fix scheduler.go log.Printf calls to convert pgtype.UUID to string before formatting
- Fix ebook.go fmt.Printf calls to convert pgtype.UUID to string before formatting
- Add missing Enabled field to rate limiter config in security test
- Prevents format string errors when logging library IDs

This resolves compilation errors where pgtype.UUID was being formatted
with %s which expects a string, not a UUID struct.
2026-01-29 15:51:05 -05:00
john-okeefe 305deac4fd fix: correct type assertions and ISBN type mismatches
- Fix type assertion panics in library.go (lines 58, 109, 237)
  Changed from *database.Users to database.Users to match JWT middleware
- Fix ISBN type mismatch in ebook.go (lines 249, 308)
  Changed from pgtype.Text to string to match database schema
- Fix ISBN type mismatch in ebook_scanner.go (line 421)
  Changed from pgtype.Text to string to match database schema

These changes fix 500 errors in library creation and ebook operations.
2026-01-29 13:32:56 -05:00
john-okeefe 07717f4f77 feat(scanner): add background worker and scheduler for async scanning
- Add Worker service with configurable worker pool for async job processing
- Implement job queue with status tracking (pending, running, completed, failed, cancelled)
- Add Scheduler service for auto-scanning based on user scan settings
- Check scan settings every 5 minutes and schedule background scan jobs
- Support multiple libraries with individual scan frequencies (15-1440 minutes)
2026-01-29 09:49:48 -05:00
john-okeefe dbc3590cad feat: implement library system database schema
- Add library_types table with ebooks, comics, manga types
- Add libraries table for multiple library support
- Add library_folders table for multi-folder libraries
- Add library_visibility table for user access control
- Add media_items table replacing ebooks for broader media support
- Create backward compatibility views for existing API
- Implement library service with type validation and file extension handling
- Support modular extension for future media types

Manga type includes cbz/cbr archives as requested
2026-01-28 11:00:06 -05:00
john-okeefe 734bad4697 feat: Add admin-only protection to ebook operations
- Update ebook handlers to require admin role for CRUD operations
- Modify folder operations to be admin-only
- Update ebook scanner to associate books with admin who added them
- Add admin ID tracking to CreateEbook operations
- Restrict scanner operations to admin users only
2026-01-26 16:55:42 -05:00
john-okeefe 0550dd3d5a Fix ebook scanner error handling for database queries
- Remove string-based error checking for no rows
- Use proper pgx.ErrNoRows comparison only
- Improve error handling consistency in processEbookFile function
2026-01-26 11:32:45 -05:00
john-okeefe 08e80ae84b refactor: reorganize project structure and update configurations
- Move migrations/ to database/schema/ for clarity on database schema definitions
- Move sqlc.yaml to internal/database/ to group with database code
- Move static/ to cmd/server/static/ to co-locate with server
- Update all configuration files and documentation
- Follow Go project conventions for better organization
2026-01-24 23:40:31 -05:00
john-okeefe c3769fe7f1 refactor: rename project back from shelf to bookmann
- Change Go module name back from 'shelf' to 'bookmann'
- Update all import paths back to 'bookmann' module
- Update README.md project name back to 'Bookmann'
- Update docker-compose.yml container names back to 'bookmann' and 'bookmann_db'
- Regenerate database code with restored module imports
2026-01-23 09:08:59 -05:00
john-okeefe 4318f8624b refactor: restructure project from bookmann to shelf
- Rename project from 'bookmann' to 'shelf'
- Move all backend/ contents to root level (flatten structure)
- Update Go module name from 'bookmann' to 'shelf'
- Update all import paths to use new 'shelf' module
- Update Dockerfile to work without backend/ subdirectory
- Update docker-compose.yml to use new structure and rename containers
- Update .gitignore for new file paths
- Update README.md with new project name and structure
- Regenerate database code with new module imports
2026-01-23 09:08:04 -05:00