Problem: - Phase 1 (Core Fixes Using Job Queue) conflicted with Phase 0.5 - Phase 1 added JobTypeSetFolders and processSetFoldersJob - Phase 0.5 makes folder configuration automatic via database - Phase 1's SetFolders() job queue approach is obsolete Changes Made: 1. Removed Phase 1 entirely (636 lines deleted) - Removed JobTypeSetFolders job type - Removed processSetFoldersJob handler - Removed test isolation fixes (to be added elsewhere if needed) - Removed default value fixes (to be added elsewhere if needed) 2. Renumbered all subsequent phases: - Phase 2 (Job Queue Expansion) → Phase 1 - Phase 3 (WebSocket Scan Progress) → Phase 2 - Phase 4 (Caching and Monitoring) → Phase 3 - Phase 5 (Job Queue Enhancements) → Phase 4 3. Updated all step numbers: - All steps renumbered to match new phase numbers - Step 2.x → Step 1.x, Step 3.x → Step 2.x, etc. 4. Updated job type counts: - Changed "8 async job types" to "7 async job types" - Removed setfolders from commit messages 5. Updated Summary section: - Removed Phase 1 time estimate - Added Phase 0.5 time estimate - Removed folder config from key design decisions - Updated Files Modified section 6. Updated references throughout: - All phase references updated to new numbers - All step references updated to match phase numbers Rationale: Phase 0.5's directory-based watching approach reads folder paths directly from the library_folders table via GetLibraryFolders(), making manual SetFolders() configuration unnecessary. The watcher automatically discovers subdirectories, so job queue-based folder configuration is no longer needed. Phase 0.5 structure: - Phase 0.5: Fix fsnotify Reliability (2-3 hours) - Directory-based watching replaces file-based event queue - File stability checks prevent processing incomplete files - Smart event merging consolidates parent/child/sibling events - 10-second batch processing for efficient bulk operations - Phase 1: Job Queue Expansion (6-8 hours) - 7 async job types (import, convert, thumbnails, reindex, backup, analytics, sync) - Job management API for CRUD operations - Real-time job status tracking - Phase 2: WebSocket Scan Progress (2-3 hours) - Real-time progress updates via WebSocket - Eliminates polling for job status - Phase 3: Caching and Monitoring (2 hours) - Settings cache reduces database load - Enhanced /health endpoint - Phase 4: Job Queue Enhancements (4-6 hours) - Job persistence across restarts - Job history and audit trail - Priority queue support Total document size: 2,974 lines (reduced from 3,620 lines) All dependencies on removed Phase 1 functionality have been eliminated. Job queue for other tasks (import, convert, etc.) and WebSocket integration remain unchanged and fully compatible.
📚 Bookhoard
A modern self-hosted media library system built with Go, PostgreSQL, HTMX, and Tailwind CSS featuring universal cross-device sync, beautiful dark themes, and comprehensive media management.
✨ Why Bookhoard?
🔄 Universal Sync: Your reading progress, highlights, and notes sync automatically across all your devices - KOReader, Kobo, web, and mobile.
📱 Multi-Library: Organize your ebooks, comics, and manga with per-library folders and smart collections.
🎨 Beautiful UI: 11 gorgeous dark themes with responsive design that works on any device.
🔒 Secure: JWT authentication, bcrypt password hashing, rate limiting, and no passwords on devices.
🚀 Quick Start
Prerequisites
- Podman (recommended) or Docker
- 5 minutes of your time
Installation
# 1. Clone the repository
git clone https://github.com/yourusername/bookhoard.git
cd bookhoard
# 2. Set up environment
cp .env.example .env
# Generate secure passwords (no special characters):
# JWT_SECRET: openssl rand -hex 32
# DBPASS: openssl rand -hex 16
# Edit .env with your generated values
# 3. Start the server
podman-compose up --build -d # or: docker-compose up --build -d
# 4. Open your browser
open http://localhost:8765
The first user to register automatically becomes an admin.
📖 Key Features
Universal Cross-Platform Sync
- Real-Time Progress: Turn a page on your Kindle, see it on your phone
- Format-Aware: EPUB CFI, page numbers, percentages - all handled correctly
- Offline Queue: Changes sync when you reconnect, priority-processed
- Conflict Resolution: Smart handling when same book read on multiple devices
- Book Matching: Automatic matching using SHA-256, ISBN, UUID
- OPDS Catalog: Wireless book delivery to e-readers over Wi-Fi
- Format Conversion: On-the-fly EPUB→KEPUB for Kobo devices
Media Management
- Smart Search: Partial matching with fuzzy search fallback for typos
- Advanced Filtering: Filter by author, series, genre, language, year, cover images
- Dynamic Sorting: By title, author, date added, published date, page count, series
- Rich Metadata: Title, author, series, publisher, ISBN, language, edition, tags
- 5-Star Ratings: Half-star precision (1-10 scale)
- Notes & Highlights: Color-coded annotations with linked notes
- Usage Analytics: Reading statistics, device usage, popular books
Smart Collections
- Auto-Assign Rules: Automatically add books based on genre, author, series, tags, language, publisher, year
- Device Shelf Mappings: Sync collections to Kobo shelves and KOReader categories
- Test Before Creating: Preview which books match your rules
Library Organization
- Multi-Library Support: Ebooks, Comics, and Manga with type-specific file formats
- Multiple Folders: Add multiple scanning folders per library
- Visibility Control: Admins control which libraries each user can see
- Background Scanning: Auto-scan with per-user frequency settings
- Watch Mode: Real-time file system monitoring for instant updates
Security
- JWT Authentication: Short-lived access tokens (1 hour) with refresh tokens (7 days)
- Strong Passwords: Complexity requirements enforced (8+ chars, uppercase, lowercase, number, special)
- Account Lockout: 5 failed attempts = 15-minute lockout
- Rate Limiting: 10 requests/minute on auth endpoints
- Input Validation: Comprehensive validation on all inputs
- No Passwords on Devices: Web-based device approval with QR codes
📚 Documentation
For Users & Self-Hosters
- docs/user/sync-guide.md - Understanding and using universal sync
- docs/user/devices/kobo-setup.md - Kobo e-reader configuration
- docs/user/devices/koreader-setup.md - KOReader configuration
- docs/user/user-guide.md - General user guide
- docs/user/admin-guide.md - Admin features and configuration
- docs/user/settings-guide.md - Settings and preferences
For Developers
- docs/developer/api/api-reference.md - Complete API documentation
- docs/contributing/DEVELOPMENT.md - Development workflow
🎯 Supported Devices
| Platform | Sync | OPDS | Status |
|---|---|---|---|
| Web Browser | ✅ | ✅ | Full support |
| KOReader | ✅ | ✅ | Kindle, Kobo, PocketBook |
| Kobo Devices | ✅ | ✅ | Clara, Libra, Sage, etc. |
| Mobile Apps | 🚧 | 🚧 | Coming Q2 2026 |
🛠 Tech Stack
- Backend: Go 1.25+ with Echo framework
- Database: PostgreSQL 15+ with pgx v5
- Frontend: HTMX + Tailwind CSS + Templ
- Auth: JWT tokens with bcrypt password hashing
- Container: Podman (Docker compatible)
🧪 Testing
# Run all tests
make test-all
# Run integration tests (with test mode)
make test-integration
# Run Bruno OpenCollection YAML API tests
npm install -g @usebruno/cli
bruno run
📊 Project Status
Version: 1.0
License: GPL-3.0
Status: Production-ready ✅
🤝 Contributing
We welcome contributions! Please see docs/DEVELOPMENT.md for guidelines.
📄 License
GPL-3.0 - See LICENSE file for details.
Built with ❤️ using Go, PostgreSQL, HTMX, and Tailwind CSS