d3b728c4583e2d4c624eae7574edecf833d0a1f0
- Fix database authentication error by exposing actual database error messages - Update error handling to follow pgx v5 standards with detailed error reporting - Restore token environment variable management in Register User.bru for subsequent requests - Enable proper debugging of database connection issues during user registration The registration API now provides detailed error messages instead of generic 'failed to check existing users' when database connection or authentication fails, making debugging easier.
📚 Bookmann
A modern self-hosted media library system built with Go, PostgreSQL, HTMX, and Tailwind CSS featuring multiple library support, beautiful dark themes, and comprehensive media management.
✨ Features
🏗 Multi-Library System
- Multiple Media Types: Support for Ebooks, Comics, and Manga with modular architecture
- Per-Library Folders: Each library can have multiple scanning folders for flexible organization
- Library Visibility Control: Admins can control which libraries are visible to each user
- Type-Specific File Extensions:
- Ebooks:
.epub,.pdf,.mobi,.azw,.azw3,.txt,.rtf,.doc,.docx,.lit,.fb2,.pdb - Comics:
.cbz,.cbr,.cb7,.cbt,.pdf - Manga:
.cbz,.cbr,.png,.jpg,.jpeg,.gif,.bmp,.webp
- Ebooks:
- Easy Extension: Designed to add new media types in the future
🔒 Authentication & Security
- Multi-User Support: Complete user registration and authentication system
- JWT-Based Sessions: Secure token-based authentication with localStorage persistence
- Role-Based Access: Admin and user roles with granular permission control
- Password Security: bcrypt hashing with secure password requirements
🎨 Beautiful UI
- 11 Dark Themes: Tokyo Night, Dracula, Nord, Solarized Dark, Monokai, One Dark Pro, Material Dark, Catppuccin variants
- Theme Persistence: User theme preferences saved to database
- Mobile-First Design: Fully responsive interface for all devices
- HTMX Integration: Dynamic interactions without page reloads
📱 Media Management
- Universal Media Support: Single system for all media types with unified interface
- Rich Metadata: Automatic extraction of title, author, series, publisher, ISBN, tags
- Advanced Rating: 5-star system with half-star precision (1-10 scale)
- Reading Progress: User-specific progress tracking with current page and total pages
- Notes & Highlights: Personal annotations and text highlighting with color customization
- Highlight Notes: Link highlights to detailed notes for comprehensive annotations
- Library Statistics: Media count and usage statistics per library
🚀 Quick Start
Prerequisites
- Docker and Docker Compose
- PostgreSQL database (handled by Docker)
Environment Setup
- Create .env file:
cp .env.example .env
- Edit .env with your secure values:
JWT_SECRET="your-secure-jwt-secret-key-here"
DBPASS="your-secure-database-password-here"
Running the Application
# Option 1: Using .env file
docker-compose up --build
# Option 2: Direct environment variables
export JWT_SECRET="your-secure-jwt-secret-key-here"
export DBPASS="your-secure-database-password-here"
docker-compose up --build
Access the application at: http://localhost:8765
👤 User Management
Role System
- Admin Users: Can create/manage libraries, add/delete media items, manage users
- Regular Users: Can view permitted libraries, rate items, track reading progress
First Admin Setup
The first user who registers automatically becomes an admin. For additional admins:
-- Connect to database
docker exec -it bookmann_db psql -U postgres -d bookmann
-- Promote user to admin
UPDATE users SET role = 'admin' WHERE email = 'user@example.com';
🏛 Library Management
Creating Libraries
- Admin Access: Only administrators can create libraries
- Library Types: Choose from Ebooks, Comics, or Manga
- Multi-Folder Support: Add multiple scanning folders per library
- Folder Organization: Organize your media collection across multiple paths
Library Visibility Control
- Admin Dashboard: Complete interface for managing library access
- User-Specific Control: Admins can show/hide libraries per user
- Personal Preferences: Admins can also hide libraries from their own view
- Simple Toggles: Checkbox-based interface for easy management
API Endpoints
Notes & Highlights (All Authenticated Users)
# Media Notes
GET /api/media-items/{id}/notes # Get user's notes for media
POST /api/media-items/{id}/notes # Create new note
GET /api/media-items/{id}/notes/{noteId} # Get specific note
PUT /api/media-items/{id}/notes/{noteId} # Update note
DELETE /api/media-items/{id}/notes/{noteId} # Delete note
# Media Highlights
GET /api/media-items/{id}/highlights # Get user's highlights for media
POST /api/media-items/{id}/highlights # Create new highlight
GET /api/media-items/{id}/highlights/{highlightId} # Get specific highlight
PUT /api/media-items/{id}/highlights/{highlightId} # Update highlight
DELETE /api/media-items/{id}/highlights/{highlightId} # Delete highlight
# Ebook Compatibility (Backward Compatible)
GET /api/ebooks/{id}/notes # Get user's notes for ebook
POST /api/ebooks/{id}/notes # Create new ebook note
PUT /api/ebooks/{id}/notes/{noteId} # Update ebook note
DELETE /api/ebooks/{id}/notes/{noteId} # Delete ebook note
GET /api/ebooks/{id}/highlights # Get user's highlights for ebook
POST /api/ebooks/{id}/highlights # Create new ebook highlight
PUT /api/ebooks/{id}/highlights/{highlightId} # Update ebook highlight
DELETE /api/ebooks/{id}/highlights/{highlightId} # Delete ebook highlight
Library Management (Admin Only)
# Create new library
POST /api/libraries
{
"name": "My Comic Collection",
"description": "Digital comics and graphic novels",
"type": "comics"
}
# List all libraries
GET /api/libraries
# Add folder to library
POST /api/libraries/{library_id}/folders
{
"folder_path": "/path/to/comics"
}
# Set library visibility for user
POST /api/libraries/visibility
{
"library_id": "library-uuid",
"is_visible": true
}
User Access
# Get user's visible libraries
GET /api/libraries/visible
# Browse media in library
GET /api/media-items?library_id={library_id}&limit=20&offset=0
# Media Progress & Ratings
GET /api/media-items/{id}/progress # Get reading progress
PUT /api/media-items/{id}/progress # Update reading progress
GET /api/media-items/{id}/rating # Get user rating
POST /api/media-items/{id}/rating # Create/update rating
PUT /api/media-items/{id}/rating # Update rating
DELETE /api/media-items/{id}/rating # Delete rating
📖 Media Support
Ebooks
- Formats: EPUB (full metadata), PDF, MOBI, AZW, TXT, DOC, FB2
- Metadata: Automatic extraction from EPUB files with Calibre support
- Reading: Built-in web reader for EPUB files
Comics
- Formats: CBZ, CBR, CB7, CBT, PDF
- Structure: Archive-based organization with chapter support
- Viewing: Image extraction and web-based comic reader
Manga
- Formats: CBZ, CBR (archives), PNG, JPG (image folders)
- Structure: Archive support with folder-based image organization
- Viewing: Chapter-by-chapter viewing with page navigation
🎨 Development
Local Development
# Backend development
go mod tidy
go run cmd/server/main.go
# Frontend development
npm run dev
# Templates automatically recompile on changes
Environment
- Backend: Go 1.25+ with pgx v5 for database operations
- Frontend: Tailwind CSS with HTMX for dynamic interactions
- Database: PostgreSQL 15+ with pgx v5 driver
- Authentication: JWT tokens with bcrypt password hashing
🐳 Deployment
Docker Configuration
# docker-compose.yml
services:
bookmann:
build: .
ports:
- "8765:8765"
environment:
- JWT_SECRET=${JWT_SECRET}
- DBHOST=db
depends_on:
- db
Database Schema
- Multi-Library Architecture: Libraries, library types, folders, visibility tables
- Annotations System: Notes, highlights with position tracking and color customization
- Backward Compatibility: Views maintain existing API contracts for ebooks
- Type Safety: pgx v5 with proper error handling
- Migration Ready: Schema designed for easy future extensions
🧪 API Documentation
Bruno Testing Collection
Complete API testing collection in bruno/ directory:
bruno/
├── user/ # Authentication & profile endpoints
├── admin/ # Admin-only operations
├── library/ # Library management
├── media-items/ # Media content browsing
├── notes/ # Notes API testing
├── highlights/ # Highlights API testing
└── collection.bru # Main dashboard
Authentication Flow
- Register:
POST /api/auth/register→ JWT token - Login:
POST /api/auth/login→ JWT token - Protected Routes: Use
Authorization: Bearer {token}header
Error Handling
- 400: Bad request (validation errors)
- 401: Unauthorized (invalid/missing token)
- 403: Forbidden (insufficient permissions)
- 404: Resource not found
- 500: Internal server error
🛡 Security Features
Authentication
- JWT Tokens: Secure, expiring tokens with localStorage persistence
- Password Hashing: bcrypt with cost factor 12
- Input Validation: Comprehensive server-side validation
- CSRF Protection: Built-in with HTMX
Authorization
- Role-Based Access: Admin vs user permissions
- Library Visibility: Per-user library access control
- Admin Middleware: Protected routes for admin operations
- Content Security: XSS protection and secure headers
Database Security
- Parameterized Queries: SQL injection prevention
- pgx v5: Modern database driver with connection pooling
- Environment Variables: Secure secret management
- Row-Level Security: User data isolation
🔧 Configuration
Environment Variables
# Required
JWT_SECRET= # JWT signing secret (64-byte random string)
DBHOST=db # PostgreSQL database host
# Optional
SERVER_PORT=8765 # Application port
NODE_ENV=development # Environment mode
Database Configuration
-- Library types are automatically seeded
INSERT INTO library_types (name, description, allowed_extensions) VALUES
('ebooks', 'Ebook files including EPUB, PDF, MOBI, etc.',
ARRAY['.epub', '.pdf', '.mobi', '.azw', '.azw3', '.txt', '.rtf', '.doc', '.docx', '.lit', '.fb2', '.pdb']),
('comics', 'Comic book archives and image formats',
ARRAY['.cbz', '.cbr', '.cb7', '.cbt', '.pdf']),
('manga', 'Manga files including archives and image folders',
ARRAY['.cbz', '.cbr', '.png', '.jpg', '.jpeg', '.gif', '.bmp', '.webp']);
🧪 Testing
API Testing
# Install Bruno
npm install -g @usebruno/cli
# Run tests
bruno run
Unit Tests
go test ./...
📊 Architecture
Backend
cmd/server/main.go # Application entry point
├── internal/
│ ├── config/ # Configuration management
│ ├── database/ # Database operations (SQLC generated)
│ │ ├── queries/ # SQL queries
│ │ └── models.go # Generated models
│ ├── handlers/ # HTTP handlers
│ │ ├── auth.go # Authentication & users
│ │ ├── library.go # Library management
│ │ └── ebook.go # Media operations
│ └── services/ # Business logic
│ └── library_service.go # Library service
templates/ # HTML templates with HTMX
Database
libraries # Library definitions
library_types # Media type definitions (ebooks, comics, manga)
library_folders # Folders per library
library_visibility # User library access control
media_items # All media content (replaces ebooks table)
media_ratings # User ratings for media items
media_notes # User notes on media items
media_highlights # User highlights with optional note links
reading_progress # User reading progress
users # User accounts and profiles
# Backward Compatibility Views
ebook_notes # Notes view for ebook API compatibility
ebook_highlights # Highlights view for ebook API compatibility
🎯 Future Roadmap
Media Type Extensions
- Audiobooks: Audio file support with chapter tracking
- Podcasts: RSS feed integration and automatic downloading
- Video: Movie/TV series management with metadata
- Music: Album and track management with artwork
Advanced Features
- Mobile App: React Native mobile application
- API v2: GraphQL API for efficient data fetching
- Webhooks: External service integrations
- Analytics: Usage statistics and reporting
- Backup/Restore: Library backup and migration tools
📝 Contributing
Development Guidelines
- Follow Go best practices and effective Go
- Use pgx v5 for all database operations
- Implement proper error handling with pgx.ErrNoRows
- Write comprehensive tests for new features
- Update documentation for API changes
Code Style
- Follow existing code formatting
- Use meaningful variable and function names
- Add comments for complex business logic
- Ensure type safety with proper error handling
📄 License
GPL-3.0 - See LICENSE file for details.
Built with ❤️ using Go, PostgreSQL, HTMX, and Tailwind CSS