Merge branch 'worktree-agent-a5f48334696288159'
# Conflicts: # gerbil-manager-web/e2e/mock-data.ts
This commit is contained in:
89
GerbilManagerWebAPI/Endpoints/AcquisitionEndpoints.cs
Normal file
89
GerbilManagerWebAPI/Endpoints/AcquisitionEndpoints.cs
Normal file
@@ -0,0 +1,89 @@
|
||||
using GerbilManagerWebAPI.Dtos;
|
||||
using GerbilManagerWebAPI.Models;
|
||||
using Microsoft.AspNetCore.Http.HttpResults;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
|
||||
namespace GerbilManagerWebAPI.Endpoints
|
||||
{
|
||||
/// <summary>
|
||||
/// ERWERB: acquisition data per animal (purchase date/price/note).
|
||||
/// GET /acquisitions?gerbilId=… -> records for one animal (or all), newest date first.
|
||||
/// GET /acquisitions/{id} -> a single record.
|
||||
/// POST /acquisitions -> create, returns 201.
|
||||
/// PUT /acquisitions/{id} -> update, returns 204.
|
||||
/// DELETE /acquisitions/{id} -> delete, returns 204.
|
||||
/// Decoupled from gerbils/contacts (loose nullable Guid columns, no FK), so rows survive
|
||||
/// the import re-ingest wipe (mirrors Feedback).
|
||||
/// </summary>
|
||||
public static class AcquisitionEndpoints
|
||||
{
|
||||
public static IEndpointRouteBuilder MapAcquisitionEndpoints(this IEndpointRouteBuilder app)
|
||||
{
|
||||
var group = app.MapGroup("/acquisitions").WithTags("Acquisitions");
|
||||
|
||||
group.MapGet("/", async (ApplicationContext db, Guid? gerbilId) =>
|
||||
{
|
||||
var rows = await db.AcquisitionRecords.AsNoTracking()
|
||||
.Where(a => gerbilId == null || a.GerbilId == gerbilId)
|
||||
.ToListAsync();
|
||||
// Order in memory: SQLite (test host) cannot ORDER BY a DateTimeOffset column,
|
||||
// and DateOnly ordering stays consistent across providers this way.
|
||||
return TypedResults.Ok(rows
|
||||
.OrderByDescending(a => a.Date ?? DateOnly.MinValue)
|
||||
.ThenByDescending(a => a.CreatedAt)
|
||||
.Select(ToDto)
|
||||
.ToList());
|
||||
});
|
||||
|
||||
group.MapGet("/{id:guid}", async Task<Results<Ok<AcquisitionDto>, NotFound>> (Guid id, ApplicationContext db) =>
|
||||
{
|
||||
var a = await db.AcquisitionRecords.AsNoTracking().FirstOrDefaultAsync(x => x.Id == id);
|
||||
return a is null ? TypedResults.NotFound() : TypedResults.Ok(ToDto(a));
|
||||
});
|
||||
|
||||
group.MapPost("/", async (AcquisitionInput input, ApplicationContext db) =>
|
||||
{
|
||||
var a = new AcquisitionRecord
|
||||
{
|
||||
Id = Guid.NewGuid(),
|
||||
GerbilId = input.GerbilId,
|
||||
SourceContactId = input.SourceContactId,
|
||||
Date = input.Date,
|
||||
Price = input.Price,
|
||||
Note = string.IsNullOrWhiteSpace(input.Note) ? null : input.Note.Trim(),
|
||||
CreatedAt = DateTimeOffset.UtcNow,
|
||||
};
|
||||
db.AcquisitionRecords.Add(a);
|
||||
await db.SaveChangesAsync();
|
||||
return TypedResults.Created($"/acquisitions/{a.Id}", ToDto(a));
|
||||
});
|
||||
|
||||
group.MapPut("/{id:guid}", async Task<Results<NoContent, NotFound>> (Guid id, AcquisitionInput input, ApplicationContext db) =>
|
||||
{
|
||||
var a = await db.AcquisitionRecords.FirstOrDefaultAsync(x => x.Id == id);
|
||||
if (a is null) return TypedResults.NotFound();
|
||||
a.GerbilId = input.GerbilId;
|
||||
a.SourceContactId = input.SourceContactId;
|
||||
a.Date = input.Date;
|
||||
a.Price = input.Price;
|
||||
a.Note = string.IsNullOrWhiteSpace(input.Note) ? null : input.Note.Trim();
|
||||
await db.SaveChangesAsync();
|
||||
return TypedResults.NoContent();
|
||||
});
|
||||
|
||||
group.MapDelete("/{id:guid}", async Task<Results<NoContent, NotFound>> (Guid id, ApplicationContext db) =>
|
||||
{
|
||||
var a = await db.AcquisitionRecords.FirstOrDefaultAsync(x => x.Id == id);
|
||||
if (a is null) return TypedResults.NotFound();
|
||||
db.AcquisitionRecords.Remove(a);
|
||||
await db.SaveChangesAsync();
|
||||
return TypedResults.NoContent();
|
||||
});
|
||||
|
||||
return app;
|
||||
}
|
||||
|
||||
private static AcquisitionDto ToDto(AcquisitionRecord a) =>
|
||||
new(a.Id, a.GerbilId, a.SourceContactId, a.Date, a.Price, a.Note, a.CreatedAt);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user