docs: add collections API endpoint files (Phase 2 completion)

This commit is contained in:
2026-02-02 15:54:59 -05:00
parent a3a3d4ed40
commit ec74650c18
11 changed files with 636 additions and 0 deletions
@@ -0,0 +1,85 @@
# Add Auto-Assign Rule
Add an automatic book assignment rule to a collection.
**Endpoint**: `POST /api/collections/{id}/rules`
**Auth**: Required
**Content-Type**: `application/json`
## Path Parameters
| Parameter | Type | Required | Description |
|-----------|------|-----------|-------------|
| id | string (UUID) | Yes | Collection UUID |
## Request Body
| Field | Type | Required | Description |
|--------|------|-----------|-------------|
| field | string | Yes | Field to match on (genre, author, series, language, publisher, copyright_year, tags) |
| operator | string | Yes | Comparison operator (equals, not_equals, contains, not_contains, starts_with, ends_with, greater_than, less_than) |
| value | string/number | Yes | Value to compare against |
| priority | integer | No | Rule priority (1 = highest, default: 1) |
| enabled | boolean | No | Whether rule is active (default: true) |
### Supported Fields
| Field | Type | Description |
|-------|------|-------------|
| genre | string | Book genre |
| author | string | Book author |
| series | string | Book series name |
| language | string | Book language |
| publisher | string | Publisher name |
| copyright_year | number | Publication year (numeric comparison) |
| tags | string | Book tags |
### Supported Operators
| Operator | Type | Description |
|----------|------|-------------|
| equals | all | Exact match |
| not_equals | all | Not equal |
| contains | string | Contains substring (case-insensitive) |
| not_contains | string | Does not contain |
| starts_with | string | Starts with (case-insensitive) |
| ends_with | string | Ends with (case-insensitive) |
| greater_than | number | Greater than |
| less_than | number | Less than |
### Example Request
```json
{
"field": "genre",
"operator": "equals",
"value": "Science Fiction",
"priority": 1,
"enabled": true
}
```
## Response (201 Created)
```json
{
"id": "rule-uuid-here",
"field": "genre",
"operator": "equals",
"value": "Science Fiction",
"priority": 1,
"enabled": true,
"created_at": "2026-02-01T10:00:00Z"
}
```
## Error Responses
| Code | Description |
|------|-------------|
| 400 | Invalid request (validation failed) |
| 401 | Authentication required |
| 404 | Collection not found |
| 500 | Internal server error |
## Try It Out
+52
View File
@@ -0,0 +1,52 @@
# Bulk Assign Books
Add multiple books to a collection at once.
**Endpoint**: `POST /api/collections/{id}/books`
**Auth**: Required
**Content-Type**: `application/json`
## Path Parameters
| Parameter | Type | Required | Description |
|-----------|------|-----------|-------------|
| id | string (UUID) | Yes | Collection UUID |
## Request Body
| Field | Type | Required | Description |
|--------|------|-----------|-------------|
| book_ids | array of UUID | Yes | Array of book IDs to add |
### Example Request
```json
{
"book_ids": [
"660e8400-e29b-41d4-a716-446655440000",
"770e8400-e29b-41d4-a716-446655440000",
"880e8400-e29b-41d4-a716-446655440000"
]
}
```
## Response (204 No Content)
Books added to collection successfully. No response body.
## Notes
- Books already in the collection are ignored
- This is more efficient than adding books individually
- Maximum 1000 books per request
## Error Responses
| Code | Description |
|------|-------------|
| 400 | Invalid request (validation failed) |
| 401 | Authentication required |
| 404 | Collection or book(s) not found |
| 500 | Internal server error |
## Try It Out
+96
View File
@@ -0,0 +1,96 @@
# Create Collection
Create a new collection.
**Endpoint**: `POST /api/collections`
**Auth**: Required
**Content-Type**: `application/json`
## Request Body
| Field | Type | Required | Description |
|--------|------|-----------|-------------|
| name | string | Yes | Collection name (max 255 chars) |
| description | string | No | Collection description |
| color | string | No | Hex color code (e.g., "#FF5733") |
| icon | string | No | Emoji icon (e.g., "🚀", "📖") |
| auto_assign_rules | array | No | Array of rule objects |
| view_settings | object | No | Per-device display preferences |
### Auto-Assign Rule Object
| Field | Type | Required | Description |
|--------|------|-----------|-------------|
| field | string | Yes | Field to match on (genre, author, series, language, publisher, copyright_year, tags) |
| operator | string | Yes | Comparison operator (equals, not_equals, contains, not_contains, starts_with, ends_with, greater_than, less_than) |
| value | string/number | Yes | Value to compare against |
| priority | integer | No | Rule priority (1 = highest, default: 1) |
| enabled | boolean | No | Whether rule is active (default: true) |
### Example Request
```json
{
"name": "To Read",
"description": "Books I want to read soon",
"color": "#00FF00",
"icon": "📖",
"auto_assign_rules": [
{
"field": "tags",
"operator": "contains",
"value": "to-read",
"priority": 1,
"enabled": true
}
],
"view_settings": {
"kobo": {
"view_mode": "grid"
},
"koreader": {
"view_mode": "list"
}
}
}
```
## Response (201 Created)
```json
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "To Read",
"description": "Books I want to read soon",
"color": "#00FF00",
"icon": "📖",
"auto_assign_rules": [
{
"field": "tags",
"operator": "contains",
"value": "to-read",
"priority": 1,
"enabled": true
}
],
"view_settings": {
"kobo": {
"view_mode": "grid"
},
"koreader": {
"view_mode": "list"
}
},
"created_at": "2026-02-01T10:00:00Z"
}
```
## Error Responses
| Code | Description |
|------|-------------|
| 400 | Invalid request (validation failed) |
| 401 | Authentication required |
| 500 | Internal server error |
## Try It Out
@@ -0,0 +1,69 @@
# Create Shelf Mapping
Map a collection to a device shelf for syncing.
**Endpoint**: `POST /api/devices/{deviceId}/collections`
**Auth**: Required
**Content-Type**: `application/json`
## Path Parameters
| Parameter | Type | Required | Description |
|-----------|------|-----------|-------------|
| deviceId | string (UUID) | Yes | Device UUID |
## Request Body
| Field | Type | Required | Description |
|--------|------|-----------|-------------|
| collection_id | string (UUID) | Yes | Collection UUID to map |
| device_shelf_name | string | Yes | Name of the shelf on the device |
| sync_direction | string | No | Sync direction (default: "bidirectional") |
### Sync Directions
| Direction | Description |
|-----------|-------------|
| bidirectional | Sync both ways between Bookhoard and device |
| book_to_hoard | Bookhoard → Device only |
| device_to_hoard | Device → Bookhoard only |
| none | No sync (mapping only for reference) |
### Example Request
```json
{
"collection_id": "550e8400-e29b-41d4-a716-446655440000",
"device_shelf_name": "Sci-Fi",
"sync_direction": "bidirectional"
}
```
## Response (201 Created)
```json
{
"id": "990e8400-e29b-41d4-a716-446655440000",
"collection_id": "550e8400-e29b-41d4-a716-446655440000",
"collection_name": "Science Fiction",
"device_shelf_name": "Sci-Fi",
"sync_direction": "bidirectional",
"created_at": "2026-02-01T10:00:00Z"
}
```
## Use Case
Collections can be synced to device-specific shelves (Kobo, KOReader). This allows automatic organization of books on your e-reader based on your Bookhoard collections.
## Error Responses
| Code | Description |
|------|-------------|
| 400 | Invalid request (validation failed) |
| 401 | Authentication required |
| 404 | Device or collection not found |
| 409 | Mapping already exists |
| 500 | Internal server error |
## Try It Out
+27
View File
@@ -0,0 +1,27 @@
# Delete Collection
Delete a collection. Books are NOT deleted.
**Endpoint**: `DELETE /api/collections/{id}`
**Auth**: Required
**Content-Type**: `application/json`
## Path Parameters
| Parameter | Type | Required | Description |
|-----------|------|-----------|-------------|
| id | string (UUID) | Yes | Collection UUID |
## Response (204 No Content)
Collection deleted successfully. No response body.
## Error Responses
| Code | Description |
|------|-------------|
| 401 | Authentication required |
| 404 | Collection not found |
| 500 | Internal server error |
## Try It Out
@@ -0,0 +1,34 @@
# Delete Shelf Mapping
Remove a collection-to-shelf mapping for a device.
**Endpoint**: `DELETE /api/devices/{deviceId}/collections/{collectionId}`
**Auth**: Required
**Content-Type**: `application/json`
## Path Parameters
| Parameter | Type | Required | Description |
|-----------|------|-----------|-------------|
| deviceId | string (UUID) | Yes | Device UUID |
| collectionId | string (UUID) | Yes | Collection UUID |
## Response (204 No Content)
Shelf mapping deleted successfully. No response body.
## Notes
- Deleting a mapping does NOT delete the collection
- Deleting a mapping does NOT delete books from the device
- It only removes the association between the collection and device shelf
## Error Responses
| Code | Description |
|------|-------------|
| 401 | Authentication required |
| 404 | Device or collection not found |
| 500 | Internal server error |
## Try It Out
+54
View File
@@ -0,0 +1,54 @@
# Get Collection
Get single collection with all books.
**Endpoint**: `GET /api/collections/{id}`
**Auth**: Required
**Content-Type**: `application/json`
## Path Parameters
| Parameter | Type | Required | Description |
|-----------|------|-----------|-------------|
| id | string (UUID) | Yes | Collection UUID |
## Query Parameters
| Parameter | Type | Required | Description |
|-----------|------|-----------|-------------|
| include_books | boolean | No | Include books in response (default: true) |
| limit | integer | No | Number of books to return (default: 50) |
| offset | integer | No | Number of books to skip (default: 0) |
## Response (200 OK)
```json
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Science Fiction",
"description": "My sci-fi collection",
"color": "#FF5733",
"icon": "🚀",
"books": [
{
"media_item_id": "660e8400-e29b-41d4-a716-446655440000",
"title": "Foundation",
"author": "Isaac Asimov",
"cover_image_path": "/covers/foundation.jpg"
}
],
"auto_assign_rules": [],
"view_settings": {},
"created_at": "2026-02-01T10:00:00Z"
}
```
## Error Responses
| Code | Description |
|------|-------------|
| 401 | Authentication required |
| 404 | Collection not found |
| 500 | Internal server error |
## Try It Out
+57
View File
@@ -0,0 +1,57 @@
# List Collections
Get all collections for the authenticated user.
**Endpoint**: `GET /api/collections`
**Auth**: Required
**Content-Type**: `application/json`
## Query Parameters
| Parameter | Type | Required | Description |
|-----------|------|-----------|-------------|
| limit | integer | No | Number of collections to return (default: 50) |
| offset | integer | No | Number of collections to skip (default: 0) |
## Response (200 OK)
```json
{
"collections": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Science Fiction",
"description": "My sci-fi collection",
"color": "#FF5733",
"icon": "🚀",
"auto_assign_rules": [
{
"field": "genre",
"operator": "equals",
"value": "Science Fiction",
"priority": 1,
"enabled": true
}
],
"view_settings": {
"kobo": {
"view_mode": "grid",
"sort_order": "name",
"items_per_page": 24
}
},
"created_at": "2026-02-01T10:00:00Z"
}
],
"total": 1
}
```
## Error Responses
| Code | Description |
|------|-------------|
| 401 | Authentication required |
| 500 | Internal server error |
## Try It Out
@@ -0,0 +1,28 @@
# Remove Auto-Assign Rule
Remove an automatic book assignment rule from a collection.
**Endpoint**: `DELETE /api/collections/{collectionId}/rules/{ruleId}`
**Auth**: Required
**Content-Type**: `application/json`
## Path Parameters
| Parameter | Type | Required | Description |
|-----------|------|-----------|-------------|
| collectionId | string (UUID) | Yes | Collection UUID |
| ruleId | string (UUID) | Yes | Rule UUID |
## Response (204 No Content)
Rule deleted successfully. No response body.
## Error Responses
| Code | Description |
|------|-------------|
| 401 | Authentication required |
| 404 | Collection or rule not found |
| 500 | Internal server error |
## Try It Out
+71
View File
@@ -0,0 +1,71 @@
# Test Rule
Test which books would match given rules without saving.
**Endpoint**: `POST /api/collections/test-rules`
**Auth**: Required
**Content-Type**: `application/json`
## Request Body
| Field | Type | Required | Description |
|--------|------|-----------|-------------|
| rules | array | Yes | Array of rule objects to test |
### Rule Object
| Field | Type | Required | Description |
|--------|------|-----------|-------------|
| field | string | Yes | Field to match on (genre, author, series, language, publisher, copyright_year, tags) |
| operator | string | Yes | Comparison operator (equals, not_equals, contains, not_contains, starts_with, ends_with, greater_than, less_than) |
| value | string/number | Yes | Value to compare against |
### Example Request
```json
{
"rules": [
{
"field": "genre",
"operator": "equals",
"value": "Science Fiction"
},
{
"field": "author",
"operator": "contains",
"value": "Asimov"
}
]
}
```
## Response (200 OK)
```json
{
"matches": [
{
"media_item_id": "660e8400-e29b-41d4-a716-446655440000",
"title": "Foundation",
"author": "Isaac Asimov",
"cover_image_path": "/covers/foundation.jpg",
"match_reason": "Matched rule: genre equals Science Fiction"
}
],
"total": 42
}
```
## Use Case
Test rules before creating a collection to verify correct book matching. This endpoint shows which books would be added without actually modifying any collections.
## Error Responses
| Code | Description |
|------|-------------|
| 400 | Invalid request (validation failed) |
| 401 | Authentication required |
| 500 | Internal server error |
## Try It Out
+63
View File
@@ -0,0 +1,63 @@
# Update Collection
Update collection details.
**Endpoint**: `PUT /api/collections/{id}`
**Auth**: Required
**Content-Type**: `application/json`
## Path Parameters
| Parameter | Type | Required | Description |
|-----------|------|-----------|-------------|
| id | string (UUID) | Yes | Collection UUID |
## Request Body
All fields are optional. Include only fields you want to update.
| Field | Type | Required | Description |
|--------|------|-----------|-------------|
| name | string | No | Collection name (max 255 chars) |
| description | string | No | Collection description |
| color | string | No | Hex color code (e.g., "#FF5733") |
| icon | string | No | Emoji icon (e.g., "🚀", "📖") |
| auto_assign_rules | array | No | Array of rule objects (replaces existing rules) |
| view_settings | object | No | Per-device display preferences |
### Example Request
```json
{
"name": "Sci-Fi Favorites",
"description": "Updated description",
"color": "#7aa2f7",
"icon": "🌟"
}
```
## Response (200 OK)
```json
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "Sci-Fi Favorites",
"description": "Updated description",
"color": "#7aa2f7",
"icon": "🌟",
"auto_assign_rules": [],
"view_settings": {},
"created_at": "2026-02-01T10:00:00Z"
}
```
## Error Responses
| Code | Description |
|------|-------------|
| 400 | Invalid request (validation failed) |
| 401 | Authentication required |
| 404 | Collection not found |
| 500 | Internal server error |
## Try It Out