Invitation system: DB + API + landing page + share links

- invitations table (token, task, inviter, expiry 7d)
- POST /invitations (create + share links: WhatsApp, Telegram, SMS, Copy)
- GET /invite/:token (public landing page)
- POST /invite/:token/accept (register + assign + JWT)
- Landing page at /invite/[token] with accept flow
- CLAUDE.md + Notion key deployed to all servers

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-30 00:31:22 +00:00
parent 653805af4c
commit 703541d29a
6 changed files with 571 additions and 1 deletions

View File

@@ -303,3 +303,44 @@ export function sendCollabRequest(token: string, taskId: string, data: { to_user
export function searchUsers(token: string, query: string) {
return apiFetch<{ data: { id: string; name: string; email: string; avatar_url: string | null }[] }>(`/api/v1/auth/users/search?q=${encodeURIComponent(query)}`, { token });
}
// Invitations
export interface Invitation {
id: string;
token: string;
task_id: string;
inviter_id: string | null;
invitee_email: string | null;
invitee_name: string | null;
message: string;
status: string;
expires_at: string;
accepted_at: string | null;
created_at: string;
}
export interface InvitationResponse {
invitation: Invitation;
link: string;
share: {
whatsapp: string;
telegram: string;
sms: string;
copy: string;
};
}
export function createInvitation(
token: string,
data: { task_id: string; invitee_email?: string; invitee_name?: string; message?: string; inviter_id?: string }
) {
return apiFetch<{ data: InvitationResponse }>("/api/v1/invitations", { method: "POST", body: data, token });
}
export function getTaskInvitations(token: string, taskId: string) {
return apiFetch<{ data: Invitation[] }>(`/api/v1/tasks/${taskId}/invitations`, { token });
}
export function revokeInvitation(token: string, invitationId: string) {
return apiFetch<{ data: Invitation }>(`/api/v1/invitations/${invitationId}`, { method: "DELETE", token });
}