Skip to content

Latest commit

 

History

History
528 lines (485 loc) · 10.4 KB

File metadata and controls

528 lines (485 loc) · 10.4 KB

Synapse Backend API Documentation

Base URL

  • Development: http://localhost:3001
  • Production: https://studious.sh (or configured via NEXT_PUBLIC_APP_URL)

API Architecture

  • Framework: tRPC (TypeScript RPC)
  • Base Path: /trpc
  • Authentication: Session-based (Bearer token in Authorization header)
  • Real-time: Pusher integration for live updates
  • Database: PostgreSQL with Prisma ORM

Authentication Endpoints

POST /trpc/auth.register

Description: Register a new user account Authentication: Public Input Schema:

{
  username: string (min 3 chars),
  email: string (valid email),
  password: string (min 6 chars),
  confirmPassword: string
}

Response:

{
  user: {
    id: string,
    username: string
  }
}

Error Codes: CONFLICT (username/email exists)

POST /trpc/auth.login

Description: Authenticate user and create session Authentication: Public Input Schema:

{
  username: string,
  password: string
}

Response:

{
  token: string, // Session ID
  user: {
    id: string,
    username: string
  }
} | {
  verified: false,
  user: {
    email: string
  }
}

Error Codes: UNAUTHORIZED (invalid credentials)

POST /trpc/auth.logout

Description: End user session Authentication: Required Input Schema: None Response:

{
  success: boolean
}

Error Codes: UNAUTHORIZED (not authenticated)

GET /trpc/auth.check

Description: Verify authentication and get user profile Authentication: Required Input Schema: None Response:

{
  user: {
    id: string,
    username: string,
    profile: {
      displayName?: string,
      bio?: string,
      location?: string,
      website?: string,
      profilePicture?: string,
      profilePictureThumbnail?: string
    }
  }
}

Error Codes: UNAUTHORIZED, NOT_FOUND

POST /trpc/auth.resendVerificationEmail

Description: Resend email verification Authentication: Public Input Schema:

{
  email: string (valid email)
}

Response:

{
  success: boolean
}

Error Codes: NOT_FOUND (user not found)

POST /trpc/auth.verify

Description: Verify email with token Authentication: Public Input Schema:

{
  token: string
}

Response:

{
  success: boolean
}

Error Codes: NOT_FOUND, UNAUTHORIZED (expired)


Conversation Endpoints

GET /trpc/conversation.list

Description: Get all conversations for authenticated user Authentication: Required Input Schema: None Response:

Array<{
  id: string,
  type: "DM" | "GROUP",
  name?: string,
  createdAt: Date,
  updatedAt: Date,
  members: Array<{
    id: string,
    userId: string,
    role: "ADMIN" | "MEMBER",
    lastViewedAt?: Date,
    lastViewedMentionAt?: Date,
    user: {
      id: string,
      username: string,
      profile: {
        displayName?: string,
        profilePicture?: string
      }
    }
  }>,
  lastMessage?: {
    id: string,
    content: string,
    createdAt: Date,
    sender: {
      id: string,
      username: string,
      profile: {
        displayName?: string
      }
    }
  },
  unreadCount: number,
  unreadMentionCount: number
}>

POST /trpc/conversation.create

Description: Create new conversation (DM or Group) Authentication: Required Input Schema:

{
  type: "DM" | "GROUP",
  name?: string, // Required for GROUP
  memberIds: string[] // Usernames
}

Response:

{
  id: string,
  type: "DM" | "GROUP",
  name?: string,
  createdAt: Date,
  updatedAt: Date,
  members: Array<{
    id: string,
    userId: string,
    role: "ADMIN" | "MEMBER",
    user: {
      id: string,
      username: string,
      profile: {
        displayName?: string,
        profilePicture?: string
      }
    }
  }>
}

Error Codes: BAD_REQUEST (invalid input, members not found)

GET /trpc/conversation.get

Description: Get specific conversation details Authentication: Required Input Schema:

{
  conversationId: string
}

Response:

{
  id: string,
  type: "DM" | "GROUP",
  name?: string,
  createdAt: Date,
  updatedAt: Date,
  members: Array<{
    id: string,
    userId: string,
    role: "ADMIN" | "MEMBER",
    user: {
      id: string,
      username: string,
      profile: {
        displayName?: string,
        profilePicture?: string
      }
    }
  }>
}

Error Codes: NOT_FOUND (conversation not found or access denied)


Message Endpoints

GET /trpc/message.list

Description: Get messages from a conversation with pagination Authentication: Required Input Schema:

{
  conversationId: string,
  cursor?: string, // ISO date string for pagination
  limit?: number // 1-100, default 50
}

Response:

{
  messages: Array<{
    id: string,
    content: string,
    senderId: string,
    conversationId: string,
    createdAt: Date,
    sender: {
      id: string,
      username: string,
      profile: {
        displayName?: string,
        profilePicture?: string
      }
    },
    mentions: Array<{
      user: {
        id: string,
        username: string,
        profile: {
          displayName?: string
        }
      }
    }>,
    mentionsMe: boolean
  }>,
  nextCursor?: string
}

Error Codes: FORBIDDEN (not a member)

POST /trpc/message.send

Description: Send a new message to conversation Authentication: Required Input Schema:

{
  conversationId: string,
  content: string, // 1-4000 chars
  mentionedUserIds?: string[] // User IDs to mention
}

Response:

{
  id: string,
  content: string,
  senderId: string,
  conversationId: string,
  createdAt: Date,
  sender: {
    id: string,
    username: string,
    profile: {
      displayName?: string,
      profilePicture?: string
    }
  },
  mentionedUserIds: string[]
}

Real-time Events: Broadcasts new-message to conversation-{id} channel Error Codes: FORBIDDEN, BAD_REQUEST

PUT /trpc/message.update

Description: Update an existing message Authentication: Required (sender only) Input Schema:

{
  messageId: string,
  content: string, // 1-4000 chars
  mentionedUserIds?: string[]
}

Response:

{
  id: string,
  content: string,
  senderId: string,
  conversationId: string,
  createdAt: Date,
  sender: {
    id: string,
    username: string,
    profile: {
      displayName?: string,
      profilePicture?: string
    }
  },
  mentionedUserIds: string[]
}

Real-time Events: Broadcasts message-updated to conversation-{id} channel Error Codes: NOT_FOUND, FORBIDDEN, BAD_REQUEST

DELETE /trpc/message.delete

Description: Delete a message Authentication: Required (sender only) Input Schema:

{
  messageId: string
}

Response:

{
  success: boolean,
  messageId: string
}

Real-time Events: Broadcasts message-deleted to conversation-{id} channel Error Codes: NOT_FOUND, FORBIDDEN

POST /trpc/message.markAsRead

Description: Mark conversation as read (update lastViewedAt) Authentication: Required Input Schema:

{
  conversationId: string
}

Response:

{
  success: boolean
}

Real-time Events: Broadcasts conversation-viewed to conversation-{id} channel Error Codes: FORBIDDEN

POST /trpc/message.markMentionsAsRead

Description: Mark mentions as read (update lastViewedMentionAt) Authentication: Required Input Schema:

{
  conversationId: string
}

Response:

{
  success: boolean
}

Real-time Events: Broadcasts mentions-viewed to conversation-{id} channel Error Codes: FORBIDDEN

GET /trpc/message.getUnreadCount

Description: Get unread message and mention counts for conversation Authentication: Required Input Schema:

{
  conversationId: string
}

Response:

{
  unreadCount: number,
  unreadMentionCount: number
}

Error Codes: FORBIDDEN


Real-time Events (Pusher)

Channels

  • conversation-{conversationId}: All conversation members

Events

  • new-message: New message sent
  • message-updated: Message edited
  • message-deleted: Message deleted
  • conversation-viewed: User viewed conversation
  • mentions-viewed: User viewed mentions

Error Handling

Standard Error Codes

  • BAD_REQUEST (400): Invalid input data
  • UNAUTHORIZED (401): Authentication required/failed
  • FORBIDDEN (403): Access denied
  • NOT_FOUND (404): Resource not found
  • CONFLICT (409): Resource already exists
  • INTERNAL_SERVER_ERROR (500): Server error

Error Response Format

{
  error: {
    code: string,
    message: string,
    data?: {
      zodError?: object, // Validation errors
      prismaError?: object // Database errors
    }
  }
}

Authentication Flow

  1. Register: POST /trpc/auth.register → Returns user info
  2. Login: POST /trpc/auth.login → Returns session token
  3. Use Token: Include Authorization: Bearer {token} in headers
  4. Verify: GET /trpc/auth.check → Verify session and get user profile
  5. Logout: POST /trpc/auth.logout → End session

Database Schema Overview

Core Models

  • User: Authentication and profile data
  • Session: User sessions and verification tokens
  • UserProfile: Extended user information
  • Conversation: Chat conversations (DM/Group)
  • ConversationMember: User membership in conversations
  • Message: Chat messages
  • Mention: User mentions in messages

Key Features

  • Session-based authentication
  • Email verification system
  • Real-time messaging with Pusher
  • Mention system with read tracking
  • Unread message/mention counting
  • Conversation member roles (ADMIN/MEMBER)

Development Notes

Environment Variables Required

  • DATABASE_URL: PostgreSQL connection string
  • PUSHER_APP_ID, PUSHER_KEY, PUSHER_SECRET, PUSHER_CLUSTER: Pusher config
  • NEXT_PUBLIC_APP_URL: Frontend URL for CORS
  • PORT: Server port (default: 3001)

Scripts

  • npm run dev: Development with hot reload
  • npm run build: Build TypeScript
  • npm start: Production server
  • npm run generate: Generate Prisma client
  • npm run seed: Seed database