Public: anyone can read this; the crew can change it.

A board can be deleted by the people it belongs to, and only by them #54

open not picked up yet opened this
opened this

A board, once created, is permanent: nothing in this app can remove one.

grep -n "deleteBoard\|DELETE FROM board" src/db.ts finds nothing on main at d9a214f. There is no route, no tool and no terminal key that deletes a board — a board made by a slip of the hand, a board whose name is wrong, a board someone filled with text you would rather not host, all stay forever. #27 capped what one board can hold; nothing bounds how many boards accumulate, and MAX_BOARDS_CREATED_PER_MINUTE only slows the rate.

Deletion has to follow this app's one access rule rather than invent a second: a board that someone kept belongs to them, and only they may delete it; a board nobody has kept is a guest board, and anyone holding the link may delete it — the same people who may already delete every card and column in it one press at a time.

Done looks like

  • [ ] db.deleteBoard(boardId) removes the board in one transaction; board_column, card and action go with it through the cascades already declared in the schema. A test asserts no row of any of the four tables survives.
  • [ ] POST /b/:id/delete: refused with 403 for a signed-in person who is not the owner of a kept board, allowed for the owner, allowed for anyone on an unowned board. Every case has a test, including a guest trying to delete a board someone else kept.
  • [ ] It asks first, and the question works with JavaScript off — the same confirm step #50 builds for a column, reused rather than reinvented: Delete "Sprint 32", its 3 columns and its 41 cards? This cannot be undone. Undo cannot bring a board back, and the page says so plainly.
  • [ ] After a delete, 303 to /, which says which board went.
  • [ ] Anyone else watching that board is not left staring at a ghost: the delete publishes on the bus, and an open page whose board is gone shows "This board was deleted" rather than silently failing its next fetch. If #12 has not landed, a page that reloads into a 404 is acceptable — say which you did in the pull.
  • [ ] The terminal keeps parity, as AGENTS.md asks: a delete key in src/keys.ts (a pure state transition, tested there) that requires a second, explicit confirm key, and never deletes a board the terminal's identity may not delete.
  • [ ] The guest list in static/boards.<hash>.js drops a board that 404s rather than listing a dead link forever.
  • [ ] README: who may delete a board, and that it is permanent. bun test green.

Files

src/db.ts, src/routes.ts, src/pages/board.ts, src/keys.ts, src/tty.ts, static/boards.<hash>.js + BOARDS_JS, src/db.test.ts, src/server.test.ts, src/tty.test.ts, README.md.

Risks

This is the one irreversible action in an app whose whole safety net is Undo, so the ownership rule and the confirm are the work — a delete that is easy to reach by accident on a shared board is worse than no delete at all. It waits for #50 so there is one confirm step in this app rather than two. Do not add a delete_board MCP tool in the same run: an agent that can delete a whole board is its own decision, with its own review.

Blocked by #50.

Suggested: scout, reviewed by sentinel.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs