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

1440 lines
32 KiB
Markdown

# SerpentRace Backend API Documentation for Frontend Developers
## Complete API Reference with All Endpoints
## Table of Contents
1. [Test User Credentials](#test-user-credentials)
2. [Data Structures & Entities](#data-structures--entities)
3. [Base URL & Service Info](#base-url--service-info)
4. [Authentication Endpoints](#authentication-endpoints)
5. [User Management](#user-management)
6. [Deck Management](#deck-management)
7. [Organization Management](#organization-management)
8. [Chat System](#chat-system)
9. [Contact Management](#contact-management)
10. [Import/Export Functionality](#importexport-functionality)
11. [Admin Endpoints](#admin-endpoints)
12. [Error Handling](#error-handling)
13. [WebSocket Real-Time Communication](#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
```typescript
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
```typescript
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
```typescript
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
```typescript
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
```typescript
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:**
```typescript
{
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:**
```typescript
{
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:**
```typescript
{
username: string; // Username or email
password: string; // Password
}
```
**Response Data (Success):**
```typescript
{
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:**
```typescript
{
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):**
```typescript
{
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
### Get Decks (Paginated) - RECOMMENDED
**Endpoint:** `GET /api/decks/page/{from}/{to}`
**Authentication:** Required
**URL Parameters:**
- `from`: Start index (0-based, ≥ 0)
- `to`: End index (inclusive, ≥ from)
**Response Data:**
```typescript
{
decks: ShortDeckDto[]; // Array of deck summaries
totalCount: number; // Total available decks
}
```
### Create Deck
**Endpoint:** `POST /api/decks`
**Authentication:** Required
**Request Data:**
```typescript
{
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:**
```typescript
{
success: boolean; // Deletion success status
}
```
---
## Organization Management
### Get Organizations (Paginated) - RECOMMENDED
**Endpoint:** `GET /api/organizations/page/{from}/{to}`
**Authentication:** Required
**URL Parameters:**
- `from`: Start index (0-based, ≥ 0)
- `to`: End index (inclusive, ≥ from)
**Response Data:**
```typescript
{
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:**
```typescript
{
loginUrl: string; // Organization login URL
organizationName: string; // Organization name
}
```
### Process Organization Auth Callback
**Endpoint:** `POST /api/organizations/auth-callback`
**Authentication:** Required
**Request Data:**
```typescript
{
organizationId: string; // Organization UUID
status: "ok" | "not_ok"; // Authentication status
authToken?: string; // Authentication token (optional)
}
```
**Response Data:**
```typescript
{
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:**
```typescript
{
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:**
```typescript
{
type: 'direct' | 'group'; // Chat type
userIds: string[]; // Participant user IDs
name?: string; // Group name (required for groups)
}
```
**Response Data:**
```typescript
{
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:**
```typescript
{
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:**
```typescript
{
success: boolean;
message: string;
}
```
### Restore Chat from Archive
**Endpoint:** `POST /api/chats/restore/{chatId}`
**Authentication:** Required
**URL Parameters:**
- `chatId`: Chat UUID (validated)
**Response Data:**
```typescript
{
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:**
```typescript
{
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:**
```typescript
{
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)
#### Get Users (Paginated) - RECOMMENDED
**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:**
```typescript
{
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:**
```typescript
{
message: string;
user: DetailUserDto;
}
```
#### Delete User (Admin)
**Endpoint:** `DELETE /api/admin/users/{userId}`
**Response Data:**
```typescript
{
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:**
```typescript
{
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:**
```typescript
{
success: boolean;
}
```
#### Hard Delete Organization (Admin)
**Endpoint:** `DELETE /api/admin/organizations/{id}/hard`
**Response Data:**
```typescript
{
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:**
```typescript
{
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:**
```typescript
{
adminResponse: string; // Admin response (required)
sendEmail?: boolean; // Send email to contact (optional)
language?: string; // Response language (optional)
}
```
**Response Data:**
```typescript
{
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:**
```typescript
{
language?: string; // Email language (optional)
}
```
**Response Data:**
```typescript
{
success: boolean;
message: string;
}
```
#### Soft Delete Contact (Admin)
**Endpoint:** `DELETE /api/admin/contacts/{id}`
**Response Data:**
```typescript
{
success: boolean;
}
```
#### Hard Delete Contact (Admin)
**Endpoint:** `DELETE /api/admin/contacts/{id}/hard`
**Response Data:**
```typescript
{
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:**
```typescript
{
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
```typescript
{
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:**
```typescript
// 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:**
```typescript
// 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:**
```typescript
// 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:
```typescript
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
```typescript
// 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:**
```typescript
// 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:**
```typescript
// 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:**
```typescript
// 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):**
```typescript
// 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:**
```typescript
// 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:**
```typescript
// 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:**
```typescript
// 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
```typescript
// 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.