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:
@@ -28,7 +28,7 @@ public sealed class JobApplicationsEndpointBehaviorTests
|
||||
await db.SaveChangesAsync();
|
||||
|
||||
var controller = CreateController(db, "user-1");
|
||||
var result = await controller.SaveApplicationDrafts(job.Id, new JobApplicationsController.SaveApplicationDraftsRequest(" Cover letter body ", " Notes body ", null), CancellationToken.None);
|
||||
var result = await controller.SaveApplicationDrafts(job.Id, new SaveApplicationDraftsRequest(" Cover letter body ", " Notes body ", null), CancellationToken.None);
|
||||
|
||||
Assert.IsType<NoContentResult>(result);
|
||||
var saved = await db.JobApplications.FirstAsync();
|
||||
@@ -83,7 +83,7 @@ public sealed class JobApplicationsEndpointBehaviorTests
|
||||
var result = await controller.GetStatusSuggestion(job.Id, CancellationToken.None);
|
||||
|
||||
var ok = Assert.IsType<OkObjectResult>(result.Result);
|
||||
var dto = Assert.IsType<JobApplicationsController.StatusSuggestionDto>(ok.Value);
|
||||
var dto = Assert.IsType<StatusSuggestionDto>(ok.Value);
|
||||
Assert.True(dto.HasSuggestion);
|
||||
Assert.Equal("Rejected", dto.SuggestedStatus);
|
||||
}
|
||||
@@ -114,7 +114,7 @@ public sealed class JobApplicationsEndpointBehaviorTests
|
||||
var result = await controller.GetStatusSuggestion(job.Id, CancellationToken.None);
|
||||
|
||||
var ok = Assert.IsType<OkObjectResult>(result.Result);
|
||||
var dto = Assert.IsType<JobApplicationsController.StatusSuggestionDto>(ok.Value);
|
||||
var dto = Assert.IsType<StatusSuggestionDto>(ok.Value);
|
||||
Assert.False(dto.HasSuggestion);
|
||||
}
|
||||
|
||||
@@ -147,7 +147,7 @@ public sealed class JobApplicationsEndpointBehaviorTests
|
||||
var result = await controller.GetMatchScore(job.Id, CancellationToken.None);
|
||||
|
||||
var ok = Assert.IsType<OkObjectResult>(result.Result);
|
||||
var dto = Assert.IsType<JobApplicationsController.MatchScoreDto>(ok.Value);
|
||||
var dto = Assert.IsType<MatchScoreDto>(ok.Value);
|
||||
Assert.True(dto.HasEnoughSignal);
|
||||
Assert.True(dto.Score >= 75, $"expected strong score, got {dto.Score}");
|
||||
Assert.Contains("C#", dto.MatchedKeywords);
|
||||
@@ -181,7 +181,7 @@ public sealed class JobApplicationsEndpointBehaviorTests
|
||||
await db.SaveChangesAsync();
|
||||
|
||||
var controller = CreateController(db, "user-1");
|
||||
var request = new JobApplicationsController.CreateJobApplicationRequest(
|
||||
var request = new CreateJobApplicationRequest(
|
||||
JobTitle: "Backend Dev",
|
||||
CompanyId: company.Id,
|
||||
Status: null,
|
||||
@@ -237,7 +237,7 @@ public sealed class JobApplicationsEndpointBehaviorTests
|
||||
await db.SaveChangesAsync();
|
||||
|
||||
var controller = CreateController(db, "user-1");
|
||||
var request = new JobApplicationsController.UpdateJobApplicationRequest(
|
||||
var request = new UpdateJobApplicationRequest(
|
||||
JobTitle: "Backend Dev",
|
||||
CompanyId: company.Id,
|
||||
Status: "Applied",
|
||||
|
||||
Reference in New Issue
Block a user