fix(account): close deletion cache gap
CI and Deploy / test (pull_request) Successful in 5m22s
CI and Deploy / deploy (pull_request) Has been skipped

Require authenticated sidecar cache purge before a deletion can complete and keep failures retryable. Mount tombstones outside restored application data while leaving deletion disabled by default.
This commit is contained in:
cesnimda
2026-08-15 19:40:07 +02:00
parent c0e190d5b5
commit 7185491a05
14 changed files with 134 additions and 20 deletions
@@ -13,6 +13,7 @@ public sealed class AccountDeletionService(
JobTrackerContext db,
AccountOwnedFileInventory fileInventory,
AccountDeletionTombstoneStore tombstones,
IAiSidecarCachePurger aiSidecarCache,
IConfiguration configuration,
IMemoryCache memoryCache,
TimeProvider timeProvider,
@@ -313,7 +314,10 @@ public sealed class AccountDeletionService(
file.Status = "purged";
}
if (memoryCache is MemoryCache cache) cache.Compact(1.0);
AppendWarning(request, "The local AI sidecar cache is content-keyed and ages out under its configured TTL; production deletion remains disabled until cache purge/restart is rehearsed.");
// The sidecar cache is content-keyed rather than owner-keyed, so deletion clears it
// globally. Keep this inside the durable stage: an unavailable sidecar leaves the request
// retryable and prevents a false completion/tombstone acknowledgement.
await aiSidecarCache.PurgeAsync(cancellationToken);
request.Stage = AccountDeletionStages.RecordingTombstone;
await db.SaveChangesAsync(cancellationToken);
}
@@ -0,0 +1,16 @@
namespace JobTrackerApi.Services;
public interface IAiSidecarCachePurger
{
Task PurgeAsync(CancellationToken cancellationToken);
}
public sealed class AiSidecarCachePurger(IHttpClientFactory clients) : IAiSidecarCachePurger
{
public async Task PurgeAsync(CancellationToken cancellationToken)
{
using var response = await clients.CreateClient("ai-service")
.DeleteAsync("/maintenance/cache", cancellationToken);
response.EnsureSuccessStatusCode();
}
}