Skip to content

Stabilize backend foundation and clarify boundaries#686

Open
therobbiedavis wants to merge 96 commits into
canaryfrom
677-backend-foundation-combined
Open

Stabilize backend foundation and clarify boundaries#686
therobbiedavis wants to merge 96 commits into
canaryfrom
677-backend-foundation-combined

Conversation

@therobbiedavis

@therobbiedavis therobbiedavis commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator

Summary

This PR completes the backend foundation roadmap from #677 by combining the dependency/test-loop stabilization from #679 with the backend boundary, workflow, worker, filesystem-safety, and startup cleanup from #685.

It makes backend validation deterministic, documents the intended architecture boundaries, moves implementation-shaped concerns out of listenarr.application, breaks large controllers/services into focused workflows, clarifies background-worker ownership, hardens file/import mutation paths, and simplifies API startup/security composition.

Closes #677. Supersedes #679 and #685.

Changes

Added

  • NuGet lock files for backend projects and tests, including CI publish runtime targets.
  • BACKEND_ARCHITECTURE.md with layer ownership, startup composition, worker ownership, retry/idempotency, and migration guidance.
  • Application-owned ports for HTML extraction, Audible author parsing, cover probing, audio tag writing, secret protection, request context access, realtime broadcasting, and worker processors.
  • Infrastructure implementations and registration extensions for those ports.
  • Focused workflow/helper types for library, search, metadata, image cache, Prowlarr/indexer, download, adapter, ffprobe, and notification paths.
  • End-to-end security pipeline coverage for auth enabled/disabled, API keys, sessions, CSRF, SignalR, and trusted forwarded headers.
  • Filesystem safety coverage using real temp directories for traversal, containment, archive extraction, cache writes, and mutation boundaries.

Changed

  • Enabled deterministic backend restore behavior with central package lock configuration and CI locked restore mode.
  • Updated CI publish jobs to use the restored graph with --no-restore.
  • Moved EF/SQLite, HTML parsing, image probing, audio tagging, Data Protection, SignalR, HTTP context, hosted worker, and framework-specific behavior out of application-facing code where appropriate.
  • Reduced very large controllers/services into smaller use-case workflows while preserving existing route and service behavior.
  • Split hosted workers so long-running services act as adapters around testable processor contracts.
  • Centralized startup registration, security setup, middleware ordering, static assets, Swagger, startup tasks, and pipeline mapping into focused API startup modules.
  • Updated AI/contributor guidance to point agents at repository rules and architecture docs before code changes.
  • Updated frontend dependency metadata and router access to remove the auth-store dynamic import warning.

Fixed

  • Fixed backend test compilation failures caused by dependency drift, including EF Core version mismatch.
  • Fixed locked restore coverage for RID-specific CI publish targets.
  • Hardened imports, moves, deletes, cache writes, archive extraction, remote mappings, and ffprobe paths with shared containment/final-target validation.
  • Stopped request context snapshots from trusting raw forwarded host/proto headers outside ASP.NET Core forwarded-header handling.
  • Preserved private webhook behavior for IPv4-mapped loopback local callers.
  • Filtered the known upstream VueUse/Rolldown annotation warning without hiding unrelated build warnings.
  • Addressed PR review findings around metadata duration comparisons and remote-path mapping test expectations.

Testing

  • dotnet build listenarr.slnx --no-restore - 0 warnings, 0 errors
  • dotnet test listenarr.slnx --no-build - 696 passed before the later worker/filesystem/security additions
  • dotnet test listenarr.slnx -c Release --filter "FullyQualifiedName~RemotePathMappingServiceTests.TranslatePathAsync_HappyPath" - 6 passed
  • dotnet test listenarr.slnx -c Release --no-build --filter "FullyQualifiedName~SecurityPipelineEndToEndTests|FullyQualifiedName~ArchiveExtractorSafetyTests|FullyQualifiedName~FileStorageSafetyTests|FullyQualifiedName~WorkerProcessorBoundaryTests|FullyQualifiedName~WorkerCycleRunnerTests" - 28 passed
  • cd fe && npm run test:unit -- --run - 378 passed, 1 skipped test file
  • cd fe && npm run build
  • cd fe && npm run lint:check
  • git diff --check origin/canary...HEAD
  • Push hook also ran backend format, frontend type check, and frontend tests successfully.

Notes

This intentionally replaces the separate dependency and architecture PRs so the backend foundation lands as one coherent review: first make validation deterministic, then clarify architecture boundaries, then harden the highest-trust runtime paths before more feature work builds on top.

Enable deterministic NuGet restores for backend projects by turning on package lock files and CI locked restore mode. Add generated NuGet lock files so local and CI test runs resolve the same dependency graph before `dotnet test --no-restore`.

Pull in the dependency updates from `chore/dependency-update`, including the Node engine update to `^24.15.0` and refreshed root/frontend npm lockfiles.

Clean up frontend build warnings introduced during dependency validation by removing the auth store's dynamic router import and moving router instance access into a small shared service. Add a narrow Vite/Rolldown warning filter for known upstream `@vueuse/core` pure annotation noise.

Validated with:
- `dotnet restore listenarr.slnx /p:CI=true`
- `dotnet test listenarr.slnx --no-restore`
- `npm install`
- `cd fe && npm install`
- `cd fe && npm run test:unit`
- `cd fe && npm run build`
- `cd fe && npm run lint:check`
- `git diff --check`
@therobbiedavis therobbiedavis requested a review from a team June 12, 2026 02:29
@therobbiedavis therobbiedavis added the patch patch version bump - backward compatible bug fixes label Jun 12, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a2700aa2f7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread listenarr.application/Notification/NotificationService.cs Outdated
Comment thread listenarr.api/Controllers/LibraryAddWorkflow.cs Dismissed
Comment thread listenarr.application/Downloads/MyAnonamouseTorrentPreparationService.cs Dismissed
- Move author catalog keying, matching, language normalization, and cache DTO mapping into a focused helper
- Keep author catalog lookup and persistence orchestration in the service
- Preserve focused author and metadata test coverage
- Move compatibility indexer response shaping into a focused builder
- Preserve read versus save API-key response behavior
- Remove the stale private field DTO from the controller
- Move final ASIN disposition auditing out of SearchService
- Preserve candidate drop reason mutation and diagnostic logging
- Register the helper in API and infrastructure service setup
- Move torrent bencode rewrite and announce parsing logic into a focused helper
- Keep MyAnonamouseHelper public methods as compatibility delegates
- Preserve MAM and torrent-focused test coverage
- Move platform-specific ffprobe download URL and checksum defaults into a focused helper
- Keep installation orchestration and provider override behavior unchanged
- Preserve ffmpeg-focused test coverage
- Move title search ASIN lookup and Discord response shaping into a focused workflow
- Keep route status codes and response payloads unchanged
- Register the workflow through API startup
- Move validated notification HTTP sending and redirect checks into a focused helper
- Preserve request-context private target rules and existing HttpClient behavior
- Keep provider-specific notification dispatch unchanged
- Replace inline search result image cache handling with SearchResponseMapper
- Remove the now-unused controller image path wrapper
- Preserve search-controller focused test coverage
- Move MyAnonamouse torrent download URL construction into a focused helper
- Preserve mam_id decode and encode behavior
- Keep parser mapping behavior unchanged
- Move SABnzbd queue/history merge behavior into a focused workflow
- Move SABnzbd import item resolution into a dedicated resolver
- Keep adapter interface and request/response semantics unchanged
- Move NZBGet add orchestration into a focused workflow

- Move NZBGet import item history resolution into a dedicated resolver

- Keep adapter interface and XML-RPC behavior unchanged
- Move MyAnonamouse debug-search orchestration into a focused workflow

- Keep route, response payloads, and local parsed-search behavior unchanged
- Move existing-quality cutoff evaluation into a focused helper

- Move automatic download-client selection into a dedicated selector

- Keep search scheduling, scoring, and download queuing behavior unchanged
- Move qBittorrent import path resolution into a focused resolver

- Keep queue-item and download-client-item import behavior unchanged
- Move Transmission import path resolution into a focused resolver

- Keep RPC lookup, content path, and source-file behavior unchanged
- Move ffprobe archive expansion and traversal checks into a focused helper

- Keep install discovery, checksum validation, and binary promotion behavior unchanged
- Add shared worker cycle and processor interfaces

- Wire hosted workers through processor contracts

- Add ownership and import handoff guard tests
- Move scan and move orchestration into processor services

- Keep hosted services as queue adapters

- Add processor tests and worker metrics
- Extract hosted worker logic into explicit processors
- Document ownership, retry, idempotency, and handoffs
- Add processor boundary and worker metric tests
- Rename moved-download cleanup hosted adapter
- Add shared containment and final-target validation for filesystem mutations

- Harden imports, moves, deletes, cache writes, archive extraction, remote mappings, and ffprobe paths

- Add temp-directory coverage for traversal, idempotent imports, mapping boundaries, and cache safety
- Cover archive extraction traversal blocking with real temp directories

- Cover file storage write/delete containment around allowed roots
- Split API startup into focused registration and pipeline modules

- Move security setup and middleware ordering into one startup module

- Add end-to-end coverage for auth, CSRF, SignalR, and proxy headers
- Use epsilon checks for metadata duration updates

- Align remote path mapping test with exact-root behavior
- Use epsilon checks for metadata duration updates

- Align remote path mapping test with exact-root behavior
- Expect exact remote path mappings to preserve directory root separators
- Remove trailing spaces from license header blank lines
- Restore clean git diff whitespace validation
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

patch patch version bump - backward compatible bug fixes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Backend architecture priorities: stabilize tests, boundaries, and runtime workflows

2 participants