Add outline import feature; drop Dto naming, map entities at the API boundary

Services now return entities; endpoints (and the agent toolsets) map to
*Response records instead of services building wire DTOs themselves.
Also brings in the outline-import agent, MCP tool, ledger and web dialog
that were already in progress on disk.
This commit is contained in:
James Wampler
2026-08-06 18:36:40 -07:00
parent 40f93e40a8
commit 189ebf3237
66 changed files with 3310 additions and 364 deletions
+6 -6
View File
@@ -12,25 +12,25 @@ public static class BeatEndpoints
.AddEndpointFilter<ValidationEndpointFilter>();
chapterScoped.MapGet("/", async (Guid chapterId, BeatService service, CancellationToken ct) =>
Results.Ok(await service.ListAsync(chapterId, ct)))
Results.Ok((await service.ListAsync(chapterId, ct)).Select(b => b.ToResponse())))
.WithSummary("Read a chapter's outline: its beats, in order.");
chapterScoped.MapPost("/", async (
Guid chapterId, CreateBeatRequest request, BeatService service, CancellationToken ct) =>
{
var created = await service.CreateAsync(chapterId, request, ct);
var created = (await service.CreateAsync(chapterId, request, ct)).ToResponse();
return Results.Created($"/api/beats/{created.Id}", created);
})
.WithSummary("Add a beat to a chapter's outline.");
chapterScoped.MapPost("/reorder", async (
Guid chapterId, ReorderBeatsRequest request, BeatService service, CancellationToken ct) =>
Results.Ok(await service.ReorderAsync(chapterId, request, ct)))
Results.Ok((await service.ReorderAsync(chapterId, request, ct)).Select(b => b.ToResponse())))
.WithSummary("Renumber a chapter's beats to match the order given.");
app.MapGet("/api/characters/{characterId:guid}/beats", async (
Guid characterId, BeatService service, CancellationToken ct) =>
(await service.ListForCharacterAsync(characterId, ct)).ToApiResult())
(await service.ListForCharacterAsync(characterId, ct))?.Select(b => b.ToCharacterBeatResponse()).ToList().ToApiResult())
.WithTags("Beats")
.WithSummary("Every beat this character appears in, in manuscript order.");
@@ -39,12 +39,12 @@ public static class BeatEndpoints
.AddEndpointFilter<ValidationEndpointFilter>();
beats.MapGet("/{id:guid}", async (Guid id, BeatService service, CancellationToken ct) =>
(await service.GetAsync(id, ct)).ToApiResult())
(await service.GetAsync(id, ct))?.ToResponse().ToApiResult())
.WithSummary("Read one beat.");
beats.MapPatch("/{id:guid}", async (
Guid id, UpdateBeatRequest request, BeatService service, CancellationToken ct) =>
(await service.UpdateAsync(id, request, ct)).ToApiResult())
(await service.UpdateAsync(id, request, ct))?.ToResponse().ToApiResult())
.WithSummary("Update a beat. Sending a tag list replaces the beat's tags.");
beats.MapDelete("/{id:guid}", async (Guid id, BeatService service, CancellationToken ct) =>