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
loading Clerk…

2. My projects
NameRoleShare linkCreated

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
Owner only. Delete detaches conversations, never deletes them.

Members

EmailRoleStatus

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

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

TitleMessagesCreatorYou can…Last activity

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.

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.

TitleProjectMessagesLast activity

Log