Make the one mutation that is silently not undoable undoable, so Undo on a shared board never reverses somebody else's older change instead.
This is the server half of the parked #23, on its own: renameBoard in src/db.ts is the only mutation that never calls logAction, so rename a board, press Undo, and the name stays while an earlier change — a card someone moved a minute ago — is reversed. Pull #32 tried all of #23 in one branch and its check failed in src/live-refresh.test.ts, because the change reached into static/board.*.js. This issue does not touch the client at all.
Done looks like
[ ] renameBoard runs inside db.transaction(...).immediate() like every other mutation, and logs what it overwrote through logAction, so MAX_UNDO_DEPTH still trims it.
[ ] Payload carries the previous name (e.g. restoreBoardName?: { id: string; name: string }), and undo restores it. Only the name — restoring the whole board row would also reverse a claim, and ownership is not undoable (say so in the comment).
[ ] A test that fails without the change: create a board, move a card, rename the board, undo() -> the old board name is back and the card has not moved. A second undo() then reverses the move.
[ ] An action row written before this change (a payload with no board name) still undoes cleanly — the old shape is not a crash.
[ ] bun test green.
Files
src/db.ts, src/db.test.ts.
Out of scope
static/board.*.js and src/pages/board.ts — the label and the button preview are the next issue, and pull #36 is rewriting the board script right now.
Risks
The rename payload shares undo's replay loop with columns and cards; restore order matters if a later action in the same log touched the same board row. Restoring a single column keeps that trivially safe.
Make the one mutation that is silently not undoable undoable, so Undo on a shared board never reverses somebody else's older change instead.
This is the server half of the parked #23, on its own:
renameBoardinsrc/db.tsis the only mutation that never callslogAction, so rename a board, press Undo, and the name stays while an earlier change — a card someone moved a minute ago — is reversed. Pull #32 tried all of #23 in one branch and its check failed insrc/live-refresh.test.ts, because the change reached intostatic/board.*.js. This issue does not touch the client at all.Done looks like
renameBoardruns insidedb.transaction(...).immediate()like every other mutation, and logs what it overwrote throughlogAction, soMAX_UNDO_DEPTHstill trims it.Payloadcarries the previous name (e.g.restoreBoardName?: { id: string; name: string }), andundorestores it. Only the name — restoring the whole board row would also reverse aclaim, and ownership is not undoable (say so in the comment).undo()-> the old board name is back and the card has not moved. A secondundo()then reverses the move.bun testgreen.Files
src/db.ts,src/db.test.ts.Out of scope
static/board.*.jsandsrc/pages/board.ts— the label and the button preview are the next issue, and pull #36 is rewriting the board script right now.Risks
The rename payload shares
undo's replay loop with columns and cards; restore order matters if a later action in the same log touched the same board row. Restoring a single column keeps that trivially safe.Suggested: scout.