feat(swagger): Add Swagger API reference, and fixes #28

Merged
Gandalf merged 28 commits from develop into main 2026-05-21 20:14:36 +01:00
Owner
No description provided.
Gandalf added 28 commits 2026-05-21 20:14:23 +01:00
- Install swagger-ui-express, swagger-jsdoc, yamljs
- Prepare for OpenAPI 3.1 spec integration
- Create server/openapi.yaml with OpenAPI 3.1.0 base
- Define info, servers, tags, securitySchemes
- Add component schemas: NormalizedDownload, DashboardPayload, ErrorResponse,
  BlocklistSearchRequest, WebhookPayload, HistoryItem, StatusResponse
- Add path placeholders for all endpoints (to be merged with JSDoc)
- Document cookie-based auth + CSRF security scheme
- Import swagger-ui-express, swagger-jsdoc, yamljs in app.js and index.js
- Load server/openapi.yaml as base spec
- Configure swagger-jsdoc to merge JSDoc comments from route files
- Mount Swagger UI at /api/swagger (publicly accessible)
- Add authentication banner explaining cookie + CSRF flow
- Ensure spec loads from both createApp (tests) and index.js (production)
- POST /api/auth/login: rate-limited, sets httpOnly cookie, issues CSRF token
- GET /api/auth/me: returns current authenticated user
- GET /api/auth/csrf: refreshes CSRF token
- POST /api/auth/logout: clears cookies, revokes Emby token
- Include x-code-samples (curl, JS fetch, TypeScript)
- Include x-integration-notes for cookie flow
- Full JSON Schema with realistic examples
- GET /api/dashboard/user-downloads: deprecated, use SSE
- GET /api/dashboard/cover-art: image proxy for CSP compliance
- GET /api/dashboard/stream: SSE real-time updates, no CSRF needed
- POST /api/dashboard/blocklist-search: admin-only, removes + re-searches
- Document SSE event format and heartbeat
- Include admin-only constraints and error responses
- GET /api/status/status: admin-only, server/cache/polling/webhook metrics
- GET /api/history/recent: filtered by user tag, deduplication logic
- Document deduplication rules (imported suppresses failed)
- Document availableForUpgrade flag
- Include query parameters (days, showAll)
- POST /api/webhook/sonarr: secret validation, rate-limited, replay protection
- POST /api/webhook/radarr: identical processing logic
- Document X-Sofarr-Webhook-Secret header requirement
- List all valid eventType values
- Document event classification (QUEUE vs HISTORY)
- Include replay protection window (5 minutes)
- Sonarr: queue, history, series, notifications CRUD, webhook setup
- Radarr: queue, history, movies, notifications CRUD, webhook setup
- SABnzbd: queue, history
- Emby: sessions, users
- Document that these are authenticated proxies to upstream services
- Include notification proxy endpoints for webhook configuration
- GET /health: returns uptime, no auth/rate-limit
- GET /ready: checks EMBY_URL configuration, returns 503 if not ready
- Document Docker HEALTHCHECK usage
- Create tests/integration/swagger-coverage.test.js
- Validate OpenAPI spec loads without errors
- Assert every Express route appears in spec
- Check all examples are valid JSON
- Verify required security schemes are referenced
- Run as part of existing test suite
- Install @stoplight/spectral-cli as dev dependency
- Add "Swagger Validation & Coverage" job to .gitea/workflows/ci.yml
- Run spectral lint on server/openapi.yaml
- Run npm test to execute coverage tests
- Fail CI if spec is invalid or coverage is incomplete
- Runs on every push/PR alongside existing jobs
- Add section on accessing Swagger UI at /api/swagger
- Explain hybrid documentation: central YAML + JSDoc merge
- Document authentication flow for testing in Swagger UI
- Include cookie + CSRF token setup instructions
- Note that proxy routes reflect upstream *arr APIs
- Convert swagger-coverage.test.js to use ES module imports
- Use dynamic import for yamljs (CommonJS library)
- Fix Vitest compatibility issue
- Follow redirects for Swagger UI endpoint test
- Accept 404 for /api/swagger.json if not mounted in test mode
- Use merged spec for x-code-samples checks if available
- Fix x-integration-notes check to look for section header format
- Skip x-code-samples test if merged spec not available
fix(swagger): use merged spec for integration-notes check
Build and Push Docker Image / build (push) Successful in 1m26s
Licence Check / Licence compatibility and copyright header verification (push) Failing after 1m16s
CI / Swagger Validation & Coverage (push) Successful in 1m37s
CI / Security audit (push) Successful in 1m45s
CI / Tests & coverage (push) Failing after 1m53s
f3e1bd17fb
- Skip x-integration-notes test if merged spec not available
- The YAML file only has path placeholders without detailed descriptions
- JSDoc comments with x-integration-notes are merged at runtime
- Test will skip gracefully when /api/swagger.json returns 404
chore(release): bump version to 1.7.0
Docs Check / Markdown lint (push) Failing after 25s
Build and Push Docker Image / build (push) Successful in 1m22s
Licence Check / Licence compatibility and copyright header verification (push) Failing after 1m8s
CI / Swagger Validation & Coverage (push) Successful in 1m51s
CI / Security audit (push) Successful in 2m2s
Docs Check / Mermaid diagram parse check (push) Successful in 2m11s
CI / Tests & coverage (push) Failing after 2m17s
1ed01d0ef0
- Increment version from 1.6.0 to 1.7.0 in package.json
- Add detailed CHANGELOG.md entry for Swagger UI & OpenAPI 3.1 documentation
- Update README.md version highlight to mention Swagger UI
- Add API Documentation System section (7.4) to ARCHITECTURE.md
- Add swagger-ui-express, swagger-jsdoc, yamljs, spectral-cli to Technology Stack
- Update High-Level Architecture diagram with Swagger UI node
- Update Request routing summary to include /api/swagger
- Update SECURITY.md: Threat Model, Rate Limits, and Supported Versions tables
feat(ci): add RAML 1.0 package generation pipeline
Build and Push Docker Image / build (push) Successful in 1m27s
CI / Security audit (push) Successful in 1m43s
CI / Swagger Validation & Coverage (push) Failing after 1m56s
CI / Tests & coverage (push) Failing after 1m56s
Licence Check / Licence compatibility and copyright header verification (push) Successful in 53s
1a4ff73067
- Add generate:openapi, generate:raml, package:raml scripts to package.json
- Add archiver dependency for creating tar.gz archives
- Create scripts/generate-openapi.js to fetch merged OpenAPI spec from running server
- Create scripts/package-raml.js to build versioned RAML tar.gz archive
- Create .spectral.yml with minimal OpenAPI linting rules
- Add /api/swagger.json endpoint to server/app.js for serving merged spec
- Extend swagger job in ci.yml with RAML generation steps
- Upload raml-package artifact to CI with 14-day retention
feat: add automated RAML 1.0 package generation to CI/CD pipeline
Docs Check / Markdown lint (push) Successful in 1m6s
Licence Check / Licence compatibility and copyright header verification (push) Successful in 1m20s
Build and Push Docker Image / build (push) Successful in 1m35s
CI / Swagger Validation & Coverage (push) Failing after 2m0s
CI / Security audit (push) Successful in 2m6s
Docs Check / Mermaid diagram parse check (push) Successful in 2m20s
CI / Tests & coverage (push) Failing after 2m30s
37bed1cd4e
- Add RAML generation scripts (generate-openapi, downgrade-openapi, simple-raml-converter, package-raml)
- Add /api/swagger.json endpoint to server/app.js
- Add minimal .spectral.yml ruleset for OpenAPI linting
- Add npm scripts for OpenAPI/RAML generation and packaging
- Extend CI swagger job with RAML generation steps
- Upload raml-package artifact with 14-day retention
- Update CHANGELOG.md for v1.7.1
fix: resolve test failures - add missing emby route and fix YAML syntax errors
Build and Push Docker Image / build (push) Successful in 47s
Licence Check / Licence compatibility and copyright header verification (push) Successful in 1m5s
CI / Security audit (push) Successful in 1m48s
CI / Swagger Validation & Coverage (push) Successful in 2m0s
CI / Tests & coverage (push) Successful in 2m15s
4941b69924
- Add GET /api/emby/users/:id endpoint to fetch individual user by ID
- Fix YAML semantic errors in dashboard.js and history.js by quoting parameter descriptions with colons
- Add x-integration-notes to /api/dashboard/stream endpoint description
- All 644 tests now passing
feat: replace static Swagger UI server selector with dynamic client-side detection
Build and Push Docker Image / build (push) Successful in 56s
Licence Check / Licence compatibility and copyright header verification (push) Successful in 1m18s
CI / Security audit (push) Successful in 2m9s
CI / Swagger Validation & Coverage (push) Successful in 2m25s
CI / Tests & coverage (push) Successful in 2m44s
52a75fd8cb
- Update openapi.yaml to use single placeholder server URL
- Add swagger-server-detection.js to auto-detect current server URL from window.location
- Configure protocol, host, and port detection based on browser connection
- Fallback to placeholder URL if detection fails
- Include detection script in both app.js and index.js Swagger UI configurations
- /api/swagger.json endpoint returns static placeholder for external consumers
fix: replace client-side Swagger server detection with server-side dynamic spec
Licence Check / Licence compatibility and copyright header verification (push) Successful in 2m43s
CI / Security audit (push) Successful in 3m15s
Build and Push Docker Image / build (push) Successful in 4m6s
CI / Swagger Validation & Coverage (push) Successful in 4m14s
CI / Tests & coverage (push) Successful in 4m32s
de9a9284dc
- Change swaggerUi.setup to pass null and fetch spec from /api/swagger.json
- Update /api/swagger.json handler to dynamically set server URL based on request
- Remove dead client-side detection script (swagger-server-detection.js)
- Server-side detection respects TRUST_PROXY for reverse proxy scenarios
- req.protocol and req.get('host') automatically use X-Forwarded headers when configured
- Fixes issue where placeholder URL was never replaced due to window.ui being unavailable
feat(ombi): Add Ombi PALDRA integration for request management
Docs Check / Markdown lint (push) Successful in 1m43s
Licence Check / Licence compatibility and copyright header verification (push) Successful in 2m1s
CI / Security audit (push) Successful in 2m48s
Docs Check / Mermaid diagram parse check (push) Successful in 3m8s
CI / Tests & coverage (push) Failing after 3m33s
CI / Swagger Validation & Coverage (push) Successful in 3m34s
Build and Push Docker Image / build (push) Successful in 4m36s
ed4237debb
- Add OmbiRetriever extending ArrRetriever for PALDRA compliance
- Add OmbiClient for low-level Ombi API communication
- Add getOmbiInstances() to config.js following multi-instance pattern
- Register Ombi in PALDRA registry with Ombi-specific methods
- Add external ID matching (TMDB/TVDB/IMDB) to Ombi requests
- Update DownloadMatcher to be async and enrich downloads with Ombi links
- Add getOmbiLink/getOmbiSearchLink helpers to DownloadAssembler
- Implement new service icon layout (Ombi + Sonarr/Radarr icons)
- Add CSS styling for service icons
- Update dashboard routes to include Ombi configuration
- Extend OpenAPI with Ombi tag and NormalizedDownload properties
- Update documentation (README, ARCHITECTURE, SECURITY, CHANGELOG)
- Add Ombi configuration to .env.sample
- Add tests for Ombi configuration parsing (OMBI_INSTANCES JSON array, legacy fallback)
- Add tests for OmbiClient API methods (movie/TV requests, search by TMDB/IMDB/TVDB)
- Add tests for OmbiRetriever caching, queue, and search functionality
- Add tests for arrRetrieverRegistry initialization and retrieval methods
- Add tests for DownloadMatcher.addOmbiMatching integration
- Add tests for DownloadAssembler Ombi link generation utilities
- Export addOmbiMatching from DownloadMatcher module
fix: make buildUserDownloads async to resolve test failures
Build and Push Docker Image / build (push) Successful in 50s
Docs Check / Markdown lint (push) Successful in 1m11s
CI / Security audit (push) Successful in 2m1s
Licence Check / Licence compatibility and copyright header verification (push) Successful in 1m23s
CI / Tests & coverage (push) Successful in 2m30s
Docs Check / Mermaid diagram parse check (push) Successful in 2m9s
CI / Swagger Validation & Coverage (push) Successful in 4m2s
ecaedbaf6a
The buildUserDownloads function was calling async matcher functions
without awaiting them, causing Promise objects to be returned instead
of resolved arrays. This resulted in empty download lists and 17 failing
tests.

- Made buildUserDownloads async
- Added await to matchSabSlots, matchSabHistory, and matchTorrents calls
- Updated unit tests to await buildUserDownloads calls

All 759 tests now pass.
Fix: Add missing await before buildUserDownloads in SSE endpoint to resolve icon display issues
Build and Push Docker Image / build (push) Successful in 31s
Licence Check / Licence compatibility and copyright header verification (push) Successful in 1m19s
CI / Security audit (push) Successful in 1m34s
CI / Swagger Validation & Coverage (push) Successful in 1m40s
CI / Tests & coverage (push) Successful in 1m51s
4d860dc787
fix: add arrType field to history items for admin icon display
Build and Push Docker Image / build (push) Successful in 1m7s
Licence Check / Licence compatibility and copyright header verification (push) Successful in 2m20s
CI / Security audit (push) Successful in 2m45s
CI / Tests & coverage (push) Successful in 3m18s
CI / Swagger Validation & Coverage (push) Successful in 3m29s
e8037afbb8
Add arrType field to Sonarr and Radarr history items for admin users to enable proper icon display in the recently downloaded section. This mirrors the existing behavior in active downloads where arrType is set by DownloadMatcher.

Generated with [Devin](https://cli.devin.ai/docs)

Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com>
Fix: Generate Ombi links directly from TMDB ID; show on downloads and history for all users
Build and Push Docker Image / build (push) Successful in 49s
Licence Check / Licence compatibility and copyright header verification (push) Successful in 2m3s
CI / Security audit (push) Successful in 2m27s
CI / Swagger Validation & Coverage (push) Successful in 2m47s
CI / Tests & coverage (push) Failing after 2m49s
CI / Security audit (pull_request) Successful in 1m53s
CI / Swagger Validation & Coverage (pull_request) Successful in 2m36s
CI / Tests & coverage (pull_request) Failing after 2m46s
884fb5285f
- Replace Ombi API-based matching with simple TMDB ID link generation
- Movies link to {ombiBaseUrl}/details/movie/{tmdbId}
- TV shows link to {ombiBaseUrl}/details/tv/{tmdbId}
- Add ombiLink to all history items (Sonarr + Radarr) for all users
- Add ombiLink to torrent history matches that were previously missing it
- addOmbiMatching is now synchronous (no Ombi API calls)
Gandalf merged commit a85747a4c5 into main 2026-05-21 20:14:36 +01:00
Gandalf added the Kind/Feature label 2026-05-28 11:53:31 +01:00
Sign in to join this conversation.
No Reviewers
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: Gandalf/sofarr#28