Sealearn’s motivation layer is built on a set of interlocking systems — experience points, levels, limited lives, a daily streak, spendable currency, and unlockable achievements — all stored directly on theDocumentation 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.
User model and updated in real time as students complete lessons, win duels, and hit daily goals. Every system is designed to reward consistency and mastery rather than mere participation.
XP and Leveling
Every action that earns experience points callsuser.addXP(amount):
pre('save') hook also enforces level-ups, catching any direct xp mutations that bypass addXP.
The xpProgress virtual computes the student’s percentage progress toward the next level, clamped to [0, 100]:
Leveling up during a lesson completion is reported in the API response as
{ leveledUp: true, newLevel: N }, allowing the frontend to display a level-up animation without an additional request.Hearts (Lives) System
Hearts are a scarce resource that gates access to lessons and keeps students focused. Thehearts sub-document on the User model contains:
- Maximum: 5 hearts at any time.
- Lose one: every wrong answer in a lesson (or a failed typing / Python exercise) calls
user.loseHeart(), which decrementshearts.currentand records the timestamp inhearts.lastRefillto start the refill timer. - Auto-refill:
user.checkHeartRefill()runs on lesson start and calculatesfloor(elapsed / 30 minutes)hearts to restore. Hearts never exceed 5. - Manual refill:
user.refillHearts()instantly restores all 5 hearts and resets the timestamp. This costs gems and is available through the in-app shop.
A student with 0 hearts cannot start a lesson. The
startLesson controller returns HTTP 403 with the message "No tenés corazones para iniciar una lección" until at least one heart has been refilled.Daily Streak
The streak system encourages students to return every single day. Callinguser.updateStreak() at lesson completion handles all the logic:
| Field | Type | Description |
|---|---|---|
current | Number | Active streak length in days |
longest | Number | All-time personal best |
lastActivityDate | Date | Timestamp of the most recent lesson completion |
freezeUsed | Boolean | Whether a streak freeze powerup has been used this period |
currentStreak virtual reads lastActivityDate and returns 0 if the gap to today is more than 1 day, even if streak.current has not been reset yet (lazy evaluation). The freeze flag (freezeUsed) mirrors Duolingo’s streak freeze mechanic, allowing one missed day to be pardoned.
Gems
Gems are Sealearn’s in-app currency, stored as a plainNumber on the User model (gems, minimum 0). They are earned by:
- Completing lessons (each lesson has a
gemsRewardfield) - Earning a perfect lesson score (+5 bonus gems)
- Unlocking achievements that specify a
reward.gemsvalue
- Heart refills — instantly restore all 5 hearts
- Frames (
ShopItemdocuments referenced byactiveFrame) - Backgrounds (
ShopItemdocuments referenced byactiveBackground)
Daily Goals
Students can set a personal daily XP target to help build a learning habit. The four available options are:| Goal | XP per Day | Intended audience |
|---|---|---|
| Casual | 10 XP | Occasional learners |
| Regular | 20 XP | Default recommendation |
| Serious | 30 XP | Motivated students |
| Intense | 50 XP | Power learners |
dailyGoal field defaults to 10 and is constrained to the enum [10, 20, 30, 50]. Progress toward the daily goal is tracked against XP earned within the current calendar day and shown in the home screen dashboard.
Achievements
TheAchievement model defines unlockable milestones. Each achievement has:
key— a unique string identifier (e.g."streak_7","perfect_lesson")category— one ofstreak,xp,lessons,accuracy,social,specialcondition.type— the event type:streak_days,total_xp,lessons_completed,perfect_lessons,subjects_started, ordaily_goal_dayscondition.threshold— the numeric target (e.g.7for a 7-day streak)reward— an{ xp, gems }object awarded on first unlockrarity—common,rare,epic, orlegendary
checkAndGrantAchievements(user, streak, progress) is called. Any newly unlocked achievements are appended to the user’s achievements array (stored as ObjectId references to Achievement documents) and returned in the lesson completion response as newAchievements.
A selection of built-in achievements seeded by Achievement.seedDefaults():
| Key | Name | Condition | Reward | Rarity |
|---|---|---|---|---|
first_lesson | ¡Primer paso! | Complete 1 lesson | 10 XP + 5 gems | Common |
streak_3 | En racha | 3-day streak | 20 XP + 10 gems | Common |
streak_7 | Semana completa | 7-day streak | 50 XP + 20 gems | Rare |
streak_30 | Imparable | 30-day streak | 200 XP + 100 gems | Legendary |
perfect_lesson | Perfección | 1 perfect lesson | 25 XP + 15 gems | Rare |
xp_100 | Estudiante aplicado | Accumulate 100 XP | 10 gems | Common |
xp_1000 | Experto | Accumulate 1000 XP | 50 gems | Epic |
lessons_10 | Constante | Complete 10 lessons | 30 XP + 20 gems | Common |
Leaderboard
Sealearn maintains two leaderboard views derived from thexp field on the User model:
- Global leaderboard — all active users ranked by total XP
- Friends leaderboard — the same ranking filtered to the user’s accepted friendships only