add a button to clear out finished share links

The dashboard listed every share ever made, including ones revoked or expired
months ago, and nothing ever pruned them. There is now a "Clean up finished links"
button next to Refresh that runs a normal cleanup pass and then drops the records
that are done with, reporting how many went.

Only revoked, expired and failed records are removed. A link that can still be
used is left alone, including a spent one-use link whose guest is still watching
until it expires, since that record is Redeemed rather than finished.

Folded into 1.0.3.0 rather than shipped as 1.0.3.1: the ceiling fix and this are
going out as one replacement of that version.
Cette révision appartient à :
Franciskid
2026-07-26 23:04:51 +02:00
Parent 34ed2c8ad9
révision 4ad6d5b1ed
5 fichiers modifiés avec 81 ajouts et 5 suppressions
+34
Voir le fichier
@@ -75,6 +75,40 @@ public sealed class ShareLinkCleanupService : IShareLinkCleanupService
await CleanupRecordInternalAsync(record, records, force, cancellationToken).ConfigureAwait(false);
}
/// <summary>
/// Runs a normal cleanup pass and then drops every record that is finished
/// with, so the admin list does not grow forever. A link that can still be
/// used is never removed, and neither is one whose guest is still watching.
/// </summary>
public async Task<int> PurgeFinishedAsync(CancellationToken cancellationToken)
{
// Teardown first: this expires anything past its date and removes the guest
// account and tags, so nothing is dropped from the store while it still has
// state hanging off it.
await CleanupAsync(cancellationToken).ConfigureAwait(false);
var records = await _store.ListAsync(cancellationToken).ConfigureAwait(false);
var removed = 0;
foreach (var record in records)
{
cancellationToken.ThrowIfCancellationRequested();
if (record.Status is not (ShareLinkStatus.Expired or ShareLinkStatus.Revoked or ShareLinkStatus.Failed))
{
continue;
}
await _store.DeleteAsync(record.Id, cancellationToken).ConfigureAwait(false);
removed++;
}
if (removed > 0)
{
_logger.LogInformation("ShareLinks: purged {Count} finished share-link record(s).", removed);
}
return removed;
}
private async Task<ShareLinkRecord> CleanupRecordInternalAsync(
ShareLinkRecord record,
IReadOnlyList<ShareLinkRecord> allRecords,