Wire NowPlayingStats to live aggregates: add SQL track duration column, stats endpoint, and duration backfill
This commit is contained in:
@@ -0,0 +1,37 @@
|
||||
using DeepDrftModels.Enums;
|
||||
|
||||
namespace DeepDrftModels.DTOs;
|
||||
|
||||
/// <summary>
|
||||
/// Aggregate figures behind the public home hero stat row (NowPlayingStats). A single read returns
|
||||
/// everything the three cards need so the client makes one round-trip. All counts exclude soft-deleted
|
||||
/// rows. The Plays card is a static placeholder and has no field here.
|
||||
/// </summary>
|
||||
public class HomeStatsDto
|
||||
{
|
||||
/// <summary>Total non-deleted tracks whose release is the Cut medium. The Studio Cuts card's primary figure.</summary>
|
||||
public int CutTrackCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Per-ReleaseType counts of non-deleted Cut releases. Only types with at least one release are
|
||||
/// present — a zero-count type is absent from the list (the card suppresses it). The Studio Cuts
|
||||
/// card's secondary breakdown.
|
||||
/// </summary>
|
||||
public List<CutReleaseTypeCount> CutReleaseTypeCounts { get; set; } = [];
|
||||
|
||||
/// <summary>Total non-deleted releases of the Mix medium. The Mixes card's primary figure ("N Sets").</summary>
|
||||
public int MixReleaseCount { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Sum of DurationSeconds across all non-deleted tracks on Mix releases. Tracks with a null
|
||||
/// duration (not yet backfilled) contribute 0. The Mixes card's secondary figure, rendered hh:mm.
|
||||
/// </summary>
|
||||
public double MixRuntimeSeconds { get; set; }
|
||||
}
|
||||
|
||||
/// <summary>One row of the Cut release-type breakdown: a ReleaseType and how many Cut releases have it.</summary>
|
||||
public class CutReleaseTypeCount
|
||||
{
|
||||
public ReleaseType ReleaseType { get; set; }
|
||||
public int Count { get; set; }
|
||||
}
|
||||
@@ -16,6 +16,7 @@ public class TrackDto : BaseModel
|
||||
public string TrackName { get; set; } = string.Empty;
|
||||
public string? OriginalFileName { get; set; }
|
||||
public int TrackNumber { get; set; } = 1;
|
||||
public double? DurationSeconds { get; set; }
|
||||
public long? ReleaseId { get; set; }
|
||||
public ReleaseDto? Release { get; set; }
|
||||
}
|
||||
|
||||
@@ -15,6 +15,10 @@ public class TrackEntity : BaseEntity, IEntity
|
||||
public required string TrackName { get; set; }
|
||||
public string? OriginalFileName { get; set; }
|
||||
public int TrackNumber { get; set; } = 1;
|
||||
// Audio runtime in seconds, extracted by the processor at upload (AudioBinary.Duration) and
|
||||
// persisted here so aggregate queries (e.g. total mix runtime) read it from SQL rather than the
|
||||
// vault. Nullable: rows that predate this column are valid until the one-time backfill populates them.
|
||||
public double? DurationSeconds { get; set; }
|
||||
public long? ReleaseId { get; set; }
|
||||
public ReleaseEntity? Release { get; set; }
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user