You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Sharing: restructure the share UI to invite-first, with "Make public" secondary #59
Per /help/documents: "You no longer set Public with a separate toggle in the editor. Whether a document is public is now controlled entirely inside the Share window." The window leads with Invite people and offers Make public below, with a copy-link row appearing once public.
The app currently exposes isPublic on the document/list editor and treats share links as the primary sharing mechanism — the inverse of the product's current model.
Acceptance criteria
One shared Share window for lists and documents: Invite people first, Make public second.
The public toggle is removed from the document/list editors and lives only in the Share window.
A copy-link row appears only when the item is public.
Copy explains that inviting keeps the item private.
⚠️ The role vocabulary in this issue is wrong — the API does not accept Read-only / Edit / Admin
I wrote these issues from /help/documents, which describes three permission levels as Read-only, Edit and Admin. Those are display names. The API rejects them. Verified live 2026-09-16 on a throwaway list:
role=read-only -> 400 {"error":"Invalid role. Must be watcher, collaborator, or manager"}
role=edit -> 400 {"error":"Invalid role. Must be watcher, collaborator, or manager"}
role=admin -> 400 {"error":"Invalid role. Must be watcher, collaborator, or manager"}
role=watcher -> 201 {"email":"…","role":"watcher","expiresAt":null,"url":"…/lists/invite/OG72S9Ee…"}
role=collaborator -> 201 {"email":"…","role":"collaborator","expiresAt":null,"url":"…"}
role=manager -> 201 {"email":"…","role":"manager","expiresAt":null,"url":"…"}
So the wire values are watcher / collaborator / manager, and any UI needs an explicit mapping to the documented labels:
Wire value
Help-doc label
Can
watcher
Read-only
view content only
collaborator
Edit
change content, but not rename, change public/private, or move
manager
Admin
also rename, switch visibility, move, delete
Don't send the display names, and don't show the wire values to users.
Other live findings from #55/#56 (PRs #168/#169) that affect these issues
The invite envelopes are asymmetric, which forces a read-after-write:
POST …/invites -> 201 {email, role, expiresAt, url} ← url, NO token
GET …/invites -> 200 {invites:[{email, role, expiresAt, accepted, createdAt, token}]} ← token, NO url
DELETE …/invites/{token} -> 200 {"revoked":true}
Revoke is keyed by token, which the create response doesn't return — so creating an invite must be followed by a GET to obtain a revocable handle. Copy-link rebuilds the URL from the token.
role works despite the published OpenAPI request schema omitting it — that schema lists only email + expiresAt. Another case of the spec being thinner than reality; /help/api/sharing is right and the spec is wrong.
Error shapes: invalid email → 400 "A valid email address is required"; unknown token → 404 "Invite not found or access denied" (note: not-found and not-permitted are deliberately indistinguishable).
Ownership envelopes differ between domains — lists nest the object under data, documents under document; both carry userId, which neither ListSummary nor DocumentSummary models.
customerStatus values are free / subscriber / subscriber:monthly / subscriber:annual — any non-free value grants access, so don't compare against the literal "subscriber".
An undocumented notify:false on invite create is accepted (201) but not echoed back. It was deliberately not exposed in the UI because there's no way to confirm it actually suppresses the email — which is exactly what #58's "Email this person" toggle needs. Confirming that flag is the blocker for #58's notify toggle, and it needs a mailbox you control to verify.
The claim/accept side (/api/{lists|documents}/invite/{token}) is cookie-session-only per the docs and needs a second verified account, so it is unimplemented. That's the substance of #57.
Activity
Adron commentedon Sep 16, 2026
I wrote these issues from
/help/documents, which describes three permission levels as Read-only, Edit and Admin. Those are display names. The API rejects them. Verified live 2026-09-16 on a throwaway list:So the wire values are
watcher/collaborator/manager, and any UI needs an explicit mapping to the documented labels:watchercollaboratormanagerDon't send the display names, and don't show the wire values to users.
Other live findings from #55/#56 (PRs #168/#169) that affect these issues
The invite envelopes are asymmetric, which forces a read-after-write:
Revoke is keyed by token, which the create response doesn't return — so creating an invite must be followed by a
GETto obtain a revocable handle. Copy-link rebuilds the URL from the token.roleworks despite the published OpenAPI request schema omitting it — that schema lists onlyemail+expiresAt. Another case of the spec being thinner than reality;/help/api/sharingis right and the spec is wrong.Error shapes: invalid email →
400 "A valid email address is required"; unknown token →404 "Invite not found or access denied"(note: not-found and not-permitted are deliberately indistinguishable).Ownership envelopes differ between domains — lists nest the object under
data, documents underdocument; both carryuserId, which neitherListSummarynorDocumentSummarymodels.customerStatusvalues arefree/subscriber/subscriber:monthly/subscriber:annual— any non-freevalue grants access, so don't compare against the literal"subscriber".An undocumented
notify:falseon invite create is accepted (201) but not echoed back. It was deliberately not exposed in the UI because there's no way to confirm it actually suppresses the email — which is exactly what #58's "Email this person" toggle needs. Confirming that flag is the blocker for #58's notify toggle, and it needs a mailbox you control to verify.Still unverified for #57
The claim/accept side (
/api/{lists|documents}/invite/{token}) is cookie-session-only per the docs and needs a second verified account, so it is unimplemented. That's the substance of #57.