refactor(api): extract JobApplications DTOs and helpers, fix N+1 aggregation
- Move inline DTOs to JobApplicationDtos.cs, pure static helpers to JobApplicationHelpers.cs - GetStats aggregates server-side (COUNT/GROUP BY) instead of loading the full table - Cache RuleSettings via IMemoryCache, keyed per-user (RulesEngine.GetSettings falls back to per-user UserRuleSettings overrides, so a single global cache key would leak settings across users) - Add missing AsNoTracking() to read-only GET endpoints (GetAll, GetById, GetBoard, GetReminders, GetStatusSuggestion, GetMatchScore, GetCandidateFit, GetFocusPlan, GetInterviewPrep, GetReadiness) Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -39,7 +39,7 @@ public sealed class JobApplicationsApplicationPackageTests
|
||||
await db.SaveChangesAsync();
|
||||
|
||||
var controller = CreateController(db, Mock.Of<ISummarizerService>(), "user-1");
|
||||
var result = await controller.SaveApplicationDrafts(job.Id, new JobApplicationsController.SaveApplicationDraftsRequest(null, "Updated notes block", null), CancellationToken.None);
|
||||
var result = await controller.SaveApplicationDrafts(job.Id, new SaveApplicationDraftsRequest(null, "Updated notes block", null), CancellationToken.None);
|
||||
|
||||
Assert.IsType<NoContentResult>(result);
|
||||
var saved = await db.JobApplications.FirstAsync();
|
||||
@@ -135,7 +135,7 @@ public sealed class JobApplicationsApplicationPackageTests
|
||||
var result = await controller.GenerateApplicationPackage(job.Id, null, null, null, CancellationToken.None);
|
||||
|
||||
var ok = Assert.IsType<OkObjectResult>(result.Result);
|
||||
var payload = Assert.IsType<JobApplicationsController.GenerateApplicationPackageDto>(ok.Value);
|
||||
var payload = Assert.IsType<GenerateApplicationPackageDto>(ok.Value);
|
||||
|
||||
Assert.Contains("Tailored CV", payload.TailoredCvText);
|
||||
Assert.Equal("Cover letter tailored with recruiter context and imported correspondence.", payload.CoverLetterDraft);
|
||||
@@ -261,7 +261,7 @@ public sealed class JobApplicationsApplicationPackageTests
|
||||
var result = await controller.GetTailoredCvDraft(job.Id, CancellationToken.None);
|
||||
|
||||
var ok = Assert.IsType<OkObjectResult>(result.Result);
|
||||
var payload = Assert.IsType<JobApplicationsController.TailoredCvDraftDto>(ok.Value);
|
||||
var payload = Assert.IsType<TailoredCvDraftDto>(ok.Value);
|
||||
Assert.True(payload.IsLegacyFallback);
|
||||
Assert.Equal("legacy-text", payload.TemplateId);
|
||||
Assert.Contains("Existing tailored CV text", payload.RenderedText);
|
||||
@@ -337,14 +337,14 @@ public sealed class JobApplicationsApplicationPackageTests
|
||||
var controller = CreateController(db, summarizer.Object, "user-1");
|
||||
var generateResult = await controller.GenerateTailoredCvDraft(job.Id, "ats", CancellationToken.None);
|
||||
var generateOk = Assert.IsType<OkObjectResult>(generateResult.Result);
|
||||
var generated = Assert.IsType<JobApplicationsController.TailoredCvDraftDto>(generateOk.Value);
|
||||
var generated = Assert.IsType<TailoredCvDraftDto>(generateOk.Value);
|
||||
|
||||
Assert.False(generated.IsLegacyFallback);
|
||||
Assert.Equal(7, generated.CanonicalProfileVersion);
|
||||
Assert.Equal("Senior Backend Engineer", generated.Headline);
|
||||
Assert.Contains("Led backend API delivery.", generated.RenderedText);
|
||||
|
||||
var saveResult = await controller.SaveTailoredCvDraft(job.Id, new JobApplicationsController.SaveTailoredCvDraftRequest(
|
||||
var saveResult = await controller.SaveTailoredCvDraft(job.Id, new SaveTailoredCvDraftRequest(
|
||||
generated.TemplateId,
|
||||
"Principal Backend Engineer",
|
||||
new List<string> { "Own backend delivery for critical APIs." },
|
||||
@@ -395,7 +395,7 @@ public sealed class JobApplicationsApplicationPackageTests
|
||||
var renderer = new TestCvTemplateRenderer();
|
||||
var exporter = new TestCvPdfExporter();
|
||||
var controller = CreateController(db, Mock.Of<ISummarizerService>(), "user-1", renderer, exporter);
|
||||
var request = new JobApplicationsController.TailoredCvRenderRequest(
|
||||
var request = new TailoredCvRenderRequest(
|
||||
"ats-minimal",
|
||||
"Backend Engineer",
|
||||
new List<string> { "Built APIs" },
|
||||
@@ -409,7 +409,7 @@ public sealed class JobApplicationsApplicationPackageTests
|
||||
|
||||
var previewResult = await controller.PreviewTailoredCv(job.Id, request, CancellationToken.None);
|
||||
var ok = Assert.IsType<OkObjectResult>(previewResult.Result);
|
||||
var preview = Assert.IsType<JobApplicationsController.TailoredCvPreviewDto>(ok.Value);
|
||||
var preview = Assert.IsType<TailoredCvPreviewDto>(ok.Value);
|
||||
Assert.Equal("ats-minimal", preview.TemplateId);
|
||||
Assert.Equal("preview.pdf", preview.SuggestedFileName);
|
||||
Assert.Equal("data:image/png;base64,abc123", renderer.LastPhotoDataUrl);
|
||||
|
||||
Reference in New Issue
Block a user