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:
Claude
2026-08-16 15:37:50 +00:00
parent e598c18d67
commit e2a2e69631
19 changed files with 447 additions and 145 deletions
@@ -49,6 +49,19 @@ public class ProjectDataTests : ServiceTestFixture
Assert.That(afterUnrelatedUpdate.Phase, Is.EqualTo(ProjectPhase.Outlining));
}
[Test]
public async Task A_project_response_carries_the_owner_id_and_the_caller_s_role()
{
var project = await Projects.CreateAsync(new CreateProjectRequest("The Salt Road"));
var response = project.ToResponse(await Access.GetMyRoleAsync(project));
Assert.Multiple(() =>
{
Assert.That(response.OwnerId, Is.EqualTo(UserContext.UserId));
Assert.That(response.MyRole, Is.EqualTo("Admin"));
});
}
[Test]
public async Task Chapters_are_numbered_in_sequence_when_no_number_is_given()
{