Repository navigation
Stop offering a signup visibility that nothing reads - #547
Conversation
Every signup opens for anyone with its link, so public, unlisted and password all behaved the same. PATCH /api/signups/[id] now refuses visibility instead of storing it and returning 200, and the MCP update_signup tool no longer offers it, nor do the read tools report it. New signups are still stored as unlisted. Fixes #517. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01H1Tj2ePc6ZEVotL7ZZZQGx
Tophat: passedRan 6f9d4f6 locally with
For the owner (UX): nothing changes on any screen. What changes is what callers see. An API call or AI assistant that tries to change a signup's visibility now gets a clear refusal, where before it got a success that did nothing. Screenshots are in https://claude.ai/code/session_01QZ2HeVDg9JFNBm9LAbvCEQ. Generated by Claude Code |
richshaw
left a comment
There was a problem hiding this comment.
Review: passed (round 1)
The PR stops offering a signup visibility that nothing reads, and it does that cleanly. SignupUpdateInputSchema now refuses any visibility with invalid_input on that path. updateSignup no longer writes the column. update_signup drops the key from both its input and its description, and signupCore no longer reports it, so list_signups, get_signup and the write tools' results all lose it in one place. The docs and CHANGELOG are updated, and the CHANGELOG tells script authors what to change. I grepped src: nothing on any screen sends visibility on update, and the only writers left are create paths that hard-code unlisted (new-signup action, Magic Compose persist, MCP fixtures). Every item in the issue's "Done when" is covered, with tests on the schema, the service (DB) and the MCP tool.
Blocking (0)
Optional (1):
src/schemas/signups.ts:92:SignupCreateInputSchemastill acceptsvisibility: "password", soPOST /api/signupscan still store a password visibility that has no password. The PR leaves create alone on purpose, and nothing reads the column, so nothing is exposed. If you want create to match, a later change could narrow it tounlisted.
Earlier threads: none. Copilot couldn't review because of its quota.
Checks: CI is green on 6f9d4f6 (lint-type-test, e2e, CodeQL). The tophat passed on this same SHA, so no runtime code has changed since. I ran nothing locally beyond the grep, because CI on this SHA covers lint, types, knip, unit and DB tests.
Why the owner: this is UX (pipeline:ux), but no screen changes. What changes is what API and AI-assistant callers see. A PATCH or update_signup that tries to change visibility now gets a clear refusal, where before it got a success that did nothing, and the read tools no longer report visibility. The tophat comment has the request and response details. The REST GET /api/signups/[id] still returns visibility, on purpose.
https://claude.ai/code/session_01L2LvNSAMut42zeFoyLbWxg
Generated by Claude Code
|
Approved by the owner at The branch is behind https://claude.ai/code/session_0115MCPHsyBah5fBHmYV2aVR Generated by Claude Code |
|
Not merged. After #541, #542 and #546 landed, this PR conflicts with https://claude.ai/code/session_017ozNhwhSPGb1Aq4KLbjyGh Generated by Claude Code |
…bility # Conflicts: # CHANGELOG.md
|
Merged
https://claude.ai/code/session_01My1XhNGLuKW2vitjpCKAzH Generated by Claude Code |
Fixes #517.
The problem
signups.visibilitywas written but never read: every/s/[slug]page isnoindex, signups aren't in the sitemap, and nothing lists them, sopublic,unlistedandpasswordall behaved the same. Yetupdate_signupoffered to change it ("public or unlisted") and reported success, the read tools echoed it back, andPATCH /api/signups/[id]storedvisibility: "password"with a 200 when no password exists anywhere.The fix
SignupUpdateInputSchemanow refuses anyvisibilitywithinvalid_input(field: "visibility", message "visibility can't be changed: anyone with a signup's link can open it"), andupdateSignupno longer writes the column. I made it refuse rather than drop the key silently: dropping it would still return 200 for a change that never happened, which is the bug. No screen sendsvisibilityon update.update_signupdrops it from its input and description (the comment besideorganizerDisplayNamenow covers both), andsignupCoreno longer includes it, solist_signups,get_signupand the write tools' results don't report it.unlisted, and the column stays (no migration).docs/connect-ai-assistant.mdno longer lists visibility among what an assistant can change. CHANGELOG entry under Changed.Tests
src/schemas/signups.test.ts: create still defaults tounlisted; update refusespublic,unlistedandpasswordon thevisibilitypath; an update without it parses.src/services/signups.db.test.ts:updateSignupwithvisibility: 'password'returnsinvalid_inputonvisibilityand leaves the stored rowunlisted.src/mcp/tools/signups-write.test.ts: replaces the password test.update_signup's schema and description no longer mention visibility, and a call that passes one reaches the service without it.src/mcp/tools/read.test.ts: thelist_signupssummary no longer hasvisibility.Ran and passed in this session:
pnpm lint && pnpm typecheck && pnpm knip && pnpm test(1300 tests) andpnpm test:db(493 tests).Generated by Claude Code