Files
SerpentRace/Documentations/FRONTEND_IMPLEMENTATION_GUIDE_COMPLETE.md
2025-08-26 00:07:13 +02:00

32 KiB

SerpentRace Backend API Documentation for Frontend Developers

Complete API Reference with All Endpoints

Table of Contents

  1. Test User Credentials
  2. Data Structures & Entities
  3. Base URL & Service Info
  4. Authentication Endpoints
  5. User Management
  6. Deck Management
  7. Organization Management
  8. Chat System
  9. Contact Management
  10. Import/Export Functionality
  11. Admin Endpoints
  12. Error Handling
  13. WebSocket Real-Time Communication

Test User Credentials

For development and testing, use these pre-configured user accounts:

Regular User (Verified)

  • Username: john_doe
  • Password: password123
  • Email: john.doe@email.com
  • Type: Regular user (state: 1 - VERIFIED_REGULAR)
  • Organization: None

Premium User (Organization Member)

  • Username: jane_premium
  • Password: password123
  • Email: jane.smith@email.com
  • Type: Premium user (state: 2 - VERIFIED_PREMIUM)
  • Organization: Tech Solutions Inc

Teacher (Premium Organization Member)

  • Username: teacher_bob
  • Password: password123
  • Email: bob.teacher@eduinst.edu
  • Type: Premium user (state: 2 - VERIFIED_PREMIUM)
  • Organization: Educational Institute

Admin User

  • Username: admin_user
  • Password: password123
  • Email: admin@serpentrace.com
  • Type: Admin (state: 5 - ADMIN)
  • Organization: None

Unverified User

  • Username: new_user
  • Password: password123
  • Email: newuser@email.com
  • Type: Unverified (state: 0 - REGISTERED_NOT_VERIFIED)
  • Organization: None

Data Structures & Entities

User DTOs

interface ShortUserDto {
  id: string;                    // UUID
  username: string;              // Username
  state: number;                 // UserState enum
  authLevel: 0 | 1;              // 0 = regular, 1 = admin
}

interface DetailUserDto {
  id: string;                    // UUID
  orgid: string | null;          // Organization ID (if member)
  username: string;              // Unique username
  email: string;                 // Email address
  fname: string;                 // First name
  lname: string;                 // Last name
  code: string | null;           // Verification code
  type: string;                  // 'personal' | 'premium' | 'admin'
  phone: string | null;          // Phone number
  state: number;                 // UserState enum value
}

enum UserState {
  REGISTERED_NOT_VERIFIED = 0,  // Email not verified
  VERIFIED_REGULAR = 1,          // Regular verified user
  VERIFIED_PREMIUM = 2,          // Premium verified user  
  SOFT_DELETE = 3,               // Soft deleted
  DEACTIVATED = 4,               // Account deactivated
  ADMIN = 5                      // Admin user
}

Deck DTOs

interface ShortDeckDto {
  id: string;                    // UUID
  name: string;                  // Deck name
  type: number;                  // DeckType enum value
  playedNumber: number;          // Times played
  ctype: number;                 // DeckVisibility enum value
}

interface DetailDeckDto {
  id: string;                    // UUID
  name: string;                  // Deck name
  type: number;                  // DeckType enum value
  userid: string;                // Owner's user ID
  creationdate: Date;            // Creation timestamp
  cards: Card[];                 // Array of cards
  playedNumber: number;          // Times played
  ctype: number;                 // DeckVisibility enum value
}

interface Card {
  text: string;                  // Question/prompt text
  type?: number;                 // CardType enum (optional)
  answer?: string | null;        // Answer (varies by type)
}

enum DeckType {
  LUCK = 0,                      // Luck-based cards
  JOKER = 1,                     // Joker/wild cards
  QUESTION = 2                   // Question-based cards
}

enum DeckVisibility {
  PUBLIC = 0,                    // Public to all
  PRIVATE = 1,                   // Private to owner
  ORGANIZATION = 2               // Shared within organization
}

enum DeckState {
  ACTIVE = 0,                    // Active deck
  SOFT_DELETE = 1                // Soft deleted
}

enum CardType {
  QUIZ = 0,                      // Multiple choice question
  SENTENCE_PAIRING = 1,          // Sentence completion
  OWN_ANSWER = 2,                // Custom answer
  TRUE_FALSE = 3,                // True/False question
  CLOSER = 4                     // Closer to answer
}

Organization DTOs

interface ShortOrganizationDto {
  id: string;                    // UUID
  name: string;                  // Organization name
  contactfname: string;          // Contact first name
  contactlname: string;          // Contact last name
  contactemail: string;          // Contact email
  state: number;                 // OrganizationState enum
  regdate: Date;                 // Registration date
  maxOrganizationalDecks: number | null; // Max org decks allowed
}

enum OrganizationState {
  REGISTERED = 0,                // Just registered
  ACTIVE = 1,                    // Active organization
  SOFT_DELETE = 2                // Soft deleted
}

Chat DTOs

interface ShortChatDto {
  id: string;                    // UUID
  userCount: number;             // Number of participants
  state: number;                 // ChatState enum value
}

interface DetailChatDto {
  id: string;                    // UUID
  users: string[];               // Participant user IDs
  messages: Message[];           // Message history
  updateDate: Date;              // Last update
  state: number;                 // ChatState enum value
}

interface Message {
  id: string;                    // Message UUID
  date: Date;                    // Message timestamp
  userid: string;                // Sender user ID
  text: string;                  // Message content
}

enum ChatType {
  DIRECT = 'direct',             // Direct message
  GROUP = 'group',               // Group chat
  GAME = 'game'                  // Game-specific chat
}

enum ChatState {
  ACTIVE = 0,                    // Active chat
  ARCHIVE = 1,                   // Archived chat
  SOFT_DELETE = 2                // Soft deleted
}

Contact DTOs

interface ContactDto {
  id: string;                    // UUID
  name: string;                  // Contact name
  email: string;                 // Contact email
  userid: string | null;         // User ID if logged in
  type: number;                  // ContactType enum
  txt: string;                   // Message content
  state: number;                 // ContactState enum
  createDate: Date;              // Creation date
  updateDate: Date;              // Last update
  adminResponse: string | null;  // Admin response
  responseDate: Date | null;     // Response date
  respondedBy: string | null;    // Responding admin ID
}

enum ContactType {
  BUG = 0,                       // Bug report
  PROBLEM = 1,                   // Problem report
  QUESTION = 2,                  // General question
  SALES = 3,                     // Sales inquiry
  OTHER = 4                      // Other type
}

enum ContactState {
  ACTIVE = 0,                    // Active/unresolved
  RESOLVED = 1,                  // Resolved
  SOFT_DELETE = 2                // Soft deleted
}

Base URL & Service Info

Base URL: http://localhost:3000 (development)

Service Information

Endpoint: GET /

Authentication: None required

Response Data:

{
  service: "SerpentRace Backend API";
  status: "running";
  version: "1.0.0";
  endpoints: {
    swagger: "/api-docs";
    users: "/api/users";
    organizations: "/api/organizations";
    decks: "/api/decks";
    chats: "/api/chats";
    contacts: "/api/contacts";
    admin: "/api/admin";
    deckImportExport: "/api/deck-import-export";
    health: "/health";
  };
  websocket: {
    enabled: true;
    events: string[];             // WebSocket event names
  };
}

Health Check

Endpoint: GET /health

Authentication: None required

Response Data:

{
  status: "healthy" | "unhealthy";
  timestamp: string;            // ISO timestamp
  service: "SerpentRace Backend API";
  version: "1.0.0";
  environment: string;          // "development" | "production"
  database: {
    connected: boolean;         // Database connection status
    type: string;               // Database type
  };
  websocket: {
    enabled: boolean;           // WebSocket status
  };
  uptime: number;               // Process uptime in seconds
}

Authentication Endpoints

User Login

Endpoint: POST /api/users/login

Authentication: None required

Validation Rules:

  • username: 3-50 characters
  • password: 6-100 characters

Request Data:

{
  username: string;             // Username or email
  password: string;             // Password
}

Response Data (Success):

{
  token: string;                // JWT token (also set as cookie)
  user: ShortUserDto;           // User information
  organizationName?: string;    // Organization name (if member)
}

Error Responses:

  • 400: Validation error
  • 401: Invalid credentials, unverified email, or account restrictions
  • 500: Internal server error

User Registration

Endpoint: POST /api/users/create

Authentication: None required

Validation Rules:

  • username: 3-50 characters, unique
  • email: valid email format, unique
  • password: 6-100 characters

Request Data:

{
  username: string;             // Unique username
  email: string;                // Valid email
  password: string;             // Password
  fname?: string;               // First name (optional)
  lname?: string;               // Last name (optional)
  phone?: string;               // Phone number (optional)
  type?: string;                // User type (optional)
}

Response Data (Success):

{
  id: string;                   // User UUID
  username: string;             // Username
  email: string;                // Email
  regdate: Date;                // Registration date
}

Error Responses:

  • 400: Validation error
  • 409: Username or email already exists
  • 500: Internal server error

User Management

Get User Profile

Endpoint: GET /api/users/profile

Authentication: Required

Response Data: DetailUserDto

Update User Profile

Endpoint: PATCH /api/users/profile

Authentication: Required

Request Data: Partial DetailUserDto fields to update

Response Data: Updated DetailUserDto

Error Responses:

  • 400: Validation error
  • 404: User not found
  • 409: Email already exists
  • 500: Internal server error

Deck Management

Endpoint: GET /api/decks/page/{from}/{to}

Authentication: Required

URL Parameters:

  • from: Start index (0-based, ≥ 0)
  • to: End index (inclusive, ≥ from)

Response Data:

{
  decks: ShortDeckDto[];        // Array of deck summaries
  totalCount: number;           // Total available decks
}

Create Deck

Endpoint: POST /api/decks

Authentication: Required

Request Data:

{
  name: string;                 // Deck name (required)
  type?: number;                // DeckType enum (optional)
  cards?: Card[];               // Initial cards (optional)
  ctype?: number;               // DeckVisibility enum (optional)
}

Response Data: ShortDeckDto

Search Decks

Endpoint: GET /api/decks/search

Authentication: Required

Query Parameters:

  • query: Search query (required, non-empty)
  • limit: Results limit (1-100, default: 20)
  • offset: Results offset (≥ 0, default: 0)

Response Data: Array of matching ShortDeckDto

Get Deck by ID

Endpoint: GET /api/decks/{id}

Authentication: Required

URL Parameters:

  • id: Deck UUID

Response Data: DetailDeckDto

Update Deck

Endpoint: PUT /api/decks/{id}

Authentication: Required (owner only)

URL Parameters:

  • id: Deck UUID

Request Data: Partial DetailDeckDto fields to update

Response Data: Updated ShortDeckDto

Delete Deck (Soft Delete)

Endpoint: DELETE /api/decks/{id}

Authentication: Required (owner only)

URL Parameters:

  • id: Deck UUID

Response Data:

{
  success: boolean;             // Deletion success status
}

Organization Management

Endpoint: GET /api/organizations/page/{from}/{to}

Authentication: Required

URL Parameters:

  • from: Start index (0-based, ≥ 0)
  • to: End index (inclusive, ≥ from)

Response Data:

{
  organizations: ShortOrganizationDto[];
  totalCount: number;
}

Search Organizations

Endpoint: GET /api/organizations/search

Authentication: Required

Query Parameters:

  • query: Search query (required, non-empty)
  • limit: Results limit (1-100, default: 20)
  • offset: Results offset (≥ 0, default: 0)

Response Data: Array of matching organizations

Get Organization Login URL

Endpoint: GET /api/organizations/{orgId}/login-url

Authentication: Required

URL Parameters:

  • orgId: Organization UUID

Response Data:

{
  loginUrl: string;             // Organization login URL
  organizationName: string;     // Organization name
}

Process Organization Auth Callback

Endpoint: POST /api/organizations/auth-callback

Authentication: Required

Request Data:

{
  organizationId: string;       // Organization UUID
  status: "ok" | "not_ok";      // Authentication status
  authToken?: string;           // Authentication token (optional)
}

Response Data:

{
  success: boolean;             // Processing success
  message: string;              // Result message
  updatedFields?: string[];     // Fields that were updated
}

Chat System

Get User Chats

Endpoint: GET /api/chats/user-chats

Authentication: Required

Query Parameters:

  • includeArchived: boolean (default: false)

Response Data: Array of ShortChatDto

Get Chat History

Endpoint: GET /api/chats/history/{chatId}

Authentication: Required

URL Parameters:

  • chatId: Chat UUID (validated)

Response Data:

{
  id: string;                   // Chat UUID
  users: string[];              // Participants
  messages: Message[];          // Message history
  isArchived: boolean;          // Archive status
  state: number;                // Chat state
}

Create Chat

Endpoint: POST /api/chats/create

Authentication: Required

Validation Rules:

  • type: must be 'direct' or 'group'
  • userIds: non-empty array
  • name: required for groups

Request Data:

{
  type: 'direct' | 'group';     // Chat type
  userIds: string[];            // Participant user IDs
  name?: string;                // Group name (required for groups)
}

Response Data:

{
  id: string;                   // Chat UUID
  type: ChatType;               // Chat type
  name: string | null;          // Chat name
  users: string[];              // Participants
  messages: Message[];          // Empty initially
}

Send Message (REST - for testing)

Endpoint: POST /api/chats/message

Authentication: Required

Validation Rules:

  • chatId: valid UUID
  • message: 1-2000 characters

Request Data:

{
  chatId: string;               // Chat UUID
  message: string;              // Message content
}

Response Data: Message object

Archive Chat

Endpoint: POST /api/chats/archive/{chatId}

Authentication: Required

URL Parameters:

  • chatId: Chat UUID (validated)

Response Data:

{
  success: boolean;
  message: string;
}

Restore Chat from Archive

Endpoint: POST /api/chats/restore/{chatId}

Authentication: Required

URL Parameters:

  • chatId: Chat UUID (validated)

Response Data:

{
  success: boolean;
  message: string;
}

Get Archived Game Chats

Endpoint: GET /api/chats/archived/game/{gameId}

Authentication: Required

URL Parameters:

  • gameId: Game UUID (validated)

Response Data: Array of archived chat objects


Contact Management

Create Contact

Endpoint: POST /api/contact

Authentication: Optional

Validation Rules:

  • name, email, type, txt: required fields
  • type: must be 0-4 (ContactType enum)

Request Data:

{
  name: string;                 // Contact name (required)
  email: string;                // Contact email (required)
  type: ContactType;            // Contact type (0-4)
  txt: string;                  // Message content (required)
}

Response Data: ContactDto

Error Responses:

  • 400: Missing fields or invalid contact type
  • 500: Internal server error

Import/Export Functionality

Export Deck

Endpoint: GET /api/deck-import-export/export/{deckId}

Authentication: Required (deck owner only)

URL Parameters:

  • deckId: Deck UUID

Response: Binary .spr file download

Headers:

  • Content-Type: application/octet-stream
  • Content-Disposition: attachment; filename="deckname.spr"

Import Deck

Endpoint: POST /api/deck-import-export/import

Authentication: Required

Request: Multipart form data

  • file: .spr or JSON file (max 10MB)

Response Data:

{
  success: boolean;
  message: string;
  deckId: string;               // Created deck ID
}

Admin Endpoints

All admin endpoints require authentication with admin role (UserState.ADMIN = 5).

User Management (Admin)

Endpoint: GET /api/admin/users/page/{from}/{to}

Query Parameters:

  • includeDeleted: boolean (default: false)

URL Parameters:

  • from: Start index (0-based)
  • to: End index (inclusive, max page size: 100)

Response Data:

{
  users: DetailUserDto[];       // Array of detailed user objects
  pagination: {
    from: number;               // Start index
    to: number;                 // End index
    returned: number;           // Actual returned count
    totalCount: number;         // Total user count
    includeDeleted: boolean;    // Include deleted flag
  };
}

Get User by ID (Admin)

Endpoint: GET /api/admin/users/{userId}

Query Parameters:

  • includeDeleted: boolean (default: false)

Response Data: DetailUserDto or null

Search Users (Admin)

Endpoint: GET /api/admin/users/search/{searchTerm}

URL Parameters:

  • searchTerm: Search term (2-100 characters)

Query Parameters:

  • includeDeleted: boolean (default: false)

Response Data: Array of matching users

Update User (Admin)

Endpoint: PATCH /api/admin/users/{userId}

Request Data: Partial user fields to update

Response Data: Updated DetailUserDto

Deactivate User (Admin)

Endpoint: POST /api/admin/users/{userId}/deactivate

Response Data:

{
  message: string;
  user: DetailUserDto;
}

Delete User (Admin)

Endpoint: DELETE /api/admin/users/{userId}

Response Data:

{
  message: string;
}

Deck Management (Admin)

Get Decks (Paginated, Admin)

Endpoint: GET /api/admin/decks/page/{from}/{to}

Query Parameters:

  • includeDeleted: boolean (default: false)

Response Data: Same as regular deck pagination but unrestricted

Get Deck by ID (Admin)

Endpoint: GET /api/admin/decks/{id}

Query Parameters:

  • includeDeleted: boolean (default: false)

Response Data: DetailDeckDto

Search Decks (Admin)

Endpoint: GET /api/admin/decks/search/{searchTerm}

Query Parameters:

  • includeDeleted: boolean (default: false)

Response Data: Array of matching decks

Hard Delete Deck (Admin)

Endpoint: DELETE /api/admin/decks/{id}/hard

Response Data:

{
  success: boolean;
}

Organization Management (Admin)

Create Organization (Admin)

Endpoint: POST /api/admin/organizations

Request Data: Organization creation data

Response Data: Created organization object

Update Organization (Admin)

Endpoint: PATCH /api/admin/organizations/{id}

Request Data: Partial organization fields to update

Response Data: Updated organization object

Get Organizations (Paginated, Admin)

Endpoint: GET /api/admin/organizations/page/{from}/{to}

Query Parameters:

  • includeDeleted: boolean (default: false)

Response Data: Organization pagination with unrestricted access

Get Organization by ID (Admin)

Endpoint: GET /api/admin/organizations/{id}

Query Parameters:

  • includeDeleted: boolean (default: false)

Response Data: Organization object

Search Organizations (Admin)

Endpoint: GET /api/admin/organizations/search/{searchTerm}

Query Parameters:

  • includeDeleted: boolean (default: false)

Response Data: Array of matching organizations

Soft Delete Organization (Admin)

Endpoint: DELETE /api/admin/organizations/{id}

Response Data:

{
  success: boolean;
}

Hard Delete Organization (Admin)

Endpoint: DELETE /api/admin/organizations/{id}/hard

Response Data:

{
  success: boolean;
}

Chat Management (Admin)

Get Chats (Paginated, Admin)

Endpoint: GET /api/admin/chats/page/{from}/{to}

Query Parameters:

  • includeDeleted: boolean (default: false)

Response Data:

{
  chats: DetailChatDto[];
  pagination: {
    from: number;
    to: number;
    returned: number;
    totalCount: number;
    includeDeleted: boolean;
  };
}

Get Chat by ID (Admin)

Endpoint: GET /api/admin/chats/{id}

Query Parameters:

  • includeDeleted: boolean (default: false)

Response Data: DetailChatDto

Contact Management (Admin)

Get Contacts (Paginated, Admin)

Endpoint: GET /api/admin/contacts/page/{from}/{to}

Query Parameters:

  • includeDeleted: boolean (default: false)

Response Data: Contact pagination with full access

Get Contact by ID (Admin)

Endpoint: GET /api/admin/contacts/{id}

Query Parameters:

  • includeDeleted: boolean (default: false)

Response Data: ContactDto

Search Contacts (Admin)

Endpoint: GET /api/admin/contacts/search/{searchTerm}

Query Parameters:

  • includeDeleted: boolean (default: false)

Response Data: Array of matching contacts

Respond to Contact (Admin)

Endpoint: PUT /api/admin/contacts/{id}/respond

Request Data:

{
  adminResponse: string;        // Admin response (required)
  sendEmail?: boolean;          // Send email to contact (optional)
  language?: string;            // Response language (optional)
}

Response Data:

{
  success: boolean;
  message: string;
  contact: ContactDto;
  emailSent: boolean;
  emailError: string | null;
}

Resend Contact Email (Admin)

Endpoint: POST /api/admin/contacts/{id}/resend-email

Request Data:

{
  language?: string;            // Email language (optional)
}

Response Data:

{
  success: boolean;
  message: string;
}

Soft Delete Contact (Admin)

Endpoint: DELETE /api/admin/contacts/{id}

Response Data:

{
  success: boolean;
}

Hard Delete Contact (Admin)

Endpoint: DELETE /api/admin/contacts/{id}/hard

Response Data:

{
  success: boolean;
}

Import/Export (Admin)

Import Deck from JSON (Admin)

Endpoint: POST /api/admin/decks/import

Request: Multipart form data

  • file: JSON file (max 10MB)

Response Data:

{
  success: boolean;
  message: string;
  deckId: string;
}

Export Deck as JSON (Admin)

Endpoint: GET /api/admin/decks/{deckId}/export

Response: JSON file download

Headers:

  • Content-Type: application/json
  • Content-Disposition: attachment; filename="deckname.json"

Error Handling

Standard Error Response Format

{
  error: string;                // Error message
  details?: string;             // Additional details (development only)
  timestamp?: string;           // Error timestamp
}

HTTP Status Codes

  • 200 - Success
  • 201 - Created
  • 204 - No Content
  • 400 - Bad Request (validation error)
  • 401 - Unauthorized (authentication required)
  • 403 - Forbidden (insufficient permissions)
  • 404 - Not Found
  • 409 - Conflict (duplicate data)
  • 500 - Internal Server Error
  • 503 - Service Unavailable

Common Error Scenarios

Authentication Errors:

// Missing or invalid token
{ error: "Authentication required" }

// Account state restrictions
{ error: "Please verify your email address" }
{ error: "Account has been deactivated" }

// Admin access required
{ error: "Admin access required" }

Validation Errors:

// Missing required fields
{ error: "Missing required fields: username, password" }

// Invalid field length
{ error: "Username must be between 3 and 50 characters" }

// Invalid parameters
{ error: "Invalid page parameters. \"from\" and \"to\" must be valid numbers with to >= from >= 0" }

// Invalid file type
{ error: "Only JSON and .spr files are allowed" }

Business Logic Errors:

// Ownership restrictions
{ error: "Access denied - you can only export your own decks" }

// Feature restrictions
{ error: "Premium subscription required to create groups" }

// Duplicate data
{ error: "Deck with this name already exists" }
{ error: "Username or email already exists" }

WebSocket Real-Time Communication

Connection & Authentication

Connect to WebSocket server with JWT authentication:

import io from 'socket.io-client';

// Option 1: JWT token in auth
const socket = io('http://localhost:3000', {
  auth: {
    token: 'your-jwt-token'
  }
});

// Option 2: Cookie authentication
const socket = io('http://localhost:3000', {
  withCredentials: true
});

Connection Events

// Connection successful
socket.on('connect', () => {
  console.log('Connected to WebSocket server');
});

// Authentication failed
socket.on('connect_error', (error) => {
  console.error('Connection failed:', error.message);
});

// Disconnected
socket.on('disconnect', (reason) => {
  console.log('Disconnected:', reason);
});

// General errors
socket.on('error', (error: { message: string }) => {
  console.error('WebSocket error:', error.message);
});

Chat Management Events

Initial Chat List:

// Automatically sent on connection
socket.on('chats:list', (chats: Array<{
  id: string;
  type: ChatType;
  name: string | null;
  users: string[];
  lastActivity: Date | null;
  isArchived: boolean;
}>) => {
  // Update chat list in UI
});

Join/Leave Chat:

// Join a chat room
socket.emit('chat:join', { chatId: 'chat-uuid' });

// Confirmation of joining
socket.on('chat:joined', (data: {
  chatId: string;
  messages: Message[];
  users: string[];
}) => {
  // Load chat messages
});

// Leave a chat room
socket.emit('chat:leave', { chatId: 'chat-uuid' });

// Confirmation of leaving
socket.on('chat:left', (data: { chatId: string }) => {
  // Update UI
});

Real-time Messaging

Send/Receive Messages:

// Send message
socket.emit('message:send', {
  chatId: 'chat-uuid',
  message: 'Hello everyone!'
});

// Receive message
socket.on('message:received', (data: {
  chatId: string;
  message: Message;
  senderInfo?: {
    username: string;
    fname: string;
    lname: string;
  };
}) => {
  // Add message to chat UI
});

// Message sent confirmation
socket.on('message:sent', (data: {
  chatId: string;
  messageId: string;
  timestamp: Date;
}) => {
  // Update UI
});

Rate Limiting: 100 messages per user per minute

Chat Creation Events

Create Group Chat (Premium Only):

// Create group
socket.emit('group:create', {
  name: 'Study Group',
  userIds: ['user-uuid-1', 'user-uuid-2']
});

// Group created
socket.on('group:created', (data: {
  chat: {
    id: string;
    type: 'group';
    name: string;
    users: string[];
    createdBy: string;
  };
}) => {
  // Add to chat list
});

// Creation failed
socket.on('group:creation:failed', (data: {
  error: string;
}) => {
  // Show error
});

Create Direct Chat:

// Create or get direct chat
socket.emit('chat:direct', {
  targetUserId: 'user-uuid'
});

// Chat created
socket.on('chat:direct:created', (data: {
  chat: {
    id: string;
    type: 'direct';
    users: string[];
  };
}) => {
  // Add to list
});

// Chat already exists
socket.on('chat:direct:exists', (data: {
  chatId: string;
}) => {
  // Navigate to existing chat
});

Create Game Chat:

// Create game chat
socket.emit('game:chat:create', {
  gameId: 'game-uuid',
  gameName: 'Quiz Game #123',
  playerIds: ['player-uuid-1', 'player-uuid-2']
});

// Game chat created
socket.on('game:chat:created', (data: {
  chat: {
    id: string;
    type: 'game';
    name: string;
    gameId: string;
    users: string[];
  };
}) => {
  // Show game chat
});

Chat History Management

Get Chat History:

// Request full history
socket.emit('chat:history', { chatId: 'chat-uuid' });

// Receive active chat history
socket.on('chat:history', (data: {
  chatId: string;
  messages: Message[];
  users: string[];
  type: ChatType;
  name: string | null;
}) => {
  // Display full history
});

// Receive archived chat history
socket.on('chat:history:archived', (data: {
  chatId: string;
  messages: Message[];
  isGameChat: boolean;
  archiveDate: Date;
}) => {
  // Display as read-only
});

Message Retention Rules

  • All chats: Messages older than 2 weeks are deleted
  • Direct & Game chats: Max 10 messages per user (FIFO)
  • Group chats: Time limit only (no per-user limit)
  • Archive: Inactive chats (30 minutes) are archived
  • Cleanup: Archived messages cleaned after 4 weeks

Complete Implementation Example

// hooks/useWebSocket.ts
import { useEffect, useRef, useState } from 'react';
import io, { Socket } from 'socket.io-client';

export const useWebSocket = (token: string | null) => {
  const socketRef = useRef<Socket | null>(null);
  const [isConnected, setIsConnected] = useState(false);
  const [chats, setChats] = useState<any[]>([]);

  useEffect(() => {
    if (!token) return;

    socketRef.current = io('http://localhost:3000', {
      auth: { token },
      withCredentials: true
    });

    const socket = socketRef.current;

    socket.on('connect', () => setIsConnected(true));
    socket.on('connect_error', () => setIsConnected(false));
    socket.on('disconnect', () => setIsConnected(false));

    socket.on('chats:list', (chatList) => {
      setChats(chatList);
    });

    socket.on('message:received', (data) => {
      setChats(prev => prev.map(chat => 
        chat.id === data.chatId 
          ? { ...chat, messages: [...chat.messages, data.message] }
          : chat
      ));
    });

    return () => {
      socket.disconnect();
    };
  }, [token]);

  const sendMessage = (chatId: string, message: string) => {
    socketRef.current?.emit('message:send', { chatId, message });
  };

  const joinChat = (chatId: string) => {
    socketRef.current?.emit('chat:join', { chatId });
  };

  const createDirectChat = (targetUserId: string) => {
    socketRef.current?.emit('chat:direct', { targetUserId });
  };

  const createGroup = (name: string, userIds: string[]) => {
    socketRef.current?.emit('group:create', { name, userIds });
  };

  return {
    socket: socketRef.current,
    isConnected,
    chats,
    sendMessage,
    joinChat,
    createDirectChat,
    createGroup
  };
};

This documentation provides a complete reference for all 50+ endpoints available in the SerpentRace backend API, with accurate data structures, validation rules, and implementation examples derived directly from the TypeScript source code.