gronod
1a4ff73067
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
- 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
2026-05-21 14:04:26 +01:00
gronod
afa6ebc3c7
fix(ci): allow Python-2.0 licence in licence-check
2026-05-21 14:03:45 +01:00
gronod
1ed01d0ef0
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
- 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
2026-05-21 13:35:31 +01:00
gronod
f3e1bd17fb
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
- 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
2026-05-21 12:51:40 +01:00
gronod
bcdbbec804
fix(swagger): adjust coverage test for test environment
...
- 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
2026-05-21 12:51:19 +01:00
gronod
db9b3e7a30
fix(swagger): convert coverage test to ES modules
...
- Convert swagger-coverage.test.js to use ES module imports
- Use dynamic import for yamljs (CommonJS library)
- Fix Vitest compatibility issue
2026-05-21 12:40:54 +01:00
gronod
e254873bee
docs(swagger): document Swagger UI and hybrid approach
...
- 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
2026-05-21 12:39:45 +01:00
gronod
7dadb849f6
ci(swagger): add OpenAPI validation job to CI
...
- 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
2026-05-21 12:39:13 +01:00
gronod
6980558ca9
test(swagger): add coverage validation test
...
- 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
2026-05-21 12:38:29 +01:00
gronod
a141bb57d6
docs(swagger): add JSDoc @openapi for public health endpoints
...
- GET /health: returns uptime, no auth/rate-limit
- GET /ready: checks EMBY_URL configuration, returns 503 if not ready
- Document Docker HEALTHCHECK usage
2026-05-21 12:38:02 +01:00
gronod
43f5a52749
docs(swagger): add JSDoc @openapi for proxy routes
...
- 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
2026-05-21 12:37:36 +01:00
gronod
5c0ad7cb1b
docs(swagger): add JSDoc @openapi for webhook endpoints
...
- 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)
2026-05-21 12:36:43 +01:00
gronod
a21bafa041
docs(swagger): add JSDoc @openapi for status and history endpoints
...
- 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)
2026-05-21 12:36:07 +01:00
gronod
12effe17d3
docs(swagger): add JSDoc @openapi for dashboard endpoints
...
- 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
2026-05-21 12:32:29 +01:00
gronod
1bb9e4014e
docs(swagger): add JSDoc @openapi for auth endpoints
...
- 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
2026-05-21 12:31:41 +01:00
gronod
964dacc588
feat(swagger): mount Swagger UI at /api/swagger
...
- 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)
2026-05-21 12:30:53 +01:00
gronod
777fa26e5b
feat(swagger): add central OpenAPI 3.1 specification file
...
- 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
2026-05-21 12:30:01 +01:00
gronod
93a8c3fd2e
feat(swagger): create develop-swagger branch and install dependencies
...
- Install swagger-ui-express, swagger-jsdoc, yamljs
- Prepare for OpenAPI 3.1 spec integration
2026-05-21 12:28:52 +01:00
gronod
5d0da45e10
chore: bump version to 1.6.0, update CHANGELOG and ARCHITECTURE docs
Build and Push Docker Image / build (push) Successful in 48s
CI / Security audit (push) Successful in 1m23s
Docs Check / Markdown lint (push) Successful in 1m10s
CI / Tests & coverage (push) Successful in 1m47s
Licence Check / Licence compatibility and copyright header verification (push) Successful in 1m18s
Docs Check / Mermaid diagram parse check (push) Successful in 1m44s
2026-05-21 11:49:57 +01:00
Gandalf
adbb0c12c1
Merge pull request 'fix: remove client/ from .dockerignore to fix Docker client-build stage' ( #27 ) from develop-refactor into develop-refactor2
...
Build and Push Docker Image / build (push) Successful in 43s
CI / Security audit (push) Successful in 1m20s
CI / Tests & coverage (push) Successful in 1m33s
Reviewed-on: #27
2026-05-21 09:28:17 +01:00
gronod
9a4408e797
Fix CSRF token and currentUser references in api.js
...
Build and Push Docker Image / build (push) Successful in 52s
Licence Check / Licence compatibility and copyright header verification (push) Successful in 1m17s
CI / Security audit (push) Successful in 1m31s
CI / Tests & coverage (push) Successful in 1m47s
- Use state.csrfToken instead of undefined csrfToken in handleLogout
- Use state.currentUser instead of undefined currentUser in handleLogout
- Use state.csrfToken instead of undefined csrfToken in enableSonarrWebhook
- Fixes ReferenceError bugs in logout and webhook functions
2026-05-21 02:17:48 +01:00
gronod
05cf5a0993
Fix blocklist CSRF token reference error
...
Build and Push Docker Image / build (push) Successful in 56s
CI / Security audit (push) Has been cancelled
CI / Tests & coverage (push) Has been cancelled
Licence Check / Licence compatibility and copyright header verification (push) Has been cancelled
- Use state.csrfToken instead of undefined csrfToken variable
- Fixes ReferenceError when clicking blocklist button
2026-05-21 02:16:34 +01:00
gronod
bb10cd4aef
Add client-side logging to blocklist button for debugging
...
Build and Push Docker Image / build (push) Successful in 53s
CI / Tests & coverage (push) Has been cancelled
Licence Check / Licence compatibility and copyright header verification (push) Successful in 1m23s
CI / Security audit (push) Has been cancelled
- Log download object and required fields when button is clicked
- Shows which fields are present/absent to diagnose blocklist issues
2026-05-21 02:15:09 +01:00
gronod
251c10f08c
Add logging to blocklist-search endpoint for debugging
...
CI / Tests & coverage (push) Failing after 31s
Build and Push Docker Image / build (push) Successful in 40s
Licence Check / Licence compatibility and copyright header verification (push) Successful in 1m10s
CI / Security audit (push) Successful in 1m28s
- Log missing required fields to help diagnose blocklist issues
- Shows which fields are present/absent in the request body
2026-05-21 02:11:45 +01:00
gronod
474ae949a9
Fix progress calculation to support both mbleft and mbmissing fields
...
Build and Push Docker Image / build (push) Successful in 35s
Licence Check / Licence compatibility and copyright header verification (push) Successful in 1m13s
CI / Security audit (push) Successful in 1m26s
CI / Tests & coverage (push) Successful in 1m44s
- SABnzbd API uses different field names for remaining bytes
- Test data uses mbmissing, but real API may use mbleft
- Support both field names to handle all cases
- Fixes DownloadBuilder test failures
2026-05-21 02:07:54 +01:00
gronod
084cb0579e
Fix missing progress bar for SABnzbd downloads
...
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 1m26s
CI / Tests & coverage (push) Failing after 1m39s
- Calculate progress from slot.mb and slot.mbleft instead of slot.percentage
- Apply fix to both series and movie downloads in matchSabSlots
- Add progress: 100 for history items in matchSabHistory (series and movie)
- SABnzbd slot data doesn't have percentage field, so progress was undefined
2026-05-21 01:55:03 +01:00
gronod
93a09e10a8
Fix background fetch to not overwrite cache with empty data
...
Build and Push Docker Image / build (push) Successful in 36s
Licence Check / Licence compatibility and copyright header verification (push) Successful in 1m18s
CI / Security audit (push) Successful in 1m13s
CI / Tests & coverage (push) Successful in 1m15s
- Only trigger background refresh if cache is incomplete (less than max records)
- Only update cache if background fetch returns records (don't overwrite on failure)
- Prevents test failures when background fetch fails to connect to Sonarr/Radarr
- Fixes integration test 'includes imported and failed records, excludes grabbed'
2026-05-21 01:53:19 +01:00
gronod
47817d057b
Fix status route test paths
...
Build and Push Docker Image / build (push) Successful in 1m3s
Licence Check / Licence compatibility and copyright header verification (push) Successful in 1m17s
CI / Security audit (push) Successful in 1m33s
CI / Tests & coverage (push) Failing after 1m41s
- Update test paths from /api/status/status to /api/status
- Matches the route change from /status to / in status.js
2026-05-21 01:51:00 +01:00
gronod
f6ad7c85bf
Fix inconsistent speed formatting in download updates
...
Build and Push Docker Image / build (push) Successful in 55s
Licence Check / Licence compatibility and copyright header verification (push) Successful in 1m7s
CI / Security audit (push) Successful in 1m32s
CI / Tests & coverage (push) Failing after 1m51s
- Use formatSpeed() when updating existing download card speed
- Ensures consistent unit display (B/s, KB/s, MB/s, GB/s) across all updates
- Previously used raw speed value causing inconsistent display
2026-05-21 01:48:00 +01:00
gronod
a349c8e2cf
Fix status route path to avoid 404
...
Build and Push Docker Image / build (push) Successful in 39s
Licence Check / Licence compatibility and copyright header verification (push) Successful in 52s
CI / Security audit (push) Successful in 1m12s
CI / Tests & coverage (push) Failing after 1m17s
- Change route from '/status' to '/' since router is mounted at '/api/status'
- Fixes HTML 404 response when client calls /api/status
2026-05-21 01:41:24 +01:00
gronod
f2b44f65af
Fix logout button by using state object references
...
Build and Push Docker Image / build (push) Successful in 38s
Licence Check / Licence compatibility and copyright header verification (push) Successful in 1m5s
CI / Security audit (push) Successful in 1m17s
CI / Tests & coverage (push) Failing after 1m32s
- Fix undefined variable references in handleLogoutClick
- Use state.statusRefreshHandle instead of statusRefreshHandle
- Use state.currentUser instead of currentUser
2026-05-21 01:39:00 +01:00
gronod
b3664747cb
Add error display for status panel failures
...
Build and Push Docker Image / build (push) Successful in 50s
Licence Check / Licence compatibility and copyright header verification (push) Successful in 1m8s
CI / Security audit (push) Successful in 1m20s
CI / Tests & coverage (push) Has been cancelled
- Show error message when status API returns error (e.g., 403 for non-admin)
- Helps debug why status panel appears empty
2026-05-21 01:37:31 +01:00
gronod
14b47ce410
Fix history pagination and status panel issues
...
Build and Push Docker Image / build (push) Successful in 52s
Docs Check / Markdown lint (push) Successful in 1m1s
CI / Tests & coverage (push) Failing after 1m32s
CI / Security audit (push) Successful in 1m33s
Docs Check / Mermaid diagram parse check (push) Successful in 1m38s
Licence Check / Licence compatibility and copyright header verification (push) Successful in 56s
- Fix history pagination: use retriever's built-in maxPages parameter instead of broken date-based cursor
- Fix status panel: correct API endpoint from /api/dashboard/status to /api/status
- Background fetch now properly fetches up to 1000 records (10 pages * 100 records)
- Status panel will now display details instead of 'Loading Status...'
2026-05-21 01:34:54 +01:00
gronod
5ec5484b91
docs(ARCHITECTURE): update to reflect develop-refactor2 changes
...
- Add Download Matching & Assembly Services section (3.3)
covering DownloadBuilder, DownloadMatcher, DownloadAssembler,
TagMatcher, and WebhookStatus
- Update High-Level Architecture diagram with /api/status route
- Update Data Flow pipeline to show service-based matching,
stable downloadId priority, deduplication, unmatched-torrent exclusion
- Update Key Subsystems: Vite+ES module frontend, client/src tree,
CSP compliance, PDCA client fix callouts
- Update Directory Structure with services/, client/src/, tests/frontend/
- Update Technology Stack with jsdom and Vite build notes
- Update webhook replay protection and PALDRA pagination details
2026-05-21 01:32:36 +01:00
gronod
05c9527189
Add comprehensive tests for staged history loading
...
Build and Push Docker Image / build (push) Successful in 50s
Licence Check / Licence compatibility and copyright header verification (push) Successful in 58s
CI / Security audit (push) Successful in 1m6s
CI / Tests & coverage (push) Successful in 1m25s
Unit tests:
- Staged loading (initial batch, background fetch, concurrent requests)
- Deduplication (by record ID, empty record sets)
- Event subscription (subscribe/unsubscribe, error handling)
- Pagination (max records limit, batch sizes)
Integration tests:
- Race conditions (concurrent requests, cache consistency, duplicate handling)
- Edge cases (empty history, single record, batch boundaries)
Tests verify:
- No records are missed during staged loading
- No duplicates are created
- Cache remains consistent during concurrent operations
- Background fetch doesn't interfere with concurrent user requests
2026-05-21 01:28:37 +01:00
gronod
f461c3669c
Add client-side handler for history-update SSE events
CI / Security audit (push) Failing after 4s
Build and Push Docker Image / build (push) Successful in 19s
Licence Check / Licence compatibility and copyright header verification (push) Successful in 30s
CI / Tests & coverage (push) Successful in 45s
2026-05-21 01:23:30 +01:00
gronod
0acd452ebd
Implement staged history loading with SSE push
...
Build and Push Docker Image / build (push) Has been cancelled
Licence Check / Licence compatibility and copyright header verification (push) Has been cancelled
CI / Tests & coverage (push) Has been cancelled
CI / Security audit (push) Has been cancelled
- Stage 1: Fetch 100 records immediately for fast display
- Stage 2+: Background fetch up to 1000 records in batches of 100
- Date-based cursor pagination to avoid race conditions
- Deduplication by record ID to prevent duplicates
- SSE push to clients when history cache is updated
- Shared background fetch state for concurrent user requests
2026-05-21 01:23:11 +01:00
gronod
dbdfe3f329
Fix status button ID mismatch - use status-btn instead of status-toggle
Build and Push Docker Image / build (push) Successful in 45s
Licence Check / Licence compatibility and copyright header verification (push) Successful in 1m3s
CI / Security audit (push) Successful in 1m17s
CI / Tests & coverage (push) Successful in 1m23s
2026-05-21 01:12:55 +01:00
gronod
b9b5d7d393
Increase history pageSize from 100 to 500 to fetch more records
...
Build and Push Docker Image / build (push) Successful in 39s
Licence Check / Licence compatibility and copyright header verification (push) Successful in 55s
CI / Security audit (push) Successful in 1m6s
CI / Tests & coverage (push) Successful in 1m15s
Fixes issue where series beyond position 100 in history were not appearing
in recently completed section.
2026-05-21 01:10:36 +01:00
gronod
7424e70ea6
Add logging for total Sonarr/Radarr records fetched
Build and Push Docker Image / build (push) Successful in 27s
Licence Check / Licence compatibility and copyright header verification (push) Successful in 59s
CI / Security audit (push) Successful in 1m13s
CI / Tests & coverage (push) Successful in 1m28s
2026-05-21 01:06:28 +01:00
gronod
830dea3d6b
Add logging for filtered event types and missing series/movie objects
Build and Push Docker Image / build (push) Successful in 39s
Licence Check / Licence compatibility and copyright header verification (push) Successful in 1m16s
CI / Security audit (push) Successful in 1m24s
CI / Tests & coverage (push) Successful in 1m43s
2026-05-21 01:02:57 +01:00
gronod
4ff462b7f4
Add detailed logging for all series/movies with raw tag IDs to debug missing items
Build and Push Docker Image / build (push) Successful in 36s
Licence Check / Licence compatibility and copyright header verification (push) Successful in 1m2s
CI / Security audit (push) Successful in 1m7s
CI / Tests & coverage (push) Has been cancelled
2026-05-21 01:01:14 +01:00
gronod
d9f1fc99a9
Add debugging logs for history filtering to diagnose missing series
Build and Push Docker Image / build (push) Successful in 31s
Licence Check / Licence compatibility and copyright header verification (push) Successful in 30s
CI / Security audit (push) Successful in 44s
CI / Tests & coverage (push) Successful in 55s
2026-05-21 00:58:10 +01:00
gronod
46b42045f1
Fix tab selection - use data-tab attribute instead of missing IDs
Build and Push Docker Image / build (push) Successful in 40s
Licence Check / Licence compatibility and copyright header verification (push) Successful in 30s
CI / Security audit (push) Successful in 49s
CI / Tests & coverage (push) Successful in 1m3s
2026-05-21 00:55:18 +01:00
gronod
d12356e8f3
fix: update test to reflect that unmatched torrents should not be displayed
Build and Push Docker Image / build (push) Successful in 34s
Licence Check / Licence compatibility and copyright header verification (push) Successful in 29s
CI / Security audit (push) Successful in 46s
CI / Tests & coverage (push) Successful in 55s
2026-05-21 00:50:33 +01:00
gronod
6124ec0f5a
Exclude public directory from copyright header check
...
Build and Push Docker Image / build (push) Successful in 30s
Licence Check / Licence compatibility and copyright header verification (push) Successful in 39s
CI / Security audit (push) Successful in 44s
CI / Tests & coverage (push) Failing after 54s
The public directory contains minified/bundled build artifacts that
should not require copyright headers.
2026-05-21 00:44:07 +01:00
gronod
fd303699db
Add file details to copyright header check failure output
...
Build and Push Docker Image / build (push) Successful in 19s
Licence Check / Licence compatibility and copyright header verification (push) Failing after 37s
CI / Security audit (push) Successful in 52s
CI / Tests & coverage (push) Failing after 53s
When copyright header check fails, now outputs the actual first 5 lines
of each failing file to help diagnose the issue.
2026-05-21 00:40:41 +01:00
gronod
8f19da3ae6
Improve license check to output failing package names
...
Build and Push Docker Image / build (push) Successful in 40s
Licence Check / Licence compatibility and copyright header verification (push) Failing after 33s
CI / Security audit (push) Successful in 55s
CI / Tests & coverage (push) Failing after 1m1s
When license compatibility check fails, now outputs full license report
showing which packages have incompatible licenses.
2026-05-21 00:38:53 +01:00
gronod
3c9dd3ca62
Fix: Remove unmatched torrents from download display
...
Build and Push Docker Image / build (push) Successful in 12s
Licence Check / Licence compatibility and copyright header verification (push) Failing after 31s
CI / Security audit (push) Successful in 44s
CI / Tests & coverage (push) Failing after 53s
Downloads with no match in Sonarr or Radarr were being displayed
when they should not be. Removed the code in matchTorrents that
was adding unmatched torrents to results.
2026-05-21 00:37:37 +01:00
gronod
f02c30efde
Fix CSP violations and ignoreAvailable reference error
...
Build and Push Docker Image / build (push) Successful in 27s
Licence Check / Licence compatibility and copyright header verification (push) Failing after 40s
CI / Security audit (push) Successful in 54s
CI / Tests & coverage (push) Successful in 1m7s
- Add .hidden utility class to style.css for CSP compliance
- Replace all inline style='display: none' with class='hidden' in HTML
- Update all UI modules to use classList.add/remove instead of style.display
- Fix ignoreAvailable reference error in history.js (use state.ignoreAvailable)
- Rebuild client bundle with vite
2026-05-21 00:33:57 +01:00