fix(cv-qa): protect import lifecycle races and terminal receipts

This commit is contained in:
cesnimda
2026-10-27 00:27:57 +01:00
parent cf0e5c23de
commit 89974a257e
8 changed files with 250 additions and 11 deletions
+4 -2
View File
@@ -355,6 +355,8 @@ public sealed class UserOperationStore(JobTrackerContext db, TimeProvider timePr
await using var transaction = await BeginTransactionAsync(cancellationToken);
var operation = await db.UserOperations.FirstOrDefaultAsync(item => item.Id == operationId, cancellationToken);
if (operation is null || operation.Status is not (OperationStatuses.Failed or OperationStatuses.Cancelled)) return false;
if (operation.TaskType == CvProcessingQueue.TaskType && operation.SubjectType == CvProcessingQueue.SubjectType
&& await SynchronizeCvRunAsync(operation, OperationStatuses.Queued, null, UtcNow, cancellationToken) != 1) return false;
operation.Status = OperationStatuses.Queued;
operation.AttemptCount = 0;
operation.AvailableAtUtc = UtcNow;
@@ -371,7 +373,6 @@ public sealed class UserOperationStore(JobTrackerContext db, TimeProvider timePr
var existingNotification = await db.UserNotifications.FirstOrDefaultAsync(item => item.OperationId == operationId, cancellationToken);
if (existingNotification is not null) db.UserNotifications.Remove(existingNotification);
await db.SaveChangesAsync(cancellationToken);
await SynchronizeCvRunAsync(operation, OperationStatuses.Queued, null, UtcNow, cancellationToken);
if (transaction is not null) await transaction.CommitAsync(cancellationToken);
return true;
}
@@ -475,7 +476,8 @@ public sealed class UserOperationStore(JobTrackerContext db, TimeProvider timePr
: (DateTimeOffset?)null;
return db.CvExtractionRuns.IgnoreQueryFilters()
.Where(run => run.Id == runId && run.OwnerUserId == operation.OwnerUserId && run.Status != "expired" && run.Status != "applied")
.Where(run => run.Id == runId && run.OwnerUserId == operation.OwnerUserId
&& (run.Status == "queued" || run.Status == "running" || run.Status == "pending_review" || run.Status == "failed" || run.Status == "cancelled"))
.ExecuteUpdateAsync(setters => setters
.SetProperty(run => run.Status, runStatus)
.SetProperty(run => run.ErrorMessage, message)