Projects
Dev page for Goal 3h. A project groups conversations and is shareable. It deliberately owns
no knowledge base and no shared instructions — every conversation inside it still
grounds on its own creator's knowledge, exactly as it would outside one.
Two permission layers: project role (editor can add their own conversations,
viewer cannot) and conversation ownership (only a conversation's creator can write
to it, whatever their project role — everyone with access can read it).
Token helper: /index.html · chat: /chat.html ·
knowledge: /knowledge.html .
1. Access token
Sign in & get Ally token
loading Clerk…
Use this token
2. My projects
Create
Refresh
Name Role Share link Created
Every project you own or are an active member of. owner is synthesized from
owner_user_id — the owner is not a membership row.
3. Selected project
Rename
Delete project
Owner only. Delete detaches conversations, never deletes them.
Members
editor
viewer
Invite
The address needs no Ally account yet — the row stays pending with a null
user_id until that person signs up and accepts. The invite email is best-effort: if
Resend is unconfigured the send is logged and this still succeeds.
Share link
viewer
editor
Get / update link
Revoke
Copy
One standing link per project. Changing the role updates the existing token rather than minting a
second one. Opening it still requires signing in — there is no anonymous access. Revoking
closes the door but does not eject anyone who already joined.
Conversations in this project
Title Messages Creator You can… Last activity
Send
Refresh
POST /chat/stream with projectId. Valid only when starting a new conversation
(sending it alongside a conversationId is a 400 — a conversation's project is fixed at
creation). Requires owner or editor access.
4. Accept flows (stand-in for the frontend pages)
The real invite/share links point at frontend pages that carry memberId/token in
their own URL, send the visitor through Clerk, then call these endpoints. Those pages live in the frontend
repo and don't exist yet — this panel is how you exercise the same two calls by hand.
Accept invite
Join via share link
Accepting an invite checks that your account email matches the address it was sent to — a
403 otherwise, so knowing a memberId isn't enough to claim someone else's invite.
5. My conversation list
GET /chat/conversations, unchanged and unfiltered: conversations you created inside a project
appear here too, merged in by last activity, now carrying projectId/projectName so a
client can badge them. They are not hidden behind the project view.
Title Project Messages Last activity
Refresh
Log