docs: restructure documentation and update guidelines

- Update PROJECT_GUIDELINES.md to reflect current architecture (Hybrid SSR)
- Integrate service layer and SSR rules into existing sections
- Update README.md paths to match new docs structure (docs/developer/api, docs/user/devices)
- Remove redundant README.md files from bruno/ directories
- Update bruno/collection.bru documentation to current API standard
- Fix architectural pattern description from API-driven to Hybrid SSR
This commit is contained in:
2026-02-02 16:45:59 -05:00
parent 253f56399d
commit 155b58aef6
6 changed files with 221 additions and 770 deletions
+33 -24
View File
@@ -10,6 +10,8 @@
-**NEVER create new migration files** - merge changes into current one until release
-**NEVER use `git checkout` on schema files** without checking what will be lost
-**NEVER break existing functionality** unless explicitly instructed
-**NEVER duplicate business logic** - keep logic in services, not handlers
-**NEVER bypass service layer** - all database operations must go through services
### Frontend & Styling
-**NEVER modify backend/API for frontend features without user confirmation**
@@ -17,6 +19,8 @@
-**NEVER use JavaScript** - convert all to TypeScript
-**NEVER use object-oriented programming patterns in TypeScript** - avoid classes, inheritance, and OOP bloat; use functional/other paradigms
- ❌ **NEVER add new Dockerfiles without user confirmation
-**NEVER fetch initial data via AJAX on page load** - use server-side rendering instead
-**NEVER break progressive enhancement** - pages must work without JavaScript
**Note:** Go methods in the backend are fine and encouraged. This guideline applies to TypeScript/JavaScript frontend code only.**
@@ -110,6 +114,15 @@ VERIFY → Compile successfully
- ✅ Always use **TailwindCSS classes** for all styling
- ✅ Convert all JavaScript to **TypeScript**
- ✅ Avoid OOP patterns - prefer functional/other paradigms
-**Render initial data server-side** in Go templates for fast page loads
-**Use JavaScript/HTMX for CRUD operations** (create, update, delete)
-**Ensure progressive enhancement** - pages work without JavaScript
### Service Layer Architecture
-**All business logic in services** - never in handlers
-**Services must be reusable** by both SSR handlers and API endpoints
-**Database operations through services only** - never direct from handlers
-**When adding features**: Add service logic → Create API endpoint → Use SSR for initial render → Use JS for updates
### Code Organization
- ✅ Minimize project structure changes
@@ -142,18 +155,19 @@ VERIFY → Compile successfully
**Documentation Structure** (updated with full docs system):
-**README.md** - Project overview, quick start, and setup instructions only
-**docs/** - Comprehensive documentation system with search
-**docs/api/** - API reference documentation (split by endpoint/category)
-**docs/devices/** - Device setup guides (KOBO, KOReader, etc.)
-**docs/developer/api/** - API reference documentation (split by endpoint/category)
-**docs/user/** - User-facing features, guides, and workflows
-**docs/user/devices/** - Device setup guides (KOBO, KOReader, etc.)
-**docs/contributing/** - Development and contribution guides
**Where to document changes**:
| Change Type | Location | Examples |
|-------------|----------|----------|
| **User-facing features** | `docs/` or appropriate subdirectory | New features, UI changes, workflows |
| **API endpoints** | `docs/api/<category>/<endpoint>.md` | New endpoints, modified responses, authentication changes |
| **API behavior** | Update existing `docs/api/` files | Parameter changes, error codes, rate limits |
| **Device setup** | `docs/devices/` | New device support, setup instructions |
| **User-facing features** | `docs/user/` | New features, UI changes, workflows |
| **API endpoints** | `docs/developer/api/<category>/<endpoint>.md` | New endpoints, modified responses, authentication changes |
| **API behavior** | Update existing `docs/developer/api/` files | Parameter changes, error codes, rate limits |
| **Device setup** | `docs/user/devices/` | New device support, setup instructions |
| **Development** | `docs/contributing/` | Build changes, architecture decisions |
| **Quick start/setup** | `README.md` | Installation, environment setup, first-run |
| **Breaking changes** | Both `README.md` and relevant `docs/` | Migration guides, deprecation notices |
@@ -166,12 +180,12 @@ VERIFY → Compile successfully
3. **Update documentation** before or with code changes
4. **Verify documentation renders** at `/docs` endpoint
5. **Test search** finds new/updated content
6. **For API changes**: Update both `docs/api/` files AND Bruno `.bru` files
6. **For API changes**: Update both `docs/developer/api/` files AND Bruno `.bru` files
7. **Commit separately** with clear message: `docs: <description>`
**When in doubt**:
- End-user visible → `docs/`
- API reference → `docs/api/`
- End-user visible → `docs/user/`
- API reference → `docs/developer/api/`
- Setup/onboarding → `README.md`
- Development related → `docs/contributing/`
@@ -251,8 +265,8 @@ git checkout -- internal/handlers/auth.go
- Alternative approaches considered
- [ ] Plan git commit structure (multiple logical commits)
- [ ] **Identify documentation location** (see Documentation section):
- [ ] User-facing feature → `docs/`
- [ ] UI/workflow changes → `docs/`
- [ ] User-facing feature → `docs/user/`
- [ ] UI/workflow changes → `docs/user/`
- [ ] Setup instructions → `README.md`
### Before Making Full-Stack Changes
@@ -262,9 +276,9 @@ git checkout -- internal/handlers/auth.go
- [ ] Verify Podman will be used for builds
- [ ] Plan git commit structure (multiple logical commits)
- [ ] **Identify documentation location**:
- [ ] API changes → `docs/api/<category>/`
- [ ] New endpoints → Create new `.md` file in `docs/api/`
- [ ] API behavior → Update existing `docs/api/` files
- [ ] API changes → `docs/developer/api/<category>/`
- [ ] New endpoints → Create new `.md` file in `docs/developer/api/`
- [ ] API behavior → Update existing `docs/developer/api/` files
- [ ] Breaking changes → Both `README.md` + relevant `docs/`
- [ ] Bruno `.bru` files → Update/create alongside API changes
@@ -291,8 +305,8 @@ git checkout -- internal/handlers/auth.go
- [ ] Ensure no secrets in changes
- [ ] Verify logical commit structure
- [ ] **Update documentation** (see Documentation section):
- [ ] User-facing changes → `docs/`
- [ ] API changes → `docs/api/` + Bruno `.bru` files
- [ ] User-facing changes → `docs/user/`
- [ ] API changes → `docs/developer/api/` + Bruno `.bru` files
- [ ] Setup/onboarding → `README.md`
- [ ] Development changes → `docs/contributing/`
- [ ] **Verify docs render** at `/docs` endpoint
@@ -321,18 +335,13 @@ git checkout -- internal/handlers/auth.go
## 🏗 ARCHITECTURAL PATTERNS
### Current: API-Driven Frontend
```
Browser → Go template (empty) → JavaScript fetch() → API → Database
```
### Future Reference: Hybrid SSR (NOT TO IMPLEMENT YET)
### Current: Hybrid SSR
```
Browser → Go template (with data) → Display instantly
JavaScript only for interactivity (CRUD)
JavaScript for interactivity (CRUD)
Shared service layer
Shared service layer
```
Ultimately, whenever you are unsure just ask for confirmation.
+8 -8
View File
@@ -87,16 +87,16 @@ The first user to register automatically becomes an admin.
## 📚 Documentation
### For Users & Self-Hosters
- **[docs/SYNC_USER_GUIDE.md](docs/SYNC_USER_GUIDE.md)** - Understanding and using universal sync
- **[docs/devices/KOBO_SETUP.md](docs/devices/KOBO_SETUP.md)** - Kobo e-reader configuration
- **[docs/devices/KOREADER_SETUP.md](docs/devices/KOREADER_SETUP.md)** - KOReader configuration
- **[docs/TROUBLESHOOTING.md](docs/TROUBLESHOOTING.md)** - Deployment troubleshooting
- **[docs/user/sync-guide.md](docs/user/sync-guide.md)** - Understanding and using universal sync
- **[docs/user/devices/kobo-setup.md](docs/user/devices/kobo-setup.md)** - Kobo e-reader configuration
- **[docs/user/devices/koreader-setup.md](docs/user/devices/koreader-setup.md)** - KOReader configuration
- **[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/API_REFERENCE.md](docs/API_REFERENCE.md)** - Complete API documentation
- **[docs/COLLECTIONS_API.md](docs/COLLECTIONS_API.md)** - Collections API reference
- **[docs/api/WEBSOCKET_API.md](docs/api/WEBSOCKET_API.md)** - WebSocket protocol
- **[docs/DEVELOPMENT.md](docs/DEVELOPMENT.md)** - Development workflow
- **[docs/developer/api/INDEX.md](docs/developer/api/INDEX.md)** - Complete API documentation
- **[docs/contributing/DEVELOPMENT.md](docs/contributing/DEVELOPMENT.md)** - Development workflow
---
-115
View File
@@ -1,115 +0,0 @@
# Bruno API Tests for Bookhoard
This directory contains Bruno collection for testing the Bookhoard API with comprehensive REST documentation.
## Setup
1. Install Bruno: https://www.usebruno.com/
2. Open Bruno and import this collection folder
3. Select the "localhost" environment
4. Start the application with `docker-compose up --build`
5. Register/Login first, then use Bearer token for protected endpoints
## Available Tests
### Authentication (Public & Private)
- **Register User**: POST /api/auth/register - Create new account with role-based restrictions
- **Login User**: POST /api/auth/login - Authenticate (email or username)
### User Profile Management
- **Get Profile**: GET /api/auth/profile - Get current user info
- **Update Profile**: PUT /api/auth/profile - Update first_name, last_name
- **Update Email**: PUT /api/auth/email - Update email address
- **Update Username**: PUT /api/auth/username - Update username
- **Update Password**: PUT /api/auth/password - Update password
- **Update Theme**: PUT /api/auth/theme - Update theme preference
### Admin User Management
- **List Users**: GET /api/auth/users - Get all users with complete info (admin only)
- **Delete Account**: DELETE /api/auth/account - Delete own account or admin deletes other accounts with `user_id` parameter
- **Register Admin User**: POST /api/auth/register - Create admin account (requires existing admin authentication)
## Collection Organization
```
bruno/user/
├── auth/ # Authentication requests
│ ├── Login User.bru # POST /api/auth/login
│ └── Register User.bru # POST /api/auth/register (with restrictions)
├── admin/ # Admin-only management
│ ├── List Users.bru # GET /api/auth/users (admin only)
│ ├── Delete Account.bru # DELETE /api/auth/account (admin override)
│ └── Register Admin User.bru # POST /api/auth/register (admin creation)
└── profile/ # Profile management
├── Get Profile.bru # GET /api/auth/profile
├── Update Profile.bru # PUT /api/auth/profile
├── Update Email.bru # PUT /api/auth/email
├── Update Password.bru # PUT /api/auth/password
├── Update Theme.bru # PUT /api/auth/theme
└── Update Username.bru # PUT /api/auth/username
```
## Security Features
### Registration Restrictions
- **First User**: Automatically gets admin role regardless of request
- **Existing Admins**: Only authenticated admins can create new admin accounts
- **Regular Users**: Anyone can create regular user accounts
- **Unauthenticated**: Can only create first admin, not subsequent admins
### Admin Deletion
- **Self-Deletion**: Users can delete their own accounts
- **Admin Override**: Admins can delete any user account via `?user_id={uuid}` parameter
- **Last Admin Protection**: Cannot delete the last admin account in the system
### User Management (Protected)
- **Delete Account**: DELETE /api/auth/account - Delete own account (self) or admin deletes other accounts with `user_id` parameter (admin only)
### Folders (Admin Only)
- **Add Ebook Folder**: POST /api/auth/ebook-folders - Add folder for scanning (admin only)
- **Get Ebook Folders**: GET /api/auth/ebook-folders - List configured folders (admin only)
- **Delete Ebook Folder**: DELETE /api/auth/ebook-folders - Remove folder (admin only)
### Ebooks (Mixed Access)
- **List Ebooks**: GET /api/ebooks - Paginated ebook list (all authenticated users)
- **Get Ebook**: GET /api/ebooks/:id - Single ebook details (all authenticated users)
- **Create Ebook**: POST /api/ebooks - Add new ebook (admin only)
- **Update Ebook**: PUT /api/ebooks/:id - Modify ebook metadata (admin only)
- **Delete Ebook**: DELETE /api/ebooks/:id - Remove ebook (admin only)
### Scanner (Admin Only)
- **Scan Ebooks**: POST /api/scanner/scan - Scan configured folders (admin only)
- **Start Scanner**: POST /api/scanner/start - Start real-time monitoring (admin only)
- **Stop Scanner**: POST /api/scanner/stop - Stop monitoring (admin only)
### Reading Progress (All Users)
- **Get Reading Progress**: GET /api/ebooks/:id/progress - User's progress
- **Update Reading Progress**: PUT /api/ebooks/:id/progress - Update progress
### Ratings (All Users)
- **Get Ebook Rating**: GET /api/ebooks/:id/rating - User's rating for ebook (returns 0 if unrated)
- **Create/Update Rating**: POST /api/ebooks/:id/rating - Rate ebook (1-5 stars)
- **Delete Rating**: DELETE /api/ebooks/:id/rating - Remove user's rating
- **Get All Ratings**: GET /api/ebooks/:id/ratings - All ratings for ebook
## Documentation Features
Each request includes:
- **Detailed descriptions** of functionality
- **Parameter specifications** (required/optional, types)
- **Request/Response examples**
- **Error response codes** and meanings
- **Authentication requirements**
## Notes
- **Authentication Flow**: Register → Login → Use Bearer token for all other requests
- **JWT Tokens**: Valid for 24 hours, include in `Authorization: Bearer <token>` header
- **Role System**: Two roles - 'admin' and 'user'. Admins can manage folders and ebooks, users can view/rate/track progress
- **Shared Library**: All users can view the complete ebook collection, but only admins can modify it
- **User Isolation**: Progress, ratings, and profile data are user-specific
- **Rating Behavior**: Get rating returns 0 when no rating exists (instead of 404)
- **Admin Setup**: First admin must be created by updating user role in database: `UPDATE users SET role = 'admin' WHERE email = 'admin@example.com';`
- **Variables**: Update `ebook_id` for testing specific ebooks
- **Security**: Passwords hashed with bcrypt, unique email/username constraints, role-based access control
- **JSON**: All requests/responses use JSON format
+180
View File
@@ -5,3 +5,183 @@ auth {
auth:bearer {
token: {{token}}
}
docs {
# Bruno API Tests for Bookhoard
This directory contains Bruno collection for testing the Bookhoard API with comprehensive REST documentation.
Setup
1. Install Bruno: https://www.usebruno.com/
2. Open Bruno and import this collection folder
3. Select the "localhost" environment
4. Start the application with `podman-compose up --build` or `docker-compose up --build`
5. Register/Login first, then use Bearer token for protected endpoints
Available Tests
Authentication (Public & Private)
- **Register User**: POST /api/auth/register - Create new account with role-based restrictions
- **Login User**: POST /api/auth/login - Authenticate (email or username)
- **Refresh Token**: POST /api/auth/refresh - Get new access token
- **Logout**: POST /api/auth/logout - Invalidate refresh token
User Profile Management
- **Get Profile**: GET /api/auth/profile - Get current user info
- **Update Profile**: PUT /api/auth/profile - Update first_name, last_name
- **Update Email**: PUT /api/auth/email - Update email address
- **Update Username**: PUT /api/auth/username - Update username
- **Update Password**: PUT /api/auth/password - Update password
- **Update Theme**: PUT /api/auth/theme - Update theme preference
Admin User Management
- **List Users**: GET /api/auth/users - Get all users with complete info (admin only)
- **Delete Account**: DELETE /api/auth/account - Delete own account or admin deletes other accounts
Libraries (Admin Only)
- **Create Library**: POST /api/libraries - Create new library (Ebooks, Comics, Manga)
- **Get Libraries**: GET /api/libraries - List all libraries (admin)
- **Get Library**: GET /api/libraries/:id - Get library details
- **Update Library**: PUT /api/libraries/:id - Update library settings
- **Delete Library**: DELETE /api/libraries/:id - Remove library
- **Add Library Folder**: POST /api/libraries/:id/folders - Add scanning folder
- **Get Library Folders**: GET /api/libraries/:id/folders - List folders
- **Delete Library Folder**: DELETE /api/libraries/:id/folders/:folder_id - Remove folder
- **Get Library Stats**: GET /api/libraries/:id/stats - Library statistics
- **Get Library Types**: GET /api/libraries/types - Available library types
Media Items (Mixed Access)
- **List Media Items**: GET /api/media-items - Paginated list (filter/sort by library, author, series, etc.)
- **Get Media Item**: GET /api/media-items/:id - Single item details (all users)
- **Create Media Item**: POST /api/media-items - Add new item (admin only)
- **Update Media Item**: PUT /api/media-items/:id - Modify metadata (admin only)
- **Delete Media Item**: DELETE /api/media-items/:id - Remove item (admin only)
- **Filter Media Items**: POST /api/media-items/filter - Advanced filtering
- **EPUB Download**: GET /api/media-items/:id/download - Download EPUB file
- **Cover Image**: GET /api/media-items/:id/cover - Get cover image
Reading Progress (All Users)
- **Get Progress**: GET /api/progress/:media_id - User's reading progress for media item
- **Update Progress**: PUT /api/progress/:media_id - Update reading progress
- **Get Device Progress**: GET /api/progress/device/:device_id - Progress by device
Universal Progress (All Users)
- **Get Universal Progress**: GET /api/universal-progress/:sha256 - Get progress by book hash
- **Update Universal Progress**: PUT /api/universal-progress - Update universal progress
Notes (All Users)
- **Get Notes**: GET /api/notes/:media_id - Get notes for media item
- **Create Note**: POST /api/notes - Add new note
- **Update Note**: PUT /api/notes/:id - Update note content
- **Delete Note**: DELETE /api/notes/:id - Remove note
Highlights (All Users)
- **Get Highlights**: GET /api/highlights/:media_id - Get highlights for media item
- **Create Highlight**: POST /api/highlights - Add new highlight
- **Update Highlight**: PUT /api/highlights/:id - Update highlight
- **Delete Highlight**: DELETE /api/highlights/:id - Remove highlight
Ratings (All Users)
- **Get Rating**: GET /api/ratings/:media_id - User's rating (returns 0 if unrated)
- **Create/Update Rating**: POST /api/ratings - Rate media item (1-5 stars, half-star precision)
- **Delete Rating**: DELETE /api/ratings/:media_id - Remove rating
Collections (All Users)
- **List Collections**: GET /api/collections - Get user's collections
- **Get Collection**: GET /api/collections/:id - Collection details with media items
- **Create Collection**: POST /api/collections - Create new collection
- **Update Collection**: PUT /api/collections/:id - Update collection
- **Delete Collection**: DELETE /api/collections/:id - Remove collection
- **Add Auto-Assign Rule**: POST /api/collections/:id/rules - Add automatic rule
- **Remove Auto-Assign Rule**: DELETE /api/collections/:id/rules/:rule_id - Remove rule
- **Test Rule**: POST /api/collections/:id/rules/test - Preview rule matches
- **Bulk Assign**: POST /api/collections/:id/assign - Manually add media items
Device Management (All Users)
- **Register Device**: POST /api/devices/register - Register new device
- **List Devices**: GET /api/devices - Get user's devices
- **Get Device**: GET /api/devices/:id - Device details
- **Delete Device**: DELETE /api/devices/:id - Unregister device
- **Sync Device**: POST /api/devices/:id/sync - Trigger device sync
Sync Protocols (Device Integration)
- **KOReader Sync**: POST /api/sync/koreader - KOReader progress/notes/highlights sync
- **Kobo Sync**: POST /api/sync/kobo - Kobo progress/notes/highlights sync
Scanner (Admin Only)
- **Scan Libraries**: POST /api/scanner/scan - Scan library folders
- **Start Scanner**: POST /api/scanner/start - Start real-time monitoring
- **Stop Scanner**: POST /api/scanner/stop - Stop monitoring
- **Get Scan Settings**: GET /api/scanner/settings - Scan configuration
Analytics (Admin Only)
- **Get Analytics**: GET /api/analytics - Usage statistics and metrics
Book Matching (All Users)
- **Search Books**: GET /api/book-matching/search - Search by ISBN, title, author
- **Link Book**: POST /api/book-matching/link - Link media item to external database
OPDS (All Users)
- **OPDS Feeds**: GET /opds/* - OPDS catalog for e-reader integration
- **OPDS Acquisition**: GET /opds/acquisition/* - Download media items
WebSocket (Real-time)
- **WebSocket**: WS /api/ws - Real-time sync events (progress, notes, highlights)
Collection Organization
bruno/
├── user/ # User authentication and profile
│ ├── auth/ # Login, register, refresh
│ ├── profile/ # Profile management
│ └── admin/ # User administration (admin only)
├── library/ # Library management
│ ├── Create/Update/Delete Libraries
│ ├── Library Folders
│ ├── Library Stats
│ └── Scan Settings
├── media-items/ # Media item operations
│ ├── List/Get/Create/Update/Delete
│ ├── Filter and Sort
│ ├── Download EPUB
│ ├── Cover Images
│ └── Ratings
├── progress/ # Reading progress tracking
├── universal-progress/ # Cross-device universal progress
├── notes/ # User notes
├── highlights/ # Book highlights
├── collections/ # Smart collections
├── devices/ # Device registration
├── sync-koreader/ # KOReader sync protocol
├── sync-kobo/ # Kobo sync protocol
├── scanner/ # Library scanning
├── analytics/ # Usage statistics
├── books/ # Book matching/linking
├── kobo/ # Kobo-specific operations
├── koreader/ # KOReader-specific operations
├── opds/ # OPDS catalog feeds
└── admin/ # Admin operations
## Security Features
### Registration Restrictions
- **First User**: Automatically gets admin role regardless of request
- **Existing Admins**: Only authenticated admins can create new admin accounts
- **Regular Users**: Anyone can create regular user accounts
- **Unauthenticated**: Can only create first admin, not subsequent admins
### User Management
- **Self-Deletion**: Users can delete their own accounts
- **Admin Override**: Admins can delete any user account
- **Last Admin Protection**: Cannot delete the last admin account in the system
### Role System
- **Admin**: Full access - manage libraries, media items, users, scanner
- **User**: Read access - view media items, create collections, track progress, rate, annotate
### Device Authentication
- **No Passwords**: Devices use QR code registration and access tokens
- **User Approval**: Device registration requires user approval via web interface
### JWT Tokens
- **Access Token**: Valid for 1 hour, sent via Bearer header
- **Refresh Token**: Valid for 7 days, used to get new access tokens
### Rate Limiting
- **Auth Endpoints**: 10 requests/minute per IP
### Data Isolation
- **Progress, Notes, Highlights, Ratings**: User-specific
- **Collections**: User-specific (admins see all users' collections)
- **Devices**: User-specific
## Documentation Features
Each request includes:
- **Detailed descriptions** of functionality
- **Parameter specifications** (required/optional, types)
- **Request/Response examples**
- **Error response codes** and meanings
- **Authentication requirements**
## Notes
- **Authentication Flow**: Register → Login → Use Bearer token for all other requests
- **Media Items vs Books**: The API uses "media items" (supports ebooks, comics, manga)
- **Library System**: Organized by libraries (Ebooks, Comics, Manga) with scanning folders
- **Universal Progress**: Cross-device sync using SHA-256 book hashes
- **Smart Collections**: Auto-assign rules based on genre, author, series, tags, etc.
- **OPDS Support**: Wireless book delivery to e-readers (Kobo, KOReader)
- **Device Protocols**: Native sync for KOReader and Kobo devices
- **Rating System**: Half-star precision (1-10 scale internally, displayed as 1-5 stars)
- **Admin Setup**: First admin must be created by updating user role in database
- **Variables**: Update collection variables for testing (media_id, library_id, device_id, etc.)
- **Security**: Passwords hashed with bcrypt, unique email/username constraints, role-based access control
- **JSON**: All requests/responses use JSON format
- **WebSocket**: Real-time events for sync updates across devices
}
-380
View File
@@ -1,380 +0,0 @@
# KOReader Integration
## Overview
Bookhoard provides full Calibre-compatible wireless sync for KOReader devices, enabling seamless reading progress, highlights, and notes synchronization.
## Setup
### 1. Register Your Device
First, register your KOReader device with Bookhoard:
```bash
POST /api/devices/register
{
"device_name": "My Kindle Paperwhite",
"device_type": "koreader",
"device_identifier": "unique-hardware-id"
}
```
You'll receive:
- A registration URL to approve the device
- A QR code for easy setup
- Setup instructions for your device type
### 2. Approve Device
Visit the approval URL in your web browser (or scan the QR code) to authenticate the device.
### 3. Configure KOReader
In KOReader settings, set:
- **Calibre wireless URL**: `https://your-bookhoard-domain.com/api/sync/koreader`
- **Enable wireless sync**: ON
- **Sync frequency**: Every page turn (recommended)
### 4. Enter Device Token
After approval, you'll receive a device token. Add this to KOReader:
- Settings → Wireless sync → Password
- Paste the token: `dev_xxxxx...`
## API Endpoints
### Sync Progress
Updates reading progress for one or more books.
```bash
POST /api/sync/koreader/progress
Authorization: Bearer {device_token}
Content-Type: application/json
{
"books": [
{
"uuid": "book-uuid",
"title": "Book Title",
"authors": ["Author Name"],
"percentage": 0.45,
"progress": 0.45,
"chapter": 5,
"character": 15432,
"epubcfi": "epubcfi(/6/4/2:15)",
"page": 89,
"total_pages": 200,
"last_read": "2026-01-30T20:00:00Z"
}
],
"sync_mode": "immediate"
}
```
**Response** (202 Accepted):
```json
{
"sync_status": "accepted",
"books_synced": 1,
"conflicts": [],
"timestamp": "2026-01-30T20:00:00Z",
"device_updated": true
}
```
### Get Book Metadata
Fetches progress and annotations for a specific book.
```bash
GET /api/sync/koreader/metadata/{book_uuid}
Authorization: Bearer {device_token}
```
**Response** (200 OK):
```json
{
"uuid": "book-uuid",
"title": "Book Title",
"authors": ["Author Name"],
"progress": {
"percentage": 0.45,
"chapter": 5,
"epubcfi": "epubcfi(/6/4/2:15)",
"character": 15432,
"page": 89,
"total_pages": 200
},
"annotations": {
"highlights": [
{
"text": "highlighted text",
"pos0": "epubcfi(/6/4/2:15)",
"pos1": "epubcfi(/6/4/2:20)",
"color": "#ffff00",
"datetime": "2026-01-30T19:55:00Z"
}
],
"notes": [
{
"text": "My note",
"pos0": "epubcfi(/6/4/2:15)",
"datetime": "2026-01-30T19:55:00Z"
}
]
},
"last_sync": "2026-01-30T20:00:00Z"
}
```
### Get Library
Fetches all books available for sync.
```bash
GET /api/sync/koreader/library
Authorization: Bearer {device_token}
```
**Response** (200 OK):
```json
{
"library_sync": [
{
"uuid": "book-uuid",
"title": "Book Title",
"author": "Author Name",
"content_type": "6",
"percent_read": 45.0,
"pages_remaining": 115,
"bookmark_count": 3,
"last_modified": "2026-01-30T20:00:00Z"
}
],
"total_books": 10,
"last_sync": "2026-01-30T20:00:00Z"
}
```
### Sync Bookmarks/Notes/Highlights
Syncs annotations for a specific book.
```bash
POST /api/sync/koreader/bookmarks
Authorization: Bearer {device_token}
Content-Type: application/json
{
"book_uuid": "book-uuid",
"bookmarks": [
{
"chapter": 3,
"datetime": "2026-01-30T19:55:00Z",
"pos0": "epubcfi(/6/4/2:15)",
"page": 45,
"text": "Bookmarked text",
"type": "bookmark"
}
],
"highlights": [
{
"chapter": 3,
"datetime": "2026-01-30T19:55:00Z",
"pos0": "epubcfi(/6/4/2:15)",
"pos1": "epubcfi(/6/4/2:20)",
"page": 45,
"text": "highlighted text",
"color": "#ffff00"
}
],
"notes": [
{
"chapter": 3,
"datetime": "2026-01-30T19:55:00Z",
"pos0": "epubcfi(/6/4/2:15)",
"notes": "My note content",
"page": 45
}
]
}
```
**Response** (200 OK):
```json
{
"sync_status": "completed",
"bookmarks_synced": 1,
"notes_synced": 1,
"highlights_synced": 1,
"total_synced": 3,
"timestamp": "2026-01-30T20:00:00Z"
}
```
## Sync Modes
### Immediate Mode (Recommended)
Syncs on every page turn for real-time updates across all devices.
```json
{ "sync_mode": "immediate" }
```
### Checkpoint Mode
Syncs periodically to save bandwidth.
```json
{
"sync_mode": "checkpoint",
"checkpoint_id": "checkpoint-uuid",
"since_timestamp": "2026-01-30T19:00:00Z"
}
```
## Rate Limits
- **Sync requests**: 60/minute
- **Progress updates**: 120/minute
- **Metadata requests**: 30/minute
## Device Matching
Bookhoard tries multiple strategies to match books:
1. **By UUID**: Most reliable if your book files have unique IDs (confidence: 1.0)
2. **By SHA-256**: Hash-based matching for reliable identification (confidence: 0.9)
3. **By file path**: Matches exact file path and creates device alias (confidence: 0.7)
4. **By title + author**: Fallback for unmatched books (confidence: 0.5)
5. **By title only**: Last resort match (confidence: 0.4)
### SHA-256 Matching (Phase 7 Enhancement)
Bookhoard now supports SHA-256 hash matching for reliable book identification:
```json
{
"books": [
{
"sha256": "a1b2c3d4e5f6...",
"file_path": "/mnt/onboard/Book.epub",
"percentage": 0.65,
"page": 142,
"total_pages": 310
}
]
}
```
**Benefits**:
- Works even if file path changes
- Reliable across device re-formats
- Automatic device file alias creation
- Per-annotation SHA-256 support for mixed-book syncs
### Device File Alias System
When a book is matched with a file path, Bookhoard automatically creates a device file alias:
- **UUID + FilePath**: Creates alias with confidence 1.0
- **SHA-256 + FilePath**: Creates alias with confidence 0.9
- **FilePath only**: Creates alias with confidence 0.7
- **Title match + FilePath**: Creates alias with confidence 0.5-0.7
Once created, aliases enable future syncs without UUID or SHA-256:
```json
{
"books": [
{
"file_path": "/mnt/onboard/Book.epub",
"percentage": 0.70
}
]
}
```
### Per-Annotation SHA-256
Sync bookmarks/notes/highlights for multiple books in one request:
```json
{
"highlights": [
{
"text": "Quote from book 1",
"pos0": "/6/4[chap1]!/4/2/1:0",
"pos1": "/6/4[chap1]!/4/2/1:50",
"color": "#ffff00",
"book_sha256": "abc123..."
},
{
"text": "Quote from book 2",
"pos0": "/6/4[chap1]!/4/2/1:0",
"pos1": "/6/4[chap1]!/4/2/1:50",
"color": "#00ff00",
"book_sha256": "def456..."
}
]
}
```
## Conflict Resolution
When the same book is read on multiple devices within 5 minutes:
- Auto-resolution uses "most recent progress wins"
- Conflicts are logged for review
- Users can manually resolve conflicts via the web UI
## Troubleshooting
### Sync Not Working
1. **Check device token**: Ensure token is valid and not revoked
2. **Verify sync enabled**: Device must have `sync_enabled: true`
3. **Check rate limits**: Device may be rate-limited
4. **Book matching**: Ensure books can be matched by UUID, path, or title
### Progress Not Updating
1. **Verify percentage value**: Must be between 0.0 and 1.0
2. **Check book ownership**: User must have access to the book
3. **Review sync logs**: Check for error messages
### Authentication Errors
1. **Token expired**: Re-register device
2. **Device revoked**: Check device status in web UI
3. **Invalid token format**: Ensure `Bearer dev_xxxxx...` format
## Testing
Use the Bruno API collection in `/bruno/koreader/` to test endpoints:
- `Sync Progress.bru` - Test progress sync
- `Get Book Metadata.bru` - Test metadata retrieval
- `Get Library.bru` - Test library sync
- `Sync Bookmarks.bru` - Test annotation sync
Required variables:
- `baseUrl` - Your Bookhoard server URL
- `device_token` - Device authentication token
- `book_uuid` - UUID of a test book
## Implementation Notes
- Compatible with Calibre wireless protocol
- Supports EPUB CFI for precise locations
- Handles reflowable and fixed-layout formats
- Bidirectional sync (KOReader ↔ Bookhoard)
- Real-time updates via WebSocket (coming in Phase 3b)
## Next Steps
See Phase 3 implementation guide for:
- WebSocket real-time sync
- Advanced conflict resolution
- Offline sync queue management
- Performance optimization
-243
View File
@@ -1,243 +0,0 @@
# Phase 8: Sidecar Configuration System - API Documentation
## Overview
This document describes the sidecar configuration system that enables easy device setup for Kobo and KOReader devices.
## What is a Sidecar File?
A sidecar file (`.bookhoard.json`) is a configuration file that contains all the information a device needs to connect to Bookhoard, including:
- OPDS catalog URL for wireless book browsing
- Sync API endpoints for progress sync
- Book inventory with SHA-256 hashes
- Collection metadata with shelf mappings
## Authentication
All endpoints require authentication:
- User endpoints: Use user JWT token (Authorization: Bearer {{user_token}})
- Admin endpoints: Use admin JWT token (Authorization: Bearer {{admin_token}})
## Endpoints
### 1. Get Device Sidecar Config
**Endpoint**: `GET /api/devices/:device_id/sidecar`
**Description**: Returns sidecar configuration for a device as JSON.
**Request Headers**:
```
Authorization: Bearer {{user_token}}
```
**Response** (200 OK):
```json
{
"version": "1.0",
"bookhoard": {
"opds_catalog": "http://192.168.1.100:8765/opds/devices/kobo-id/catalog",
"sync_api": "http://192.168.1.100:8765/api/sync/kobo",
"opds_base_url": "http://192.168.1.100:8765/opds",
"api_base_url": "http://192.168.1.100:8765/api",
"device_id": "kobo-device-uuid",
"device_token": "dev_xxxxx..."
},
"books": {
"sha256:abc123...": {
"bookhoard_uuid": "uuid-123",
"title": "The Hobbit",
"author": "J.R.R. Tolkien",
"available_formats": ["epub", "kepub"],
"sha256": "abc123...",
"file_path": "/path/to/book.epub"
}
},
"collections": [
{
"name": "Sci-Fi",
"shelf_mapping": "Science Fiction",
"book_ids": ["uuid-1", "uuid-2", "uuid-3"]
}
],
"opds_enabled": true,
"sidecar_enabled": true,
"last_updated": "2026-01-31T12:00:00Z"
}
```
### 2. Download Device Sidecar File
**Endpoint**: `GET /api/devices/:device_id/sidecar/download`
**Description**: Downloads a `.bookhoard.json` configuration file for device setup.
**Request Headers**:
```
Authorization: Bearer {{user_token}}
```
**Response** (200 OK):
```
Content-Type: application/json
Content-Disposition: attachment; filename="MyKoboClara.bookhoard.json"
```
File contains formatted JSON (pretty-printed) suitable for:
- Manual device configuration
- Backup and restore
- Transfer via USB
### 3. Get System Configuration
**Endpoint**: `GET /api/system/config`
**Description**: Returns system-wide configuration settings (admin only).
**Request Headers**:
```
Authorization: Bearer {{admin_token}}
```
**Response** (200 OK):
```json
{
"base_url": "https://bookhoard.example.com",
"opds_base_url": "https://bookhoard.example.com/opds",
"api_base_url": "https://bookhoard.example.com/api"
}
```
### 4. Update System Configuration
**Endpoint**: `PUT /api/system/config`
**Description**: Updates system-wide configuration settings (admin only).
**Request Headers**:
```
Authorization: Bearer {{admin_token}}
Content-Type: application/json
```
**Request Body**:
```json
{
"base_url": "https://bookhoard.example.com",
"opds_base_url": "https://bookhoard.example.com/opds",
"api_base_url": "https://bookhoard.example.com/api"
}
```
**Response** (200 OK):
```json
{
"status": "success",
"message": "System configuration updated"
}
```
## Sidecar File Format
### Version
Always "1.0" - enables future format changes
### Bookhoard Section
Contains device connection information:
- **opds_catalog**: Full URL to device's OPDS catalog
- **sync_api**: Sync API endpoint
- **opds_base_url**: Base URL for all OPDS operations
- **api_base_url**: Base URL for all API operations
- **device_id**: Device's unique identifier
- **device_token**: Device authentication token
### Books Section
Map of book identifiers to book metadata:
- **Key**: SHA-256 hash (preferred) or Bookhoard UUID
- **bookhoard_uuid**: Canonical Bookhoard UUID
- **title**: Book title
- **author**: Book author
- **available_formats**: Array of formats ("epub", "kepub")
- **sha256**: SHA-256 hash of book file
- **file_path**: Original file path
### Collections Section
Array of collection definitions:
- **name**: Collection name in Bookhoard
- **shelf_mapping**: Device-specific shelf name (e.g., "Science Fiction")
- **book_ids**: Array of Bookhoard UUIDs in collection
## Device Setup Workflow
### Kobo E-Reader
1. **Download Configuration**
- Log into Bookhoard web UI
- Navigate to Device Management
- Click "Download Configuration" for your Kobo device
- File saves as `MyKoboClara.bookhoard.json`
2. **Manual Configuration** (if needed)
- Copy `.bookhoard.json` to Kobo device
- Kobo can import configuration automatically
3. **OPDS Setup** (Recommended)
- Use `opds_catalog` URL from sidecar
- Add as new content catalog in Kobo settings
- Browse and download books wirelessly
### KOReader
1. **Download Configuration**
- Same process as Kobo above
2. **Configure Wireless Sync**
- In KOReader, set Calibre wireless URL to `sync_api` from sidecar
- Enable password and use `device_token`
- Set sync frequency to desired interval
## Environment Variables
Set these in your Bruno collection:
```json
{
"base_url": "http://localhost:8765/api",
"user_token": "your-user-jwt-token",
"admin_token": "your-admin-jwt-token",
"device_id": "uuid-of-device"
}
```
## Error Codes
- `200`: Success
- `400`: Bad Request (invalid device ID, invalid JSON)
- `401`: Unauthorized (missing or invalid token)
- `403`: Forbidden (admin access required)
- `404`: Not Found (device not found)
- `500`: Internal Server Error (database error, generation failure)
## Benefits
1. **Easy Setup**: One file contains all configuration
2. **No Manual Entry**: URLs and tokens pre-populated
3. **SHA-256 Matching**: Reliable book identification
4. **Collection Sync**: Shelf mappings included
5. **Backup/Restore**: Save and transfer device configs
6. **Offline Configuration**: Configure devices without network access initially
## Testing Scenarios
### Scenario 1: New Kobo Device
1. Register Kobo device in Bookhoard
2. Download sidecar configuration
3. Add OPDS catalog URL from sidecar to Kobo
4. Browse and download books wirelessly
5. Progress syncs automatically
### Scenario 2: Device Re-configuration
1. Download current sidecar file
2. Update system configuration if needed
3. Re-download sidecar with new settings
4. Re-configure device with updated file
### Scenario 3: Collection Management
1. Create collections in Bookhoard
2. Set up device-specific shelf mappings
3. Sidecar automatically includes collection info
4. Device shelves reflect collection structure