Skip to content

Mindbricks/weChess

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

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: pendingcloninginstallingstartinghealthcheckready

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>

} />

About

weChess is a real-time multiplayer chess platform featuring lobby and in-game chat, leaderboards, and support for both guest and registered players. The system provides chat moderation, matchmaking (public and private games), ongoing/resumable matches, and administrative tools for game and user management.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors