Remove Scenes, group beats by multiple characters; strip comments repo-wide
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/.
This commit is contained in:
@@ -22,14 +22,12 @@ public class ChapterService(
|
||||
return await db.Chapters
|
||||
.Include(c => c.PovCharacter)
|
||||
.Include(c => c.Beats)
|
||||
.Include(c => c.Scenes)
|
||||
.Include(c => c.Tags)
|
||||
.Where(c => c.ProjectId == projectId)
|
||||
.OrderBy(c => c.Number)
|
||||
.ToListAsync(ct);
|
||||
}
|
||||
|
||||
/// <summary>Null when no chapter has this id — a lookup miss is expected, not exceptional.</summary>
|
||||
public async Task<Chapter?> GetAsync(Guid id, CancellationToken ct = default)
|
||||
{
|
||||
Guard.Default(id, nameof(id));
|
||||
@@ -38,7 +36,6 @@ public class ChapterService(
|
||||
return await FindAsync(id, ct);
|
||||
}
|
||||
|
||||
/// <summary>Null when no project has this id — a lookup miss is expected, not exceptional.</summary>
|
||||
public async Task<Chapter?> CreateAsync(Guid projectId, CreateChapterRequest request, CancellationToken ct = default)
|
||||
{
|
||||
Guard.Default(projectId, nameof(projectId));
|
||||
@@ -63,7 +60,9 @@ public class ChapterService(
|
||||
Setting = request.Setting,
|
||||
Notes = request.Notes,
|
||||
Status = request.Status,
|
||||
TargetWordCount = request.TargetWordCount
|
||||
TargetWordCount = request.TargetWordCount,
|
||||
Prose = request.Prose,
|
||||
WordCount = ChapterMapping.CountWords(request.Prose)
|
||||
};
|
||||
|
||||
if (request.Tags is { } names)
|
||||
@@ -74,7 +73,6 @@ public class ChapterService(
|
||||
db.Chapters.Add(chapter);
|
||||
await db.SaveChangesAsync(ct);
|
||||
|
||||
// Just created it — the reload is only to pick up includes, not to check existence.
|
||||
return (await FindAsync(chapter.Id, ct))!;
|
||||
}
|
||||
|
||||
@@ -100,6 +98,13 @@ public class ChapterService(
|
||||
chapter.Notes = Patch.Apply(chapter.Notes, request.Notes);
|
||||
chapter.Status = request.Status ?? chapter.Status;
|
||||
chapter.TargetWordCount = request.TargetWordCount ?? chapter.TargetWordCount;
|
||||
|
||||
if (request.Prose is not null)
|
||||
{
|
||||
chapter.Prose = Patch.Apply(chapter.Prose, request.Prose);
|
||||
chapter.WordCount = ChapterMapping.CountWords(chapter.Prose);
|
||||
}
|
||||
|
||||
chapter.UpdatedAt = DateTimeOffset.UtcNow;
|
||||
|
||||
if (request.Tags is { } names)
|
||||
@@ -111,7 +116,6 @@ public class ChapterService(
|
||||
return (await FindAsync(id, ct))!;
|
||||
}
|
||||
|
||||
/// <summary>True if a chapter was deleted; false if no chapter had this id.</summary>
|
||||
public async Task<bool> DeleteAsync(Guid id, CancellationToken ct = default)
|
||||
{
|
||||
Guard.Default(id, nameof(id));
|
||||
@@ -148,10 +152,8 @@ public class ChapterService(
|
||||
|
||||
var chapter = await db.Chapters
|
||||
.Include(c => c.PovCharacter)
|
||||
.Include(c => c.Beats).ThenInclude(b => b.Character)
|
||||
.Include(c => c.Beats).ThenInclude(b => b.Scene)
|
||||
.Include(c => c.Beats).ThenInclude(b => b.Characters)
|
||||
.Include(c => c.Beats).ThenInclude(b => b.Tags)
|
||||
.Include(c => c.Scenes).ThenInclude(s => s.PovCharacter)
|
||||
.Include(c => c.Tags)
|
||||
.FirstOrDefaultAsync(c => c.Id == id, ct);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user