Let a board that has been used for a month be tidied in one press, instead of deleting finished cards one at a time.
What it is like today. A shared board fills up and never empties. MAX_CARDS_PER_BOARD is 500 (src/limits.ts) and the only ways to remove cards are the ✕ on each card — one request, one undo row, one live event per card — or deleting the whole column, which takes the column with it and is the wrong tool for "Done is finished, clear it". A team moving twenty cards a week hits the cap in six months and then meets this board is full — 500 cards with no ordinary way out. The undo log is capped at 200 rows (MAX_UNDO_DEPTH), so clearing 60 cards by hand also pushes everything else out of undo.
Done looks like
[ ] db.clearColumn(boardId, columnId) empties a column's cards in oneimmediate() transaction, logging one action row that restores every card it removed, so a single Undo brings the whole column back exactly as it was (same ids, positions, timestamps) — the pattern deleteColumn already uses for the cards it cascades.
[ ] It refuses politely when the column is already empty (no action row, no event) and when the column is not on this board.
[ ] POST /b/:id/columns/:columnId/clear with the same-origin guard, the same rate-limit spend and the same three answer shapes as every other write, publishing one column.cleared event (or one external-style refresh if adding a kind is not worth it — say which in the pull).
[ ] The column header carries Clear with a count in it (Clear 12 cards), asking once before it fires, in whatever confirm pattern #50 establishes — not a second, different one.
[ ] The terminal gets the same action on a column, guarded the same way.
[ ] One live event, so another open tab empties the column without a reload, and the count in the header follows.
[ ] Tests that fail without the change: twelve cards cleared in one transaction; one undo restores all twelve with their original positions; an empty column is a no-op; clearing a column of another board is refused; the page renders the count and the confirm; the event reaches a second subscriber.
Waits for #50, which decides how a destructive action asks once. Two confirm patterns in one board page is worse than no confirm at all.
One action row holding 500 cards is a large JSON payload in action.payload. Cap what one clear may restore (the board's own card cap is the natural bound) and check the row still parses on undo — the test is a full column at the cap.
Do not fold this into deleteColumn: keeping the column is the entire point, and the two must stay separately undoable.
Suggested: scout, reviewed by juniper. Waits for #50.
Let a board that has been used for a month be tidied in one press, instead of deleting finished cards one at a time.
What it is like today. A shared board fills up and never empties.
MAX_CARDS_PER_BOARDis 500 (src/limits.ts) and the only ways to remove cards are the ✕ on each card — one request, one undo row, one live event per card — or deleting the whole column, which takes the column with it and is the wrong tool for "Done is finished, clear it". A team moving twenty cards a week hits the cap in six months and then meetsthis board is full — 500 cardswith no ordinary way out. The undo log is capped at 200 rows (MAX_UNDO_DEPTH), so clearing 60 cards by hand also pushes everything else out of undo.Done looks like
db.clearColumn(boardId, columnId)empties a column's cards in oneimmediate()transaction, logging one action row that restores every card it removed, so a single Undo brings the whole column back exactly as it was (same ids, positions, timestamps) — the patterndeleteColumnalready uses for the cards it cascades.POST /b/:id/columns/:columnId/clearwith the same-origin guard, the same rate-limit spend and the same three answer shapes as every other write, publishing onecolumn.clearedevent (or oneexternal-style refresh if adding a kind is not worth it — say which in the pull).Clear 12 cards), asking once before it fires, in whatever confirm pattern #50 establishes — not a second, different one.Files I expect to change
src/db.ts,src/routes.ts,src/pages/board.ts,src/keys.ts,src/db.test.ts,src/server.test.ts,README.md.Risks
action.payload. Cap what one clear may restore (the board's own card cap is the natural bound) and check the row still parses on undo — the test is a full column at the cap.deleteColumn: keeping the column is the entire point, and the two must stay separately undoable.Suggested: scout, reviewed by juniper. Waits for #50.