Surface project ownership/role on the wire and gate the web UI by it
ProjectResponse now carries OwnerId and a server-resolved MyRole so Editors/Reviewers see read-only fields and no delete/grant-management affordances instead of only finding out via a 403 after the fact. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PuBH9QSv66DPXSSBERmPs6
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
using Novelly.Api.Common;
|
||||
using Novelly.Api.Common.Validation;
|
||||
using Novelly.Api.Users;
|
||||
|
||||
namespace Novelly.Api.Projects;
|
||||
|
||||
@@ -15,20 +16,36 @@ public static class ProjectEndpoints
|
||||
Results.Ok(await service.ListAsync(ct)))
|
||||
.WithSummary("List all novel projects.");
|
||||
|
||||
group.MapGet("/{id:guid}", async (Guid id, ProjectService service, CancellationToken ct) =>
|
||||
(await service.GetAsync(id, ct))?.ToResponse().ToApiResult())
|
||||
group.MapGet("/{id:guid}", async (Guid id, ProjectService service, ProjectAccessService access, CancellationToken ct) =>
|
||||
{
|
||||
var project = await service.GetAsync(id, ct);
|
||||
if (project is null)
|
||||
return Results.NotFound();
|
||||
|
||||
var myRole = await access.GetMyRoleAsync(project, ct);
|
||||
return Results.Ok(project.ToResponse(myRole));
|
||||
})
|
||||
.WithSummary("Read a project's brief.");
|
||||
|
||||
group.MapPost("/", async (CreateProjectRequest request, ProjectService service, CancellationToken ct) =>
|
||||
group.MapPost("/", async (CreateProjectRequest request, ProjectService service, ProjectAccessService access, CancellationToken ct) =>
|
||||
{
|
||||
var created = (await service.CreateAsync(request, ct)).ToResponse();
|
||||
var project = await service.CreateAsync(request, ct);
|
||||
var myRole = await access.GetMyRoleAsync(project, ct);
|
||||
var created = project.ToResponse(myRole);
|
||||
return Results.Created($"/api/projects/{created.Id}", created);
|
||||
})
|
||||
.WithSummary("Create a novel project.");
|
||||
|
||||
group.MapPatch("/{id:guid}", async (
|
||||
Guid id, UpdateProjectRequest request, ProjectService service, CancellationToken ct) =>
|
||||
(await service.UpdateAsync(id, request, ct))?.ToResponse().ToApiResult())
|
||||
Guid id, UpdateProjectRequest request, ProjectService service, ProjectAccessService access, CancellationToken ct) =>
|
||||
{
|
||||
var project = await service.UpdateAsync(id, request, ct);
|
||||
if (project is null)
|
||||
return Results.NotFound();
|
||||
|
||||
var myRole = await access.GetMyRoleAsync(project, ct);
|
||||
return Results.Ok(project.ToResponse(myRole));
|
||||
})
|
||||
.WithSummary("Update a project's brief.");
|
||||
|
||||
group.MapDelete("/{id:guid}", async (Guid id, ProjectService service, CancellationToken ct) =>
|
||||
|
||||
Reference in New Issue
Block a user