From d4903feb71b7270b906b98ddb899f9b74fe5f9d3 Mon Sep 17 00:00:00 2001 From: John O'Keefe Date: Tue, 10 Feb 2026 19:58:47 -0500 Subject: [PATCH] docs: add media-items bulk operation and download documentation - Add comprehensive documentation for bulk delete endpoint - Add comprehensive documentation for bulk update endpoint - Add comprehensive documentation for download endpoint - Document all request/response fields with correct names - Include examples and error codes - Add notes on tag normalization and partial success --- .../media-items/bulk_delete_media_items.md | 78 +++++++++++++ .../media-items/bulk_update_media_items.md | 106 ++++++++++++++++++ .../api/media-items/download_media_item.md | 41 +++++++ 3 files changed, 225 insertions(+) create mode 100644 docs/developer/api/media-items/bulk_delete_media_items.md create mode 100644 docs/developer/api/media-items/bulk_update_media_items.md create mode 100644 docs/developer/api/media-items/download_media_item.md diff --git a/docs/developer/api/media-items/bulk_delete_media_items.md b/docs/developer/api/media-items/bulk_delete_media_items.md new file mode 100644 index 0000000..2a409f2 --- /dev/null +++ b/docs/developer/api/media-items/bulk_delete_media_items.md @@ -0,0 +1,78 @@ +# Bulk Delete Media Items + +Delete multiple media items at once (supports ebooks, comics, manga). + +**Endpoint**: `POST /api/media-items/bulk-delete` +**Auth**: Required +**Content-Type**: `application/json` + +## Request Body + +| Field | Type | Required | Description | +|--------|------|-----------|-------------| +| media_item_ids | array of UUID | Yes | Array of media item UUIDs to delete | + +### Example Request + +```json +{ + "media_item_ids": [ + "550e8400-e29b-41d4-a716-446655440001", + "660e8400-e29b-41d4-a716-446655440002", + "770e8400-e29b-41d4-a716-446655440003" + ] +} +``` + +## Response (200 OK) + +```json +{ + "results": [ + { + "media_item_id": "550e8400-e29b-41d4-a716-446655440001", + "status": "success" + }, + { + "media_item_id": "660e8400-e29b-41d4-a716-446655440002", + "status": "error", + "error": "Media item not found" + }, + { + "media_item_id": "770e8400-e29b-41d4-a716-446655440003", + "status": "success" + } + ], + "total": 3, + "deleted": 2, + "failed": 1 +} +``` + +## Response Fields + +| Field | Type | Description | +|-------|------|-------------| +| results | array | Individual result for each media item | +| results[].media_item_id | string | UUID of the media item | +| results[].status | string | "success" or "error" | +| results[].error | string | Error message (only present if status is "error") | +| total | number | Total number of media items processed | +| deleted | number | Number of media items successfully deleted | +| failed | number | Number of media items that failed to delete | + +## Error Responses + +| Code | Description | +|------|-------------| +| 400 | Invalid request data or empty media_item_ids array | +| 401 | Invalid or expired token | +| 403 | User does not have permission | +| 500 | Server error during deletion | + +## Notes + +- **File deletion**: Successfully deleted media items will also have their associated files removed from disk +- **Invalid UUIDs**: Invalid UUID formats are counted as failures in the results array +- **Non-existent items**: Media items that don't exist are counted as failures (not errors) +- **Partial success**: The operation continues even if some deletions fail diff --git a/docs/developer/api/media-items/bulk_update_media_items.md b/docs/developer/api/media-items/bulk_update_media_items.md new file mode 100644 index 0000000..7980621 --- /dev/null +++ b/docs/developer/api/media-items/bulk_update_media_items.md @@ -0,0 +1,106 @@ +# Bulk Update Media Items + +Update multiple media items at once (supports ebooks, comics, manga). + +**Endpoint**: `POST /api/media-items/bulk-update` +**Auth**: Required +**Content-Type**: `application/json` + +## Request Body + +| Field | Type | Required | Description | +|--------|------|-----------|-------------| +| media_item_updates | array of objects | Yes | Array of update operations | +| media_item_updates[].media_item_id | string (UUID) | Yes | Media item UUID to update | +| media_item_updates[].updates | object | Yes | Fields to update | + +### Update Fields + +| Field | Type | Required | Description | +|--------|------|-----------|-------------| +| title | string | No | Updated title | +| author | string | No | Updated author | +| genre | string | No | Updated genre | +| language | string | No | Updated language (ISO 639-1 code) | +| tags | array of strings | No | Updated tags (auto-normalized) | + +### Example Request + +```json +{ + "media_item_updates": [ + { + "media_item_id": "550e8400-e29b-41d4-a716-446655440001", + "updates": { + "title": "Updated Title", + "genre": "Science Fiction", + "tags": ["science fiction", "space opera", "ACME CORP."] + } + }, + { + "media_item_id": "660e8400-e29b-41d4-a716-446655440002", + "updates": { + "author": "Updated Author Name", + "language": "en" + } + } + ] +} +``` + +## Response (200 OK) + +```json +{ + "results": [ + { + "media_item_id": "550e8400-e29b-41d4-a716-446655440001", + "status": "success" + }, + { + "media_item_id": "660e8400-e29b-41d4-a716-446655440002", + "status": "error", + "error": "Media item not found" + } + ], + "total": 2, + "updated": 1, + "failed": 1 +} +``` + +## Response Fields + +| Field | Type | Description | +|-------|------|-------------| +| results | array | Individual result for each media item | +| results[].media_item_id | string | UUID of the media item | +| results[].status | string | "success" or "error" | +| results[].error | string | Error message (only present if status is "error") | +| total | number | Total number of media items processed | +| updated | number | Number of media items successfully updated | +| failed | number | Number of media items that failed to update | + +## Tag and Contributor Normalization + +The backend automatically normalizes tags: + +- **Tags**: Titlecased, punctuation preserved, deduplicated +- **Search fields**: Lowercase, no punctuation, stored in `tags_search` + +## Error Responses + +| Code | Description | +|------|-------------| +| 400 | Invalid request data or empty media_item_updates array | +| 401 | Invalid or expired token | +| 403 | User does not have permission | +| 404 | One or more media items not found | +| 500 | Server error during update | + +## Notes + +- **Partial success**: The operation continues even if some updates fail +- **Invalid UUIDs**: Invalid UUID formats are counted as failures +- **Non-existent items**: Media items that don't exist are counted as failures +- **No changes**: If updates object is empty, the item still counts as success diff --git a/docs/developer/api/media-items/download_media_item.md b/docs/developer/api/media-items/download_media_item.md new file mode 100644 index 0000000..58f55aa --- /dev/null +++ b/docs/developer/api/media-items/download_media_item.md @@ -0,0 +1,41 @@ +# Download Media Item + +Download a media item file (EPUB, PDF, etc.) from the Bookhoard server. + +**Endpoint**: `GET /api/media-items/:uuid/download` +**Auth**: None (public endpoint for Kobo devices) +**Content-Type**: Binary file download + +## Path Parameters + +| Parameter | Type | Required | Description | +|-----------|------|-----------|-------------| +| uuid | string | Yes | Media item UUID | + +## Response + +**Success (200 OK)**: Binary file data + +**Response Headers**: +- `Content-Type`: `application/epub+zip`, `application/pdf`, or appropriate MIME type +- `Content-Disposition`: `attachment; filename="filename.epub"` + +## Error Responses + +| Code | Description | +|------|-------------| +| 404 | Media item not found | +| 500 | Server error during file download | + +## Example + +```bash +curl -O http://localhost:8765/api/media-items/550e8400-e29b-41d4-a716-446655440000/download +``` + +## Notes + +- **Public endpoint**: No authentication required for Kobo device downloads +- **File format**: Returns the original file format (EPUB, PDF, etc.) +- **Kobo integration**: Designed for direct downloads from Kobo e-readers +- **Cover images**: Use `/api/media-items/:uuid/cover` for cover images