feat(cv): qualify templates and reliable local import processing

This commit is contained in:
cesnimda
2026-10-28 14:36:12 +01:00
parent 73ea888375
commit 3f4db8ca81
69 changed files with 2597 additions and 180 deletions
@@ -20,6 +20,63 @@ public class CvImportLifecycleConcurrencyTests
private const string Owner = "rd21-owner";
private static readonly ProfileCvController.ApplyReviewedRequest Review = new(0, new[] { new CvImportDecision("skills.0", "use") });
[Fact]
public async Task Document_only_claim_is_owner_bound_and_translates_on_MariaDb_without_restricting_general_claims()
{
await using var database = await MariaDbDatabase.CreateAsync();
Guid documentId, legacyId, strategyId, mismatchedId, wrongTriggerId;
await using (var seed = database.Context())
{
seed.Users.AddRange(new ApplicationUser { Id = Owner, UserName = "claim-owner" },
new ApplicationUser { Id = "other-owner", UserName = "claim-other" });
var document = new CvExtractionRun { OwnerUserId = Owner, ParserVersion = ProfileCvController.DocumentParserVersion, Trigger = "document_import", Status = "queued" };
var foreign = new CvExtractionRun { OwnerUserId = "other-owner", ParserVersion = ProfileCvController.DocumentParserVersion, Trigger = "document_import", Status = "queued" };
var legacy = new CvExtractionRun { OwnerUserId = Owner, ParserVersion = "legacy-text", Trigger = "document_import", Status = "queued" };
var wrongTrigger = new CvExtractionRun { OwnerUserId = Owner, ParserVersion = ProfileCvController.DocumentParserVersion, Trigger = "text_extraction", Status = "queued" };
seed.CvExtractionRuns.AddRange(document, foreign, legacy, wrongTrigger);
await seed.SaveChangesAsync();
UserOperation Queued(CvExtractionRun run, int priority)
{
var operation = Operation(run.Id, OperationStatuses.Queued);
operation.IdempotencyKey = operation.Id.ToString("N");
operation.LeaseToken = null;
operation.Priority = priority;
return operation;
}
var eligible = Queued(document, 100);
var legacyOperation = Queued(legacy, 1000);
var mismatched = Queued(foreign, 900);
var wrongTriggerOperation = Queued(wrongTrigger, 800);
var strategy = Queued(document, 1100);
strategy.TaskType = StrategySnapshotService.TaskType;
strategy.SubjectType = "job_application";
seed.UserOperations.AddRange(eligible, legacyOperation, mismatched, wrongTriggerOperation, strategy);
await seed.SaveChangesAsync();
(documentId, legacyId, strategyId, mismatchedId, wrongTriggerId) =
(eligible.Id, legacyOperation.Id, strategy.Id, mismatched.Id, wrongTriggerOperation.Id);
}
await using var neutral = database.Context(null!);
var store = new UserOperationStore(neutral, TimeProvider.System);
var claimed = Assert.IsType<UserOperationLease>(await store.ClaimNextAsync(TimeSpan.FromMinutes(1), default, documentImportsOnly: true));
Assert.Equal(documentId, claimed.OperationId);
Assert.Equal(Owner, claimed.OwnerUserId);
Assert.Null(await store.ClaimNextAsync(TimeSpan.FromMinutes(1), default, documentImportsOnly: true));
var generalCv = Assert.IsType<UserOperationLease>(await store.ClaimNextAsync(TimeSpan.FromMinutes(1), default, new[] { CvProcessingQueue.TaskType }));
Assert.Equal(legacyId, generalCv.OperationId);
var generalOther = Assert.IsType<UserOperationLease>(await store.ClaimNextAsync(TimeSpan.FromMinutes(1), default, new[] { StrategySnapshotService.TaskType }));
Assert.Equal(strategyId, generalOther.OperationId);
var excluded = await neutral.UserOperations.IgnoreQueryFilters().AsNoTracking()
.Where(operation => operation.Id == mismatchedId || operation.Id == wrongTriggerId).ToListAsync();
Assert.Equal(2, excluded.Count);
Assert.All(excluded, operation =>
{
Assert.Equal(OperationStatuses.Queued, operation.Status);
Assert.Equal(0, operation.AttemptCount);
Assert.Null(operation.LeaseToken);
});
}
[Fact]
public async Task Acknowledged_discard_prevents_an_apply_that_already_read_pending()
{