Improve seeding rule customization#553
Conversation
|
@sourcery-ai review |
Codecov Report❌ Patch coverage is 📢 Thoughts on this report? Let us know! |
Greptile SummaryThis PR significantly extends seeding rule customization by adding per-rule
Confidence Score: 4/5Safe to merge after fixing the Categories sanitization gap; all other logic is sound. Two P1 findings (create and update paths both skip SanitizeStringList for Categories) mean rules with whitespace in category values will silently never fire. The fix is a one-liner in each location. Everything else — migration, evaluator logic, priority ordering, tag filtering, tests — looks correct. code/backend/Cleanuparr.Api/Features/DownloadCleaner/Controllers/SeedingRulesController.cs — both CreateRule and UpdateSeedingRule methods
|
| Filename | Overview |
|---|---|
| code/backend/Cleanuparr.Api/Features/DownloadCleaner/Controllers/SeedingRulesController.cs | New CRUD + reorder endpoints for seeding rules; Categories list skips sanitization on both create and update, causing potential silent match failures. |
| code/backend/Cleanuparr.Infrastructure/Services/SeedingRuleEvaluator.cs | New evaluator that matches torrents to seeding rules by category, tracker pattern, tags (ITagFilterable), and privacy type; logic is correct and well-tested. |
| code/backend/Cleanuparr.Api/Features/DownloadCleaner/SeedingRuleHelper.cs | Helper for querying per-type seeding rule tables; clean dispatch pattern with both tracked and no-tracking variants. |
| code/backend/Cleanuparr.Persistence/Migrations/Data/20260408081126_AddSeedingRuleEnhancements.cs | Adds categories, priority, tracker_patterns, tags_any, tags_all columns across all five seeding rule tables; data migration backfills categories from name and assigns sequential priorities. |
| code/backend/Cleanuparr.Infrastructure.Tests/Services/SeedingRuleEvaluatorTests.cs | Comprehensive unit tests for the new evaluator using NSubstitute; covers category, tracker, tags, privacy, priority ordering, and edge cases. |
| code/backend/Cleanuparr.Infrastructure/Features/DownloadClient/DownloadService.cs | Base service wired to inject ISeedingRuleEvaluator; CleanDownloadsAsync delegates per-torrent rule selection to the evaluator correctly. |
| code/backend/Cleanuparr.Persistence/Models/Configuration/DownloadCleaner/ISeedingRule.cs | Interface extended with Categories, TrackerPatterns, and Priority; clean design. |
| code/backend/Cleanuparr.Persistence/Models/Configuration/DownloadCleaner/ITagFilterable.cs | New interface for tag-based filtering, implemented only by qBittorrent and Transmission rule models. |
| code/backend/Cleanuparr.Infrastructure.Tests/Features/DownloadClient/DelugeServiceFixture.cs | Fixture updated to add ISeedingRuleEvaluator mock; uses Moq for the new mock while CLAUDE.md prefers NSubstitute for new additions. |
| code/backend/Cleanuparr.Api/Features/DownloadCleaner/Contracts/Requests/SeedingRuleRequest.cs | Request record extended with Categories, TrackerPatterns, TagsAny, TagsAll, and optional Priority; validation annotations are appropriate. |
Sequence Diagram
sequenceDiagram
participant Client as API Client
participant SC as SeedingRulesController
participant SRH as SeedingRuleHelper
participant DB as DataContext (SQLite)
participant DS as DownloadService
participant SRE as SeedingRuleEvaluator
Client->>SC: POST /api/seeding-rules/{clientId}
SC->>DB: GetForClientAsync (existing rules)
SC->>SC: Auto-assign Priority (max+1) or use provided
SC->>DB: AddRuleToDbSet + SaveChanges
Client->>SC: PUT /api/seeding-rules/{clientId}/reorder
SC->>SRH: GetForClientTrackedAsync
SC->>SC: Validate IDs (no dupes, count match, all exist)
SC->>DB: Assign sequential priorities + SaveChanges
Note over DS,SRE: During cleanup job execution
DS->>DS: FilterDownloadsToBeCleanedAsync (category pre-filter)
DS->>SRH: GetForClientAsync (bulk load rules)
loop Each torrent
DS->>SRE: GetMatchingRule(torrent, rules)
SRE->>SRE: OrderBy Priority → FirstOrDefault(Matches)
SRE-->>DS: ISeedingRule? (matched rule)
DS->>DS: ShouldCleanDownload(ratio, seedTime, rule)
DS->>DS: DeleteDownload if threshold met
end
Reviews (1): Last reviewed commit: "removed confusing doc phrases" | Re-trigger Greptile
There was a problem hiding this comment.
Pull request overview
Adds tracker/tag-aware seeding rules with explicit priority ordering (including UI drag-and-drop reorder) to enable fine-grained cleanup policies per tracker and rule precedence (relates to #200).
Changes:
- Extend seeding rules with
categories,trackerPatterns, optional tag/label filters, andpriority; evaluate rules by lowest priority first. - Add a reorder API endpoint plus frontend drag-and-drop UI to persist rule priority order.
- Update persistence schema/migrations and expand automated coverage (backend unit tests + Playwright e2e).
Reviewed changes
Copilot reviewed 72 out of 73 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| e2e/tests/helpers/app-api.ts | Adds API helpers for rule reordering and download client CRUD used by e2e tests. |
| e2e/tests/12-seeding-rules-api.spec.ts | New Playwright coverage for CRUD + reorder semantics + validation. |
| docs/docs/configuration/download-cleaner/index.mdx | Updates docs to describe rule-based matching (categories/tracker/tags) and priority evaluation. |
| code/frontend/src/app/shared/models/download-cleaner-config.model.ts | Extends seeding rule model with new matching/prioritization fields and defaults. |
| code/frontend/src/app/features/settings/download-cleaner/download-cleaner.component.ts | Adds modal fields for new rule criteria and drag-drop reorder behavior. |
| code/frontend/src/app/features/settings/download-cleaner/download-cleaner.component.scss | Styles for draggable rule cards, priority badge, and hint text. |
| code/frontend/src/app/features/settings/download-cleaner/download-cleaner.component.html | UI updates: categories badges, tracker-pattern count badge, reorder controls, and new form fields. |
| code/frontend/src/app/core/services/documentation.service.ts | Adds doc anchors for new seeding rule fields. |
| code/frontend/src/app/core/api/download-cleaner.api.ts | Adds reorderSeedingRules API call. |
| code/backend/Cleanuparr.Persistence/Models/Configuration/DownloadCleaner/UTorrentSeedingRule.cs | Adds categories/tracker patterns/priority; validates categories non-empty. |
| code/backend/Cleanuparr.Persistence/Models/Configuration/DownloadCleaner/TransmissionSeedingRule.cs | Adds categories/tracker patterns/tags + priority; implements tag filtering interface. |
| code/backend/Cleanuparr.Persistence/Models/Configuration/DownloadCleaner/RTorrentSeedingRule.cs | Adds categories/tracker patterns/priority; validates categories non-empty. |
| code/backend/Cleanuparr.Persistence/Models/Configuration/DownloadCleaner/QBitSeedingRule.cs | Adds categories/tracker patterns/tags + priority; implements tag filtering interface. |
| code/backend/Cleanuparr.Persistence/Models/Configuration/DownloadCleaner/ITagFilterable.cs | New marker interface for rules supporting tag/label filtering. |
| code/backend/Cleanuparr.Persistence/Models/Configuration/DownloadCleaner/ISeedingRule.cs | Expands seeding rule contract to include categories/tracker patterns/priority. |
| code/backend/Cleanuparr.Persistence/Models/Configuration/DownloadCleaner/DelugeSeedingRule.cs | Adds categories/tracker patterns/priority; validates categories non-empty. |
| code/backend/Cleanuparr.Persistence/Migrations/Data/DataContextModelSnapshot.cs | Snapshot updates for new columns. |
| code/backend/Cleanuparr.Persistence/Migrations/Data/20260408081126_AddSeedingRuleEnhancements.Designer.cs | New EF migration designer for schema enhancements. |
| code/backend/Cleanuparr.Persistence/Migrations/Data/20260408081126_AddSeedingRuleEnhancements.cs | Migration adds new columns + data backfill + priority assignment. |
| code/backend/Cleanuparr.Persistence/DataContext.cs | Adds JSON list conversions for new list fields on seeding rule entities. |
| code/backend/Cleanuparr.Persistence/Converters/JsonStringListConverter.cs | New EF value converter to store List<string> as JSON in SQLite TEXT columns. |
| code/backend/Cleanuparr.Persistence.Tests/Models/Configuration/DownloadCleaner/SeedingRuleTests.cs | Updates tests to populate required Categories. |
| code/backend/Cleanuparr.Infrastructure/Services/UriService.cs | Refactors domain parsing regex to use GeneratedRegex. |
| code/backend/Cleanuparr.Infrastructure/Services/SeedingRuleEvaluator.cs | New evaluator: priority-ordered matching across category/tracker/tags/privacy. |
| code/backend/Cleanuparr.Infrastructure/Services/QueueRuleManager.cs | Renames queue rule manager implementation and logger types. |
| code/backend/Cleanuparr.Infrastructure/Services/QueueRuleEvaluator.cs | Renames queue rule evaluator and updates injected interfaces. |
| code/backend/Cleanuparr.Infrastructure/Services/Interfaces/ISeedingRuleEvaluator.cs | New interface for seeding rule matching logic. |
| code/backend/Cleanuparr.Infrastructure/Services/Interfaces/IQueueRuleManager.cs | Renames queue rule manager interface. |
| code/backend/Cleanuparr.Infrastructure/Services/Interfaces/IQueueRuleEvaluator.cs | Renames queue rule evaluator interface. |
| code/backend/Cleanuparr.Infrastructure/Features/DownloadClient/UTorrent/UTorrentServiceQC.cs | Switches to IQueueRuleEvaluator naming. |
| code/backend/Cleanuparr.Infrastructure/Features/DownloadClient/UTorrent/UTorrentServiceDC.cs | Updates filtering to use rule.Categories instead of rule.Name. |
| code/backend/Cleanuparr.Infrastructure/Features/DownloadClient/UTorrent/UTorrentService.cs | Updates constructor DI to use queue + seeding evaluators. |
| code/backend/Cleanuparr.Infrastructure/Features/DownloadClient/UTorrent/UTorrentItemWrapper.cs | Adds tracker domain extraction + tag list (empty for µTorrent). |
| code/backend/Cleanuparr.Infrastructure/Features/DownloadClient/Transmission/TransmissionServiceQC.cs | Switches to IQueueRuleEvaluator naming. |
| code/backend/Cleanuparr.Infrastructure/Features/DownloadClient/Transmission/TransmissionServiceDC.cs | Updates filtering to use rule.Categories. |
| code/backend/Cleanuparr.Infrastructure/Features/DownloadClient/Transmission/TransmissionService.cs | Requests Transmission labels field; updates constructor DI. |
| code/backend/Cleanuparr.Infrastructure/Features/DownloadClient/Transmission/TransmissionItemWrapper.cs | Adds tracker domain extraction + exposes labels as tags. |
| code/backend/Cleanuparr.Infrastructure/Features/DownloadClient/RTorrent/RTorrentServiceQC.cs | Switches to IQueueRuleEvaluator naming. |
| code/backend/Cleanuparr.Infrastructure/Features/DownloadClient/RTorrent/RTorrentServiceDC.cs | Updates filtering to use rule.Categories. |
| code/backend/Cleanuparr.Infrastructure/Features/DownloadClient/RTorrent/RTorrentService.cs | Updates constructor DI to use queue + seeding evaluators. |
| code/backend/Cleanuparr.Infrastructure/Features/DownloadClient/RTorrent/RTorrentItemWrapper.cs | Adds tracker domain extraction + tag list (empty for rTorrent). |
| code/backend/Cleanuparr.Infrastructure/Features/DownloadClient/QBittorrent/QBitServiceQC.cs | Switches to IQueueRuleEvaluator naming. |
| code/backend/Cleanuparr.Infrastructure/Features/DownloadClient/QBittorrent/QBitServiceDC.cs | Updates filtering to use rule.Categories. |
| code/backend/Cleanuparr.Infrastructure/Features/DownloadClient/QBittorrent/QBitService.cs | Updates constructor DI to use queue + seeding evaluators. |
| code/backend/Cleanuparr.Infrastructure/Features/DownloadClient/QBittorrent/QBitItemWrapper.cs | Adds tracker domain extraction + exposes qBittorrent tags. |
| code/backend/Cleanuparr.Infrastructure/Features/DownloadClient/DownloadServiceFactory.cs | Updates DI resolution to use new evaluator interfaces. |
| code/backend/Cleanuparr.Infrastructure/Features/DownloadClient/DownloadService.cs | Uses ISeedingRuleEvaluator for matching; updates rule selection logic. |
| code/backend/Cleanuparr.Infrastructure/Features/DownloadClient/Deluge/DelugeServiceQC.cs | Switches to IQueueRuleEvaluator naming. |
| code/backend/Cleanuparr.Infrastructure/Features/DownloadClient/Deluge/DelugeServiceDC.cs | Updates filtering to use rule.Categories. |
| code/backend/Cleanuparr.Infrastructure/Features/DownloadClient/Deluge/DelugeService.cs | Updates constructor DI to use queue + seeding evaluators. |
| code/backend/Cleanuparr.Infrastructure/Features/DownloadClient/Deluge/DelugeItemWrapper.cs | Adds tracker domain extraction + tag list (empty for Deluge). |
| code/backend/Cleanuparr.Infrastructure.Tests/Services/SeedingRuleEvaluatorTests.cs | New unit test suite for combined matching + priority ordering. |
| code/backend/Cleanuparr.Infrastructure.Tests/Services/QueueRuleManagerTests.cs | Renames tests for queue rule manager. |
| code/backend/Cleanuparr.Infrastructure.Tests/Services/QueueRuleEvaluatorTests.cs | Renames tests for queue rule evaluator. |
| code/backend/Cleanuparr.Infrastructure.Tests/Features/DownloadClient/UTorrentServiceFixture.cs | Updates fixtures for renamed interfaces + new seeding evaluator dependency. |
| code/backend/Cleanuparr.Infrastructure.Tests/Features/DownloadClient/UTorrentServiceDCTests.cs | Updates tests to provide Categories. |
| code/backend/Cleanuparr.Infrastructure.Tests/Features/DownloadClient/TransmissionServiceTests.cs | Updates expected requested fields to include labels. |
| code/backend/Cleanuparr.Infrastructure.Tests/Features/DownloadClient/TransmissionServiceFixture.cs | Updates fixtures for renamed interfaces + new seeding evaluator dependency. |
| code/backend/Cleanuparr.Infrastructure.Tests/Features/DownloadClient/TransmissionServiceDCTests.cs | Updates tests to provide Categories. |
| code/backend/Cleanuparr.Infrastructure.Tests/Features/DownloadClient/RTorrentServiceFixture.cs | Updates fixtures for renamed interfaces + new seeding evaluator dependency. |
| code/backend/Cleanuparr.Infrastructure.Tests/Features/DownloadClient/RTorrentServiceDCTests.cs | Updates tests to provide Categories. |
| code/backend/Cleanuparr.Infrastructure.Tests/Features/DownloadClient/QBitServiceFixture.cs | Updates fixtures for renamed interfaces + new seeding evaluator dependency. |
| code/backend/Cleanuparr.Infrastructure.Tests/Features/DownloadClient/QBitServiceDCTests.cs | Updates tests to provide Categories. |
| code/backend/Cleanuparr.Infrastructure.Tests/Features/DownloadClient/DownloadServiceFactoryTests.cs | Updates service registrations for renamed/new interfaces. |
| code/backend/Cleanuparr.Infrastructure.Tests/Features/DownloadClient/DelugeServiceFixture.cs | Updates fixtures for renamed interfaces + new seeding evaluator dependency. |
| code/backend/Cleanuparr.Infrastructure.Tests/Features/DownloadClient/DelugeServiceDCTests.cs | Updates tests to provide Categories. |
| code/backend/Cleanuparr.Domain/Entities/ITorrentItemWrapper.cs | Adds tracker domains + tags to torrent wrapper contract. |
| code/backend/Cleanuparr.Api/Features/DownloadCleaner/SeedingRuleHelper.cs | Adds ordering and tracked-query helper for reorder persistence. |
| code/backend/Cleanuparr.Api/Features/DownloadCleaner/Controllers/SeedingRulesController.cs | Adds priority assignment, new fields on update, and reorder endpoint. |
| code/backend/Cleanuparr.Api/Features/DownloadCleaner/Controllers/DownloadCleanerConfigController.cs | Extends config response to include new seeding rule fields. |
| code/backend/Cleanuparr.Api/Features/DownloadCleaner/Contracts/Requests/SeedingRuleRequest.cs | Extends request contract with new matching/prioritization fields + validation. |
| code/backend/Cleanuparr.Api/Features/DownloadCleaner/Contracts/Requests/ReorderSeedingRulesRequest.cs | New request contract for reorder endpoint. |
| code/backend/Cleanuparr.Api/DependencyInjection/ServicesDI.cs | Registers new evaluator + renamed queue rule services. |
Files not reviewed (1)
- code/backend/Cleanuparr.Persistence/Migrations/Data/20260408081126_AddSeedingRuleEnhancements.Designer.cs: Language not supported
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
|
/review |
Code Review by Qodo
|
390911b to
9b9c395
Compare
Relates to #200