Rename project documentation: Bookmann → Bookhoard
Documentation updates: - Update README.md title and all references - Update PROJECT_GUIDELINES.md title and guidelines - Update all documentation files in docs/ directory - Update device setup guides (Kobo, KOReader) - Update API and architecture documentation - Update completion summaries and progress reports This is part 5 of the project rename to Bookhoard.
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
# Bookmann Implementation Plan
|
||||
# Bookhoard Implementation Plan
|
||||
|
||||
## Executive Summary
|
||||
|
||||
@@ -33,7 +33,7 @@ This plan implements a complete cross-device ebook management system with three
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ Bookmann Server │
|
||||
│ Bookhoard Server │
|
||||
│ ┌──────────────────────────────────────────────────────────────┐ │
|
||||
│ │ Layer 1: Universal Book Identification │ │
|
||||
│ │ SHA-256, UUID, ISBN, ASIN, OPF identifiers │ │
|
||||
@@ -52,7 +52,7 @@ This plan implements a complete cross-device ebook management system with three
|
||||
│ │ Per-device OPDS feeds (Kobo, KOReader, etc.) │ │
|
||||
│ │ Format conversion (EPUB → KEPUB on-the-fly) │ │
|
||||
│ │ Dual hash storage (original + converted) │ │
|
||||
│ │ ContentId mapping (Bookmann UUID ↔ Device ID) │ │
|
||||
│ │ ContentId mapping (Bookhoard UUID ↔ Device ID) │ │
|
||||
│ └──────────────────────────────────────────────────────────────────────┘ │
|
||||
│ ↓ delivers books + provides IDs │
|
||||
│ ┌──────────────────────────────────────────────────────────────────────┐ │
|
||||
@@ -70,7 +70,7 @@ This plan implements a complete cross-device ebook management system with three
|
||||
|
||||
| Platform | Access Method | Purpose | Why This Method |
|
||||
|-----------|----------------|---------|-----------------|
|
||||
| **Kobo** | OPDS catalog | Kobo has built-in OPDS client, no custom Bookmann client exists |
|
||||
| **Kobo** | OPDS catalog | Kobo has built-in OPDS client, no custom Bookhoard client exists |
|
||||
| **KOReader** | OPDS catalog (primary) + Sidecar + Internal API | KOReader has OPDS client, also supports plugins/sidecars for enhanced features |
|
||||
| **Web App** | Internal API directly | We own and control web app, can make direct API calls efficiently |
|
||||
| **Mobile App** | Internal API directly | We own and control mobile app, can make direct API calls efficiently |
|
||||
@@ -78,7 +78,7 @@ This plan implements a complete cross-device ebook management system with three
|
||||
|
||||
### Key Design Principles
|
||||
|
||||
1. **Canonical UUID Always Wins** - Bookmann UUID (from `media_items.id`) is always used for progress tracking, never SHA-256. SHA-256 is only for matching books across devices, preventing format conversion issues.
|
||||
1. **Canonical UUID Always Wins** - Bookhoard UUID (from `media_items.id`) is always used for progress tracking, never SHA-256. SHA-256 is only for matching books across devices, preventing format conversion issues.
|
||||
|
||||
2. **Collections ≠ Device Inventory** - Collections are organizational metadata (like "smart playlists"). Books can be in collections without being on any device. Progress/annotations sync independently of collection membership.
|
||||
|
||||
@@ -93,7 +93,7 @@ This plan implements a complete cross-device ebook management system with three
|
||||
- Tier 2 (Sync APIs): Device tokens for progress/annotation sync
|
||||
- Tier 3 (OPDS): Device tokens for catalog access (optional per-device)
|
||||
|
||||
6. **Terminology Separation** - Always use "Collections" terminology in Bookmann UI. Map Collections to device-specific "Shelves" only at API/device level. Kobo devices see "Shelves", KOReader/Web/Mobile see "Collections". Prevents legal issues.
|
||||
6. **Terminology Separation** - Always use "Collections" terminology in Bookhoard UI. Map Collections to device-specific "Shelves" only at API/device level. Kobo devices see "Shelves", KOReader/Web/Mobile see "Collections". Prevents legal issues.
|
||||
|
||||
7. **OPDS Primary for All Devices** - Kobo, KOReader, Web, and Mobile all use OPDS as primary book delivery method. Sidecar files provide fallback/enhanced features but are optional.
|
||||
|
||||
@@ -211,7 +211,7 @@ CREATE INDEX idx_collection_items_media ON collection_items(media_item_id);
|
||||
### Table: device_shelf_mappings (NEW)
|
||||
|
||||
```sql
|
||||
-- Map Bookmann collections to device-specific shelf names
|
||||
-- Map Bookhoard collections to device-specific shelf names
|
||||
-- This is where "Collections" terminology maps to Kobo's "Shelves"
|
||||
|
||||
CREATE TABLE device_shelf_mappings (
|
||||
@@ -219,7 +219,7 @@ CREATE TABLE device_shelf_mappings (
|
||||
collection_id UUID REFERENCES collections(id) ON DELETE CASCADE,
|
||||
device_id UUID REFERENCES devices(id) ON DELETE CASCADE,
|
||||
device_shelf_name VARCHAR(100), -- What appears on Kobo device
|
||||
sync_direction VARCHAR(20), -- 'bidirectional', 'book_to_device', 'device_to_book', 'none'
|
||||
sync_direction VARCHAR(20), -- 'bidirectional', 'book_to_hoard', 'device_to_hoard', 'none'
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
|
||||
UNIQUE(collection_id, device_id)
|
||||
);
|
||||
@@ -231,7 +231,7 @@ CREATE INDEX idx_device_shelf_mappings_device ON device_shelf_mappings(device_id
|
||||
### Table: device_catalogs (NEW)
|
||||
|
||||
```sql
|
||||
-- Track OPDS downloads and map Bookmann UUIDs to device ContentIds
|
||||
-- Track OPDS downloads and map Bookhoard UUIDs to device ContentIds
|
||||
-- Critical for bidirectional progress sync with format conversion handling
|
||||
|
||||
CREATE TABLE device_catalogs (
|
||||
@@ -326,7 +326,7 @@ users
|
||||
|
||||
#### POST `/api/sync/books/query`
|
||||
|
||||
Query Bookmann for a book by multiple identifier types with confidence scoring.
|
||||
Query Bookhoard for a book by multiple identifier types with confidence scoring.
|
||||
|
||||
**Request**:
|
||||
```json
|
||||
@@ -355,7 +355,7 @@ Query Bookmann for a book by multiple identifier types with confidence scoring.
|
||||
```
|
||||
|
||||
**Matching Priority**:
|
||||
1. Bookmann UUID (canonical) - Confidence: 1.0
|
||||
1. Bookhoard UUID (canonical) - Confidence: 1.0
|
||||
2. OPF UUID (from EPUB metadata) - Confidence: 0.95
|
||||
3. SHA-256 hash (content-based match) - Confidence: 0.9
|
||||
4. OPF identifier (non-UUID) - Confidence: 0.85
|
||||
@@ -655,7 +655,7 @@ Main OPDS 1.2 catalog feed.
|
||||
xmlns:opds="http://opds-spec.org/2010/"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<id>urn:uuid:device-id</id>
|
||||
<title>Bookmann Library</title>
|
||||
<title>Bookhoard Library</title>
|
||||
<updated>2026-01-31T12:00:00Z</updated>
|
||||
|
||||
<link rel="self" href="http://192.168.1.100:8765/opds/devices/kobo-id/catalog"/>
|
||||
@@ -734,9 +734,9 @@ Download book with optional format conversion.
|
||||
**Response Headers**:
|
||||
- `Content-Type`: application/epub+zip (or format-specific)
|
||||
- `Content-Disposition`: attachment; filename="The Hobbit.epub"
|
||||
- `X-Bookmann-UUID`: uuid-123
|
||||
- `X-Bookmann-SHA256`: abc123... (for format-specific if available)
|
||||
- `X-Bookmann-KEPUB-SHA256`: xyz789... (if format=kepub)
|
||||
- `X-Bookhoard-UUID`: uuid-123
|
||||
- `X-Bookhoard-SHA256`: abc123... (for format-specific if available)
|
||||
- `X-Bookhoard-KEPUB-SHA256`: xyz789... (if format=kepub)
|
||||
|
||||
**Format Conversion Logic**:
|
||||
```go
|
||||
@@ -746,7 +746,7 @@ case "kepub":
|
||||
// Check media_item_formats table for pre-converted KEPUB
|
||||
if kepubFormat.Exists && kepubFormat.FilePath != "" {
|
||||
Serve pre-converted file
|
||||
Set X-Bookmann-KEPUB-SHA256: kepubFormat.SHA256
|
||||
Set X-Bookhoard-KEPUB-SHA256: kepubFormat.SHA256
|
||||
}
|
||||
case "pdf":
|
||||
// Serve PDF directly
|
||||
@@ -853,8 +853,8 @@ Kobo progress sync with ContentId mapping (enhanced).
|
||||
// Step 1: Try direct ContentId lookup
|
||||
catalog, err := db.GetDeviceCatalogByKoboContentId(ctx, contentId)
|
||||
if err == nil && catalog.Valid {
|
||||
// Found! Use canonical Bookmann UUID
|
||||
bookmannUUID = catalog.BookmannUUID
|
||||
// Found! Use canonical Bookhoard UUID
|
||||
bookmannUUID = catalog.BookhoardUUID
|
||||
return bookmannUUID, nil
|
||||
}
|
||||
|
||||
@@ -891,7 +891,7 @@ Kobo library sync with collection metadata (enhanced).
|
||||
|
||||
// NEW: Collection metadata
|
||||
"Categories": ["Science Fiction", "Reading"],
|
||||
"BookmannUUID": "uuid-123" // Canonical ID
|
||||
"BookhoardUUID": "uuid-123" // Canonical ID
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -1119,7 +1119,7 @@ LOW (confidence = 0.5):
|
||||
|
||||
**Matching Algorithm**:
|
||||
```
|
||||
Priority 1: Bookmann UUID (canonical)
|
||||
Priority 1: Bookhoard UUID (canonical)
|
||||
- If device sends UUID, use directly
|
||||
- Confidence = 1.0
|
||||
|
||||
@@ -1257,12 +1257,12 @@ When user downloads with ?format=kepub:
|
||||
1. Check media_item_formats table
|
||||
2. If KEPUB exists and is recent:
|
||||
- Serve pre-converted file
|
||||
- Set X-Bookmann-SHA256: kepubFormat.SHA256
|
||||
- Set X-Bookhoard-SHA256: kepubFormat.SHA256
|
||||
3. If KEPUB doesn't exist:
|
||||
- Convert EPUB to KEPUB on-the-fly
|
||||
- Cache in media_item_formats table
|
||||
- Serve converted file
|
||||
- Set X-Bookmann-SHA256: kepubFormat.SHA256
|
||||
- Set X-Bookhoard-SHA256: kepubFormat.SHA256
|
||||
4. Serve PDF directly
|
||||
```
|
||||
|
||||
@@ -1287,8 +1287,8 @@ When user downloads with ?format=kepub:
|
||||
// Step 1: Try direct ContentId lookup
|
||||
catalog, err := db.GetDeviceCatalogByKoboContentId(ctx, contentId)
|
||||
if err == nil && catalog.Valid {
|
||||
// Found! Use canonical Bookmann UUID
|
||||
return catalog.BookmannUUID, nil
|
||||
// Found! Use canonical Bookhoard UUID
|
||||
return catalog.BookhoardUUID, nil
|
||||
}
|
||||
|
||||
// Step 2: ContentId not found - try SHA-256
|
||||
@@ -1440,7 +1440,7 @@ if book.FilePath != "" {
|
||||
|
||||
**Step 1: Download Configuration File**
|
||||
```
|
||||
1. Log into Bookmann web UI
|
||||
1. Log into Bookhoard web UI
|
||||
2. Go to Device Management → Your Kobo device
|
||||
3. Click "Download Configuration" button
|
||||
4. File downloads as `.bookmann.json`
|
||||
@@ -1453,16 +1453,16 @@ if book.FilePath != "" {
|
||||
3. Enter URL from `.bookmann.json`:
|
||||
http://192.168.1.100:8765/opds/devices/YOUR_DEVICE_ID/catalog
|
||||
4. Kobo will automatically:
|
||||
- Connect to Bookmann
|
||||
- Connect to Bookhoard
|
||||
- Browse your library wirelessly
|
||||
- Download books directly
|
||||
- Sync reading progress back to Bookmann
|
||||
- Sync reading progress back to Bookhoard
|
||||
```
|
||||
|
||||
**Step 3: Wireless Book Acquisition**
|
||||
```
|
||||
1. On Kobo, go to "My Books" section
|
||||
2. Browse Bookmann catalog via OPDS
|
||||
2. Browse Bookhoard catalog via OPDS
|
||||
3. Tap on any book to download wirelessly
|
||||
4. Book appears on Kobo device
|
||||
5. Start reading - progress syncs automatically
|
||||
@@ -1470,8 +1470,8 @@ if book.FilePath != "" {
|
||||
|
||||
**How Progress Sync Works**:
|
||||
- Kobo generates ContentId for each book
|
||||
- ContentId mapped to Bookmann UUID in device_catalogs table
|
||||
- When Kobo syncs progress, Bookmann uses canonical UUID
|
||||
- ContentId mapped to Bookhoard UUID in device_catalogs table
|
||||
- When Kobo syncs progress, Bookhoard uses canonical UUID
|
||||
- Format conversion (KEPUB) doesn't break progress tracking
|
||||
|
||||
### KOReader Setup
|
||||
@@ -1490,7 +1490,7 @@ Same as Kobo setup above
|
||||
3. Enter OPDS URL from `.bookmann.json`:
|
||||
http://192.168.1.100:8765/opds/devices/YOUR_DEVICE_ID/catalog
|
||||
4. KOReader will automatically:
|
||||
- Connect to Bookmann catalog
|
||||
- Connect to Bookhoard catalog
|
||||
- Browse and download books wirelessly
|
||||
- Sync progress using SHA-256 matching
|
||||
- Create file aliases automatically
|
||||
@@ -1500,7 +1500,7 @@ Same as Kobo setup above
|
||||
```
|
||||
1. Open KOReader file browser
|
||||
2. Tap "+" button to add OPDS catalog
|
||||
3. Browse Bookmann catalog
|
||||
3. Browse Bookhoard catalog
|
||||
4. Download books directly
|
||||
5. Start reading
|
||||
```
|
||||
@@ -1522,7 +1522,7 @@ Place in KOReader's config directory
|
||||
**Step 3: Use Sidecar for Progress Sync**
|
||||
```
|
||||
KOReader plugin reads .bookmann.json
|
||||
→ Matches local files to Bookmann UUIDs via SHA-256
|
||||
→ Matches local files to Bookhoard UUIDs via SHA-256
|
||||
→ Syncs progress using canonical UUIDs
|
||||
→ Works offline
|
||||
```
|
||||
@@ -1628,7 +1628,7 @@ Can be: Public (no authentication required)
|
||||
- [ ] Browse catalog wirelessly
|
||||
- [ ] Download book
|
||||
- [ ] Read 50% of book
|
||||
- [ ] Verify progress syncs to Bookmann
|
||||
- [ ] Verify progress syncs to Bookhoard
|
||||
|
||||
**KOReader Workflow**:
|
||||
- [ ] Download `.bookmann.json` from web UI
|
||||
@@ -1636,10 +1636,10 @@ Can be: Public (no authentication required)
|
||||
- [ ] Browse catalog wirelessly
|
||||
- [ ] Download book
|
||||
- [ ] Read 75% of book
|
||||
- [ ] Verify progress syncs to Bookmann
|
||||
- [ ] Verify progress syncs to Bookhoard
|
||||
|
||||
**Cross-Device Scenario**:
|
||||
- [ ] Add book to Bookmann (EPUB scanned)
|
||||
- [ ] Add book to Bookhoard (EPUB scanned)
|
||||
- [ ] Download to Kobo via OPDS
|
||||
- [ ] Sync progress (60%) from Kobo
|
||||
- [ ] Open same book on KOReader (side-loaded)
|
||||
@@ -1651,18 +1651,18 @@ Can be: Public (no authentication required)
|
||||
|
||||
## Glossary
|
||||
|
||||
- **Bookmann UUID**: Canonical identifier for a book in Bookmann system (from `media_items.id`). Always used for progress tracking, never SHA-256. SHA-256 is only for matching books across devices.
|
||||
- **ContentId**: Device-generated identifier (e.g., Kobo's "kobo_abc"). Mapped to Bookmann UUID in `device_catalogs` table. Used for progress sync after OPDS downloads.
|
||||
- **Bookhoard UUID**: Canonical identifier for a book in Bookhoard system (from `media_items.id`). Always used for progress tracking, never SHA-256. SHA-256 is only for matching books across devices.
|
||||
- **ContentId**: Device-generated identifier (e.g., Kobo's "kobo_abc"). Mapped to Bookhoard UUID in `device_catalogs` table. Used for progress sync after OPDS downloads.
|
||||
- **SHA-256**: Cryptographic hash of file contents. Used for content-based matching across devices. Critical for identifying same book on different devices.
|
||||
- **OPF UUID**: Unique identifier from EPUB metadata `<dc:identifier id="...">`. High-confidence identifier format.
|
||||
- **OPF Identifier**: Any identifier from EPUB OPF file (custom format). Medium-confidence identifier format.
|
||||
- **ISBN**: International Standard Book Number (13 digits). Medium-confidence standard identifier.
|
||||
- **ASIN**: Amazon Standard Identification Number (10 characters). Medium-confidence standard identifier.
|
||||
- **Collections**: Device-neutral organizational groups in Bookmann (e.g., "Science Fiction", "Reading"). Books can be in collections without being on any device. Collections organize library, not track device inventory.
|
||||
- **Shelves**: Device-specific organization (e.g., Kobo's terminology). Map Collections to device-specific "Shelves" only at device-level. Bookmann UI always uses "Collections" terminology.
|
||||
- **Collections**: Device-neutral organizational groups in Bookhoard (e.g., "Science Fiction", "Reading"). Books can be in collections without being on any device. Collections organize library, not track device inventory.
|
||||
- **Shelves**: Device-specific organization (e.g., Kobo's terminology). Map Collections to device-specific "Shelves" only at device-level. Bookhoard UI always uses "Collections" terminology.
|
||||
- **OPDS**: Open Publication Distribution System. Industry standard for book catalogs. All e-reader platforms have OPDS clients. Kobo, KOReader, Aldiko, FBReader, Web browsers can use OPDS catalogs.
|
||||
- **Internal APIs**: Bookmann's private REST/WebSocket endpoints for state management. Web and mobile apps use these directly. Used for two-way sync, collections, WebSocket real-time updates.
|
||||
- **Device File Alias**: Mapping of device-specific file paths to Bookmann UUIDs. Enables cross-device matching when same book has different file paths.
|
||||
- **Internal APIs**: Bookhoard's private REST/WebSocket endpoints for state management. Web and mobile apps use these directly. Used for two-way sync, collections, WebSocket real-time updates.
|
||||
- **Device File Alias**: Mapping of device-specific file paths to Bookhoard UUIDs. Enables cross-device matching when same book has different file paths.
|
||||
- **Hash Confidence**: Scoring system (0.0-1.0) for automatic book matching reliability. Higher values = more reliable match.
|
||||
- **Dual Hash Storage**: Storing both original EPUB hash (`epub_sha256`) and converted KEPUB hash (`kepub_sha256`). Preserves hash integrity when files are converted. OPDS responses include format-specific hash for sidecar matching.
|
||||
- **Format Conversion**: Transcoding between book formats (EPUB → KEPUB). KEPUB adds Kobo-specific markup. Critical for Kobo optimization but shouldn't break progress tracking.
|
||||
@@ -1671,7 +1671,7 @@ Can be: Public (no authentication required)
|
||||
- **OPDS Tokens**: Per-device access tokens for OPDS catalog browsing. Optional - can also support user-scoped and admin tokens.
|
||||
- **Sidecar File**: `.bookmann.json` - Unified configuration file for devices. Contains OPDS URLs, sync API endpoints, book mappings, collection mappings.
|
||||
- **Auto-Assign Rules**: Configurable criteria for automatically adding books to collections. Fields: genre, series, author, language, publisher, copyright_year, tags. Operators: equals, contains, starts_with, ends_with, greater_than, less_than.
|
||||
- **Sync Direction**: For device shelf mappings. 'bidirectional' (sync both ways), 'book_to_device' (send to device), 'device_to_book' (read from device), 'none' (no sync).
|
||||
- **Sync Direction**: For device shelf mappings. 'bidirectional' (sync both ways), 'book_to_hoard' (send to device), 'device_to_hoard' (read from device), 'none' (no sync).
|
||||
- **View Settings**: Per-device preferences for how collections are displayed (grid vs list, which collections are visible).
|
||||
- **Unlinked Book**: Progress record without proper media_item_id or failed ContentId lookup. Needs manual user resolution.
|
||||
|
||||
@@ -1689,4 +1689,4 @@ This comprehensive implementation plan provides:
|
||||
- **Glossary** of all terminology and concepts
|
||||
- **Testing strategies** covering unit, integration, and manual validation
|
||||
|
||||
The plan is designed for systematic execution while maintaining architectural consistency and enabling human oversight throughout the development process. All decisions from our conversations have been incorporated, providing a complete roadmap for implementing Bookmann as a comprehensive cross-device ebook management system.
|
||||
The plan is designed for systematic execution while maintaining architectural consistency and enabling human oversight throughout the development process. All decisions from our conversations have been incorporated, providing a complete roadmap for implementing Bookhoard as a comprehensive cross-device ebook management system.
|
||||
Reference in New Issue
Block a user