Move simulation history into profile
This commit is contained in:
@@ -53,6 +53,19 @@ public class ExamSimulationsController(ExamSimulationStore simulations) : Contro
|
||||
return Ok(await simulations.GetCompletedAsync(UserId(), limit, cursor));
|
||||
}
|
||||
|
||||
[HttpGet("history")]
|
||||
public async Task<IActionResult> History([FromQuery] int limit = 20, [FromQuery] string? before = null)
|
||||
{
|
||||
DateTime? cursor = null;
|
||||
if (!string.IsNullOrWhiteSpace(before))
|
||||
{
|
||||
if (!DateTime.TryParse(before, null, System.Globalization.DateTimeStyles.RoundtripKind, out var parsed))
|
||||
return BadRequest("The simulation-history cursor is invalid.");
|
||||
cursor = parsed;
|
||||
}
|
||||
return Ok(await simulations.GetHistoryAsync(UserId(), limit, cursor));
|
||||
}
|
||||
|
||||
[HttpGet("{id}")]
|
||||
public async Task<IActionResult> Get(string id)
|
||||
{
|
||||
|
||||
@@ -137,6 +137,28 @@ public class CompletedExamSimulationPage
|
||||
public DateTime? NextBefore { get; set; }
|
||||
}
|
||||
|
||||
public class ExamSimulationHistorySummary
|
||||
{
|
||||
public string Id { get; set; } = "";
|
||||
public string State { get; set; } = "";
|
||||
public DateTime CreatedUtc { get; set; }
|
||||
public DateTime UpdatedUtc { get; set; }
|
||||
public DateTime? CompletedUtc { get; set; }
|
||||
public int CurrentBlock { get; set; }
|
||||
public int TotalBlocks { get; set; } = 12;
|
||||
public int? PredictedScore { get; set; }
|
||||
public int? RangeLow { get; set; }
|
||||
public int? RangeHigh { get; set; }
|
||||
public int? Correct { get; set; }
|
||||
public int Total { get; set; }
|
||||
}
|
||||
|
||||
public class ExamSimulationHistoryPage
|
||||
{
|
||||
public List<ExamSimulationHistorySummary> Items { get; set; } = [];
|
||||
public DateTime? NextBefore { get; set; }
|
||||
}
|
||||
|
||||
public class Step3Outcome
|
||||
{
|
||||
[BsonId]
|
||||
|
||||
@@ -35,6 +35,8 @@ public class ExamSimulationStore
|
||||
Builders<ExamSimulation>.IndexKeys.Ascending(item => item.UserId).Ascending(item => item.State)));
|
||||
_simulations.Indexes.CreateOne(new CreateIndexModel<ExamSimulation>(
|
||||
Builders<ExamSimulation>.IndexKeys.Ascending(item => item.UserId).Ascending(item => item.State).Descending(item => item.CompletedUtc)));
|
||||
_simulations.Indexes.CreateOne(new CreateIndexModel<ExamSimulation>(
|
||||
Builders<ExamSimulation>.IndexKeys.Ascending(item => item.UserId).Descending(item => item.CreatedUtc)));
|
||||
_simulations.Indexes.CreateOne(new CreateIndexModel<ExamSimulation>(
|
||||
Builders<ExamSimulation>.IndexKeys.Ascending(item => item.UpdatedUtc)));
|
||||
_outcomes.Indexes.CreateOne(new CreateIndexModel<Step3Outcome>(
|
||||
@@ -183,6 +185,37 @@ public class ExamSimulationStore
|
||||
};
|
||||
}
|
||||
|
||||
public async Task<ExamSimulationHistoryPage> GetHistoryAsync(string userId, int limit, DateTime? before)
|
||||
{
|
||||
limit = Math.Clamp(limit, 1, 50);
|
||||
var filter = Builders<ExamSimulation>.Filter.Eq(item => item.UserId, userId);
|
||||
if (before is not null)
|
||||
filter &= Builders<ExamSimulation>.Filter.Lt(item => item.CreatedUtc, before.Value);
|
||||
var simulations = await _simulations.Find(filter).SortByDescending(item => item.CreatedUtc).Limit(limit + 1).ToListAsync();
|
||||
var hasMore = simulations.Count > limit;
|
||||
if (hasMore) simulations.RemoveAt(simulations.Count - 1);
|
||||
return new ExamSimulationHistoryPage
|
||||
{
|
||||
Items = simulations.Select(ToHistorySummary).ToList(),
|
||||
NextBefore = hasMore && simulations.Count > 0 ? simulations[^1].CreatedUtc : null
|
||||
};
|
||||
}
|
||||
|
||||
public static ExamSimulationHistorySummary ToHistorySummary(ExamSimulation item) => new()
|
||||
{
|
||||
Id = item.Id ?? "",
|
||||
State = item.State,
|
||||
CreatedUtc = item.CreatedUtc,
|
||||
UpdatedUtc = item.UpdatedUtc,
|
||||
CompletedUtc = item.CompletedUtc,
|
||||
CurrentBlock = item.CurrentBlock,
|
||||
PredictedScore = item.Score?.PredictedScore,
|
||||
RangeLow = item.Score?.RangeLow,
|
||||
RangeHigh = item.Score?.RangeHigh,
|
||||
Correct = item.Score?.Correct,
|
||||
Total = item.Score?.Total ?? item.Items.Count
|
||||
};
|
||||
|
||||
public async Task<ExamSimulation> StartNextBlockAsync(ExamSimulation simulation)
|
||||
{
|
||||
if (simulation.State != ExamSimulationStates.BetweenBlocks)
|
||||
|
||||
Reference in New Issue
Block a user