78 lines
3.0 KiB
C#
78 lines
3.0 KiB
C#
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using QuestionsApi.Models;
|
|
using QuestionsApi.Services;
|
|
using System.Security.Claims;
|
|
|
|
namespace QuestionsApi.Controllers;
|
|
|
|
[ApiController]
|
|
[Route("api/ccs")]
|
|
[Authorize(Roles = "USER,SUPER")]
|
|
public sealed class CcsController(CcsStore store, CcsRatingStore ratings) : ControllerBase
|
|
{
|
|
[HttpGet("cases")]
|
|
public async Task<IActionResult> Cases() => Ok(await store.ListCasesAsync());
|
|
|
|
[HttpGet("orders/search")]
|
|
public async Task<IActionResult> SearchOrders([FromQuery] string q, [FromQuery] int limit = 20) =>
|
|
Ok(await store.SearchOrdersAsync(q ?? "", limit));
|
|
|
|
[HttpPost("attempts")]
|
|
public async Task<IActionResult> CreateAttempt(CreateCcsAttemptRequest request)
|
|
{
|
|
try { return Ok(await store.ToResponseAsync(await store.CreateAttemptAsync(UserId(), request))); }
|
|
catch (ArgumentException exception) { return BadRequest(exception.Message); }
|
|
catch (KeyNotFoundException) { return NotFound(); }
|
|
catch (InvalidOperationException exception) { return Conflict(exception.Message); }
|
|
}
|
|
|
|
[HttpGet("attempts/{id}")]
|
|
public async Task<IActionResult> Attempt(string id)
|
|
{
|
|
var attempt = await store.GetOwnedAsync(id, UserId());
|
|
return attempt is null ? NotFound() : Ok(await store.ToResponseAsync(attempt));
|
|
}
|
|
|
|
[HttpPost("attempts/{id}/commands")]
|
|
public async Task<IActionResult> Command(string id, CcsCommandRequest request)
|
|
{
|
|
var attempt = await store.GetOwnedAsync(id, UserId());
|
|
if (attempt is null) return NotFound();
|
|
try { return Ok(await store.ToResponseAsync(await store.ApplyCommandAsync(attempt, request))); }
|
|
catch (ArgumentException exception) { return BadRequest(exception.Message); }
|
|
catch (InvalidOperationException exception) { return Conflict(exception.Message); }
|
|
}
|
|
|
|
[HttpPost("attempts/{id}/abandon")]
|
|
public async Task<IActionResult> Abandon(string id)
|
|
{
|
|
var attempt = await store.GetOwnedAsync(id, UserId());
|
|
if (attempt is null) return NotFound();
|
|
await store.AbandonAsync(attempt);
|
|
return NoContent();
|
|
}
|
|
|
|
[HttpGet("history")]
|
|
public async Task<IActionResult> History([FromQuery] int limit = 50) => Ok(await store.HistoryAsync(UserId(), limit));
|
|
|
|
[HttpGet("prediction")]
|
|
public async Task<IActionResult> Prediction() => Ok(await store.PredictionAsync(UserId()));
|
|
|
|
[HttpGet("ratings/me")]
|
|
public async Task<IActionResult> Rating() => Ok(await ratings.GetProfileAsync(UserId()));
|
|
|
|
[HttpPost("admin/import")]
|
|
[Authorize(Roles = "SUPER")]
|
|
public async Task<IActionResult> Import(CcsImportRequest request)
|
|
{
|
|
var response = await store.ImportAsync(request);
|
|
return response.Errors.Count > 0 ? BadRequest(response) : Ok(response);
|
|
}
|
|
|
|
private string UserId() => User.FindFirstValue(ClaimTypes.NameIdentifier)
|
|
?? User.FindFirstValue(ClaimTypes.Name)
|
|
?? User.Identity?.Name
|
|
?? throw new UnauthorizedAccessException();
|
|
}
|