feat: replace /archive with release-cardinal searchable browser (Phase 9 §8.H)

Retire the three-card overview for a search + medium + genre browser over all
releases. Adds q/genre filter params to the api/release paged read path,
mirroring the existing api/track/page TrackFilter pattern.
This commit is contained in:
daniel-c-harvey
2026-06-13 20:47:50 -04:00
parent 18f4b596f2
commit 737c423d9c
13 changed files with 607 additions and 59 deletions
+25
View File
@@ -0,0 +1,25 @@
namespace DeepDrftModels.DTOs;
/// <summary>
/// Cross-project release filter contract for the paged release read surface. Threaded alongside
/// (never inside) the external <c>PagingParameters&lt;T&gt;</c>, which cannot carry a where-clause,
/// and beside the medium filter (a separate enum param, not a free-text field). Mirrors
/// <see cref="TrackFilter"/> for the release-cardinal browse path. An instance with all properties
/// null is equivalent to no filter — see <see cref="IsEmpty"/>.
/// </summary>
public class ReleaseFilter
{
/// <summary>Free-text, case-insensitive LIKE across the release Title and Artist.</summary>
public string? SearchText { get; set; }
/// <summary>Exact genre match.</summary>
public string? Genre { get; set; }
/// <summary>
/// True when no predicate is set. An empty filter must produce identical results to a null
/// filter, so callers collapse it to null before querying.
/// </summary>
public bool IsEmpty =>
string.IsNullOrWhiteSpace(SearchText)
&& string.IsNullOrWhiteSpace(Genre);
}