refactor(bruno): reorganize file structure from bruno-yaml to flat bruno directory

- Move all files from bruno-yaml/* to bruno/*
- Maintains existing directory structure within categories
- Updates bruno/user/auth files with OAuth2 refresh token flow
- Updates bruno/user/profile files for user profile management
- Adds bruno/dashboard/ directory with dashboard API tests
- Preserves all existing test scenarios and OpenCollection YAML format
- No functional changes - file reorganization only
This commit is contained in:
2026-02-17 20:22:21 -05:00
parent 96730d9475
commit f859b2714d
221 changed files with 0 additions and 0 deletions
+34
View File
@@ -0,0 +1,34 @@
info:
name: Create Media Item
type: http
seq: 1
http:
method: POST
url: '{{base_url}}/api/media-items'
auth: inherit
body:
type: json
jsonBody: '"library_id": "{{library_id'
headers:
- key: Content-Type
value: application/json
runtime:
scripts:
- type: tests
code: "test_create_media_item_success(status, headers, body) {\n if (status\
\ !== 201) {\n throw new Error(\"Expected status 201, got \" + status);"
docs: |-
## Create Media Item
Creates a new media item in a library with full metadata.
**Method:** POST
**Endpoint:** /api/media-items
**Authentication:** Required (Bearer token, admin only)
**Prerequisites**
- Library must have at least one folder configured before media items can be added
- Use `POST /api/libraries/{library_id
+23
View File
@@ -0,0 +1,23 @@
info:
name: Create Media Rating
type: http
seq: 1
http:
method: POST
url: '{{base_url}}/api/media-items/{{media_item_id}}/rating'
auth: inherit
body:
type: json
jsonBody: "{\n \"rating\": 8"
headers:
- key: Content-Type
value: application/json
docs: |-
## Create Media Rating
Creates or updates the authenticated user's rating for a specific media item.
**Method:** POST
**Endpoint:** /api/media-items/{id
+27
View File
@@ -0,0 +1,27 @@
info:
name: Delete Media Item
type: http
seq: 3
http:
method: DELETE
url: '{{base_url}}/api/media-items/{{media_item_id}}'
auth: inherit
body:
type: none
headers:
- key: Content-Type
value: application/json
runtime:
scripts:
- type: tests
code: "test_delete_media_item_success(status, headers, body) {\n if (status\
\ !== 204) {\n throw new Error(\"Expected status 204, got \" + status);"
docs: |-
## Delete Media Item
Deletes a media item from the library.
**Method:** DELETE
**Endpoint:** /api/media-items/{id
+27
View File
@@ -0,0 +1,27 @@
info:
name: Delete Media Rating
type: http
seq: 5
http:
method: DELETE
url: '{{base_url}}/api/media-items/{{media_item_id}}/rating'
auth: inherit
body:
type: none
headers:
- key: Content-Type
value: application/json
runtime:
scripts:
- type: tests
code: "test_delete_media_rating_success(status, headers, body) {\n if (status\
\ !== 204) {\n throw new Error(\"Expected status 204, got \" + status);"
docs: |-
## Delete Media Rating
Deletes a user's rating for a specific media item.
**Method:** DELETE
**Endpoint:** /api/media-items/{id
+19
View File
@@ -0,0 +1,19 @@
info:
name: Download Media Item
type: http
seq: 1
http:
method: GET
url: '{{baseURL}}/api/media-items/{{bookUUID}}/download'
auth: none
body:
type: none
docs: |-
## Download Media Item
Download a media item file (EPUB, PDF, etc.) from Bookhoard server.
**Method:** GET
**Endpoint:** /api/media-items/{bookUUID
+25
View File
@@ -0,0 +1,25 @@
info:
name: Get Media Item
type: http
seq: 1
http:
method: GET
url: '{{base_url}}/api/media-items/{{media_item_id}}'
auth: inherit
headers:
- key: Content-Type
value: application/json
runtime:
scripts:
- type: tests
code: "test_get_media_item_success(status, headers, body) {\n if (status !==\
\ 200) {\n throw new Error(\"Expected status 200, got \" + status);"
docs: |-
## Get Media Item
Retrieves detailed information about a specific media item.
**Method:** GET
**Endpoint:** /api/media-items/{id
+27
View File
@@ -0,0 +1,27 @@
info:
name: Get Media Rating
type: http
seq: 4
http:
method: GET
url: '{{base_url}}/api/media-items/{{media_item_id}}/rating'
auth: inherit
body:
type: none
headers:
- key: Content-Type
value: application/json
runtime:
scripts:
- type: tests
code: "test_get_media_rating_success(status, headers, body) {\n if (status\
\ !== 200) {\n throw new Error(\"Expected status 200, got \" + status);"
docs: |-
## Get Media Rating
Retrieves a user's rating for a specific media item.
**Method:** GET
**Endpoint:** /api/media-items/{id
+52
View File
@@ -0,0 +1,52 @@
info:
name: Update Media Item
type: http
seq: 2
http:
method: PUT
url: '{{base_url}}/api/media-items/{{media_item_id}}'
auth: inherit
body:
type: json
json:
title: Updated Media Item Title
author: Updated Author Name
isbn: 978-9876543210
description: Updated description
cover_image_path: /updated/path/to/cover.jpg
series: Updated Series Name
series_number: 2
tags:
- updated
- fiction
- adventure
asin: B09XYZ789
date_published: '2023-02-20'
publisher: Updated Publisher
contributors:
- Updated Contributor
language: en
edition: Updated Edition
page_count: 400
genre: Updated Genre
copyright_year: 2023
goodreads_id: '7890123'
openlibrary_id: OL789012M
google_books_id: GB789012
headers:
- key: Content-Type
value: application/json
runtime:
scripts:
- type: tests
code: "test_update_media_item_success(status, headers, body) {\n if (status\
\ !== 200) {\n throw new Error(\"Expected status 200, got \" + status);"
docs: |-
## Update Media Item
Updates an existing media item's metadata.
**Method:** PUT
**Endpoint:** /api/media-items/{id
+53
View File
@@ -0,0 +1,53 @@
info:
name: Update Media Rating
type: http
seq: 1
http:
method: PUT
url: '{{base_url}}/api/media-items/{{media_item_id}}/rating'
auth: inherit
body:
type: json
jsonBody: "{\n \"rating\": 4,\n \"review\": \"Great book! Very enjoyable\
\ read.\""
headers:
- key: Content-Type
value: application/json
runtime:
scripts:
- type: tests
code: "test_update_media_rating_success(status, headers, body) {\n if (status\
\ !== 200) {\n throw new Error(\"Expected status 200, got \" + status);"
docs: |-
## Update Media Rating
Updates an existing rating for a media item.
**Method:** PUT
**Endpoint:** /api/media-items/:id/rating
**Authentication:** Required (Bearer token)
**Path Parameters:**
- `id` (string, required): Media item UUID
**Request Body:**
- `rating` (number, required): Rating value (typically 1-5)
- `review` (string, optional): Review text
**Response:** Updated rating object
- `id` (string): Rating ID
- `media_item_id` (string): Media item UUID
- `rating` (number): Rating value
- `review` (string): Review text
- `created_at` (string): Creation timestamp
- `updated_at` (string): Last update timestamp
**Status Codes:**
- 200: Success
- 400: Invalid request body
- 401: Unauthorized
- 404: Media item or rating not found
- 500: Internal server error
@@ -0,0 +1,58 @@
info:
name: Filter Media Items
type: http
seq: 1
http:
method: GET
url: '{{base_url}}/api/media-items/filtered?library_id={{library_id}}&genre_filter=Fiction&language_filter=en&year_min=2000&year_max=2024&limit=10&offset=0'
auth: inherit
body:
type: none
headers:
- key: Content-Type
value: application/json
docs: |-
## Filter Media Items
**Method:** GET
**Endpoint:** /api/media-items/filtered
**Authentication:** Required (Bearer token)
**Query Parameters:**
- `library_id` (string, required): UUID of the library
- `author_filter` (string, optional): Filter by author (partial match)
- `series_filter` (string, optional): Filter by series (partial match)
- `genre_filter` (string, optional): Filter by genre (exact match)
- `language_filter` (string, optional): Filter by language (exact match, e.g., 'en', 'es', 'fr')
- `year_min` (integer, optional): Minimum copyright year
- `year_max` (integer, optional): Maximum copyright year
- `has_cover` (boolean, optional): Filter for items with cover images only
- `sort` (string, optional): Sort field and direction (same options as ListMediaItems)
- `limit` (integer, optional): Number of items to return (default: 50, max: 1000)
- `offset` (integer, optional): Number of items to skip (default: 0)
**Response:** Object containing array of filtered media items
**Status Codes:**
- 200: Success
- 400: Bad request (invalid parameters)
- 401: Unauthorized
- 500: Internal server error
**Examples:**
- Filter by genre: `/api/media-items/filtered?library_id=xxx&genre_filter=Fiction`
- Filter by language: `/api/media-items/filtered?library_id=xxx&language_filter=es`
- Filter by year range: `/api/media-items/filtered?library_id=xxx&year_min=2000&year_max=2024`
- Filter by cover: `/api/media-items/filtered?library_id=xxx&has_cover=true`
- Combine filters: `/api/media-items/filtered?library_id=xxx&genre_filter=Sci-Fi&year_min=2010&language_filter=en`
**Filter Behavior:**
- Multiple filters can be combined (AND logic)
- Author and series filters use partial matching (ILIKE)
- Genre and language filters use exact matching
- Year range filters are inclusive
- Filters are applied before sorting and pagination
- User library visibility is respected
@@ -0,0 +1,63 @@
info:
name: List Media Items with Sorting
type: http
seq: 1
http:
method: GET
url: '{{base_url}}/api/media-items?library_id={{library_id}}&sort=title+ASC&limit=10&offset=0'
auth: inherit
body:
type: none
headers:
- key: Content-Type
value: application/json
docs: |-
## List Media Items with Sorting
**Method:** GET
**Endpoint:** /api/media-items
**Authentication:** Required (Bearer token)
**Query Parameters:**
- `library_id` (string, required): UUID of the library
- `sort` (string, optional): Sort field and direction
- Available options:
- `created_at ASC` - Oldest added first
- `created_at DESC` - Newest added first (default)
- `title ASC` - Title A-Z
- `title DESC` - Title Z-A
- `author ASC` - Author A-Z
- `author DESC` - Author Z-A
- `series ASC` - Series order
- `series DESC` - Series reverse order
- `date_published ASC` - Oldest published first
- `date_published DESC` - Newest published first
- `copyright_year ASC` - Oldest copyright first
- `copyright_year DESC` - Newest copyright first
- `page_count ASC` - Shortest first
- `page_count DESC` - Longest first
- `genre ASC` - Genre A-Z
- `genre DESC` - Genre Z-A
- `limit` (integer, optional): Number of items to return (default: 50, max: 1000)
- `offset` (integer, optional): Number of items to skip (default: 0)
**Response:** Object containing array of media items
**Status Codes:**
- 200: Success
- 400: Bad request (invalid parameters)
- 401: Unauthorized
- 500: Internal server error
**Examples:**
- Sort by title: `/api/media-items?library_id=xxx&sort=title+ASC`
- Sort by author descending: `/api/media-items?library_id=xxx&sort=author+DESC`
- Sort by page count: `/api/media-items?library_id=xxx&sort=page_count+ASC`
**Sorting Behavior:**
- All sorts are secondary-sorted by series_number then title for consistency
- NULL values are sorted last for ascending, first for descending
- Sorting is case-insensitive for text fields
@@ -0,0 +1,49 @@
info:
name: List Media Items
type: http
seq: 1
http:
method: GET
url: '{{base_url}}/api/media-items?library_id={{library_id}}&limit=20&offset=0'
auth: inherit
headers:
- key: Content-Type
value: application/json
runtime:
scripts:
- type: tests
code: "test_list_media_items_success(status, headers, body) {\n if (status\
\ !== 200) {\n throw new Error(\"Expected status 200, got \" + status);"
docs: |-
## List Media Items
Retrieves a paginated list of media items from a specific library.
**Method:** GET
**Endpoint:** /api/media-items
**Authentication:** Required (Bearer token)
**Query Parameters:**
- `library_id` (string, required): Library UUID to filter items
- `limit` (number, optional): Number of results per page (default: 20, max: 100)
- `offset` (number, optional): Pagination offset (default: 0)
**Response:** Array of media item objects
- `id` (string): Media item UUID
- `title` (string): Media item title
- `library_id` (string): Library UUID
- `media_type` (string): Type of media (e.g., "ebook", "audiobook")
- `file_path` (string): Path to media file
- `created_at` (string): Creation timestamp
- `updated_at` (string): Last update timestamp
**Status Codes:**
- 200: Success
- 400: Invalid query parameters
- 401: Unauthorized
- 403: Forbidden (library access denied)
- 404: Library not found
- 500: Internal server error
@@ -0,0 +1,62 @@
info:
name: Search Media Items
type: http
seq: 1
http:
method: GET
url: '{{base_url}}/api/media-items/search?q=harry'
auth: inherit
headers:
- key: Content-Type
value: application/json
runtime:
scripts:
- type: tests
code: "test_search_media_items_success(status, headers, body) {\n if (status\
\ !== 200 && status !== 404) {\n throw new Error(\"Expected status 200\
\ or 404, got \" + status);"
docs: |-
## Search Media Items
Performs a search across all visible media items using partial matching with fuzzy fallback.
**Method:** GET
**Endpoint:** /api/media-items/search
**Authentication:** Required (Bearer token)
**Query Parameters:**
- `q` (string, required): Search query (minimum 2 characters)
**Search Behavior:**
1. First performs case-insensitive partial matching across:
- Title
- Author
- Series
- Tags
- Contributors
2. If no results found, falls back to fuzzy search using word_similarity with 0.3 threshold
**Response:** Array of media item objects (same structure as List Media Items)
**Status Codes:**
- 200: Success (results found)
- 404: No results found
- 400: Missing or invalid query parameter
- 401: Unauthorized
- 500: Internal server error
**Examples:**
- Search by title: `q=harry potter`
- Search by author: `q=king`
- Fuzzy search: `q=hary poter` (will find "harry potter")
**Ranking:**
Results are ranked by relevance:
- Title matches: Highest priority
- Author matches: High priority
- Series matches: Medium priority
- Tag matches: Lower priority
- Fuzzy matches: Sorted by similarity score