Claude: changes for issue #157 #158

Merged
Grandiras merged 1 commit from claude/issue-157 into main 2026-08-26 18:40:54 +00:00
Collaborator

Closes #157.

Closes #157.
Let everyone set a due date and put themselves on a card
All checks were successful
CI / build (pull_request) Successful in 32s
5703db06f8
A card stays its author's (or an admin's) to rewrite, but two things
on it were never really about what it says, and locking them behind
authorship made the board worse:

- **A due date is everybody's.** It is the one field on a card that
  goes stale without anybody editing the card, and the member who
  learns that Thursday has moved is hardly ever the member who wrote
  it. Same argument a drag is already open under — the card still says
  exactly what its author wrote. The calendar is what makes it urgent:
  a date is the only thing on a card that is visible from there, so a
  calendar of other people's dates was a screen for reading only.
- **Assignees are everybody's, but only about themselves.** Signing up
  for work is the point of a shared board; putting somebody else's
  name on a card is a claim about them and stays the card's own rule.

`CardPermissions` grows `CanSetDueDate` (which takes no card — the
answer does not depend on one) and `CanSetAssignees`, the one rule in
the file that judges a *difference* rather than a row: whoever may edit
the card may write any list, everybody else may write the one list whose
symmetric difference from the stored one is their own DID.

`CardService.SetDueDateAsync` is its own method rather than a lenient
`UpdateCardAsync`, so the write that is allowed physically cannot carry
a title with it and does not have to be trusted not to.
`MemberService.SetCardAssigneesAsync` now reads the current rows before
it checks — the opposite order to every other guard here, because the
question needs both lists.

The dialog on somebody else's card is therefore no longer read-only: the
date input and an assignee picker narrowed to the people on the card plus
the reader's own chip (`AssigneePicker.OnlyDid`) stay live, so Save is
unconditional and Cancel no longer becomes Close. Both pages split the
save by what each rule governs rather than by diffing what came back.

Verified: dotnet build + 395 unit tests green (six new `CardPermissions`
cases, including every direction the assignee difference can point), and
`permissions.spec.js` — extended to drive a second member through setting
a date and taking themselves on and off somebody else's card, and to read
both back — passes against the compose stack.
Author
Collaborator

🤖 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.

🤖 Reviewing this PR — follow along in [the action run](https://git.grandiras.net/Grandiras/claude-bot/actions/runs/385); the reply will link the full session transcript. <!-- claude-run:pr_review --> 📜 [Live transcript](https://git.grandiras.net/Grandiras/claude-bot/src/branch/claude-logs/transcripts/Grandiras/Ponente/pr-158/run-385.md) — updating every ~5 minutes while the task runs.
claude-reviewer left a comment

✅ Verdict: approve — no blocking issues found.

Solid, well-scoped implementation of issue #157 (everybody may set a due date and their own assignment on any visible card; the rest of the card stays the author's).

What I checked:

  • CardPermissions.CanSetAssignees's symmetric-difference logic is correct: moved = current XOR desired, allowed only if every DID in moved is the actor's own. Verified against all the new unit tests (add self, remove self, no-op save, non-self moves rejected, author/admin bypass) and the logic matches.
  • MemberService.SetCardAssigneesAsync now reads existing before calling CardPermissions.RequireAssignees, which is required since the check needs both the stored and desired lists — correctly reordered.
  • CardService.SetDueDateAsync and CardPermissions.CanSetDueDate don't re-check board membership, only identity (IsSomebody) — but this matches the pre-existing, explicitly documented design (CardPermissions's own remarks: board access is answered by the page before a card is ever reached, CardService methods don't re-derive it). UpdateCardAsync already worked this way, so this isn't a new gap introduced by the PR.
  • BoardPage.SaveCard / Calendar.SaveCard correctly branch: editable → full update + tags; read-only → due date only; assignees always attempted (the permission call inside decides). Tags are now correctly gated on _modalCanEdit where they previously ran unconditionally.
  • AssigneePicker's OnlyDid/Shown/CanToggle narrowing looks right: shows people currently on the card plus the viewer's own (always toggleable) chip, with the empty-string OnlyDid degenerate case documented and safe (matches no DID).
  • CardModal.OnSaveClick's title-required check is now correctly gated on CanEdit (no _titleInput exists to focus otherwise).
  • Localization keys reused (assignees.empty, modal.assignees.none, modal.due.clear, modal.cancel, modal.close) all pre-exist in LocaleService.cs; modal.close remains used elsewhere so nothing is orphaned by the footer button change. Changelog entries added in both locales as required.
  • Docs (boards-and-permissions.md, calendar.md, ui.md) are updated consistently with the code changes, including the footer/Cancel-never-becomes-Close behavior and the split-save rationale.
  • The new Playwright test extends the existing single fixture-based spec appropriately (round-trips date and assignee changes through the modal, verifies the card body stays untouched).

No correctness or security issues found.


⏱ 1m 57s · 10 turns · tokens: 51.2k in / 10.3k out (+578.9k cache-read)
📜 Full session transcript

✅ **Verdict: approve** — no blocking issues found. Solid, well-scoped implementation of issue #157 (everybody may set a due date and their own assignment on any visible card; the rest of the card stays the author's). What I checked: - `CardPermissions.CanSetAssignees`'s symmetric-difference logic is correct: `moved = current XOR desired`, allowed only if every DID in `moved` is the actor's own. Verified against all the new unit tests (add self, remove self, no-op save, non-self moves rejected, author/admin bypass) and the logic matches. - `MemberService.SetCardAssigneesAsync` now reads `existing` before calling `CardPermissions.RequireAssignees`, which is required since the check needs both the stored and desired lists — correctly reordered. - `CardService.SetDueDateAsync` and `CardPermissions.CanSetDueDate` don't re-check board membership, only identity (`IsSomebody`) — but this matches the pre-existing, explicitly documented design (`CardPermissions`'s own remarks: board access is answered by the page before a card is ever reached, `CardService` methods don't re-derive it). `UpdateCardAsync` already worked this way, so this isn't a new gap introduced by the PR. - `BoardPage.SaveCard` / `Calendar.SaveCard` correctly branch: editable → full update + tags; read-only → due date only; assignees always attempted (the permission call inside decides). Tags are now correctly gated on `_modalCanEdit` where they previously ran unconditionally. - `AssigneePicker`'s `OnlyDid`/`Shown`/`CanToggle` narrowing looks right: shows people currently on the card plus the viewer's own (always toggleable) chip, with the empty-string `OnlyDid` degenerate case documented and safe (matches no DID). - `CardModal.OnSaveClick`'s title-required check is now correctly gated on `CanEdit` (no `_titleInput` exists to focus otherwise). - Localization keys reused (`assignees.empty`, `modal.assignees.none`, `modal.due.clear`, `modal.cancel`, `modal.close`) all pre-exist in `LocaleService.cs`; `modal.close` remains used elsewhere so nothing is orphaned by the footer button change. Changelog entries added in both locales as required. - Docs (`boards-and-permissions.md`, `calendar.md`, `ui.md`) are updated consistently with the code changes, including the footer/Cancel-never-becomes-Close behavior and the split-save rationale. - The new Playwright test extends the existing single fixture-based spec appropriately (round-trips date and assignee changes through the modal, verifies the card body stays untouched). No correctness or security issues found. --- ⏱ 1m 57s · 10 turns · tokens: 51.2k in / 10.3k out (+578.9k cache-read) 📜 [Full session transcript](https://git.grandiras.net/Grandiras/claude-bot/src/branch/claude-logs/transcripts/Grandiras/Ponente/pr-158/run-385.md) <!-- claude-verdict:approve --> <!-- claude-reviewed-head:5703db06f845caef078b9ccae51dcc41ada92503 -->
Grandiras deleted branch claude/issue-157 2026-08-26 18:40:55 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Grandiras/Ponente!158
No description provided.