using MediatR; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Mws.Application.Common; using Mws.Application.Tasks; using TaskPriority = Mws.Domain.Tasks.TaskPriority; using TaskStatus = Mws.Domain.Tasks.TaskStatus; namespace Mws.Api.Controllers; [ApiController] [Route("api")] [Authorize] public class TasksController(ISender sender) : ControllerBase { [HttpGet("tasks/search")] public async Task>> Search([FromQuery] string? q, CancellationToken ct) { return Ok(await sender.Send(new SearchTasksQuery(User.GetUserId(), q ?? string.Empty), ct)); } [HttpGet("projects/{projectId:guid}/tasks")] public async Task>> GetAll( Guid projectId, [FromQuery] string? status, [FromQuery] string? priority, [FromQuery] Guid? assigneeId, CancellationToken ct) { var statusValue = ParseOptional(status); var priorityValue = ParseOptional(priority); return Ok(await sender.Send(new GetTasksQuery(User.GetUserId(), projectId, statusValue, priorityValue, assigneeId), ct)); } [HttpPost("projects/{projectId:guid}/tasks")] public async Task> Create(Guid projectId, [FromBody] CreateTaskRequest request, CancellationToken ct) { var result = await sender.Send(new CreateTaskCommand(User.GetUserId(), projectId, request), ct); return CreatedAtAction(nameof(Get), new { id = result.Id }, result); } [HttpGet("tasks/{id:guid}")] public async Task> Get(Guid id, CancellationToken ct) { return Ok(await sender.Send(new GetTaskQuery(User.GetUserId(), id), ct)); } [HttpPut("tasks/{id:guid}")] public async Task> Update(Guid id, [FromBody] UpdateTaskRequest request, CancellationToken ct) { return Ok(await sender.Send(new UpdateTaskCommand(User.GetUserId(), id, request), ct)); } [HttpDelete("tasks/{id:guid}")] public async Task Delete(Guid id, CancellationToken ct) { await sender.Send(new DeleteTaskCommand(User.GetUserId(), id), ct); return NoContent(); } private static TEnum? ParseOptional(string? value) where TEnum : struct, Enum { if (string.IsNullOrWhiteSpace(value)) { return null; } return Enum.TryParse(value, ignoreCase: true, out var result) ? result : throw new BadRequestException($"Invalid {typeof(TEnum).Name}: {value}"); } }