Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/DerBasilisk/SEA-ServicioEvaluaconAsistida/llms.txt

Use this file to discover all available pages before exploring further.

Sealearn is built to be learned together. Beyond individual progress, the platform offers a complete social layer: you can add friends, compare your XP on a friends-only leaderboard, chat in real time, challenge friends to duels from inside a conversation, and customise your public profile with uploaded avatars and banners. Every social interaction is designed to reinforce the learning habit by keeping the community visible and active.

Friend System

Send, accept, and reject friend requests. Friends appear in your leaderboard and are available to challenge to duels. The Friendship model tracks the state of every pair.

Friends Leaderboard

A ranked view of your friends’ total XP — the same xp field from the User model, filtered to your accepted friendships. Motivates consistent practice through friendly rivalry.

Real-Time Chat

A Socket.IO /chat namespace powers one-on-one messaging. Conversations persist in MongoDB and duel results are posted automatically as special duel_result messages.

Public Profiles

Every user has a shareable profile page showing their level, league, streak, achievements, active frame, and active background. Searchable by username.

Friend System

Friendships are modelled as a directed Friendship document:
{
  requester: ObjectId,   // user who sent the request
  recipient: ObjectId,   // user who received it
  status:    "pending" | "accepted" | "rejected",
}
A compound unique index on { requester, recipient } prevents duplicate requests. The full friendship flow:
  1. Send requestPOST /api/friends/request creates a Friendship with status: "pending".
  2. AcceptPUT /api/friends/:id/accept sets status: "accepted". Both users now appear in each other’s friends lists.
  3. RejectPUT /api/friends/:id/reject sets status: "rejected".
  4. Remove friendDELETE /api/friends/:id deletes the Friendship document entirely.
Only accepted friendships are counted for leaderboard ranking and duel invitations.

Friends Leaderboard

The friends leaderboard queries all accepted Friendship documents where the current user is either requester or recipient, collects the friend user IDs, and returns those users sorted by xp descending. The current user is also included in the ranking so the student can see where they stand relative to their circle.

Public Profiles

Any authenticated user can view another user’s public profile:
GET /api/friends/profile/:username
The response returns the following public fields from the User model:
FieldSource
username / displayNameUser model
avatar / bannerCloudinary URLs
xp, level, xpProgressUser model + virtual
leagueUser model
streak.current, streak.longestUser model
achievementsPopulated Achievement refs
activeFramePopulated ShopItem ref
activeBackgroundPopulated ShopItem ref
duelsStatsUser model
GET /api/friends/search?q=<query>
Performs a case-insensitive partial match against the username field. Returns a list of public user summaries (avatar, username, level, league) so that students can discover and add new friends.

Real-Time Chat

Chat is handled by a dedicated Socket.IO namespace (/chat). Like the duel socket, it authenticates via JWT on handshake. Each conversation corresponds to a Conversation document linking two user IDs; messages are stored in a Message collection. REST endpoint for conversation list:
GET /api/chat
Returns all conversations the authenticated user participates in, including the last message preview and unread count. Key Socket.IO events in the /chat namespace:
EventDirectionDescription
chat:messageServer → ClientNew message delivered to the conversation room conv:<conversationId>
chat:sendClient → ServerSend a new text message
chat:readClient → ServerMark messages in a conversation as read

Duel Invites via Chat

Players can initiate a duel directly from a chat conversation by sending a duel:invite event that includes the conversationId. When the duel concludes, a duel_result message is automatically posted to the conversation by the server:
⚔️ Duelo finalizado — Ganador: <winnerCorrect>✓ vs <loserCorrect>✓
The message carries a structured duelData payload with winnerName, loserName, correct answer counts, total questions, and duration in seconds — allowing the frontend to render a rich result card inside the chat thread.

Avatar and Banner Customisation

Profile images are hosted on Cloudinary. Avatars and banners are updated through the general profile update endpoint:
MethodEndpointDescription
PUT/api/profile/Update profile fields including avatar and banner (Cloudinary URLs). Also supports displayName, dailyGoal, and notification preferences.
PUT/api/profile/passwordChange the authenticated user’s password.
The activeFrame and activeBackground fields reference ShopItem documents purchased with gems, letting students further personalise how their profile appears to the rest of the community.

Build docs developers (and LLMs) love