diff --git a/README.md b/README.md index cc5bd1cc..8e9fd632 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,6 @@ services: PGPORT: ${DB_PORT:-5432} volumes: - postgres_data:/var/lib/postgresql/data - - ./database/schema:/docker-entrypoint-initdb.d ports: - "127.0.0.1:${DB_PORT:-5432}:${DB_PORT:-5432}" - "[::1]:${DB_PORT:-5432}:${DB_PORT:-5432}" @@ -65,11 +64,14 @@ services: # transfers object ownership to it (RLS prerequisite). Idempotent โ€” # safe on every startup; the app waits for its success. Passwords # accept inline values or .env, like the rest of this file. + # NOTE: plpgsql $$ tags are written $$$$ โ€” compose eats one dollar + # per pair before the container sees the SQL. db-init: image: postgres:15-alpine container_name: bookhoard_db_init environment: PGHOST: db + PGPORT: ${DB_PORT:-5432} PGUSER: postgres PGDATABASE: bookhoard PGPASSWORD: ${DBPASS} @@ -180,163 +182,6 @@ volumes: bookhoard_conversion_cache: ``` -**`.env`** โ€” create alongside the compose file and fill in the three -secrets (no special characters): - -```bash -openssl rand -hex 32 # JWT_SECRET -openssl rand -hex 16 # DBPASS (bootstrap database password) -openssl rand -hex 16 # DBSRVPASS (runtime role password) -``` - -Then start: - -```bash -docker compose pull -docker compose up -d -open http://localhost:8765 -``` - -Notes: -- `db-init` runs on every startup and converges the runtime role - (idempotent, ~1 second); the app refuses to start before it succeeds. -- `uploads/` on the host is where your book files live; libraries scan - folders under it from the Admin โ†’ Libraries page. -- First user to register automatically becomes an admin. -- Upgrades: `docker compose pull && docker compose up -d` (pin a version - with `IMAGE_TAG` in `.env`). - ---- - -## ๐Ÿ“– Key Features - -### Universal Cross-Platform Sync - -- **Real-Time Progress**: Turn a page on your e-reader, see it in your browser -- **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 conversion (for upcoming native Kobo support) - -### Media Management - -- **Calibre Integration**: Automatic metadata import from Calibre `metadata.opf` sidecar files -- **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**: Map collections to device shelves (used by native Kobo sync, coming soon) -- **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/calibre-integration.md](docs/user/calibre-integration.md)** - Calibre library integration -- **[docs/user/sync-guide.md](docs/user/sync-guide.md)** - Understanding and using universal sync -- **[docs/user/devices/koreader-setup.md](docs/user/devices/koreader-setup.md)** - KOReader configuration -- **[docs/user/devices/kobo-setup.md](docs/user/devices/kobo-setup.md)** - Kobo e-reader configuration (coming soon) -- **[docs/user/user-guide.md](docs/user/user-guide.md)** - General user guide -- **[docs/user/admin-guide.md](docs/user/admin-guide.md)** - Admin features and configuration -- **[docs/user/settings-guide.md](docs/user/settings-guide.md)** - Settings and preferences - -### For Developers - -- **[docs/developer/api/api-reference.md](docs/developer/api/api-reference.md)** - Complete API documentation -- **[docs/developer/android-app.md](docs/developer/android-app.md)** - Android app design & roadmap -- **[docs/contributing/development.md](docs/contributing/development.md)** - Development workflow - ---- - -## ๐ŸŽฏ Supported Devices - -| Platform | Sync | OPDS | Status | -| ---------------- | ---- | ---- | ------------------------------------------------------------- | -| **Web Browser** | โœ… | โœ… | Full support | -| **KOReader** | โœ… | โœ… | Runs on Kindle, Kobo, PocketBook hardware | -| **Kobo Devices** | ๐Ÿšง | ๐Ÿšง | Native Kobo sync coming soon (use KOReader on Kobo today) | -| **Mobile Apps** | ๐Ÿšง | ๐Ÿšง | Native Android app in design ([docs](docs/developer/android-app.md)); iOS later | - ---- - -## ๐Ÿ’พ Network Storage (NAS / NFS / SMB) - -Libraries on network mounts are supported for everyday use โ€” serving, -reading, progress, and annotation sync all work over the mount โ€” with a -few behaviors worth knowing: - -- **Outage hysteresis.** When the mount drops, files miss one scan - (marked missing, hidden) then a second (archived, still recoverable). - When the mount returns โ€” by path or by identical content elsewhere โ€” - everything is restored automatically: annotations, progress, and - covers included. -- **Retention purge.** Archived items older than `ARCHIVE_RETENTION_DAYS` - (default **90**, `0` = never auto-purge) are deleted for good by - library scans, annotations included. A NAS offline longer than the - retention window loses those books' metadata on return. -- **Deleting while the storage is down is refused.** Deleting a book - cascades its annotations, so deletes are rejected with a clear error - while the item's library storage is unreachable. Archive the item - instead, or retry when the mount is back. -- **Watch mode does not fire on network mounts** (inotify doesn't work - over NFS/SMB). The periodic scan is the change detector. -- **Latency** โ€” folder reachability checks are cached ~30s; large - libraries on slow mounts will still feel slower than local disk. - ---- - -## ๐Ÿ›  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 - -```bash -# 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