Drop the Scene entity/grouping in favor of chapters carrying prose directly and beats belonging to many characters. Add markdown editor + character multi-select components to the web client. Remove all XML doc and inline comments across the touched C#/TS/CSS files in favor of self-documenting names, and record that convention in CLAUDE.md. Add .mcp.json (local MCP server config, no secrets) and ignore .idea/.
52 lines
2.3 KiB
C#
52 lines
2.3 KiB
C#
using Novelly.Api.Common;
|
|
using Novelly.Api.Common.Validation;
|
|
|
|
namespace Novelly.Api.Chapters;
|
|
|
|
public static class ChapterEndpoints
|
|
{
|
|
public static IEndpointRouteBuilder MapChapterEndpoints(this IEndpointRouteBuilder app)
|
|
{
|
|
var projectScoped = app.MapGroup("/api/projects/{projectId:guid}/chapters").WithTags("Chapters")
|
|
.AddEndpointFilter<RequestLoggingEndpointFilter>()
|
|
.AddEndpointFilter<ValidationEndpointFilter>();
|
|
|
|
projectScoped.MapGet("/", async (Guid projectId, ChapterService service, CancellationToken ct) =>
|
|
Results.Ok((await service.ListAsync(projectId, ct)).Select(c => c.ToSummaryResponse())))
|
|
.WithSummary("List a project's chapters in manuscript order.");
|
|
|
|
projectScoped.MapPost("/", async (
|
|
Guid projectId, CreateChapterRequest request, ChapterService service, CancellationToken ct) =>
|
|
{
|
|
var chapter = await service.CreateAsync(projectId, request, ct);
|
|
if (chapter is null)
|
|
{
|
|
return Results.NotFound();
|
|
}
|
|
|
|
var created = chapter.ToResponse();
|
|
return Results.Created($"/api/chapters/{created.Id}", created);
|
|
})
|
|
.WithSummary("Add a chapter.");
|
|
|
|
var chapters = app.MapGroup("/api/chapters").WithTags("Chapters")
|
|
.AddEndpointFilter<RequestLoggingEndpointFilter>()
|
|
.AddEndpointFilter<ValidationEndpointFilter>();
|
|
|
|
chapters.MapGet("/{id:guid}", async (Guid id, ChapterService service, CancellationToken ct) =>
|
|
(await service.GetAsync(id, ct))?.ToResponse().ToApiResult())
|
|
.WithSummary("Read a chapter with its beats and prose.");
|
|
|
|
chapters.MapPatch("/{id:guid}", async (
|
|
Guid id, UpdateChapterRequest request, ChapterService service, CancellationToken ct) =>
|
|
(await service.UpdateAsync(id, request, ct))?.ToResponse().ToApiResult())
|
|
.WithSummary("Update a chapter.");
|
|
|
|
chapters.MapDelete("/{id:guid}", async (Guid id, ChapterService service, CancellationToken ct) =>
|
|
await service.DeleteAsync(id, ct) ? Results.NoContent() : Results.NotFound())
|
|
.WithSummary("Delete a chapter.");
|
|
|
|
return app;
|
|
}
|
|
}
|