john-okeefe 3af3fd180f fix: add test files to TestWorker_ConcurrentJobs for scanner
Problem:
TestWorker_ConcurrentJobs was failing because it created empty temporary
directories and submitted scan jobs, but never added any test files for the
scanner to process. The scanner would complete successfully but create no
media items, causing the test to fail with 'Should NOT be empty, but was []'.

Root Cause:
The test was incomplete - it created the directory structure but didn't
populate the directories with test .epub files that the scanner could
process into media items.

Solution:
Added code to create 2 test .epub files in each of the 3 temporary
directories before submitting concurrent scan jobs:
- Directory 1: book0.epub, book1.epub
- Directory 2: book0.epub, book1.epub
- Directory 3: book0.epub, book1.epub
- Total: 6 test files to be scanned concurrently

This matches the pattern used in TestWorker_DirectoryScanJob which creates
test files before scanning.

Files changed:
- cmd/server/tests/worker_test.go: Added test file creation loop
2026-03-24 21:13:43 -04:00
2026-03-22 20:35:15 -04:00
2026-03-22 20:35:15 -04:00

📚 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

For Developers


🎯 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

S
Description
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.
Readme AGPL-3.0
27 MiB
v1.0.1
Latest
2026-08-22 13:59:19 -04:00
Languages
Go 69.4%
TypeScript 12.7%
templ 12%
PLpgSQL 2.7%
CSS 1.5%
Other 1.6%