Files
work-club-manager/backend/WorkClub.Api/Endpoints/Shifts/ShiftEndpoints.cs

168 lines
5.2 KiB
C#
Raw Permalink Normal View History

using Microsoft.AspNetCore.Http.HttpResults;
using Microsoft.AspNetCore.Mvc;
using WorkClub.Api.Services;
using WorkClub.Application.Shifts.DTOs;
namespace WorkClub.Api.Endpoints.Shifts;
public static class ShiftEndpoints
{
public static void MapShiftEndpoints(this IEndpointRouteBuilder app)
{
var group = app.MapGroup("/api/shifts");
group.MapGet("", GetShifts)
.RequireAuthorization("RequireMember")
.WithName("GetShifts");
group.MapGet("{id:guid}", GetShift)
.RequireAuthorization("RequireMember")
.WithName("GetShift");
group.MapPost("", CreateShift)
.RequireAuthorization("RequireManager")
.WithName("CreateShift");
group.MapPut("{id:guid}", UpdateShift)
.RequireAuthorization("RequireManager")
.WithName("UpdateShift");
group.MapDelete("{id:guid}", DeleteShift)
.RequireAuthorization("RequireAdmin")
.WithName("DeleteShift");
group.MapPost("{id:guid}/signup", SignUpForShift)
.RequireAuthorization("RequireMember")
.WithName("SignUpForShift");
group.MapDelete("{id:guid}/signup", CancelSignup)
.RequireAuthorization("RequireMember")
.WithName("CancelSignup");
}
private static async Task<Ok<ShiftListDto>> GetShifts(
ShiftService shiftService,
[FromQuery] DateTimeOffset? from = null,
[FromQuery] DateTimeOffset? to = null,
[FromQuery] int page = 1,
[FromQuery] int pageSize = 20)
{
var result = await shiftService.GetShiftsAsync(from, to, page, pageSize);
return TypedResults.Ok(result);
}
private static async Task<Results<Ok<ShiftDetailDto>, NotFound>> GetShift(
Guid id,
ShiftService shiftService)
{
var result = await shiftService.GetShiftByIdAsync(id);
if (result == null)
return TypedResults.NotFound();
return TypedResults.Ok(result);
}
private static async Task<Results<Created<ShiftDetailDto>, BadRequest<string>>> CreateShift(
CreateShiftRequest request,
ShiftService shiftService,
HttpContext httpContext)
{
var userIdClaim = httpContext.User.FindFirst("sub")?.Value;
if (string.IsNullOrEmpty(userIdClaim) || !Guid.TryParse(userIdClaim, out var createdById))
{
return TypedResults.BadRequest("Invalid user ID");
}
var (shift, error) = await shiftService.CreateShiftAsync(request, createdById);
if (error != null || shift == null)
return TypedResults.BadRequest(error ?? "Failed to create shift");
return TypedResults.Created($"/api/shifts/{shift.Id}", shift);
}
private static async Task<Results<Ok<ShiftDetailDto>, NotFound, Conflict<string>>> UpdateShift(
Guid id,
UpdateShiftRequest request,
ShiftService shiftService)
{
var (shift, error, isConflict) = await shiftService.UpdateShiftAsync(id, request);
if (error != null)
{
if (error == "Shift not found")
return TypedResults.NotFound();
if (isConflict)
return TypedResults.Conflict(error);
}
return TypedResults.Ok(shift!);
}
private static async Task<Results<NoContent, NotFound>> DeleteShift(
Guid id,
ShiftService shiftService)
{
var deleted = await shiftService.DeleteShiftAsync(id);
if (!deleted)
return TypedResults.NotFound();
return TypedResults.NoContent();
}
private static async Task<Results<Ok, NotFound, UnprocessableEntity<string>, Conflict<string>>> SignUpForShift(
Guid id,
ShiftService shiftService,
HttpContext httpContext)
{
var userIdClaim = httpContext.User.FindFirst("sub")?.Value;
if (string.IsNullOrEmpty(userIdClaim) || !Guid.TryParse(userIdClaim, out var memberId))
{
return TypedResults.UnprocessableEntity("Invalid user ID");
}
var (success, error, isConflict) = await shiftService.SignUpForShiftAsync(id, memberId);
if (!success)
{
if (error == "Shift not found")
return TypedResults.NotFound();
if (error == "Cannot sign up for past shifts")
return TypedResults.UnprocessableEntity(error);
if (isConflict)
return TypedResults.Conflict(error!);
}
return TypedResults.Ok();
}
private static async Task<Results<Ok, NotFound, UnprocessableEntity<string>>> CancelSignup(
Guid id,
ShiftService shiftService,
HttpContext httpContext)
{
var userIdClaim = httpContext.User.FindFirst("sub")?.Value;
if (string.IsNullOrEmpty(userIdClaim) || !Guid.TryParse(userIdClaim, out var memberId))
{
return TypedResults.UnprocessableEntity("Invalid user ID");
}
var (success, error) = await shiftService.CancelSignupAsync(id, memberId);
if (!success)
{
if (error == "Sign-up not found")
return TypedResults.NotFound();
return TypedResults.UnprocessableEntity(error!);
}
return TypedResults.Ok();
}
}