using Novelly.Api.Common; using Novelly.Api.Common.Validation; namespace Novelly.Api.Locations; public static class LocationEndpoints { public static IEndpointRouteBuilder MapLocationEndpoints(this IEndpointRouteBuilder app) { var novelScoped = app.MapGroup("/api/novels/{novelId:guid}/locations").WithTags("Locations") .AddEndpointFilter() .AddEndpointFilter(); novelScoped.MapGet("/", async (Guid novelId, LocationService service, CancellationToken ct) => Results.Ok(await service.ListAsync(novelId, ct))) .WithSummary("List a novel's locations with usage counts."); novelScoped.MapPost("/", async ( Guid novelId, CreateLocationRequest request, LocationService service, CancellationToken ct) => { var location = await service.CreateAsync(novelId, request, ct); if (location is null) { return Results.NotFound(); } var created = location.ToResponse(); return Results.Created($"/api/locations/{created.Id}", created); }) .WithSummary("Create a location. Locations are also created on demand when applied by name."); var locations = app.MapGroup("/api/locations").WithTags("Locations") .AddEndpointFilter() .AddEndpointFilter(); locations.MapGet("/{id:guid}/references", async (Guid id, LocationService service, CancellationToken ct) => (await service.GetReferencesAsync(id, ct))?.ToReferencesResponse().ToApiResult()) .WithSummary("Cross-reference: every chapter set at this location."); locations.MapPatch("/{id:guid}", async ( Guid id, UpdateLocationRequest request, LocationService service, CancellationToken ct) => (await service.UpdateAsync(id, request, ct))?.ToResponse().ToApiResult()) .WithSummary("Rename a location."); locations.MapDelete("/{id:guid}", async (Guid id, LocationService service, CancellationToken ct) => await service.DeleteAsync(id, ct) ? Results.NoContent() : Results.NotFound()) .WithSummary("Delete a location. Whatever carried it is left alone."); return app; } }