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

A board someone shared with you is on your list wherever you sign in #94

open not picked up yet opened this
opened this

A board someone shared with you should be on your list wherever you sign in, not only in the browser that first opened the link.

What it is like today. / shows db.listBoardsByOwner(who.id) — boards you kept — plus a this-browser list that static/boards.<hash>.js reads out of localStorage. A board another person owns, that you were given the link to and work on every day, is in neither: it exists for you only as a localStorage entry in one browser. Clear site data, switch to your phone, or sign in on a second machine, and the board is gone unless you still have the link in a chat somewhere. For an app whose sharing model is the link, "I lost the link" is losing the board.

Done looks like

  • [ ] board_visit (board_id TEXT, user_id TEXT, last_seen TEXT, PRIMARY KEY (board_id, user_id)) with board_id REFERENCES board(id) ON DELETE CASCADE, so #87's deletion takes these rows with it.
  • [ ] One upsert on GET /b/:id, done after the response (AGENTS.md: work that can wait), and only when the caller is signed in and is not the board's owner. Never for a guest, never on /b/:id/events, never on a POST — nothing is recorded about anyone who is not signed in.
  • [ ] Bounded per person: at most 100 boards remembered, the oldest last_seen falling off as part of the same write, so the table cannot grow with traffic (the shape #16 established for the undo log).
  • [ ] / gains a Shared with you section under the kept boards: these boards, most recently opened first, each with the owner's name when it has one. Server-rendered, no new JavaScript. The this-browser list stays exactly as it is, for guests and for boards visited before signing in.
  • [ ] A row can be forgotten: one same-origin POST that removes a single board from the caller's own list, matching #55's Forget control in shape and wording. It removes only the caller's row, touches no board, and a signed-in person cannot forget anyone else's.
  • [ ] The README says plainly what is stored: which boards a signed-in person opened, for their own list, never shown to the board's owner or to anyone else, and deleted when they forget the board or the board goes.
  • [ ] Tests: your own board does not appear in Shared with you; a guest's visit writes nothing; a second visit updates one row rather than adding one; the 100 cap drops the least recently opened; deleting a board removes its visit rows; Forget removes only the caller's row; the landing page still renders for an anon caller unchanged.

Files

src/db.ts (table, upsert, listSharedWith, forgetShared), src/routes.ts (the after-response write and the forget route), src/pages/board.ts (landingPage), src/db.test.ts, src/server.test.ts, README.md.

Risks

  • This is a record of who opened what, which is the most sensitive row in the file. It must be readable only by its own subject — no route, no MCP tool and no terminal view lists a board's visitors.
  • The board page is the app's hot path (2 ms today); the write happens after the response and is a single indexed upsert, or it does not belong here.
  • It rebuilds the landing list, which #55 is also rebuilding — hence the dependency, so one builder does that page once.

Waits for #55.

Sign in to join this conversation.

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs