Skip to content

Latest commit

 

History

History
896 lines (703 loc) · 34.4 KB

DEVELOPMENT.md

File metadata and controls

896 lines (703 loc) · 34.4 KB

weChess Development Process Documentation

Real-time multiplayer chess platform with lobby and in-game chat, leaderboards, and support for guest and registered players.


Table of Contents

  1. Architecture Overview
  2. Backend Development (Mindbricks)
  3. Frontend Development (Cursor + React)
  4. API Reference & Integration Guide
  5. Real-Time Communication (WebSockets)
  6. Authentication & Authorization
  7. Development Workflows
  8. Deployment

Architecture Overview

weChess follows a decoupled architecture with a Mindbricks-generated Node.js microservices backend and a standalone React SPA frontend.

┌──────────────────────────────────────────────────────────────┐
│                      Frontend (React SPA)                    │
│  React 19 · Vite 7 · TypeScript · Tailwind CSS v4           │
│  Zustand (state) · TanStack Query (data) · Socket.IO        │
└──────────────────┬───────────────────────────────────────────┘
                   │ HTTPS / WSS
                   ▼
┌──────────────────────────────────────────────────────────────┐
│               API Gateway (Frontgate / BFF)                  │
│                 https://wechess.mindbricks.co                │
└──────┬───────┬───────┬───────┬───────┬───────┬──────────────┘
       │       │       │       │       │       │
       ▼       ▼       ▼       ▼       ▼       ▼
   ┌──────┐┌──────┐┌──────┐┌──────┐┌──────┐┌──────┐
   │ Auth ││Game- ││InGame││Lobby ││Leader││Notif.│
   │      ││ play ││ Chat ││ Chat ││board ││      │
   └──────┘└──────┘└──────┘└──────┘└──────┘└──────┘
   PostgreSQL databases per service · Redis for real-time

Backend Services

Service Route Prefix Port Purpose
auth /auth-api 3011 User registration, login, JWT tokens, roles, verification, password reset, 2FA
gameplay /gameplay-api 3000 Game CRUD, matchmaking, moves, invitations, game lifecycle, WebSocket game hub
ingamechat /ingamechat-api 3000 In-game chat messages, moderation, WebSocket chat hub
lobbychat /lobbychat-api 3000 Lobby rooms, lobby messages, moderation, WebSocket lobby hub
leaderboard /leaderboard-api 3000 ELO ratings, player stats, leaderboard rankings
notification — — Email/SMS templates for verification, 2FA, password reset
bff — — Backend-for-Frontend aggregation layer
mcpbff — — MCP (Model Context Protocol) BFF for AI integrations
document — — Static documentation server with Flexsearch
frontgate — — API gateway / routing layer

Backend Development (Mindbricks)

What is Mindbricks?

Mindbricks is an AI-driven backend development platform that generates production-ready Node.js microservices from declarative project configurations. Instead of writing backend code manually, you define your data models, APIs, business logic, and authentication in a structured configuration — Mindbricks generates and deploys the entire backend.

Project Identifiers

  • Project ID: 19cbe0a3-ff70-4285-968b-504239115f3d
  • Project Codename: wechess
  • Production URL: https://wechess.mindbricks.co

How to Access the Backend Configuration

There are two ways to work with the Mindbricks backend:

  1. Mindbricks Web UI: Navigate to https://app.mindbricks.com and open the weChess project
  2. Mindbricks MCP Server (in Cursor): Use the integrated MCP tools directly from the IDE

Core MCP Tools for Backend Development

When working in Cursor with the Mindbricks MCP server connected, these are the primary tools:

Tool Purpose
getProjectOverview See the top-level project structure
readAt Read configuration at any path (e.g., services/gameplay/dataObjects/chessGame)
updateAt Update configuration — deep merges changes with existing data
deleteAt Remove items (properties, data objects, APIs, services)
validateService / validateProject Catch configuration errors before building
buildServiceRepo Regenerate code and push to GitLab (triggers auto-deploy)
getPreviewStatus Check which version is running on the preview environment
getPreviewLogs / getServicePreviewLogs Debug runtime errors in the preview
httpRequest Test API endpoints directly from Cursor
loginAsSuperadmin Get an authenticated token for testing
getServiceApiDocument Get the full API specification for a service
getOntologyDocByPath Learn the schema for a specific configuration path
getOntologyTree See the full configuration hierarchy

Backend Modification Workflow

1. Understand current state
   └─> getProjectOverview / readAt

2. Consult the ontology (schema)
   └─> getOntologyDocByPath / getOntologyDocByPatternName

3. Make changes
   └─> updateAt (deep merge) / deleteAt (remove items)

4. Validate
   └─> validateService / validateProject

5. Build & Deploy
   └─> buildServiceRepo → auto-deploys via GitLab webhook

6. Verify deployment
   └─> getPreviewStatus (poll until commitId matches and status = "ready")

7. Test
   └─> loginAsSuperadmin → httpRequest to live endpoints

Data Model Overview

gameplay service — chessGame

Property Type Required Description
playerWhiteId ID Yes References auth:user.id
playerBlackId ID No References auth:user.id
createdById ID Yes Who created the game
status Enum Yes pending, active, paused, completed, terminated
mode Enum Yes public, private
gameType Enum Yes timed, untimed, blitz, rapid
currentFEN String Yes Board state in FEN notation
invitationCode String No For private games
result Enum No whiteWin, blackWin, draw, aborted
saveStatus Enum Yes notSaveable, requested, paused
saveRequestWhite Boolean No White's save/pause request
saveRequestBlack Boolean No Black's save/pause request
terminatedById ID No Admin who terminated
guestPlayerWhite Boolean No Is white a guest?
guestPlayerBlack Boolean No Is black a guest?
movedAt DateTime No Last move timestamp
reportStatus Enum No none, reported, underReview

gameplay service — gameMove

Property Type Required Description
gameId ID Yes References chessGame.id
movedById ID Yes References auth:user.id
moveNotation String Yes Standard algebraic notation
moveNumber Integer Yes Sequential move number
moveTime Integer No Time taken in milliseconds
moveTimestamp DateTime Yes When the move was made

gameplay service — gameInvitation

Property Type Required Description
gameId ID Yes References chessGame.id
senderId ID Yes Who sent the invitation
recipientId ID Yes Who receives it
status Enum Yes pending, accepted, declined, cancelled
expiresAt DateTime Yes Invitation expiry

ingamechat service — gameChatMessage

Property Type Required Description
gameId ID Yes Which game this message belongs to
content String Yes Message text
removed Boolean No Soft-removed by moderation
reportStatus Enum No none, reported, underReview

lobbychat service — lobbyRoom / lobbyMessage

Lobby rooms are created per day. Messages belong to rooms and support moderation (remove, report, mute).

leaderboard service — playerStats / leaderboardEntry

Tracks ELO ratings, win/loss/draw counts, streaks, and ranked standings.

Adding a New Data Object (Example)

1. Fetch the ontology for DataObject:
   getOntologyDocByPatternName("DataObject")

2. Create the data object:
   updateAt("wechess", "services/gameplay/dataObjects/tournament", {
     objectSettings: {
       basicSettings: { name: "tournament" },
       authorization: { dataObjectAccess: "accessPrivate" }
     },
     properties: [
       {
         basicSettings: { name: "name", type: "String", isRequired: true, allowUpdate: true },
         indexSettings: { indexedInDb: true }
       },
       {
         basicSettings: { name: "startDate", type: "DateTime", isRequired: true, allowUpdate: true }
       }
     ]
   })

3. Add business APIs for it:
   updateAt("wechess", "services/gameplay/businessLogic/createTournament", { ... })

4. Validate:
   validateService("wechess", "gameplay")

5. Build:
   buildServiceRepo("wechess")

Adding a New Business API (Example)

1. Fetch the ontology:
   getOntologyDocByPatternName("BusinessApi")

2. Define the API:
   updateAt("wechess", "services/gameplay/businessLogic/getActiveGames", {
     basicApiSettings: {
       name: "getActiveGames",
       type: "custom",
       httpMethod: "get",
       httpRoute: "/v1/activegames",
       authorization: { ... }
     },
     actions: { ... }
   })

3. Validate and build as above.

Roles & Permissions

The project uses role-based access control (RBAC) with three roles:

Role Value Description
Guest guest Auto-registered temporary users, limited features
Registered Player registeredPlayer Full access to games, leaderboard, chat
Administrator administrator Full access + user management, game moderation, chat moderation

Environment & Preview

  • Preview environments auto-deploy when code is pushed via buildServiceRepo
  • Cold previews (inactive) can be woken with wakeupPreview
  • Use getPreviewStatus to get live service URLs
  • Use getPreviewLogs / getServicePreviewLogs for debugging
  • Use restartPreviewService if a service missed an update

Frontend Development (Cursor + React)

Tech Stack

Technology Version Purpose
React 19.2 UI framework
TypeScript 5.9 Type safety
Vite 7.3 Build tool and dev server
Tailwind CSS 4.2 Utility-first styling
Zustand 5.0 Lightweight state management
TanStack Query 5.90 Server state, caching, data fetching
React Router 7.13 Client-side routing
Socket.IO Client 4.8 Real-time WebSocket communication
chess.js 1.4 Chess logic and move validation
react-chessboard 5.10 Interactive chess board UI
Axios 1.13 HTTP client

Project Structure

frontend/
├── index.html                  # HTML shell
├── vite.config.ts              # Vite config (React, Tailwind, aliases, code-splitting)
├── tsconfig.json               # TypeScript project references
├── tsconfig.app.json           # App TS config (paths: @/* → ./src/*)
├── eslint.config.js            # ESLint flat config
├── package.json
├── Dockerfile                  # Production Docker build
├── nginx.conf                  # Production Nginx config
├── .gitlab-ci.yml              # CI/CD pipeline (Docker build on main)
└── src/
    ├── main.tsx                # Entry point
    ├── App.tsx                 # Root component (providers, routing)
    ├── index.css               # Global styles (Tailwind imports)
    │
    ├── api/                    # API layer (Axios clients + service modules)
    │   ├── clients.ts          # Base URL config, interceptors, service clients
    │   ├── auth.ts             # Auth service API functions
    │   ├── gameplay.ts         # Gameplay service API functions
    │   ├── chat.ts             # In-game chat API functions
    │   ├── lobby.ts            # Lobby chat API functions
    │   ├── leaderboard.ts      # Leaderboard API functions
    │   ├── bucket.ts           # File upload (S3 bucket) API
    │   └── mcpbff.ts           # MCP BFF API functions
    │
    ├── components/             # Shared UI components
    │   ├── Header.tsx          # Global navigation header
    │   ├── ProtectedRoute.tsx  # Auth guard (supports requireAdmin)
    │   ├── ErrorBoundary.tsx   # React error boundary
    │   ├── Toast.tsx           # Toast notification system (ToastContainer)
    │   ├── NotificationCenter.tsx
    │   ├── ChatPanel.tsx       # Reusable chat panel component
    │   └── SecretField.tsx     # Hidden/reveal input field
    │
    ├── pages/                  # Route-level page components
    │   ├── Home.tsx            # Landing page
    │   ├── Login.tsx           # Login form
    │   ├── Register.tsx        # Registration form
    │   ├── Verification.tsx    # Email/mobile verification
    │   ├── ForgotPassword.tsx  # Password reset flow
    │   ├── Email2FA.tsx        # Two-factor authentication
    │   ├── Profile.tsx         # User profile management
    │   ├── GameLobby.tsx       # Game lobby with matchmaking
    │   ├── GamePlay.tsx        # Active chess game with board
    │   ├── GameHistory.tsx     # Past games viewer
    │   ├── Leaderboard.tsx     # Rankings and stats
    │   ├── ComputerPlay.tsx    # Play against AI (offline)
    │   ├── UserManagement.tsx  # Admin: manage users
    │   ├── AdminGames.tsx      # Admin: manage games
    │   └── AdminChat.tsx       # Admin: moderate chat
    │
    ├── hooks/
    │   └── useAuth.ts          # Authentication hook (login, logout, guest, session restore)
    │
    ├── stores/                 # Zustand state stores
    │   ├── authStore.ts        # Auth state (user, tokens, isAuthenticated)
    │   └── notificationStore.ts # In-app notification state
    │
    ├── lib/                    # Utility libraries
    │   ├── socketManager.ts    # WebSocket hub manager (game, chat, lobby hubs)
    │   ├── gameTypeConfig.ts   # Game type definitions and settings
    │   ├── lobbyRoomUtils.ts   # Lobby room ID generation
    │   ├── notificationSounds.ts
    │   └── utils.ts            # General utilities
    │
    ├── types/
    │   └── index.ts            # TypeScript interfaces for all domain entities
    │
    └── assets/                 # Static assets (currently empty)

Route Map

Path Component Auth Required Admin Only
/ Home No No
/login Login No No
/register Register No No
/verify Verification No No
/forgot-password ForgotPassword No No
/2fa-verify Email2FA No No
/computer ComputerPlay No No
/profile Profile Yes No
/lobby GameLobby Yes No
/game/:gameId GamePlay Yes No
/history GameHistory Yes No
/leaderboard Leaderboard Yes No
/admin/users UserManagement Yes Yes
/admin/games AdminGames Yes Yes
/admin/chat AdminChat Yes Yes

State Management Pattern

Zustand is used for client-side state that persists across routes:

  • authStore — User object, JWT tokens, authentication status. Tokens are persisted to localStorage under wechess_accessToken, wechess_userBucketToken, wechess_applicationBucketToken.
  • notificationStore — In-app notification queue for game events.

TanStack Query is used for server state:

  • Configured with refetchOnWindowFocus: false, retry: 1, staleTime: 30_000
  • Used for API data that should be cached and revalidated (games list, leaderboard, user data)

API Client Architecture

All API communication goes through Axios clients defined in src/api/clients.ts:

  • Base URL: https://wechess.mindbricks.co (hardcoded, no env variable)
  • Request interceptor: Automatically attaches Authorization: Bearer <token> from Zustand store
  • Response interceptor: Auto-logout on 401 responses
  • Service clients: authApi, gameApi, chatApi, leaderboardApi, lobbyApi, bucketApi

Each service has its own API module (src/api/*.ts) that exports typed functions wrapping Axios calls.

Adding a New Page (Checklist)

  1. Create the page component in src/pages/NewPage.tsx
  2. Add TypeScript types to src/types/index.ts if new entities are needed
  3. Create API functions in the relevant src/api/*.ts module
  4. Register the route in src/App.tsx — wrap with <ProtectedRoute> if auth is required
  5. Add navigation in src/components/Header.tsx if it should appear in the nav bar
  6. Connect WebSocket if real-time features are needed (use socketManager.ts)

Adding a New API Integration (Checklist)

  1. Check if a client exists in src/api/clients.ts for the target service
  2. If not, create a new service client: export const newApi = createServiceClient('/new-api');
  3. Create the API module: src/api/newService.ts
  4. Define types in src/types/index.ts
  5. Use in components via TanStack Query hooks or direct calls

Styling Conventions

  • Tailwind CSS v4 with the @tailwindcss/vite plugin
  • Dark theme by default (bg-background text-foreground)
  • Brand color: green (#22c55e / green-500)
  • Utility classes from clsx, tailwind-merge, class-variance-authority available
  • No component library — all UI is custom-built

Code Quality

  • ESLint flat config with TypeScript ESLint, React Hooks, and React Refresh plugins
  • Path alias @/* maps to ./src/* (configured in both Vite and TSConfig)
  • Code splitting: manual chunks for react, chess, and socket.io in Vite config

API Reference & Integration Guide

Base URL

All API requests go through: https://wechess.mindbricks.co

Authentication Endpoints (/auth-api)

Method Endpoint Auth Description
POST /login No Login with email + password
POST /logout Yes End session
GET /currentuser Yes Get current user and refresh tokens
POST /v1/registeruser No Register a new user
GET /v1/users/:id Yes Get user by ID
GET /v1/users Admin List users (filterable by email, fullname, roleId)
GET /v1/searchusers?keyword= Admin Search users
POST /v1/users Admin Create user
PATCH /v1/users/:id Admin Update user
DELETE /v1/users/:id Admin Delete user
PATCH /v1/profile/:id Yes Update own profile (fullname, avatar)
PATCH /v1/userpassword/:id Yes Change own password
DELETE /v1/archiveprofile/:id Yes Archive own account
PATCH /v1/userrole/:id Admin Change user role
PATCH /v1/userpasswordbyadmin/:id Admin Reset user password

Verification Endpoints (/auth-api)

Method Endpoint Description
POST /verification-services/email-verification/start Send verification email
POST /verification-services/email-verification/complete Verify email code/link
POST /verification-services/password-reset-by-email/start Request password reset
POST /verification-services/password-reset-by-email/complete Complete password reset
POST /verification-services/email-2factor/complete Complete 2FA verification

Gameplay Endpoints (/gameplay-api)

Method Endpoint Description
POST /v1/game Create a new game
GET /v1/game/:id Get game by ID
PATCH /v1/game/:id Update game (status, FEN, result, etc.)
DELETE /v1/game/:id Delete game
GET /v1/games List games (filter by status, mode, invitationCode)
POST /v1/gamemove Record a move
GET /v1/gamemoves?gameId= List moves for a game
POST /v1/gameinvitation Create a private game invitation
PATCH /v1/gameinvitation/:id Update invitation status
GET /v1/gameinvitations List invitations (filter by recipientId, senderId, status)
GET /game-hub/:roomId/eligible Check WebSocket room eligibility

In-Game Chat Endpoints (/ingamechat-api)

Method Endpoint Description
GET /v1/listgamechatmessages/:gameId List chat messages for a game
POST /v1/gamechatmessages Send a chat message
PATCH /v1/gamechatmessagemoderation/:id Moderate a message (report, remove)
DELETE /v1/gamechatmessages/:id Delete a message

Lobby Chat Endpoints (/lobbychat-api)

Method Endpoint Description
GET /v1/listlobbyrooms/:roomId Get lobby room by ID
POST /v1/ensurelobbyroom Create or get a lobby room
GET /v1/listlobbymessages/:roomId List messages in a lobby room
POST /v1/lobbymessages Send a lobby message
PATCH /v1/lobbymessagemoderation/:id Moderate a lobby message
DELETE /v1/lobbymessages/:id Delete a lobby message

Leaderboard Endpoints (/leaderboard-api)

Method Endpoint Description
GET /v1/leaderboardtopn?topN= Get top N leaderboard entries
GET /v1/leaderboardentries/:userId Get user's leaderboard entry
POST /v1/leaderboardentries Create leaderboard entry
PATCH /v1/leaderboardentries/:id Update leaderboard entry
GET /v1/playerstatses/:userId Get player stats
POST /v1/playerstatses Create player stats
PATCH /v1/playerstatses/:id Update player stats

File Upload (/bucket)

Method Endpoint Description
POST /upload Upload file (multipart form data with bucketId and files)

Bucket IDs follow the pattern {userId}-public-user-bucket for user uploads.

Standard API Response Format

interface ApiResponse<T> {
  status: string;          // "success" or "error"
  statusCode: number;      // HTTP status code
  dataName?: string;       // Name of the data key (e.g., "chessGame")
  rowCount?: number;       // Number of rows returned
  paging?: {
    pageNumber: number;
    pageRowCount: number;
    totalRowCount: number;
    pageCount: number;
  };
  [dataName]: T;           // Dynamic key containing the data
}

Standard Error Response

interface ApiError {
  result: string;    // "error"
  status: number;    // HTTP status
  message: string;   // Human-readable error
  errCode: number;   // Application error code
  date: string;      // ISO timestamp
  detail?: string;   // Additional detail
}

Real-Time Communication (WebSockets)

weChess uses Socket.IO for real-time features with three distinct hubs:

Hub Configuration

Hub Namespace Path Purpose
gameHub /gameplay-api/hub/gameHub /gameplay-api/socket.io/ Game moves, lifecycle events, matchmaking
gameChatHub /ingamechat-api/hub/gameChatHub /ingamechat-api/socket.io/ In-game chat messages
lobbyChatHub /lobbychat-api/hub/lobbyChatHub /lobbychat-api/socket.io/ Lobby room chat messages

Event Subscriptions

Subscription Namespace Purpose
gameLifecycleEvents /ingamechat-api/events/gameLifecycleEvents Game start/end/pause notifications
gameEvents /leaderboard-api/events/gameEvents Score and stat updates

Socket.IO Protocol

Connection: Authenticated via auth.token callback (JWT from Zustand store).

const socket = io(`${BASE_URL}${namespace}`, {
  path: socketPath,
  auth: (cb) => cb({ token: accessToken }),
  transports: ['websocket', 'polling'],
  reconnection: true,
});

Room operations:

Event (emit) Payload Description
hub:join { roomId, meta? } Join a room (game, lobby)
hub:leave { roomId } Leave a room
hub:send { roomId, messageType, content } Send a message to a room
hub:event { roomId, event, data? } Emit a custom event (typing, moves)
hub:block { roomId, userId, reason?, duration? } Block a user from a room
hub:unblock { roomId, userId } Unblock a user
hub:silence { roomId, userId, reason?, duration? } Mute a user
hub:unsilence { roomId, userId } Unmute a user

Socket Manager Usage

import { connectHub, joinRoom, sendHubMessage, disconnectHub } from '@/lib/socketManager';

// Connect to a hub
const socket = connectHub('gameHub');

// Join a game room
joinRoom('gameHub', gameId, { userId, username });

// Listen for events
socket.on('hub:message', (msg) => { /* handle */ });
socket.on('hub:event', (evt) => { /* handle */ });

// Send a game move
sendHubMessage('gameHub', gameId, 'move', { from: 'e2', to: 'e4', fen: '...' });

// Cleanup
disconnectHub('gameHub');

Authentication & Authorization

Authentication Flow

1. User submits email + password
   └─> POST /auth-api/login

2. Server returns JWT + user data
   ├─> accessToken (30-day expiry)
   ├─> userBucketToken (for file uploads)
   └─> applicationBucketToken

3. Tokens stored in Zustand + localStorage
   └─> Axios interceptor attaches to all requests

4. If 2FA is enabled:
   └─> Server returns { status: "2fa_required", userId }
   └─> User redirected to /2fa-verify
   └─> POST /verification-services/email-2factor/complete

5. Session restore on page reload:
   └─> useAuth hook checks stored token
   └─> GET /auth-api/currentuser
   └─> Re-hydrates user state

Guest User Flow

  1. Frontend generates random credentials (Guest_XXXXXXXX / guest_XXXXXXXX@wechess.guest)
  2. Auto-registers via POST /auth-api/v1/registeruser
  3. Auto-logs in via POST /auth-api/login
  4. Assigned guest role — limited to playing games, no leaderboard stats

JWT Configuration

  • Algorithm: JWT with auto-rotating keys
  • Token period: 30 days
  • Key refresh: Every 150 days
  • Storage: localStorage keys wechess_accessToken, wechess_userBucketToken, wechess_applicationBucketToken

Route Protection

The ProtectedRoute component in src/components/ProtectedRoute.tsx:

  • Checks isAuthenticated from Zustand store
  • Shows loading state while isLoading is true
  • Redirects to /login if not authenticated
  • Optionally requires administrator role via requireAdmin prop

Development Workflows

Local Frontend Development

# Navigate to frontend directory
cd frontend

# Install dependencies
npm install

# Start development server
npm run dev
# → http://localhost:5173

# Build for production
npm run build

# Preview production build
npm run preview

# Run linting
npm run lint

Backend Changes via Cursor + Mindbricks MCP

The recommended workflow for making backend changes from within Cursor:

Step 1: Understand the Current State
────────────────────────────────────
• Use getProjectOverview to see top-level structure
• Use readAt("wechess", "services/gameplay") to inspect a service
• Use readAt("wechess", "services/gameplay/dataObjects/chessGame") to inspect a data object

Step 2: Consult the Ontology
────────────────────────────
• Use getOntologyTree to see the config hierarchy
• Use getOntologyDocByPath("services/gameplay/dataObjects") to learn the schema
• Fetch each pattern type ONCE — reuse from context

Step 3: Make Changes
────────────────────
• Use updateAt for adding or modifying configuration
  - Deep merge: only specified fields change, everything else preserved
  - Scalar fields: updated if specified, preserved if omitted
  - Objects: recursively merged

• Use deleteAt for removing items
  - deleteAt("wechess", "services/gameplay/dataObjects/chessGame/properties/fieldName")

Step 4: Validate
────────────────
• validateService("wechess", "gameplay") — catches design errors

Step 5: Build & Deploy
──────────────────────
• buildServiceRepo("wechess") — regenerates code, pushes to GitLab
• Save the returned commitId

Step 6: Monitor Deployment
──────────────────────────
• Poll getPreviewStatus until service commitId matches
• Check getServicePreviewLogs for runtime errors

Step 7: Test APIs
─────────────────
• loginAsSuperadmin("wechess") — get auth token
• httpRequest to test endpoints using URLs from getPreviewStatus
• Always call getServiceApiDocument first to learn correct endpoint paths

Frontend Development Workflow with Backend Docs

When building new frontend features that consume backend APIs:

Step 1: Get the API Documentation
─────────────────────────────────
• Use getServiceApiDocument("wechess", "serviceName") from the MCP
• Or read the existing src/api/*.ts modules for established patterns

Step 2: Define Types
────────────────────
• Add TypeScript interfaces to src/types/index.ts
• Match the backend data model (use readAt to inspect field names and types)

Step 3: Create API Functions
────────────────────────────
• Add functions to the appropriate src/api/*.ts module
• Follow existing patterns: export async functions, destructure { data }

Step 4: Build the UI
────────────────────
• Create page component in src/pages/
• Use TanStack Query for data fetching
• Use Zustand stores for cross-component state
• Use socketManager for real-time features

Step 5: Register Routes
───────────────────────
• Add route in src/App.tsx
• Wrap with ProtectedRoute if auth needed
• Add navigation link in Header.tsx

Testing API Endpoints

From Cursor with the Mindbricks MCP, you can test endpoints directly:

1. loginAsSuperadmin({ projectId: "wechess" })
   → Returns auth token

2. getPreviewStatus({ projectId: "wechess" })
   → Returns service URLs

3. httpRequest({
     projectId: "wechess",
     url: "https://wechess.mindbricks.co/gameplay-api/v1/games",
     method: "GET",
     useProjectToken: true
   })

Deployment

Frontend Deployment

The frontend deploys via GitLab CI/CD on push to main:

  1. Trigger: Push to main branch
  2. Build: Docker builds the image using the Dockerfile
  3. Tag: Image tagged as wechess-frontend:latest and wechess-frontend:<commit-sha>
  4. Deploy: docker compose up -d wechess on the production server

The Dockerfile uses a multi-stage build:

  • Stage 1: Node.js to build the Vite app
  • Stage 2: Nginx to serve the static files (configured via nginx.conf)

Backend Deployment

Backend services are automatically deployed through Mindbricks:

  1. Run buildServiceRepo("wechess") — pushes generated code to GitLab
  2. GitLab webhook triggers the matrix preview server
  3. Preview server clones, installs, and starts each service
  4. Services go through: pending → cloning → installing → starting → healthcheck → ready

Service statuses can be monitored via getPreviewStatus.

Cold Starts

Preview environments go cold after inactivity:

  1. getPreviewStatus returns status: "cold"
  2. Call wakeupPreview("wechess")
  3. Poll getPreviewStatus every 3–5 seconds until ready: true

Production URLs

Resource URL
API Gateway https://wechess.mindbricks.co
Auth Service https://wechess.mindbricks.co/auth-api
Gameplay Service https://wechess.mindbricks.co/gameplay-api
Chat Service https://wechess.mindbricks.co/ingamechat-api
Lobby Service https://wechess.mindbricks.co/lobbychat-api
Leaderboard Service https://wechess.mindbricks.co/leaderboard-api
File Bucket https://wechess.mindbricks.co/bucket

Quick Reference

Key Files to Know

File Purpose
frontend/src/api/clients.ts API base URL and Axios client factory
frontend/src/lib/socketManager.ts WebSocket connection management
frontend/src/stores/authStore.ts Auth state and token persistence
frontend/src/hooks/useAuth.ts Login, logout, guest login, session restore
frontend/src/types/index.ts All shared TypeScript interfaces
frontend/src/App.tsx Route definitions and provider tree
wechess/.mbx-services.json Mindbricks project config (project ID + service list)

Common Patterns

Fetching data with TanStack Query:

const { data, isLoading } = useQuery({
  queryKey: ['games', status],
  queryFn: () => listGames({ status }),
});

Authenticated API call:

// Token is automatically attached by the Axios interceptor
const game = await getGame(gameId);

Real-time game move:

sendHubMessage('gameHub', gameId, 'move', {
  from: 'e2', to: 'e4',
  fen: chess.fen(),
  moveNotation: 'e4',
});

Protected admin route:

<Route path="/admin/users" element={
  <ProtectedRoute requireAdmin>
    <UserManagement />
  </ProtectedRoute>
} />