workspace/projects/gamilit/docs/95-guias-desarrollo/PORTAL-STUDENT-GUIDE.md
rckrdmrd ea1879f4ad feat: Initial workspace structure with multi-level Git configuration
- Configure workspace Git repository with comprehensive .gitignore
- Add Odoo as submodule for ERP reference code
- Include documentation: SETUP.md, GIT-STRUCTURE.md
- Add gitignore templates for projects (backend, frontend, database)
- Structure supports independent repos per project/subproject level

Workspace includes:
- core/ - Reusable patterns, modules, orchestration system
- projects/ - Active projects (erp-suite, gamilit, trading-platform, etc.)
- knowledge-base/ - Reference code and patterns (includes Odoo submodule)
- devtools/ - Development tools and templates
- customers/ - Client implementations template

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-08 10:44:23 -06:00

51 KiB

Guía de Desarrollo - Portal Student

Fecha de creación: 2025-11-29 Versión: 1.0.0 Estado: VIGENTE Aplica a: apps/frontend/src/apps/student/ + apps/backend/src/modules/[progress, gamification, educational]


1. Visión General

1.1 Propósito

El Portal Student es la interfaz principal para estudiantes en GAMILIT. Es una plataforma educativa gamificada con temática de detective e inspiración Maya que proporciona:

  • Aprendizaje Interactivo: Módulos educativos con ejercicios de comprensión lectora
  • Gamificación Completa: Sistema de rangos Maya, achievements, misiones y ML Coins
  • Progreso Personalizado: Dashboard con métricas de desempeño y actividades recientes
  • Economía Virtual: Tienda de power-ups, comodines y items cosméticos
  • Social: Leaderboards, guilds, friends y competencia sana
  • Notificaciones: Sistema de alertas y celebraciones por logros

1.2 Usuarios Objetivo

Rol Acceso Funcionalidades
Student Completo Todas las funcionalidades del portal
Teacher Supervisión Vista de progreso de estudiantes
Admin Monitoreo Vista de todas las métricas y configuración

1.3 Temática y Narrativa

Tema Principal: Detective educativo con elementos de cultura Maya

  • Rangos: Jerarquía Maya (Ajaw → Nacom → Ah K'in → Halach Uinic → K'uk'ulkan)
  • Moneda: ML Coins (Marie Learning Coins)
  • Narrativa: Estudiante como "Detective" que resuelve "casos" (ejercicios)
  • Iconografía: Lupa, expediente, evidencias, rango Maya

2. Arquitectura del Portal

2.1 Estructura de Carpetas

Frontend (apps/frontend/src/apps/student/)

student/
├── pages/                              # 27 páginas principales
│   ├── DashboardComplete.tsx           # ⭐ Dashboard principal
│   ├── ExercisePage.tsx                # ⭐ Ejercicios interactivos (mecánicas)
│   ├── GamificationPage.tsx            # ⭐ Hub de gamificación
│   ├── ModuleDetailPage.tsx            # Detalle de módulo educativo
│   ├── AchievementsPage.tsx            # Logros desbloqueados
│   ├── ShopPage.tsx                    # Tienda ML Coins
│   ├── LeaderboardPage.tsx             # Rankings globales
│   ├── MissionsPage.tsx                # Misiones activas
│   ├── InventoryPage.tsx               # Inventario de comodines
│   ├── FriendsPage.tsx                 # Sistema de amigos
│   ├── GuildsPage.tsx                  # Guilds/clanes
│   ├── EnhancedProfilePage.tsx         # Perfil de usuario
│   ├── SettingsPage.tsx                # Configuración
│   ├── NotificationsPage.tsx           # Centro de notificaciones
│   ├── AssignmentsPage.tsx             # Tareas del teacher
│   ├── LoginPage.tsx                   # Autenticación
│   ├── RegisterPage.tsx                # Registro
│   ├── PasswordRecoveryPage.tsx        # Recuperación contraseña
│   └── ...
├── components/                         # Componentes organizados por dominio
│   ├── dashboard/                      # 17 componentes del dashboard
│   │   ├── BottomNavigation.tsx        # ⭐ Navegación móvil (6 tabs)
│   │   ├── EnhancedStatsGrid.tsx       # Estadísticas detective
│   │   ├── RankProgressWidget.tsx      # Widget de rango Maya
│   │   ├── MLCoinsWidget.tsx           # Balance de ML Coins
│   │   ├── MissionsPanel.tsx           # Misiones activas
│   │   ├── ModulesSection.tsx          # Grid de módulos
│   │   ├── RecentActivityPanel.tsx     # Actividades recientes
│   │   ├── QuickActionsWidget.tsx      # Acciones rápidas
│   │   ├── AchievementMilestones.tsx   # Hitos de logros
│   │   └── ...
│   ├── exercise/                       # Componentes de ejercicios
│   │   ├── ExerciseHeader.tsx          # Header con timer y score
│   │   ├── CompletionModal.tsx         # Modal de finalización
│   │   ├── HintModal.tsx               # Sistema de pistas
│   │   ├── PowerUpEffects.tsx          # Efectos de power-ups
│   │   └── ExerciseSidebar.tsx         # Sidebar con progreso
│   ├── gamification/                   # Componentes de gamificación
│   │   ├── GamificationHero.tsx        # Hero section
│   │   ├── RanksSection.tsx            # Sección de rangos
│   │   ├── MLCoinsSection.tsx          # Sección de economía
│   │   ├── AchievementsPreview.tsx     # Preview de logros
│   │   ├── LeaderboardPreview.tsx      # Preview de ranking
│   │   └── StreaksMissionsSection.tsx  # Rachas y misiones
│   ├── achievements/                   # Sistema de logros
│   │   ├── AchievementGrid.tsx         # Grid de achievements
│   │   ├── AchievementDetailModal.tsx  # Modal de detalle
│   │   ├── AchievementFilters.tsx      # Filtros (rarity, category)
│   │   └── AchievementStatistics.tsx   # Estadísticas
│   ├── notifications/                  # Notificaciones y celebraciones
│   │   ├── AchievementToast.tsx        # Toast de logro desbloqueado
│   │   └── CelebrationModal.tsx        # Modal de celebración
│   ├── interactions/                   # Interacciones gestuales
│   │   └── SwipeableContainer.tsx      # Swipe para móvil
│   └── PowerUpBar.tsx                  # Barra de power-ups activos
├── hooks/                              # 14 custom hooks
│   ├── useDashboardData.ts             # ⭐ Dashboard data + React Query
│   ├── useUserModules.ts               # Módulos del usuario
│   ├── useRecentActivities.ts          # Actividades recientes
│   ├── useGamificationData.ts          # Datos de gamificación
│   ├── useAchievementsEnhanced.ts      # Achievements con filtros
│   ├── useExerciseState.ts             # Estado de ejercicio
│   ├── useExerciseAutoSave.ts          # Auto-save de progreso
│   ├── useExercisePowerUps.ts          # Power-ups en ejercicios
│   ├── useUserClassroom.ts             # Classroom del usuario
│   ├── useSwipeGesture.ts              # Gestos táctiles
│   ├── useResponsiveLayout.ts          # Responsive breakpoints
│   └── index.ts                        # Barrel export
└── types/
    └── index.ts                        # 40+ interfaces/types

Backend - Módulos Principales

apps/backend/src/modules/
├── progress/                           # Sistema de progreso
│   ├── controllers/
│   │   ├── exercise-submission.controller.ts
│   │   ├── exercise-attempt.controller.ts
│   │   ├── module-progress.controller.ts
│   │   └── learning-session.controller.ts
│   ├── services/
│   │   ├── exercise-submission.service.ts
│   │   ├── module-progress.service.ts
│   │   └── learning-session.service.ts
│   ├── entities/
│   │   ├── exercise-submission.entity.ts
│   │   ├── module-progress.entity.ts
│   │   └── learning-session.entity.ts
│   └── dto/
│       ├── create-exercise-submission.dto.ts
│       └── exercise-submission-response.dto.ts
├── gamification/                       # Sistema de gamificación
│   ├── controllers/
│   │   ├── achievements.controller.ts
│   │   ├── missions.controller.ts
│   │   ├── ml-coins.controller.ts
│   │   ├── ranks.controller.ts
│   │   ├── leaderboard.controller.ts
│   │   └── comodines.controller.ts
│   ├── services/
│   │   ├── achievements.service.ts
│   │   ├── missions.service.ts
│   │   ├── ml-coins.service.ts
│   │   ├── ranks.service.ts
│   │   └── user-stats.service.ts
│   └── entities/
│       ├── achievement.entity.ts
│       ├── user-achievement.entity.ts
│       ├── mission.entity.ts
│       ├── user-rank.entity.ts
│       ├── ml-coins-transaction.entity.ts
│       └── user-stats.entity.ts
├── educational/                        # Contenido educativo
│   ├── controllers/
│   │   ├── modules.controller.ts
│   │   ├── exercises.controller.ts
│   │   └── media.controller.ts
│   ├── services/
│   │   ├── modules.service.ts
│   │   └── exercises.service.ts
│   └── entities/
│       ├── module.entity.ts
│       └── exercise.entity.ts
└── social/                             # Características sociales
    ├── controllers/
    │   ├── friendships.controller.ts
    │   ├── teams.controller.ts
    │   └── peer-challenges.controller.ts
    └── services/
        ├── friendships.service.ts
        └── teams.service.ts

2.2 Diagrama de Flujo de Datos

┌─────────────────────────────────────────────────────────────────┐
│                     STUDENT PORTAL                               │
├─────────────────────────────────────────────────────────────────┤
│                                                                  │
│  ┌──────────────┐    ┌──────────────┐    ┌──────────────┐      │
│  │  Dashboard   │───►│  Modules     │───►│  Exercise    │      │
│  │  Complete    │    │  (Learning)  │    │  Page        │      │
│  └──────────────┘    └──────────────┘    └──────────────┘      │
│         │                    │                    │              │
│         │                    │                    │              │
│         ▼                    ▼                    ▼              │
│  ┌──────────────────────────────────────────────────────┐       │
│  │          Custom Hooks Layer (React Query)            │       │
│  │  - useDashboardData()    - useUserModules()          │       │
│  │  - useExerciseState()    - useGamificationData()     │       │
│  └──────────────────────────────────────────────────────┘       │
│         │                    │                    │              │
│         │                    │                    │              │
│         ▼                    ▼                    ▼              │
│  ┌──────────────────────────────────────────────────────┐       │
│  │           API Services Layer (Axios)                 │       │
│  │  - progressAPI    - gamificationAPI                  │       │
│  │  - educationalAPI - socialAPI                        │       │
│  └──────────────────────────────────────────────────────┘       │
│                              │                                   │
└──────────────────────────────┼───────────────────────────────────┘
                               │
                          HTTP/REST
                               │
┌──────────────────────────────▼───────────────────────────────────┐
│                        BACKEND API                                │
├──────────────────────────────────────────────────────────────────┤
│  Controllers ──► Services ──► Repositories ──► Database          │
│       │             │                                            │
│       │             ├──► Gamification Module                     │
│       │             ├──► Progress Module                         │
│       │             ├──► Educational Module                      │
│       │             └──► Social Module                           │
└──────────────────────────────────────────────────────────────────┘

3. Módulos Principales

3.1 Dashboard (DashboardComplete)

Ruta: /

Propósito: Centro de control del estudiante con visión general de progreso, misiones, módulos y actividades recientes.

Componentes Clave:

  1. GamifiedHeader

    • Usuario autenticado
    • Balance de ML Coins
    • Rank actual con icono Maya
    • Botón de logout
  2. QuickActionsWidget

    • Continuar último ejercicio
    • Ver misiones activas
    • Ir a tienda
    • Ver perfil
  3. RankProgressWidget (4 columnas)

    • Rank actual con icono Maya
    • XP actual / XP requerido
    • Barra de progreso
    • Multiplicador activo
  4. ModulesSection (8 columnas)

    • Grid de 4 módulos (2 col c/u)
    • Estado: available, in_progress, locked
    • Progreso porcentual
    • Dificultad (fácil, medio, difícil)
  5. EnhancedStatsGrid (4 columnas)

    • Casos resueltos (ejercicios completados)
    • Racha actual de días
    • Tiempo total invertido
    • XP total acumulado
  6. MissionsPanel (4 columnas)

    • Top 3 misiones activas
    • Progreso de cada misión
    • Recompensas (XP, ML Coins)
    • Tiempo límite
  7. RecentActivityPanel (4 columnas)

    • Últimas 5 actividades
    • Timestamps relativos
    • Iconos por tipo de actividad

Hooks Utilizados:

// Dashboard data (React Query)
const { rank, progress, loading, error, refresh } = useDashboardData();

// Missions from backend
const { allMissions, activeMissions } = useMissions();

// Modules filtered by classroom
const { modules, loading: modulesLoading } = useUserModules({
  classroomId: userClassroomId,
});

// Recent activities
const { activities, loading: activitiesLoading } = useRecentActivities(5);

// Gamification data (mock until backend ready)
const { gamificationData } = useUserGamification(user?.id);

APIs:

// Dashboard aggregated data
GET /api/v1/gamification/users/:userId/ml-coins
GET /api/v1/gamification/ranks/current
GET /api/v1/gamification/ranks/users/:userId/rank-progress
GET /api/v1/gamification/users/:userId/achievements
GET /api/v1/progress/users/:userId

// Missions
GET /api/v1/gamification/missions/active

// Modules
GET /api/v1/educational/modules
GET /api/v1/educational/modules/:classroomId/assigned

// Activities
GET /api/v1/progress/users/:userId/recent-activities

3.2 Módulos Educativos

Ruta: /modules/:moduleId

Propósito: Vista detallada de un módulo con sus ejercicios, progreso y recomendaciones.

Estructura de Módulo:

  • Módulo 1: Comprensión Literal
  • Módulo 2: Comprensión Inferencial
  • Módulo 3: Comprensión Crítica
  • Módulo 4: Textos Digitales y Multimediales

Componentes:

  • ModuleHeader: Título, descripción, progreso general
  • ExercisesList: Lista de ejercicios con estado (locked, available, in_progress, completed)
  • ProgressChart: Gráfico de progreso por competencia
  • RecommendedExercises: Ejercicios sugeridos según desempeño

APIs:

GET /api/v1/educational/modules/:moduleId
GET /api/v1/educational/modules/:moduleId/exercises
GET /api/v1/progress/modules/:moduleId/progress

3.3 Ejercicios Interactivos (ExercisePage)

Ruta: /exercises/:exerciseId

Propósito: Interfaz para completar ejercicios con mecánicas interactivas variadas.

Mecánicas Implementadas (por módulo):

Módulo 1 - Comprensión Literal

  • crucigrama - Crucigrama científico
  • timeline / linea_tiempo - Línea de tiempo
  • sopa_letras - Sopa de letras
  • mapa_conceptual - Mapa conceptual
  • emparejamiento - Emparejamiento
  • verdadero_falso - Verdadero/Falso
  • completar_espacios - Completar espacios en blanco

Módulo 2 - Comprensión Inferencial

  • detective_textual - Detective textual
  • lectura_inferencial - Lectura inferencial
  • construccion_hipotesis - Construcción de hipótesis
  • prediccion_narrativa - Predicción narrativa
  • puzzle_contexto - Puzzle de contexto
  • rueda_inferencias - Rueda de inferencias

Módulo 3 - Comprensión Crítica

  • analisis_fuentes - Análisis de fuentes
  • debate_digital - Debate digital
  • matriz_perspectivas - Matriz de perspectivas
  • podcast_argumentativo - Podcast argumentativo
  • tribunal_opiniones - Tribunal de opiniones

Módulo 4 - Textos Digitales

  • verificador_fakenews - Verificador de fake news
  • quiz_tiktok - Quiz TikTok
  • navegacion_hipertextual - Navegación hipertextual
  • analisis_memes - Análisis de memes
  • infografia_interactiva - Infografía interactiva
  • email_formal - Email formal
  • chat_literario - Chat literario
  • ensayo_argumentativo - Ensayo argumentativo
  • resena_critica - Reseña crítica

Componentes de Ejercicio:

// Layout principal
<div className="exercise-page">
  <ExerciseHeader
    title={exercise.title}
    difficulty={exercise.difficulty}
    points={exercise.points}
  />

  <div className="exercise-container">
    <ExerciseSidebar>
      <TimerWidget />
      <ScoreDisplay score={progress.score} />
      <ProgressTracker current={step} total={totalSteps} />
      <HintSystem hints={hints} onUseHint={handleHint} />
    </ExerciseSidebar>

    <Suspense fallback={<Loader />}>
      <DynamicMechanic
        mechanicType={exercise.type}
        data={exercise.mechanicData}
        onProgressUpdate={handleProgress}
        onSubmit={handleSubmit}
      />
    </Suspense>
  </div>

  <PowerUpBar powerUps={activePowerUps} />

  <FeedbackModal
    isOpen={showFeedback}
    feedback={feedbackData}
    onClose={handleCloseFeedback}
  />
</div>

Flujo de Ejercicio:

  1. Carga: GET /api/v1/educational/exercises/:exerciseId
  2. Auto-save: POST /api/v1/progress/exercises/:exerciseId/save (cada 30s)
  3. Uso de Hint: POST /api/v1/progress/exercises/:exerciseId/use-hint
  4. Uso de Power-up: POST /api/v1/gamification/comodines/use
  5. Envío: POST /api/v1/progress/exercises/:exerciseId/submit
  6. Feedback: Recibe calificación, XP ganado, ML Coins, achievements desbloqueados

Hooks:

// Exercise state management
const { exerciseState, updateProgress } = useExerciseState(exerciseId);

// Auto-save every 30s
useExerciseAutoSave(exerciseId, exerciseState, {
  interval: 30000,
  enabled: !exerciseState.completed,
});

// Power-ups activation
const { activePowerUps, usePowerUp } = useExercisePowerUps();

APIs:

GET  /api/v1/educational/exercises/:exerciseId
GET  /api/v1/educational/exercises/:exerciseId/hints
POST /api/v1/progress/exercises/:exerciseId/save
POST /api/v1/progress/exercises/:exerciseId/submit
POST /api/v1/gamification/comodines/use

3.4 Sistema de Gamificación

Ruta: /gamification

Propósito: Hub central de gamificación con ranks, achievements, economy y stats.

Secciones:

3.4.1 Ranks Maya System

Jerarquía de Rangos:

Rango Icono XP Requerido Multiplicador
Ajaw 🏹 0 1.0x
Nacom 🔍 1,000 1.2x
Ah K'in 🗡️ 5,000 1.5x
Halach Uinic ⚔️ 15,000 2.0x
K'uk'ulkan 👑 50,000 3.0x

Componentes:

<RankBadgeAdvanced
  rank={userProgress.currentRank}
  prestigeLevel={userProgress.prestigeLevel}
  showGlow={true}
  animated={true}
/>

<RankProgressBar
  currentXP={userProgress.xp}
  requiredXP={userProgress.nextRankXP}
  currentRank={userProgress.currentRank}
  nextRank={userProgress.nextRank}
/>

<MultiplierWidget
  multiplier={multiplierBreakdown.total}
  breakdown={multiplierBreakdown}
/>

<ProgressTimeline
  progressionHistory={progressionHistory}
/>

<PrestigeSystem
  prestigeProgress={prestigeProgress}
  onPrestige={handlePrestige}
/>

APIs:

GET  /api/v1/gamification/ranks/current
GET  /api/v1/gamification/ranks/users/:userId/rank-progress
GET  /api/v1/gamification/ranks/users/:userId/history
POST /api/v1/gamification/ranks/users/:userId/prestige

3.4.2 ML Coins Economy

Fuentes de Ingresos:

  • Completar ejercicios: 10-100 ML Coins (según dificultad y score)
  • Completar misiones: 50-500 ML Coins
  • Desbloquear achievements: 20-200 ML Coins
  • Bonificaciones del teacher: Variable
  • Daily login bonus: 10 ML Coins

Gastos:

  • Power-ups (comodines): 50-200 ML Coins
  • Items cosméticos: 100-1,000 ML Coins
  • Profile customizations: 50-500 ML Coins

Componentes:

<CoinBalanceWidget
  balance={balance.current}
  todayEarned={balance.earnedToday}
  todaySpent={balance.spentToday}
/>

<TransactionHistory
  transactions={transactions}
  limit={10}
/>

<EarningSourcesBreakdown
  sources={earningSources}
/>

<SpendingAnalytics
  data={spendingData}
  period="week"
/>

APIs:

GET  /api/v1/gamification/users/:userId/ml-coins
GET  /api/v1/gamification/users/:userId/ml-coins/transactions
POST /api/v1/gamification/users/:userId/ml-coins/add
POST /api/v1/gamification/users/:userId/ml-coins/deduct

3.4.3 Achievements System

Categorías:

  • Progress: Completar módulos, ejercicios
  • Mastery: Puntuaciones perfectas, rachas
  • Social: Amigos, guild, colaboración
  • Explorer: Descubrir contenido, probar mecánicas
  • Economy: Gastar ML Coins, comprar items
  • Special: Eventos, logros únicos

Rarities:

  • Common (Común) - Gris
  • Rare (Raro) - Azul
  • Epic (Épico) - Morado
  • Legendary (Legendario) - Dorado

Componentes:

<AchievementGrid
  achievements={achievements}
  filters={filters}
  sort={sortBy}
/>

<AchievementDetailModal
  achievement={selectedAchievement}
  isOpen={showModal}
  onClose={closeModal}
/>

<AchievementStatistics
  stats={achievementStats}
/>

// Toast cuando se desbloquea
<AchievementToast
  achievement={unlockedAchievement}
  onClose={handleCloseToast}
/>

APIs:

GET  /api/v1/gamification/achievements
GET  /api/v1/gamification/users/:userId/achievements
GET  /api/v1/gamification/achievements/:achievementId
POST /api/v1/gamification/users/:userId/achievements/:achievementId/claim

3.4.4 Missions System

Tipos de Misiones:

  • Daily: Reseteables cada día (ej: "Completa 3 ejercicios")
  • Weekly: Reseteables cada semana (ej: "Completa 1 módulo")
  • Seasonal: Eventos especiales (ej: "Participa en Halloween Challenge")
  • Progressive: Una sola vez (ej: "Alcanza Rank Nacom")

Dificultades:

  • Easy: 50 XP, 20 ML Coins
  • Medium: 100 XP, 50 ML Coins
  • Hard: 200 XP, 100 ML Coins

Componentes:

<MissionCard
  mission={mission}
  progress={mission.currentProgress}
  target={mission.targetProgress}
  onClaim={handleClaim}
/>

<MissionProgress
  current={progress}
  required={target}
  percentage={percentage}
/>

<MissionRewards
  xp={mission.xpReward}
  mlCoins={mission.mlCoinsReward}
/>

APIs:

GET  /api/v1/gamification/missions/active
GET  /api/v1/gamification/missions/completed
POST /api/v1/gamification/missions/:missionId/claim

3.5 Tienda (ShopPage)

Ruta: /shop

Propósito: Compra de power-ups, comodines y items cosméticos con ML Coins.

Categorías:

  1. Power-ups (Premium) - IMPLEMENTADO

    • Hint Revealer (50 ML Coins) - Revela una pista gratis
    • Time Freeze (100 ML Coins) - Pausa el timer 60s
    • XP Boost (150 ML Coins) - +50% XP por 1 hora
    • Score Multiplier (200 ML Coins) - +2x score en próximo ejercicio
  2. Cosmetics - NO IMPLEMENTADO

    • Avatares
    • Marcos de perfil
    • Badges decorativos
  3. Profile - NO IMPLEMENTADO

    • Títulos
    • Efectos de partículas
    • Temas de color

Componentes:

<ShopGrid
  items={shopItems}
  category={selectedCategory}
  onPurchase={handlePurchase}
/>

<ShopItem
  item={item}
  balance={userBalance}
  isOwned={item.isOwned}
  onBuy={handleBuy}
/>

<PurchaseConfirmationModal
  item={selectedItem}
  balance={userBalance}
  onConfirm={confirmPurchase}
  onCancel={cancelPurchase}
/>

APIs:

GET  /api/v1/gamification/shop/items
GET  /api/v1/gamification/shop/power-ups
POST /api/v1/gamification/shop/purchase
GET  /api/v1/gamification/users/:userId/inventory

3.6 Leaderboard

Ruta: /leaderboard

Propósito: Rankings globales y por classroom para competencia sana.

Tipos de Rankings:

  1. Global XP: Top 100 usuarios por XP total
  2. Weekly XP: Top 50 usuarios por XP de esta semana
  3. Classroom: Top estudiantes del aula
  4. Streak Leaders: Top rachas activas
  5. ML Coins: Top por balance de ML Coins

Componentes:

<LeaderboardTabs
  tabs={['Global', 'Weekly', 'Classroom', 'Streaks']}
  activeTab={activeTab}
  onChange={setActiveTab}
/>

<LeaderboardTable
  entries={leaderboardEntries}
  currentUserId={user.id}
  highlightCurrentUser={true}
/>

<UserRankCard
  rank={userRank}
  xp={userXP}
  position={userPosition}
/>

APIs:

GET /api/v1/gamification/leaderboard/global
GET /api/v1/gamification/leaderboard/weekly
GET /api/v1/gamification/leaderboard/classroom/:classroomId
GET /api/v1/gamification/leaderboard/streaks
GET /api/v1/gamification/leaderboard/user-position/:userId

3.7 Perfil de Usuario

Ruta: /profile

Propósito: Visualizar y editar perfil personal, estadísticas y configuración.

Secciones:

  1. Profile Header

    • Avatar
    • Username
    • Rank actual con icono
    • Titles (si tiene)
  2. Stats Overview

    • Total XP
    • ML Coins balance
    • Achievements desbloqueados
    • Módulos completados
    • Racha actual
  3. Recent Achievements

    • Últimos 5 logros desbloqueados
  4. Activity Graph

    • Actividad de los últimos 30 días
  5. Edit Profile

    • Cambiar avatar
    • Cambiar username
    • Bio

APIs:

GET   /api/v1/auth/users/:userId/profile
PATCH /api/v1/auth/users/:userId/profile
GET   /api/v1/progress/users/:userId/stats
GET   /api/v1/gamification/users/:userId/activity-graph

4. Navegación

4.1 BottomNavigation (Móvil)

Componente: BottomNavigation.tsx

Ubicación: Fixed bottom en mobile (< 768px)

Tabs:

ID Label Icon Path Descripción
home Home Home / Dashboard principal
modules Modules BookOpen /modules Módulos educativos
gamification Gamification Trophy /gamification Hub de gamificación
notifications Alerts Bell /notifications Centro de notificaciones
profile Profile User /profile Perfil de usuario
settings Settings Settings /settings Configuración

Features:

  • Active indicator: Tab activo resaltado con color detective-orange
  • Notification badge: Badge rojo en Bell si hay notificaciones sin leer
  • Smooth animations: Framer Motion para transiciones
  • Accessibility: ARIA labels y roles correctos
<BottomNavigation />

// Detecta pathname y resalta tab activo
const isActive = (path: string) => {
  if (path === '/') return location.pathname === '/';
  return location.pathname.startsWith(path);
};

// Muestra badge de notificaciones
{item.id === 'notifications' && unreadCount > 0 && (
  <Badge count={unreadCount} />
)}

4.2 Desktop Navigation

Componente: GamifiedHeader

Features:

  • Logo GAMILIT
  • ML Coins balance widget
  • Rank badge
  • Notifications dropdown
  • User menu (perfil, settings, logout)

5. Hooks Principales

5.1 useDashboardData

Propósito: Fetches aggregated dashboard data con React Query.

Endpoints llamados (en paralelo):

GET /api/v1/gamification/users/:userId/ml-coins
GET /api/v1/gamification/ranks/current
GET /api/v1/gamification/ranks/users/:userId/rank-progress
GET /api/v1/gamification/users/:userId/achievements
GET /api/v1/progress/users/:userId

Return value:

{
  coins: MLCoinsData | null,
  rank: RankData | null,
  achievements: AchievementData[],
  progress: ProgressData | null,
  recentAchievements: AchievementData[],
  loading: boolean,
  error: string | null,
  isRefreshing: boolean,
  refresh: () => Promise<void>
}

Configuración React Query:

  • staleTime: 5 minutos
  • gcTime: 10 minutos
  • refetchOnWindowFocus: true
  • retry: 2 veces con backoff exponencial

5.2 useUserModules

Propósito: Fetches módulos educativos del usuario, opcionalmente filtrados por classroom.

API:

GET /api/v1/educational/modules
GET /api/v1/educational/modules/:classroomId/assigned

Return value:

{
  modules: Module[],
  loading: boolean,
  error: string | null
}

5.3 useExerciseState

Propósito: Gestiona estado local de ejercicio en progreso.

State:

{
  currentStep: number,
  totalSteps: number,
  score: number,
  answers: Record<string, any>,
  hintsUsed: number,
  timeSpent: number,
  powerupsUsed: string[],
  completed: boolean
}

Métodos:

  • updateProgress(progress: Partial<ExerciseProgress>)
  • submitExercise()
  • resetExercise()

5.4 useExerciseAutoSave

Propósito: Auto-save de progreso cada 30s mientras ejercicio no completado.

API:

POST /api/v1/progress/exercises/:exerciseId/save
{
  progress: ExerciseProgress,
  answers: any
}

Configuración:

useExerciseAutoSave(exerciseId, exerciseState, {
  interval: 30000, // 30 segundos
  enabled: !exerciseState.completed,
});

5.5 useExercisePowerUps

Propósito: Gestión de power-ups activos durante ejercicio.

API:

POST /api/v1/gamification/comodines/use
{
  comodinId: string,
  exerciseId: string
}

Métodos:

  • usePowerUp(powerUpId: string)
  • getActivePowerUps()
  • checkPowerUpActive(type: string)

6. APIs del Portal Student

6.1 Endpoints Principales

Módulo Método Endpoint Descripción Guard
Progress
GET /progress/users/:userId Progreso general del usuario JwtAuth
GET /progress/users/:userId/recent-activities Últimas actividades JwtAuth
GET /progress/modules/:moduleId/progress Progreso en módulo JwtAuth
POST /progress/exercises/:exerciseId/save Auto-save de ejercicio JwtAuth
POST /progress/exercises/:exerciseId/submit Enviar ejercicio completo JwtAuth
Gamification
GET /gamification/users/:userId/ml-coins Balance de ML Coins JwtAuth
GET /gamification/users/:userId/ml-coins/transactions Historial de transacciones JwtAuth
GET /gamification/ranks/current Ranks disponibles JwtAuth
GET /gamification/ranks/users/:userId/rank-progress Progreso de rank JwtAuth
GET /gamification/achievements Todos los achievements JwtAuth
GET /gamification/users/:userId/achievements Achievements del usuario JwtAuth
GET /gamification/missions/active Misiones activas JwtAuth
POST /gamification/missions/:missionId/claim Reclamar recompensa JwtAuth
GET /gamification/leaderboard/global Ranking global JwtAuth
GET /gamification/leaderboard/classroom/:id Ranking del aula JwtAuth
GET /gamification/shop/items Items de la tienda JwtAuth
POST /gamification/shop/purchase Comprar item JwtAuth
POST /gamification/comodines/use Usar power-up JwtAuth
Educational
GET /educational/modules Lista de módulos JwtAuth
GET /educational/modules/:id Detalle de módulo JwtAuth
GET /educational/modules/:id/exercises Ejercicios del módulo JwtAuth
GET /educational/exercises/:id Detalle de ejercicio JwtAuth
GET /educational/exercises/:id/hints Pistas disponibles JwtAuth
Social
GET /social/friendships Lista de amigos JwtAuth
POST /social/friendships Enviar solicitud de amistad JwtAuth
GET /social/teams/:id Detalle de guild JwtAuth

6.2 Frontend API Services

services/api/
├── educationalAPI.ts          # Módulos y ejercicios
├── progressAPI.ts             # Progreso y submissions
├── gamificationAPI.ts         # Gamificación general
├── ranksAPI.ts                # Sistema de ranks
├── achievementsAPI.ts         # Achievements
├── missionsAPI.ts             # Misiones
├── economyAPI.ts              # ML Coins y shop
├── socialAPI.ts               # Amigos, guilds, leaderboard
└── apiClient.ts               # Axios instance configurado

7. Estado y Stores (Zustand)

7.1 Stores Principales

// Auth Store
authStore:
  - user: User | null
  - isAuthenticated: boolean
  - login()
  - logout()
  - register()

// Ranks Store
ranksStore:
  - userProgress: UserRankProgress
  - multiplierBreakdown: MultiplierData
  - prestigeProgress: PrestigeData
  - progressionHistory: ProgressEvent[]
  - fetchUserProgress()
  - showRankUpModal: boolean
  - closeRankUpModal()

// Economy Store
economyStore:
  - balance: MLCoinsBalance
  - transactions: Transaction[]
  - fetchBalance()
  - addTransaction()

// Achievements Store
achievementsStore:
  - achievements: Achievement[]
  - userAchievements: UserAchievement[]
  - stats: AchievementStats
  - fetchAchievements()
  - claimAchievement()

// Notifications Store
notificationsStore:
  - notifications: Notification[]
  - unreadCount: number
  - fetchNotifications()
  - markAsRead()
  - fetchUnreadCount()

8. Flujos Principales

8.1 Flujo: Completar Ejercicio

1. Student navega a /exercises/:exerciseId
   ↓
2. ExercisePage carga ejercicio: GET /educational/exercises/:exerciseId
   ↓
3. useExerciseState inicializa estado local
   ↓
4. useExerciseAutoSave inicia (cada 30s):
   POST /progress/exercises/:exerciseId/save
   ↓
5. Student completa ejercicio y presiona "Submit"
   ↓
6. POST /progress/exercises/:exerciseId/submit
   {
     answers: {...},
     timeSpent: 180,
     hintsUsed: 1,
     powerupsUsed: ['hint_revealer']
   }
   ↓
7. Backend calcula score, XP ganado, ML Coins
   ↓
8. Response:
   {
     score: 85,
     maxScore: 100,
     xpEarned: 120,
     mlCoinsEarned: 50,
     achievements: ['first_completion'],
     feedback: {...}
   }
   ↓
9. FeedbackModal muestra resultados
   ↓
10. Si achievement desbloqueado → AchievementToast
   ↓
11. Si rank up → RankUpModal
   ↓
12. Redirect a /modules o /dashboard

8.2 Flujo: Ganar XP y Subir de Rango

1. Student completa ejercicio → Gana XP (ej: 120 XP)
   ↓
2. Backend actualiza user_stats.total_xp
   ↓
3. Backend verifica si XP >= siguiente rank:
   SELECT * FROM gamification.maya_ranks
   WHERE xp_required <= :totalXP
   ORDER BY xp_required DESC LIMIT 1
   ↓
4. Si cambió rank:
   - Actualizar user_rank.current_rank
   - Crear entry en rank_progression_history
   - Crear achievement 'rank_up_{rankName}'
   ↓
5. Response incluye:
   {
     rankUp: true,
     newRank: 'Nacom',
     newMultiplier: 1.2,
     prestigePoints: 0
   }
   ↓
6. Frontend muestra RankUpModal con celebración
   ↓
7. ranksStore.fetchUserProgress() actualiza estado

8.3 Flujo: Comprar Item en Shop

1. Student navega a /shop
   ↓
2. GET /gamification/shop/items → Lista items disponibles
   ↓
3. Student selecciona item → Modal de confirmación
   ↓
4. Verificar balance suficiente
   ↓
5. POST /gamification/shop/purchase
   {
     itemId: 'hint_revealer',
     quantity: 1
   }
   ↓
6. Backend:
   - Verifica balance >= item.price
   - Deducir ML Coins
   - Agregar item a inventory
   - Crear transaction log
   ↓
7. Response:
   {
     success: true,
     newBalance: 450,
     item: {...}
   }
   ↓
8. Frontend:
   - economyStore.fetchBalance() (actualiza balance)
   - Toast: "Item comprado exitosamente"
   - Modal cierra

9. Sistema de Gamificación Detallado

9.1 Cálculo de XP

Fórmula Base:

baseXP = exercise.points; // Ej: 100 XP

// Multiplicadores
scoreMultiplier = (score / maxScore); // Ej: 85/100 = 0.85
rankMultiplier = userRank.multiplier;  // Ej: 1.2x (Nacom)
streakBonus = min(currentStreak * 0.05, 0.5); // Max +50%

totalXP = baseXP * scoreMultiplier * rankMultiplier * (1 + streakBonus);

// Ejemplo:
// 100 XP * 0.85 * 1.2 * 1.15 = 117.3 XP → 117 XP

Bonuses Adicionales:

  • Perfect Score: +20% XP si score = 100%
  • Speed Bonus: +10% XP si completa en < 50% tiempo estimado
  • No Hints Used: +15% XP si no usó pistas
  • First Try: +25% XP si completa en primer intento

9.2 Cálculo de ML Coins

Fórmula Base:

baseCoins = Math.floor(exercise.points / 10); // Ej: 100 XP → 10 ML Coins

// Multiplicadores
scoreMultiplier = (score / maxScore);
difficultyBonus = {
  easy: 1.0,
  medium: 1.5,
  hard: 2.0
}[exercise.difficulty];

totalCoins = baseCoins * scoreMultiplier * difficultyBonus;

// Ejemplo (hard, 85% score):
// 10 * 0.85 * 2.0 = 17 ML Coins

9.3 Sistema de Streaks

Cómo funciona:

  • Racha (Streak): Días consecutivos con al menos 1 ejercicio completado
  • Zona horaria: UTC-5 (Colombia)
  • Reset: Si pasa 1 día completo sin actividad → streak = 0
  • Bonus XP: +5% por cada día de racha (max +50% a 10 días)

Guardado:

-- En user_stats
current_streak: integer DEFAULT 0
longest_streak: integer DEFAULT 0
last_activity_date: date

Lógica:

const today = new Date().toISOString().split('T')[0];
const lastActivity = user.lastActivityDate;

if (lastActivity === today) {
  // Mismo día, no cambiar streak
} else {
  const daysSince = daysBetween(lastActivity, today);

  if (daysSince === 1) {
    // Día consecutivo
    user.currentStreak++;
    user.longestStreak = Math.max(user.longestStreak, user.currentStreak);
  } else {
    // Se rompió la racha
    user.currentStreak = 1;
  }

  user.lastActivityDate = today;
}

9.4 Achievements: Triggers y Lógica

Ejemplos de Achievements:

ID Nombre Trigger Condición Recompensa
first_steps Primeros Pasos exercise_completed count === 1 20 XP, 10 ML Coins
speed_demon Demonio de Velocidad exercise_completed timeSpent < estimatedTime * 0.5 50 XP, 25 ML Coins
perfectionist Perfeccionista exercise_completed score === 100 && attempts === 1 100 XP, 50 ML Coins
rank_nacom Ascenso a Nacom rank_up newRank === 'Nacom' 200 XP, 100 ML Coins
module_master Maestro de Módulo module_completed completionRate === 100% 500 XP, 200 ML Coins
streak_warrior Guerrero Constante daily_activity currentStreak === 7 150 XP, 75 ML Coins
coin_collector Coleccionista ml_coins_earned totalCoinsEarned >= 1000 100 XP, 50 ML Coins

Backend Logic:

// En exercise-submission.service.ts
async checkAchievements(userId: string, context: AchievementContext) {
  const triggers = await this.achievementsRepo.find({
    where: { trigger: context.trigger }
  });

  for (const achievement of triggers) {
    const meetsCondition = await this.evaluateCondition(
      achievement.condition,
      userId,
      context
    );

    if (meetsCondition) {
      await this.unlockAchievement(userId, achievement.id);
    }
  }
}

10. Responsive Design

10.1 Breakpoints

// tailwind.config.js
screens: {
  'sm': '640px',   // Mobile landscape
  'md': '768px',   // Tablet
  'lg': '1024px',  // Desktop
  'xl': '1280px',  // Large desktop
  '2xl': '1536px'  // Extra large
}

10.2 Layout Adaptations

Mobile (< 768px):

  • BottomNavigation visible
  • Single column layouts
  • Swipeable carousels
  • Collapsible sections
  • Touch-optimized controls (min 44x44px)

Tablet (768px - 1024px):

  • BottomNavigation hidden
  • GamifiedHeader expanded
  • 2-column grids
  • Sidebars overlay

Desktop (> 1024px):

  • Full navigation
  • 3-4 column grids
  • Persistent sidebars
  • Hover states

Hook:

const { isMobile, isTablet, isDesktop } = useResponsiveLayout();

// Usage
{isMobile && <MobileView />}
{isDesktop && <DesktopSidebar />}

11. Buenas Prácticas

11.1 Frontend

11.1.1 React Query

// DO: Query keys descriptivas y jerárquicas
queryKey: ['dashboard', userId, 'coins']
queryKey: ['modules', moduleId, 'exercises']

// DO: Usar staleTime para reducir re-fetches
staleTime: 5 * 60 * 1000, // 5 min

// DO: Invalidar queries relacionadas después de mutations
onSuccess: () => {
  queryClient.invalidateQueries({ queryKey: ['dashboard'] });
  queryClient.invalidateQueries({ queryKey: ['gamification', 'coins'] });
}

// DON'T: Queries sin enabled cuando dependen de parámetros
enabled: !!userId, // SIEMPRE verificar

11.1.2 State Management

// DO: Zustand para global state, React Query para server state
// Global UI state → Zustand
// Server data → React Query

// DO: Hooks para lógica reutilizable
export function useDashboardData() { ... }

// DON'T: Props drilling más de 2 niveles
// Usar context o store

11.1.3 Performance

// DO: Lazy load de mecánicas
const DynamicMechanic = React.lazy(() =>
  import(`@/features/mechanics/${mechanicType}`)
);

// DO: Memoizar cálculos pesados
const expNeeded = useMemo(() =>
  calculateNextRankXP(currentRank),
  [currentRank]
);

// DO: Debounce en búsquedas
const debouncedSearch = useDebounce(searchQuery, 300);

11.2 Backend

11.2.1 Controllers

// DO: DTOs con validación completa
@Post('submit')
@ApiOperation({ summary: 'Submit exercise completion' })
@ApiOkResponse({ type: SubmissionResultDto })
async submitExercise(
  @CurrentUser() user: User,
  @Param('exerciseId') exerciseId: string,
  @Body() dto: SubmitExerciseDto,
): Promise<SubmissionResultDto> {
  return this.submissionService.submitExercise(user.id, exerciseId, dto);
}

11.2.2 Services

// DO: Transactions para operaciones atómicas
async submitExercise(userId: string, dto: SubmitExerciseDto) {
  return this.dataSource.transaction(async (manager) => {
    // 1. Crear submission
    const submission = await manager.save(ExerciseSubmission, {...});

    // 2. Actualizar progreso
    await manager.update(ModuleProgress, {...});

    // 3. Otorgar XP y ML Coins
    await this.grantRewards(userId, submission, manager);

    // 4. Check achievements
    await this.checkAchievements(userId, submission, manager);

    return submission;
  });
}

11.2.3 Optimización

// DO: Eager loading para evitar N+1 queries
const exercises = await this.exercisesRepo.find({
  where: { module_id: moduleId },
  relations: ['module', 'submissions'],
});

// DO: Cache para datos que cambian poco
@Cacheable('ranks', 3600) // 1 hora
async getRanks(): Promise<Rank[]> {
  return this.ranksRepo.find();
}

12. Testing

12.1 Tests Unitarios Frontend

// useDashboardData.test.ts
describe('useDashboardData', () => {
  it('should fetch dashboard data successfully', async () => {
    const { result } = renderHook(() => useDashboardData(), {
      wrapper: createWrapper(),
    });

    await waitFor(() => {
      expect(result.current.loading).toBe(false);
    });

    expect(result.current.rank).toBeDefined();
    expect(result.current.coins).toBeDefined();
  });
});

12.2 Tests de Integración

// ExerciseSubmission.integration.test.ts
describe('Exercise Submission Flow', () => {
  it('should complete exercise and grant rewards', async () => {
    const user = await createTestUser();
    const exercise = await createTestExercise();

    const response = await request(app.getHttpServer())
      .post(`/progress/exercises/${exercise.id}/submit`)
      .set('Authorization', `Bearer ${user.token}`)
      .send({
        answers: { q1: 'correct' },
        timeSpent: 120,
        hintsUsed: 0,
      })
      .expect(201);

    expect(response.body.xpEarned).toBeGreaterThan(0);
    expect(response.body.mlCoinsEarned).toBeGreaterThan(0);
  });
});

13. Checklist de Desarrollo

13.1 Nueva Funcionalidad

  • Definir types en student/types/ o @shared/types
  • Crear/actualizar DTOs en backend
  • Implementar service en backend
  • Crear/modificar controller con guards
  • Agregar validaciones (class-validator)
  • Crear API service en frontend
  • Implementar custom hook si necesario
  • Crear componentes UI necesarios
  • Integrar en página correspondiente
  • Agregar tests unitarios
  • Probar responsive (mobile, tablet, desktop)
  • Documentar en Swagger (decoradores)
  • Actualizar esta guía si aplica

13.2 Code Review

  • Types alineados frontend/backend
  • Guards aplicados correctamente (JwtAuth mínimo)
  • Validación de DTOs completa
  • Error handling implementado
  • React Query keys descriptivas
  • Invalidación de cache correcta después de mutations
  • Loading y error states manejados
  • Responsive design verificado
  • Accessibility (ARIA labels, keyboard navigation)
  • Performance optimizado (memo, lazy load)

14. Troubleshooting

14.1 Problemas Comunes

Problema Causa Probable Solución
401 Unauthorized Token JWT expirado/inválido Renovar token con refresh endpoint
Data desactualizada Cache no invalidado queryClient.invalidateQueries()
Types mismatch Desync FE/BE Regenerar types desde DTOs backend
Exercise no se guarda Auto-save disabled Verificar enabled en useExerciseAutoSave
XP no se actualiza Estado local no sincroniza Llamar refresh() de useDashboardData
Achievements no se desbloquean Condiciones no se cumplen Verificar lógica en backend service
Power-up no aplica Item no en inventory Verificar inventario antes de usar

14.2 Debugging

// Habilitar logs de React Query en dev
if (import.meta.env.DEV) {
  import('@tanstack/react-query-devtools').then(({ ReactQueryDevtools }) => {
    // Montar devtools
  });
}

// Log de API calls
apiClient.interceptors.request.use((config) => {
  console.log(`[API] ${config.method?.toUpperCase()} ${config.url}`);
  return config;
});

// Log de state changes (Zustand)
devtools(storeImpl, { name: 'RanksStore' })

15. Performance y Optimización

15.1 Frontend Optimization

Lazy Loading de Rutas:

const DashboardComplete = lazy(() => import('./pages/DashboardComplete'));
const ExercisePage = lazy(() => import('./pages/ExercisePage'));
const GamificationPage = lazy(() => import('./pages/GamificationPage'));

<Suspense fallback={<PageLoader />}>
  <Routes>
    <Route path="/" element={<DashboardComplete />} />
    <Route path="/exercises/:id" element={<ExercisePage />} />
    <Route path="/gamification" element={<GamificationPage />} />
  </Routes>
</Suspense>

Code Splitting:

// Dynamic imports for mechanics
const loadMechanic = (type: string) => {
  return import(`@/features/mechanics/${type}/${type}Exercise`);
};

Image Optimization:

  • Usar WebP para imágenes modernas
  • Lazy load de imágenes con loading="lazy"
  • Sprites para iconos pequeños

15.2 Backend Optimization

Database Indexing:

-- Indices críticos
CREATE INDEX idx_exercise_submissions_user ON progress.exercise_submissions(user_id);
CREATE INDEX idx_user_stats_total_xp ON gamification.user_stats(total_xp DESC);
CREATE INDEX idx_achievements_trigger ON gamification.achievements(trigger);

Query Optimization:

// Usar select específico en vez de SELECT *
const stats = await this.userStatsRepo.findOne({
  where: { user_id: userId },
  select: ['total_xp', 'total_ml_coins', 'current_streak'],
});

Caching:

  • Redis para leaderboards (TTL 5 min)
  • Cache de ranks/achievements (TTL 1 hora)
  • Invalidación al actualizar datos

16. Seguridad

16.1 Autenticación y Autorización

Guards:

  • JwtAuthGuard: TODOS los endpoints (excepto public)
  • RolesGuard: Si endpoint específico para rol

Validación de Ownership:

// Verificar que submission pertenece al usuario
const submission = await this.submissionRepo.findOne({
  where: {
    id: submissionId,
    user_id: userId // CRÍTICO
  }
});

if (!submission) {
  throw new ForbiddenException('Not your submission');
}

16.2 Validación de Datos

// DTOs con class-validator
export class SubmitExerciseDto {
  @IsObject()
  @ValidateNested()
  answers!: Record<string, any>;

  @IsNumber()
  @Min(0)
  @Max(7200) // Max 2 horas
  timeSpent!: number;

  @IsNumber()
  @Min(0)
  @Max(10)
  hintsUsed!: number;
}

16.3 Rate Limiting

// Exercise submission: max 100/día por usuario
@ThrottlerGuard({ limit: 100, ttl: 86400 })
@Post('submit')
async submitExercise(...) { ... }

17. Referencias

Documentos Complementarios del Portal Student

Documento Descripción
EXERCISE-MECHANICS-REFERENCE.md Referencia completa de 30+ mecánicas implementadas
GAMIFICATION-SYSTEM-GUIDE.md Sistema de gamificación en profundidad
STUDENT-API-REFERENCE.md Referencia de 60+ APIs con ejemplos

Guías Generales

Documentación de Arquitectura


Changelog

Versión Fecha Cambios
1.0.0 2025-11-29 Creación inicial - Documentación completa del Portal Student

Mantenido por: Tech Lead - GAMILIT Project Última revisión: 2025-11-29