docs: align swagger spec and README with Ombi features and blocklist eligibility (closes #37)
Build and Push Docker Image / build (push) Successful in 38s
Docs Check / Markdown lint (push) Successful in 1m18s
Licence Check / Licence compatibility and copyright header verification (push) Failing after 2m11s
CI / Security audit (push) Successful in 2m27s
Docs Check / Mermaid diagram parse check (push) Successful in 3m5s
CI / Swagger Validation & Coverage (push) Successful in 3m19s
CI / Tests & coverage (push) Successful in 3m34s

This commit is contained in:
2026-05-22 22:42:44 +01:00
parent 2e9fe8e049
commit 4cd9faaf25
5 changed files with 328 additions and 32 deletions
+269 -4
View File
@@ -276,7 +276,6 @@ components:
- arrQueueId
- arrType
- arrInstanceUrl
- arrInstanceKey
- arrContentId
- arrContentType
properties:
@@ -296,7 +295,7 @@ components:
example: "http://sonarr:8989"
arrInstanceKey:
type: string
description: API key for the *arr instance
description: API key for the *arr instance. Only required for admin users; non-admin requests resolve the key from server-side configurations using arrInstanceUrl.
example: "abc123def456"
arrContentId:
type: integer
@@ -686,7 +685,7 @@ paths:
post:
tags: [Dashboard]
summary: Blocklist and re-search
description: Admin-only. Removes queue item with blocklist=true, then triggers new automatic search.
description: Removes queue item with blocklist=true, then triggers new automatic search. Accessible by admins, or by non-admins who own the item under specific eligibility conditions (has import issues, or torrent older than 1h and availability < 100%).
security:
- CookieAuth: []
- CsrfToken: []
@@ -708,7 +707,7 @@ paths:
type: boolean
example: true
'403':
description: Admin access required
description: Permission denied (admin or qualifying conditions required)
content:
application/json:
schema:
@@ -853,6 +852,72 @@ paths:
schema:
$ref: '#/components/schemas/ErrorResponse'
/api/webhook/ombi:
post:
tags: [Webhook]
summary: Ombi webhook
description: Receives webhook events from Ombi. Requires X-Sofarr-Webhook-Secret header.
security: []
requestBody:
required: true
content:
application/json:
schema:
type: object
responses:
'200':
description: Event received
content:
application/json:
schema:
type: object
properties:
received:
type: boolean
example: true
'401':
description: Invalid or missing secret
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'400':
description: Invalid payload
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
/api/webhook/config:
get:
tags: [Webhook]
summary: Get webhook configuration status
description: Returns whether the required webhook configuration is properly configured.
security:
- CookieAuth: []
responses:
'200':
description: Webhook configuration status
content:
application/json:
schema:
type: object
properties:
valid:
type: boolean
example: true
missing:
type: array
items:
type: string
example: []
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
# Sonarr proxy endpoints (detailed in JSDoc)
/api/sonarr/queue:
get:
@@ -1478,3 +1543,203 @@ paths:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
# Ombi endpoints
/api/ombi/requests:
get:
tags: [Ombi]
summary: Get Ombi requests
description: Returns Ombi movie and TV requests. Non-admin users only see their own requests, while admins see all requests. Supports server-side filtering by media type, request status, title search, and sorting.
security:
- CookieAuth: []
parameters:
- name: type
in: query
schema:
type: array
items:
type: string
enum: [movie, tv, all]
default: [all]
description: Filter by media type. Omit or use `all` for both.
style: form
explode: true
- name: status
in: query
schema:
type: array
items:
type: string
enum: [pending, approved, available, denied]
description: Filter by request status. Omit for all statuses.
style: form
explode: true
- name: sort
in: query
schema:
type: string
enum: [requestedDate_desc, requestedDate_asc, title_asc, title_desc]
default: requestedDate_desc
description: Sort mode.
- name: search
in: query
schema:
type: string
description: Case-insensitive substring match on title.
- name: showAll
in: query
schema:
type: string
enum: ['true', 'false']
description: Admin only. Show all users' requests.
responses:
'200':
description: Ombi requests retrieved successfully
content:
application/json:
schema:
type: object
properties:
user:
type: string
isAdmin:
type: boolean
showAll:
type: boolean
requests:
type: object
properties:
movie:
type: array
items:
$ref: '#/components/schemas/OmbiRequest'
tv:
type: array
items:
$ref: '#/components/schemas/OmbiRequest'
total:
type: integer
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
/api/ombi/webhook/enable:
post:
tags: [Ombi]
summary: Enable Ombi webhook
description: Registers or updates the Sofarr webhook in Ombi. Requires authentication and CSRF protection.
security:
- CookieAuth: []
responses:
'200':
description: Webhook enabled successfully
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
webhookUrl:
type: string
applicationToken:
type: string
'400':
description: Invalid request or missing configuration
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
/api/ombi/webhook/status:
get:
tags: [Ombi]
summary: Get Ombi webhook status
description: Returns the current Ombi webhook configuration status and metrics.
security:
- CookieAuth: []
responses:
'200':
description: Webhook status retrieved successfully
content:
application/json:
schema:
type: object
properties:
enabled:
type: boolean
webhookUrl:
type: string
nullable: true
applicationToken:
type: string
nullable: true
triggers:
type: object
properties:
requestAvailable:
type: boolean
requestApproved:
type: boolean
requestDeclined:
type: boolean
requestPending:
type: boolean
requestProcessing:
type: boolean
stats:
type: object
nullable: true
properties:
eventsReceived:
type: integer
pollsSkipped:
type: integer
lastWebhookTimestamp:
type: integer
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
/api/ombi/webhook/test:
post:
tags: [Ombi]
summary: Test Ombi webhook
description: Sends a test webhook event to the Sofarr Ombi webhook endpoint.
security:
- CookieAuth: []
- CsrfToken: []
responses:
'200':
description: Test webhook sent successfully
content:
application/json:
schema:
type: object
properties:
success:
type: boolean
'400':
description: Invalid request or missing configuration
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'401':
description: Unauthorized
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
+15 -13
View File
@@ -558,15 +558,18 @@ router.get('/stream', requireAuth, async (req, res) => {
* tags: [Dashboard]
* summary: Blocklist and re-search
* description: |
* Admin-only endpoint that removes a queue item from Sonarr/Radarr with blocklist=true
* (so the release is not grabbed again), then immediately triggers a new automatic search
* for the same episode/movie.
* Removes a queue item from Sonarr/Radarr with blocklist=true (so the release is not grabbed again),
* then immediately triggers a new automatic search for the same episode/movie.
*
* **Authentication:** Requires valid `emby_user` cookie (admin only) and `X-CSRF-Token` header.
* Accessible by admins, or by non-admins who own the item under specific qualifying eligibility conditions:
* - The download has import issues OR
* - The torrent is older than 1 hour and has availability below 100%
*
* **Authentication:** Requires valid `emby_user` cookie and `X-CSRF-Token` header.
*
* **Workflow:**
* 1. Validate user is admin
* 2. Validate all required fields are present
* 1. Validate user and required fields
* 2. Check blocklist eligibility (admin status or non-admin qualifying criteria)
* 3. Delete queue item from Sonarr/Radarr with `removeFromClient=true` and `blocklist=true`
* 4. Trigger automatic search command:
* - Sonarr: EpisodeSearch with episodeIds
@@ -577,18 +580,17 @@ router.get('/stream', requireAuth, async (req, res) => {
* - `arrQueueId`: Sonarr/Radarr queue record ID
* - `arrType`: Must be "sonarr" or "radarr"
* - `arrInstanceUrl`: Base URL of the *arr instance
* - `arrInstanceKey`: API key for the *arr instance
* - `arrInstanceKey`: API key for the *arr instance (only required for admins; non-admins resolve via server config)
* - `arrContentId`: episodeId (Sonarr) or movieId (Radarr)
* - `arrContentType`: Must be "episode" (Sonarr) or "movie" (Radarr)
*
* **Error Responses:**
* - 403: Non-admin user attempts access
* - 403: User lacks permissions (admin or qualifying conditions required)
* - 400: Missing required fields or invalid arrType
* - 502: Failed to communicate with *arr instance
*
* **x-integration-notes:** This endpoint is used from the dashboard UI when an admin
* clicks "Blocklist + Re-search" on a failed download. The arr instance credentials
* are passed from the download object (which includes them for admin users).
* **x-integration-notes:** This endpoint is used from the dashboard UI when a qualified user or admin
* clicks "Blocklist + Re-search" on a stalled or failed download.
* security:
* - CookieAuth: []
* - CsrfToken: []
@@ -627,13 +629,13 @@ router.get('/stream', requireAuth, async (req, res) => {
* example:
* error: "Missing required fields"
* '403':
* description: Admin access required
* description: Permission denied (admin or qualifying conditions required)
* content:
* application/json:
* schema:
* $ref: '#/components/schemas/ErrorResponse'
* example:
* error: "Admin access required"
* error: "Permission denied: admin or qualifying conditions required"
* '502':
* description: Failed to communicate with *arr instance
* content: