130 lines
6.1 KiB
C#
130 lines
6.1 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"/> when this upload
|
|
/// creates the release. The medium is authoritative only on creation — adding a track to an existing
|
|
/// release never changes its medium (that is the edit path, <see cref="UpdateAsync"/>).
|
|
/// <paramref name="contentLength"/> is the total payload size (the browser file's <c>Size</c>); it
|
|
/// sets Content-Length and is the denominator for <paramref name="progress"/>, which reports cumulative
|
|
/// bytes pushed to the wire. Each progress tick also resets the idle/heartbeat upload timeout, so a
|
|
/// stalled connection aborts without a fixed total-duration cap.
|
|
/// </summary>
|
|
Task<ResultContainer<TrackDto>> UploadTrackAsync(
|
|
Stream wavStream,
|
|
long contentLength,
|
|
string fileName,
|
|
string contentType,
|
|
string trackName,
|
|
string artist,
|
|
string? album,
|
|
string? genre,
|
|
string? description,
|
|
string? releaseDate,
|
|
string? originalFileName,
|
|
long createdByUserId,
|
|
ReleaseType releaseType,
|
|
int trackNumber,
|
|
ReleaseMedium medium = ReleaseMedium.Cut,
|
|
IProgress<long>? progress = null,
|
|
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. <paramref name="medium"/>
|
|
/// is null = no change; a non-null, non-Cut value resets the release's ReleaseType to its default
|
|
/// server-side, since ReleaseType is meaningful only for Cut.
|
|
/// </summary>
|
|
Task<Result> UpdateAsync(
|
|
long id, string trackName, string artist,
|
|
string? album, string? genre, string? description, DateOnly? releaseDate,
|
|
string? imagePath = null,
|
|
ReleaseType? releaseType = null,
|
|
ReleaseMedium? medium = 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>
|
|
/// Trigger high-res visualizer datum generation for a single track via
|
|
/// <c>POST api/track/{entryKey}/waveform/high-res</c> (phase-12 §5). Re-runnable — recomputes on each
|
|
/// call. Drives the per-row generate action and the batch backfill. Maps a 404 to a "Track audio not
|
|
/// found." failure.
|
|
/// </summary>
|
|
Task<Result> GenerateHighResWaveformAsync(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 the total track count by calling GET api/track/page with pageSize=1 and reading TotalCount.
|
|
/// </summary>
|
|
Task<ResultContainer<int>> GetTrackCountAsync(CancellationToken ct = default);
|
|
}
|