fix(jobs): align table and board query contracts
This commit is contained in:
@@ -478,6 +478,13 @@ Canonical profile:
|
||||
[FromQuery] string? sortDir = null,
|
||||
CancellationToken cancellationToken = default
|
||||
)
|
||||
=> await ReadJobsAsync(page, pageSize, q, status, companyId, location, needsFollowUp, readiness,
|
||||
includeDeleted, deletedOnly, sortBy, sortDir, false, cancellationToken);
|
||||
|
||||
// One logical query; only the response projection/pagination differs between the two views.
|
||||
private async Task<ActionResult> ReadJobsAsync(int page, int pageSize, string? q, string? status,
|
||||
int? companyId, string? location, bool needsFollowUp, string? readiness, bool includeDeleted,
|
||||
bool deletedOnly, string? sortBy, string? sortDir, bool board, CancellationToken cancellationToken)
|
||||
{
|
||||
if (page < 1) page = 1;
|
||||
if (pageSize is not (15 or 20 or 25)) pageSize = 15;
|
||||
@@ -565,15 +572,18 @@ Canonical profile:
|
||||
if (matchesFollowUp && matchesReadiness) filtered.Add(j);
|
||||
}
|
||||
|
||||
filtered = key switch
|
||||
var ordered = key switch
|
||||
{
|
||||
"company" => dirDesc ? filtered.OrderByDescending(j => j.Company.Name).ToList() : filtered.OrderBy(j => j.Company.Name).ToList(),
|
||||
"jobTitle" => dirDesc ? filtered.OrderByDescending(j => j.JobTitle).ToList() : filtered.OrderBy(j => j.JobTitle).ToList(),
|
||||
"status" => dirDesc ? filtered.OrderByDescending(j => j.Status).ToList() : filtered.OrderBy(j => j.Status).ToList(),
|
||||
"location" => dirDesc ? filtered.OrderByDescending(j => j.Location).ToList() : filtered.OrderBy(j => j.Location).ToList(),
|
||||
"daysSince" => dirDesc ? filtered.OrderBy(j => j.DateApplied).ToList() : filtered.OrderByDescending(j => j.DateApplied).ToList(),
|
||||
_ => dirDesc ? filtered.OrderByDescending(j => j.DateApplied).ToList() : filtered.OrderBy(j => j.DateApplied).ToList(),
|
||||
"company" => dirDesc ? filtered.OrderByDescending(j => j.Company.Name) : filtered.OrderBy(j => j.Company.Name),
|
||||
"jobTitle" => dirDesc ? filtered.OrderByDescending(j => j.JobTitle) : filtered.OrderBy(j => j.JobTitle),
|
||||
"status" => dirDesc ? filtered.OrderByDescending(j => j.Status) : filtered.OrderBy(j => j.Status),
|
||||
"location" => dirDesc ? filtered.OrderByDescending(j => j.Location) : filtered.OrderBy(j => j.Location),
|
||||
"daysSince" => dirDesc ? filtered.OrderBy(j => j.DateApplied) : filtered.OrderByDescending(j => j.DateApplied),
|
||||
_ => dirDesc ? filtered.OrderByDescending(j => j.DateApplied) : filtered.OrderBy(j => j.DateApplied),
|
||||
};
|
||||
filtered = ordered.ThenBy(j => j.Id).ToList();
|
||||
|
||||
if (board) return Ok(filtered);
|
||||
|
||||
var totalCount = filtered.Count;
|
||||
var pageItems = filtered.Skip((page - 1) * pageSize).Take(pageSize).ToList();
|
||||
@@ -589,7 +599,7 @@ Canonical profile:
|
||||
return Ok(new PagedResult<JobApplicationDto>(dtoItems, totalCount, page, pageSize));
|
||||
}
|
||||
|
||||
query = key switch
|
||||
var orderedQuery = key switch
|
||||
{
|
||||
"company" => dirDesc ? query.OrderByDescending(j => j.Company.Name) : query.OrderBy(j => j.Company.Name),
|
||||
"jobTitle" => dirDesc ? query.OrderByDescending(j => j.JobTitle) : query.OrderBy(j => j.JobTitle),
|
||||
@@ -599,6 +609,11 @@ Canonical profile:
|
||||
"daysSince" => dirDesc ? query.OrderBy(j => j.DateApplied) : query.OrderByDescending(j => j.DateApplied),
|
||||
_ => dirDesc ? query.OrderByDescending(j => j.DateApplied) : query.OrderBy(j => j.DateApplied),
|
||||
};
|
||||
query = orderedQuery.ThenBy(j => j.Id);
|
||||
|
||||
// ponytail: existing full-array Board contract is O(N); use a separately designed
|
||||
// server-paged/virtualized Board if account size makes this unsuitable. Never truncate.
|
||||
if (board) return Ok(await query.ToListAsync(cancellationToken));
|
||||
|
||||
var total = await query.CountAsync(cancellationToken);
|
||||
|
||||
@@ -648,22 +663,19 @@ Canonical profile:
|
||||
[HttpGet("board")]
|
||||
public async Task<ActionResult<List<JobApplication>>> GetBoard(
|
||||
[FromQuery] bool includeDeleted = false,
|
||||
CancellationToken cancellationToken = default
|
||||
CancellationToken cancellationToken = default,
|
||||
[FromQuery] string? q = null,
|
||||
[FromQuery] string? status = null,
|
||||
[FromQuery] int? companyId = null,
|
||||
[FromQuery] string? location = null,
|
||||
[FromQuery] bool needsFollowUp = false,
|
||||
[FromQuery] string? readiness = null,
|
||||
[FromQuery] bool deletedOnly = false,
|
||||
[FromQuery] string? sortBy = null,
|
||||
[FromQuery] string? sortDir = "desc"
|
||||
)
|
||||
{
|
||||
var query = _db.JobApplications
|
||||
.AsNoTracking()
|
||||
.Include(j => j.Company)
|
||||
.AsQueryable();
|
||||
|
||||
if (!includeDeleted) query = query.Where(j => !j.IsDeleted);
|
||||
|
||||
var items = await query
|
||||
.OrderByDescending(j => j.DateApplied)
|
||||
.ToListAsync(cancellationToken);
|
||||
|
||||
return Ok(items);
|
||||
}
|
||||
=> await ReadJobsAsync(1, 15, q, status, companyId, location, needsFollowUp, readiness,
|
||||
includeDeleted, deletedOnly, sortBy, sortDir, true, cancellationToken);
|
||||
|
||||
[HttpGet("reminders")]
|
||||
public async Task<ActionResult<List<JobApplicationDto>>> GetReminders(
|
||||
|
||||
Reference in New Issue
Block a user