122 lines
4.4 KiB
C#
122 lines
4.4 KiB
C#
using Microsoft.AspNetCore.Authorization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using Nexus.Api.DTOs;
|
|
using Nexus.Api.Models;
|
|
using Nexus.Api.Services;
|
|
|
|
namespace Nexus.Api.Controllers;
|
|
|
|
[Authorize]
|
|
[ApiController]
|
|
[Route("api/v1/projects")]
|
|
public class ProjectsController(IProjectService projectService) : ControllerBase
|
|
{
|
|
[HttpGet]
|
|
[ProducesResponseType(typeof(IReadOnlyList<ProjectDto>), StatusCodes.Status200OK)]
|
|
public async Task<ActionResult<IReadOnlyList<ProjectDto>>> GetAll(CancellationToken ct)
|
|
=> Ok((await projectService.GetAllAsync(ct)).Select(project => Map(project)).ToArray());
|
|
|
|
[HttpGet("{id:guid}")]
|
|
[ProducesResponseType(typeof(ProjectDto), StatusCodes.Status200OK)]
|
|
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
|
public async Task<ActionResult<ProjectDto>> GetById(Guid id, CancellationToken ct)
|
|
{
|
|
var project = await projectService.GetByIdAsync(id, ct);
|
|
return project is null ? NotFound() : Ok(Map(project));
|
|
}
|
|
|
|
[HttpGet("{id:guid}/tasks")]
|
|
[ProducesResponseType(typeof(IReadOnlyList<ProjectTaskDto>), StatusCodes.Status200OK)]
|
|
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
|
public async Task<ActionResult<IReadOnlyList<ProjectTaskDto>>> GetTasks(
|
|
Guid id,
|
|
CancellationToken ct)
|
|
{
|
|
if (await projectService.GetByIdAsync(id, ct) is null)
|
|
return NotFound();
|
|
|
|
var tasks = await projectService.GetTasksAsync(id, ct);
|
|
return Ok(tasks.Select(task => new ProjectTaskDto(
|
|
task.Id,
|
|
task.Title,
|
|
task.State,
|
|
task.Priority,
|
|
id,
|
|
task.AssignedTo,
|
|
task.ExpectedFrom,
|
|
task.IsAgentTask,
|
|
task.UpdatedAt)).ToArray());
|
|
}
|
|
|
|
[HttpPost]
|
|
[ProducesResponseType(typeof(ProjectDto), StatusCodes.Status201Created)]
|
|
[ProducesResponseType(typeof(ValidationProblemDetails), StatusCodes.Status400BadRequest)]
|
|
public async Task<ActionResult<ProjectDto>> Create(
|
|
[FromBody] CreateProjectRequest request,
|
|
CancellationToken ct)
|
|
{
|
|
if (string.IsNullOrWhiteSpace(request.Name))
|
|
{
|
|
ModelState.AddModelError("name", "Name is required.");
|
|
return ValidationProblem(ModelState);
|
|
}
|
|
|
|
var project = await projectService.CreateAsync(request, ct);
|
|
return Created(
|
|
$"/api/v1/projects/{project.Id}",
|
|
Map(project, ProjectOperation(project, "created")));
|
|
}
|
|
|
|
[HttpPatch("{id:guid}")]
|
|
[ProducesResponseType(typeof(ProjectDto), StatusCodes.Status200OK)]
|
|
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
|
public async Task<ActionResult<ProjectDto>> Update(
|
|
Guid id,
|
|
[FromBody] UpdateProjectRequest request,
|
|
CancellationToken ct)
|
|
{
|
|
var project = await projectService.UpdateAsync(id, request, ct);
|
|
return project is null
|
|
? NotFound()
|
|
: Ok(Map(project, ProjectOperation(project, "updated")));
|
|
}
|
|
|
|
[HttpDelete("{id:guid}")]
|
|
[ProducesResponseType(typeof(ProjectDto), StatusCodes.Status200OK)]
|
|
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
|
public async Task<IActionResult> Delete(Guid id, CancellationToken ct)
|
|
{
|
|
var result = await projectService.DeleteAsync(id, ct);
|
|
return result.Outcome switch
|
|
{
|
|
ProjectDeleteOutcome.NotFound => NotFound(),
|
|
ProjectDeleteOutcome.Archived => Ok(Map(
|
|
result.Project!,
|
|
ProjectOperation(result.Project!, "archived"))),
|
|
_ => Ok(Map(
|
|
result.Project!,
|
|
ProjectOperation(result.Project!, "deleted")))
|
|
};
|
|
}
|
|
|
|
private OperationResultDto ProjectOperation(
|
|
Nexus.Api.Data.Project project,
|
|
string status)
|
|
=> OperationResultFactory.FromHttpContext(
|
|
HttpContext,
|
|
status,
|
|
new EntityRefDto("project", project.Id.ToString(), project.Name));
|
|
|
|
private static ProjectDto Map(
|
|
Nexus.Api.Data.Project project,
|
|
OperationResultDto? operation = null)
|
|
=> new(
|
|
project.Id,
|
|
project.Name,
|
|
project.Description,
|
|
project.Status.ToString(),
|
|
project.Progress,
|
|
project.UpdatedAt,
|
|
operation);
|
|
}
|