Claude: changes for issue #111 #127
No reviewers
Labels
No labels
No milestone
No project
No assignees
2 participants
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Grandiras/Ponente!127
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "claude/issue-111"
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 #111.
🤖 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.
Solid, well-scoped implementation of cross-board card moves.
CardMove(pure, static) cleanly separates the name-matching rule fromCardService, which mirrors the pattern used forBoardFilter; the unit tests inCardMoveTestscover the interesting edge cases (case/whitespace matching, exact-over-case-insensitive preference, duplicate merge-on-arrival, no-columns, no-matching-tags).MoveCardToBoardAsyncandPlanMoveAsyncare symmetric (both re-check target board access viaRequireTargetBoardAsync, both use the sameCardMoverule), so the plan the dialog shows can't drift from what the move actually does. The write path (db.SaveChangesAsynconce, after all reads) is atomic, andBoardHasNoColumnsExceptionis thrown before any mutation happens, so a refused move leaves no partial state. Permission handling looks right:MoveCardToBoardAsyncrequiresCardPermissions.RequireCardEdit(author-or-admin, matching the doc's stated rule for this operation), whilePlanMoveAsyncbeing read-only doesn't need it — the source card is always one the actor can already see (opened from a board they're on), so the only access boundary that matters for a preview is the target board, and that is checked. Docs (boards-and-permissions.md,calendar.md,orientation.md,ui.md) are updated in step with the code, and the changelog/locale entries are added in bothen/de.One minor, non-blocking observation: in
CardModal.razor,OnMoveTargetPicked/OnSelectedTagsChangedcallRequestMovePlan()without any request-ordering guard, andBoardPage.OnMoveTargetChangeddoesn't check that theTargetBoardIdit's about to answer for is still the one currently selected before assigning_movePlan. If a member switches the target-board dropdown twice in quick succession, the twoPlanMoveAsynccalls could resolve out of order and the UI could briefly show the sentence ("Lands in ‚Done'", dropped tags) for the board that is not the one currently selected. It's cosmetic only —MoveCardToBoardAsyncrecomputes the real plan fresh from the database at write time, so the actual move is unaffected — but worth a stale-response guard (e.g. compareargs.TargetBoardIdagainst_moveTargetId, or a generation counter) if it's ever noticed in practice.Also worth double-checking outside this diff:
MoveCardToBoardAsync's landing-column max-position computation (db.Cards.Where(...).MaxAsync() ?? 0.0, then+1.0) is a read-then-write without a transaction/lock, so two concurrent moves into the same column could compute the same max and collide on position. If that's an accepted, pre-existing pattern elsewhere inCardService(e.g.MoveCardAsync), this is just consistent with it and not a new risk introduced here.⏱ 2m 45s · 3 turns · tokens: 58.6k in / 14.7k out (+168.5k cache-read)
📜 Full session transcript