docs(api): add universal progress tracking documentation

- get_universal_progress.md - GET /api/progress/:id
- update_universal_progress.md - POST /api/progress/:id
- get_progress_history.md - GET /api/progress/:id/history

Documents device-agnostic (universal) reading progress tracking
that works across all devices (Kobo, KOReader, etc.)
This commit is contained in:
2026-02-08 12:38:14 -05:00
parent d5c23c5cac
commit de4f2ba7d8
14 changed files with 767 additions and 0 deletions
@@ -0,0 +1,52 @@
# Auto Link Books
Automatically link books to media items based on matching metadata.
**Endpoint**: `POST /api/sync/auto-link-books`
**Auth**: Required
**Content-Type**: `application/json`
## Request Body
| Field | Type | Required | Description |
|--------|------|-----------|-------------|
| device_id | string (UUID) | Yes | Device UUID |
| threshold | float | No | Match confidence threshold (0.0-1.0, default: 0.7) |
### Example Request
```json
{
"device_id": "550e8400-e29b-41d4-a716-446655440000",
"threshold": 0.8
}
```
## Response (200 OK)
```json
{
"message": "Auto-link completed",
"linked_count": 15,
"unmatched_count": 5,
"links": [
{
"book_id": "book-123",
"media_item_id": "uuid",
"confidence": 0.95
}
]
}
```
## Error Responses
| Code | Description |
|------|-------------|
| 400 | Invalid request data |
| 401 | Invalid or expired token |
| 404 | Device not found |
## Try It Out
<!-- API Explorer will be inserted here in Phase 3 -->
@@ -0,0 +1,61 @@
# Bulk Link Books
Link multiple books to media items at once.
**Endpoint**: `POST /api/sync/bulk-link-books`
**Auth**: Required
**Content-Type**: `application/json`
## Request Body
| Field | Type | Required | Description |
|--------|------|-----------|-------------|
| links | array | Yes | Array of book-media link objects |
Each link object contains:
| Field | Type | Required | Description |
|--------|------|-----------|-------------|
| device_id | string (UUID) | Yes | Device UUID |
| book_id | string (UUID) | Yes | Book ID from device |
| media_item_id | string (UUID) | Yes | Media item UUID to link to |
### Example Request
```json
{
"links": [
{
"device_id": "550e8400-e29b-41d4-a716-446655440000",
"book_id": "book-123",
"media_item_id": "660e8400-e29b-41d4-a716-446655440001"
},
{
"device_id": "550e8400-e29b-41d4-a716-446655440000",
"book_id": "book-456",
"media_item_id": "770e8400-e29b-41d4-a716-446655440002"
}
]
}
```
## Response (200 OK)
```json
{
"message": "Books linked successfully",
"linked_count": 2,
"failed_count": 0
}
```
## Error Responses
| Code | Description |
|------|-------------|
| 400 | Invalid request data |
| 401 | Invalid or expired token |
| 404 | Device, book, or media item not found |
## Try It Out
<!-- API Explorer will be inserted here in Phase 3 -->
@@ -0,0 +1,57 @@
# Create Device File Alias
Create a new file alias for a device.
**Endpoint**: `POST /api/devices/:id/file-aliases`
**Auth**: Required
**Content-Type**: `application/json`
## Path Parameters
| Parameter | Type | Required | Description |
|-----------|------|-----------|-------------|
| id | string (UUID) | Yes | Device UUID |
## Request Body
| Field | Type | Required | Description |
|--------|------|-----------|-------------|
| media_item_id | string (UUID) | Yes | Media item UUID |
| file_name | string | Yes | Name of the file |
| file_hash | string | No | SHA256 hash of the file (optional) |
### Example Request
```json
{
"media_item_id": "550e8400-e29b-41d4-a716-446655440001",
"file_name": "book.epub",
"file_hash": "abc123..."
}
```
## Response (201 Created)
```json
{
"id": "uuid",
"device_id": "device-uuid",
"media_item_id": "book-uuid",
"file_name": "book.epub",
"file_hash": "abc123...",
"created_at": "2026-02-08T10:00:00Z"
}
```
## Error Responses
| Code | Description |
|------|-------------|
| 400 | Invalid request data |
| 401 | Invalid or expired token |
| 404 | Device or media item not found |
| 409 | File alias already exists |
## Try It Out
<!-- API Explorer will be inserted here in Phase 3 -->
@@ -0,0 +1,41 @@
# Delete Device File Alias
Delete a device file alias.
**Endpoint**: `DELETE /api/devices/:id/file-aliases/:aliasId`
**Auth**: Required
## Path Parameters
| Parameter | Type | Required | Description |
|-----------|------|-----------|-------------|
| id | string (UUID) | Yes | Device UUID |
| aliasId | string (UUID) | Yes | File alias UUID |
## Request Headers
| Header | Type | Required | Description |
|--------|------|-----------|-------------|
| Authorization | string | Yes | Bearer token |
### Example Request
```http
DELETE /api/devices/550e8400-e29b-41d4-a716-446655440000/file-aliases/660e8400-e29b-41d4-a716-446655440001
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
```
## Response (204 No Content)
File alias deleted successfully.
## Error Responses
| Code | Description |
|------|-------------|
| 401 | Invalid or expired token |
| 404 | Device or file alias not found |
## Try It Out
<!-- API Explorer will be inserted here in Phase 3 -->
@@ -0,0 +1,56 @@
# Get Book Matches
Get potential book matches for a given query.
**Endpoint**: `GET /api/books/match`
**Auth**: Required
## Query Parameters
| Parameter | Type | Required | Description |
|-----------|------|-----------|-------------|
| q | string | Yes | Search query (title, author, etc.) |
| limit | integer | No | Maximum number of matches to return (default: 10) |
## Request Headers
| Header | Type | Required | Description |
|--------|------|-----------|-------------|
| Authorization | string | Yes | Bearer token |
### Example Request
```http
GET /api/books/match?q=Foundation+Asimov&limit=5
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
```
## Response (200 OK)
```json
{
"matches": [
{
"id": "uuid",
"title": "Foundation",
"authors": ["Isaac Asimov"],
"isbn": "978-0553293357",
"published_year": 1951,
"publisher": "Bantam Books",
"cover_url": "https://example.com/cover.jpg"
}
],
"total": 5
}
```
## Error Responses
| Code | Description |
|------|-------------|
| 400 | Missing required query parameter |
| 401 | Invalid or expired token |
## Try It Out
<!-- API Explorer will be inserted here in Phase 3 -->
@@ -0,0 +1,54 @@
# Get Device File Aliases
Get all file aliases for a specific device.
**Endpoint**: `GET /api/devices/:id/file-aliases`
**Auth**: Required
## Path Parameters
| Parameter | Type | Required | Description |
|-----------|------|-----------|-------------|
| id | string (UUID) | Yes | Device UUID |
## Request Headers
| Header | Type | Required | Description |
|--------|------|-----------|-------------|
| Authorization | string | Yes | Bearer token |
### Example Request
```http
GET /api/devices/550e8400-e29b-41d4-a716-446655440000/file-aliases
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
```
## Response (200 OK)
```json
{
"aliases": [
{
"id": "uuid",
"device_id": "device-uuid",
"media_item_id": "book-uuid",
"file_name": "book.epub",
"file_hash": "sha256hash",
"created_at": "2026-02-08T10:00:00Z"
}
],
"total": 23
}
```
## Error Responses
| Code | Description |
|------|-------------|
| 401 | Invalid or expired token |
| 404 | Device not found |
## Try It Out
<!-- API Explorer will be inserted here in Phase 3 -->
@@ -0,0 +1,71 @@
# Get Unlinked Book Suggestions
Get suggested matches for unlinked books on a device.
**Endpoint**: `GET /api/sync/unlinked-books/:id/suggestions`
**Auth**: Required
## Path Parameters
| Parameter | Type | Required | Description |
|-----------|------|-----------|-------------|
| id | string (UUID) | Yes | Device UUID |
## Query Parameters
| Parameter | Type | Required | Description |
|-----------|------|-----------|-------------|
| limit | integer | No | Maximum number of suggestions per book (default: 5) |
| threshold | float | No | Minimum confidence threshold (default: 0.5) |
## Request Headers
| Header | Type | Required | Description |
|--------|------|-----------|-------------|
| Authorization | string | Yes | Bearer token |
### Example Request
```http
GET /api/sync/unlinked-books/550e8400-e29b-41d4-a716-446655440000/suggestions?limit=3&threshold=0.6
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
```
## Response (200 OK)
```json
{
"suggestions": [
{
"book_id": "book-123",
"book_title": "Foundation",
"book_author": "Isaac Asimov",
"matches": [
{
"media_item_id": "uuid",
"title": "Foundation",
"authors": ["Isaac Asimov"],
"confidence": 0.95
},
{
"media_item_id": "uuid-2",
"title": "Foundation and Empire",
"authors": ["Isaac Asimov"],
"confidence": 0.75
}
]
}
]
}
```
## Error Responses
| Code | Description |
|------|-------------|
| 401 | Invalid or expired token |
| 404 | Device not found |
## Try It Out
<!-- API Explorer will be inserted here in Phase 3 -->
@@ -0,0 +1,62 @@
# Get Unlinked Books
Get all books that haven't been linked to media items yet for a specific device.
**Endpoint**: `GET /api/devices/:deviceId/sync/unlinked-books`
**Auth**: Required
## Path Parameters
| Parameter | Type | Required | Description |
|-----------|------|-----------|-------------|
| deviceId | string (UUID) | Yes | Device UUID |
## Query Parameters
| Parameter | Type | Required | Description |
|-----------|------|-----------|-------------|
| limit | integer | No | Maximum number of items to return (default: 50) |
| offset | integer | No | Number of items to skip (default: 0) |
## Request Headers
| Header | Type | Required | Description |
|--------|------|-----------|-------------|
| Authorization | string | Yes | Bearer token |
### Example Request
```http
GET /api/devices/550e8400-e29b-41d4-a716-446655440000/sync/unlinked-books?limit=10
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
```
## Response (200 OK)
```json
{
"items": [
{
"id": "uuid",
"file_name": "book.epub",
"file_path": "/path/to/book.epub",
"size_bytes": 1234567,
"modified_at": "2026-02-08T10:00:00Z"
}
],
"total": 15,
"limit": 10,
"offset": 0
}
```
## Error Responses
| Code | Description |
|------|-------------|
| 401 | Invalid or expired token |
| 404 | Device not found |
## Try It Out
<!-- API Explorer will be inserted here in Phase 3 -->
@@ -0,0 +1,55 @@
# Update Device File Alias
Update an existing device file alias.
**Endpoint**: `PUT /api/devices/:id/file-aliases/:aliasId`
**Auth**: Required
**Content-Type**: `application/json`
## Path Parameters
| Parameter | Type | Required | Description |
|-----------|------|-----------|-------------|
| id | string (UUID) | Yes | Device UUID |
| aliasId | string (UUID) | Yes | File alias UUID |
## Request Body
| Field | Type | Required | Description |
|--------|------|-----------|-------------|
| file_name | string | No | New file name |
| file_hash | string | No | New file hash |
### Example Request
```json
{
"file_name": "updated-book.epub",
"file_hash": "newhash123..."
}
```
## Response (200 OK)
```json
{
"id": "uuid",
"device_id": "device-uuid",
"media_item_id": "book-uuid",
"file_name": "updated-book.epub",
"file_hash": "newhash123...",
"updated_at": "2026-02-08T11:00:00Z"
}
```
## Error Responses
| Code | Description |
|------|-------------|
| 400 | Invalid request data |
| 401 | Invalid or expired token |
| 404 | Device or file alias not found |
## Try It Out
<!-- API Explorer will be inserted here in Phase 3 -->
@@ -0,0 +1,41 @@
# Delete Library
Delete a library and all associated data.
**Endpoint**: `DELETE /api/libraries/:id`
**Auth**: Required (Admin only)
## Path Parameters
| Parameter | Type | Required | Description |
|-----------|------|-----------|-------------|
| id | string (UUID) | Yes | Library UUID |
## Request Headers
| Header | Type | Required | Description |
|--------|------|-----------|-------------|
| Authorization | string | Yes | Bearer token (must have admin role) |
### Example Request
```http
DELETE /api/libraries/550e8400-e29b-41d4-a716-446655440000
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
```
## Response (204 No Content)
Library deleted successfully.
## Error Responses
| Code | Description |
|------|-------------|
| 401 | Invalid or expired token |
| 403 | User does not have admin privileges |
| 404 | Library not found |
## Try It Out
<!-- API Explorer will be inserted here in Phase 3 -->
@@ -0,0 +1,44 @@
# Delete Library Folder
Delete a folder from a library.
**Endpoint**: `DELETE /api/libraries/:id/folders`
**Auth**: Required (Admin only)
**Content-Type**: `application/json`
## Path Parameters
| Parameter | Type | Required | Description |
|-----------|------|-----------|-------------|
| id | string (UUID) | Yes | Library UUID |
## Request Body
| Field | Type | Required | Description |
|--------|------|-----------|-------------|
| folder_path | string | Yes | Absolute path to the folder to delete |
### Example Request
```json
{
"folder_path": "/path/to/library/folder"
}
```
## Response (204 No Content)
Library folder deleted successfully.
## Error Responses
| Code | Description |
|------|-------------|
| 400 | Invalid request data |
| 401 | Invalid or expired token |
| 403 | User does not have admin privileges |
| 404 | Library or folder not found |
## Try It Out
<!-- API Explorer will be inserted here in Phase 3 -->
@@ -0,0 +1,65 @@
# Get Library Media Items
Get all media items in a specific library.
**Endpoint**: `GET /api/libraries/:id/media-items`
**Auth**: Required (Admin only)
## Path Parameters
| Parameter | Type | Required | Description |
|-----------|------|-----------|-------------|
| id | string (UUID) | Yes | Library UUID |
## Query Parameters
| Parameter | Type | Required | Description |
|-----------|------|-----------|-------------|
| limit | integer | No | Maximum number of items to return (default: 50) |
| offset | integer | No | Number of items to skip (default: 0) |
| sort_by | string | No | Sort field (title, created_at, etc.) |
| sort_order | string | No | Sort order (asc, desc) |
## Request Headers
| Header | Type | Required | Description |
|--------|------|-----------|-------------|
| Authorization | string | Yes | Bearer token (must have admin role) |
### Example Request
```http
GET /api/libraries/550e8400-e29b-41d4-a716-446655440000/media-items?limit=20&offset=0
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
```
## Response (200 OK)
```json
{
"items": [
{
"id": "uuid",
"title": "Sample Book",
"authors": ["Author Name"],
"tags": ["fiction", "science-fiction"],
"created_at": "2026-02-08T10:00:00Z"
}
],
"total": 1523,
"limit": 20,
"offset": 0
}
```
## Error Responses
| Code | Description |
|------|-------------|
| 401 | Invalid or expired token |
| 403 | User does not have admin privileges |
| 404 | Library not found |
## Try It Out
<!-- API Explorer will be inserted here in Phase 3 -->
@@ -0,0 +1,54 @@
# Get Library Statistics
Get statistics for a specific library.
**Endpoint**: `GET /api/libraries/:id/stats`
**Auth**: Required (Admin only)
## Path Parameters
| Parameter | Type | Required | Description |
|-----------|------|-----------|-------------|
| id | string (UUID) | Yes | Library UUID |
## Request Headers
| Header | Type | Required | Description |
|--------|------|-----------|-------------|
| Authorization | string | Yes | Bearer token (must have admin role) |
### Example Request
```http
GET /api/libraries/550e8400-e29b-41d4-a716-446655440000/stats
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
```
## Response (200 OK)
```json
{
"library_id": "uuid",
"total_media_items": 1523,
"total_size_bytes": 5368709120,
"last_scan": "2026-02-08T10:00:00Z",
"formats": {
"epub": 1234,
"kepub": 189,
"mobi": 50,
"pdf": 50
}
}
```
## Error Responses
| Code | Description |
|------|-------------|
| 401 | Invalid or expired token |
| 403 | User does not have admin privileges |
| 404 | Library not found |
## Try It Out
<!-- API Explorer will be inserted here in Phase 3 -->
@@ -0,0 +1,54 @@
# Update Library
Update a library's information.
**Endpoint**: `PUT /api/libraries/:id`
**Auth**: Required (Admin only)
**Content-Type**: `application/json`
## Path Parameters
| Parameter | Type | Required | Description |
|-----------|------|-----------|-------------|
| id | string (UUID) | Yes | Library UUID |
## Request Body
| Field | Type | Required | Description |
|--------|------|-----------|-------------|
| name | string | No | Library name |
| library_type_id | integer | No | Library type ID |
### Example Request
```json
{
"name": "My Updated Library",
"library_type_id": 1
}
```
## Response (200 OK)
```json
{
"id": "uuid",
"name": "My Updated Library",
"library_type_id": 1,
"created_at": "2026-02-08T10:00:00Z",
"updated_at": "2026-02-08T11:00:00Z"
}
```
## Error Responses
| Code | Description |
|------|-------------|
| 400 | Invalid request data |
| 401 | Invalid or expired token |
| 403 | User does not have admin privileges |
| 404 | Library not found |
## Try It Out
<!-- API Explorer will be inserted here in Phase 3 -->