Claude: changes for issue #98 #100
No reviewers
Labels
No labels
No milestone
No project
No assignees
3 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Grandiras/Ponente!100
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "claude/issue-98"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Closes #98.
🤖 Reviewing this PR — follow along in the action run; the reply will link the full session transcript.
📜 Live transcript — updating every ~5 minutes while the task runs.
✅ Verdict: approve — no blocking issues found.
This implements per-card and per-comment permissions (issue #98) exactly in line with the codebase's established patterns: the rule lives once in
CardPermissions(mirroringBoardAccess's single-expression philosophy), is enforced in the services (CardService,CommentService,TagService,MemberService) rather than only in markup, and the dialog (CardModal) purely renders the answer. Verified several load-bearing details:BoardViewer.None.Didisstring.Empty, andCardPermissions.IsSomebodycorrectly guards against an unidentified caller matching a card/comment whose author column is empty — pinned byCardPermissionsTests.Nobody_edits_anything._viewer/_modalCanEditare recomputed on every reload in bothBoardPage.razorandCalendar.razor, so a promotion/demotion under an open circuit is reflected without a reconnect — consistent with the rest of the app's revalidation model.UpdateCardAsync,DeleteCardAsync,SetCardTagsAsync,SetCardAssigneesAsync,CommentService.DeleteAsync) are updated at every call site; no orphaned old-signature calls remain.Comment.EditedAtis correctly left unencrypted (a clock reading, not user-supplied content), matching the encryption convention documented in CLAUDE.md.modal.closeused by the new Cancel/Close button already existed pre-PR, so nothing is missing there).CardPermissionsTests, covering cases no screen can reach) and a single consolidated e2e spec (permissions.spec.js, following the repo's "group by shared fixture" testing philosophy) back the change.I did not find correctness or security bugs. The permission checks are done server-side as the ultimate gate, with the UI as a convenience layer only, so even a stale/tampered client can't bypass the rule.
⏱ 1m 55s · 8 turns · tokens: 111.4k in / 9.5k out (+939.0k cache-read)
📜 Full session transcript
@claude-bot Remove the info banner at the top of cards, this is unnecessary.
🤖 On it — follow along in the action run; the reply will link the full session transcript.
📜 Live transcript — updating every ~5 minutes while the task runs.
Removed the read-only note from the card dialog and pushed to
claude/issue-98(commit15ebd5a), which updates PR #100.What went:
CardModal.razor— the@if (!IsNew && !CanEdit)block rendering<p class="modal-note" data-readonly="card">, and its comment.app.css— the.modal-noterule.LocaleService.cs— themodal.readonlykey in bothenandde(key parity is enforced byLocaleServiceTests, so both had to go together).permissions.spec.js— the two assertions that were about the banner (present on somebody else's card, absent on your own). Everything else that spec pins is the dialog itself.CLAUDE.md— the sentence describing the note, replaced with why there isn't one: the dialog says it in the heading (modal.view— "Card" rather than "Edit card") and nowhere else.The changelog entry needed no change; it never mentioned the note.
Verified:
dotnet build Ponente.slnclean (one pre-existingCalendar.razornullable warning, untouched by this),dotnet test Ponente.sln— 282/282 pass. I also ran the app for real (Postgres +dotnet runin Development, a second non-admin member seeded and signed in via/dev/login) and screenshotted the same card opened by someone who did not create it, before and after:The heading, the static title, the read-only pickers and the lone Close button all still say read-only on their own — and the comment box below is still there, since commenting was never what the permission was about.
⏱ 7m 8s · 44 turns · tokens: 84.1k in / 12.0k out (+3873.1k cache-read)
📜 Full session transcript
🤖 Reviewing this PR — follow along in the action run; the reply will link the full session transcript.
📜 Live transcript — updating every ~5 minutes while the task runs.
✅ Verdict: approve — no blocking issues found.
This is a re-review; no new commits changed the substance since my prior approval — the diff is identical in content. I re-verified the full PR branch directly (not just the diff) to check for anything the diff context might hide:
CardService.UpdateCardAsync/DeleteCardAsync,TagService.SetCardTagsAsync,MemberService.SetCardAssigneesAsync, andCommentService.UpdateAsync/DeleteAsyncacross the whole branch (bothBoardPage.razorandCalendar.razor) correctly pass the newBoardViewer actor/_viewerargument — no orphaned old-signature calls remain anywhere in the tree.BoardVieweris the existingreadonly record structfromBoardAccess.cs, reused as intended rather than duplicated.AssigneePicker.Initials(member)(called from the new read-only assignee chips inCardModal.razor) exists and ispublic static, so that reference resolves.CommentList.razor's_vieweris recomputed inReloadAsync(which also runs on everyBoardNotifier.CommentsChangedevent and page reload), andcanEdit/canDeleteare recalculated per comment on every render, so permission state stays live under promotion/demotion exactly as documented.CreateCardAsync, which doesn't take an actor since creation is intentionally open) is followed bySetCardTagsAsync/SetCardAssigneesAsyncusing_viewer, and since a freshly created card'sCreatedByDidis the creating member's own DID,CanEditCardcorrectly evaluates true for the same session.No correctness or security issues found. Confirming approval from the previous pass.
⏱ 1m 17s · 21 turns · tokens: 104.7k in / 5.7k out (+2622.8k cache-read)
📜 Full session transcript