using GerbilManagerWebAPI.Common; using GerbilManagerWebAPI.Dtos; using GerbilManagerWebAPI.Models; using Gridify; using Microsoft.AspNetCore.Http.HttpResults; using Microsoft.EntityFrameworkCore; namespace GerbilManagerWebAPI.Endpoints { public static class EnclosureEndpoints { public static IEndpointRouteBuilder MapEnclosureEndpoints(this IEndpointRouteBuilder app) { var group = app.MapGroup("/enclosures").WithTags("Enclosures"); group.MapGet("/", async ([AsParameters] GridifyParams query, ApplicationContext db) => TypedResults.Ok(await db.Enclosures.AsNoTracking().ToPagedResultAsync(query, ToDto))); group.MapGet("/{id:guid}", async Task, NotFound>> (Guid id, ApplicationContext db) => { var e = await db.Enclosures.AsNoTracking().FirstOrDefaultAsync(x => x.Id == id); return e is null ? TypedResults.NotFound() : TypedResults.Ok(ToDto(e)); }); group.MapPost("/", async (EnclosureInput input, ApplicationContext db) => { var e = new Enclosure { Id = Guid.NewGuid(), Name = input.Name, Notes = input.Notes }; Apply(e, input); db.Enclosures.Add(e); await db.SaveChangesAsync(); return TypedResults.Created($"/enclosures/{e.Id}", ToDto(e)); }); group.MapPut("/{id:guid}", async Task> (Guid id, EnclosureInput input, ApplicationContext db) => { var e = await db.Enclosures.FirstOrDefaultAsync(x => x.Id == id); if (e is null) return TypedResults.NotFound(); e.Name = input.Name; e.Notes = input.Notes; Apply(e, input); await db.SaveChangesAsync(); return TypedResults.NoContent(); }); // Reinigung dokumentieren: setzt LastCleanedDate auf heute (NextCleaningDate folgt aus dem Zyklus). group.MapPost("/{id:guid}/mark-cleaned", async Task, NotFound>> (Guid id, ApplicationContext db) => { var e = await db.Enclosures.FirstOrDefaultAsync(x => x.Id == id); if (e is null) return TypedResults.NotFound(); e.LastCleanedDate = DateOnly.FromDateTime(DateTime.Today); await db.SaveChangesAsync(); return TypedResults.Ok(ToDto(e)); }); // 409 if the enclosure still houses gerbils. group.MapDelete("/{id:guid}", async Task>> (Guid id, ApplicationContext db) => { var e = await db.Enclosures.FirstOrDefaultAsync(x => x.Id == id); if (e is null) return TypedResults.NotFound(); bool occupied = await db.Gerbils.AnyAsync(g => g.EnclosureId == id); if (occupied) return TypedResults.Conflict("Enclosure still contains gerbils and cannot be deleted."); db.Enclosures.Remove(e); await db.SaveChangesAsync(); return TypedResults.NoContent(); }); return app; } private static void Apply(Enclosure e, EnclosureInput input) { e.Size = input.Size; e.Capacity = input.Capacity; e.LastCleanedDate = input.LastCleanedDate; e.CleaningCycleDays = input.CleaningCycleDays; } private static EnclosureDto ToDto(Enclosure e) => new(e.Id, e.Name, e.Notes, e.Size, e.Capacity, e.LastCleanedDate, e.CleaningCycleDays, e.NextCleaningDate); } }