2f47efeb46
Renames Genre tab to Release Archive with switch-free medium card group (Enum.GetValues-driven). Adds MediumFields single dispatch + CutFields/SessionFields/ MixFields per-medium sections embedded by all five upload/edit forms. BatchUpload enforces single-track invariant for Session/Mix. Adds CmsSessionBrowser (hero-image upload) and CmsMixBrowser (waveform status + per-row Generate trigger). ICmsReleaseService/CmsReleaseService wraps api/release endpoints. Note: medium selector is forward-compat only — API write path pending.
116 lines
5.3 KiB
C#
116 lines
5.3 KiB
C#
using DeepDrftModels.DTOs;
|
|
using DeepDrftModels.Enums;
|
|
using Models.Common;
|
|
using NetBlocks.Models;
|
|
|
|
namespace DeepDrftManager.Services;
|
|
|
|
/// <summary>
|
|
/// CMS-side track operations for the Manager host. Every read and write goes over HTTP to the
|
|
/// DeepDrftAPI API, which is the single authority over both the SQL metadata store and the
|
|
/// binary audio vault. DeepDrftManager holds no in-process data layer.
|
|
/// </summary>
|
|
public interface ICmsTrackService
|
|
{
|
|
/// <summary>
|
|
/// Proxy a WAV upload to DeepDrftAPI. The Content API owns the dual-database write and
|
|
/// returns the persisted track carrying the SQL-assigned <c>Id</c>. A vault-without-SQL
|
|
/// orphan is handled and logged server-side; here it surfaces as a failed result.
|
|
/// <paramref name="originalFileName"/> is the browser's filename, captured at upload time and
|
|
/// stored as metadata; it is not user-editable afterwards.
|
|
/// <paramref name="medium"/> sets the parent release's <see cref="ReleaseMedium"/>. NOTE: the
|
|
/// current <c>POST api/track/upload</c> endpoint has no <c>medium</c> form field, so the value is
|
|
/// sent forward-compatibly and ignored server-side until the API binds it (Cut is the server
|
|
/// default). Wiring the selector through here keeps the CMS ready for that API change.
|
|
/// </summary>
|
|
Task<ResultContainer<TrackDto>> UploadTrackAsync(
|
|
Stream wavStream,
|
|
string fileName,
|
|
string contentType,
|
|
string trackName,
|
|
string artist,
|
|
string? album,
|
|
string? genre,
|
|
string? releaseDate,
|
|
string? originalFileName,
|
|
long createdByUserId,
|
|
ReleaseType releaseType,
|
|
int trackNumber,
|
|
ReleaseMedium medium = ReleaseMedium.Cut,
|
|
CancellationToken ct = default);
|
|
|
|
/// <summary>
|
|
/// Delete a track via the Content API, which removes the SQL row then the vault entry.
|
|
/// Maps a 404 to a "Track not found." failure.
|
|
/// </summary>
|
|
Task<Result> DeleteTrackAsync(long id, CancellationToken ct = default);
|
|
|
|
/// <summary>
|
|
/// Soft-delete a release record via DELETE api/track/release/{id}. Use when a release
|
|
/// has no live tracks and needs to be removed from the albums browser.
|
|
/// </summary>
|
|
Task<Result> DeleteReleaseAsync(long releaseId, CancellationToken ct = default);
|
|
|
|
/// <summary>
|
|
/// Fetch a page of track metadata from the Content API's <c>GET api/track/page</c>. Optional
|
|
/// <paramref name="album"/> and <paramref name="genre"/> filters narrow the result to a single
|
|
/// release title or genre; null leaves the dimension unfiltered.
|
|
/// </summary>
|
|
Task<ResultContainer<PagedResult<TrackDto>>> GetPagedAsync(
|
|
int page, int pageSize, string? sortColumn, bool sortDescending,
|
|
string? album = null, string? genre = null,
|
|
CancellationToken ct = default);
|
|
|
|
/// <summary>
|
|
/// Fetch a single track's metadata from <c>GET api/track/meta/{id}</c>. A 404 returns a
|
|
/// passing result with a null value.
|
|
/// </summary>
|
|
Task<ResultContainer<TrackDto?>> GetByIdAsync(long id, CancellationToken ct = default);
|
|
|
|
/// <summary>
|
|
/// Upload a cover-art image to the images vault via <c>POST api/image/upload</c>.
|
|
/// Returns the generated entry key on success. Maps a 400 to a validation failure message.
|
|
/// </summary>
|
|
Task<ResultContainer<string>> UploadImageAsync(
|
|
Stream imageStream,
|
|
string fileName,
|
|
string contentType,
|
|
CancellationToken ct = default);
|
|
|
|
/// <summary>
|
|
/// Update a track's metadata via <c>PUT api/track/meta/{id}</c>. EntryKey is immutable and
|
|
/// not part of the update. <paramref name="imagePath"/> is tri-state: <c>null</c> leaves the
|
|
/// cover art unchanged, <c>""</c> clears it, and any other value sets it.
|
|
/// </summary>
|
|
Task<Result> UpdateAsync(
|
|
long id, string trackName, string artist,
|
|
string? album, string? genre, DateOnly? releaseDate,
|
|
string? imagePath = null,
|
|
ReleaseType? releaseType = null,
|
|
int? trackNumber = null,
|
|
CancellationToken ct = default);
|
|
|
|
/// <summary>
|
|
/// Fetch per-track waveform profile status from <c>GET api/track/waveform-status</c> for the
|
|
/// CMS PreProcessing panel. Unpaged — the admin catalogue is small.
|
|
/// </summary>
|
|
Task<ResultContainer<WaveformStatusDto[]>> GetWaveformStatusAsync(CancellationToken ct = default);
|
|
|
|
/// <summary>
|
|
/// Trigger waveform profile generation for a single track via
|
|
/// <c>POST api/track/{entryKey}/waveform</c>. Maps a 404 to a "Track audio not found." failure.
|
|
/// </summary>
|
|
Task<Result> GenerateWaveformProfileAsync(string entryKey, CancellationToken ct = default);
|
|
|
|
/// <summary>Returns all releases with track counts from GET api/track/albums.</summary>
|
|
Task<ResultContainer<List<ReleaseDto>>> GetReleasesAsync(CancellationToken ct = default);
|
|
|
|
/// <summary>Returns all distinct genres with track counts from GET api/track/genres.</summary>
|
|
Task<ResultContainer<List<GenreSummaryDto>>> GetGenreSummariesAsync(CancellationToken ct = default);
|
|
|
|
/// <summary>
|
|
/// Returns the total track count by calling GET api/track/page with pageSize=1 and reading TotalCount.
|
|
/// </summary>
|
|
Task<ResultContainer<int>> GetTrackCountAsync(CancellationToken ct = default);
|
|
}
|