fix: write DurationSeconds to SQL after replace-audio vault swap
This commit is contained in:
@@ -168,12 +168,13 @@ public class UnifiedTrackService
|
|||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Replace an existing track's audio in place: look up the SQL row, swap only the vault bytes
|
/// Replace an existing track's audio in place: look up the SQL row, swap only the vault bytes
|
||||||
/// keyed by its EntryKey, then regenerate both waveform datums from the new audio. Track id,
|
/// keyed by its EntryKey, regenerate both waveform datums from the new audio, then write the
|
||||||
/// EntryKey, release membership, track number, and all metadata are preserved — nothing in SQL
|
/// new duration to SQL. Track id, EntryKey, release membership, track number, and all other
|
||||||
/// is written. The waveform regen is best-effort (a missing datum renders as a flat seekbar /
|
/// metadata are preserved. The waveform regen is best-effort (a missing datum renders as a flat
|
||||||
/// blank visualizer downstream), so a datum failure is logged and swallowed rather than failing
|
/// seekbar / blank visualizer downstream), so a datum failure is logged and swallowed rather than
|
||||||
/// the replace. No release-cardinality cascade applies: the track count is unchanged, so the
|
/// failing the replace. The duration write is not best-effort — a failure is surfaced so derived
|
||||||
/// single-track-Mix case stays intact.
|
/// aggregates (e.g. MixRuntimeSeconds) do not silently go stale. No release-cardinality cascade
|
||||||
|
/// applies: the track count is unchanged, so the single-track-Mix case stays intact.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public async Task<Result> ReplaceAudioAsync(long trackId, string tempFilePath, CancellationToken ct)
|
public async Task<Result> ReplaceAudioAsync(long trackId, string tempFilePath, CancellationToken ct)
|
||||||
{
|
{
|
||||||
@@ -212,6 +213,20 @@ public class UnifiedTrackService
|
|||||||
_logger.LogError(ex, "ReplaceAudioAsync: waveform regen failed for {EntryKey}; replace unaffected.", entryKey);
|
_logger.LogError(ex, "ReplaceAudioAsync: waveform regen failed for {EntryKey}; replace unaffected.", entryKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Write the new duration to SQL. The vault bytes are already swapped, so this is the
|
||||||
|
// authoritative metadata update for the replace. A failure here is surfaced (unlike the
|
||||||
|
// best-effort waveform regen above) because a stale DurationSeconds silently corrupts
|
||||||
|
// derived aggregates (e.g. MixRuntimeSeconds on the home stats endpoint).
|
||||||
|
var durationWrite = await _sqlTrackService.UpdateDuration(trackId, newAudio.Duration, ct);
|
||||||
|
if (!durationWrite.Success)
|
||||||
|
{
|
||||||
|
var error = durationWrite.Messages.FirstOrDefault()?.Message ?? "Unknown error";
|
||||||
|
_logger.LogError(
|
||||||
|
"ReplaceAudioAsync: vault swap succeeded but SQL duration update failed for track {TrackId} ({EntryKey}): {Error}",
|
||||||
|
trackId, entryKey, error);
|
||||||
|
return Result.CreateFailResult("Audio replaced but duration metadata could not be updated.");
|
||||||
|
}
|
||||||
|
|
||||||
return Result.CreatePassResult();
|
return Result.CreatePassResult();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user