workspace/projects/gamilit/docs/95-guias-desarrollo/frontend/ESTRUCTURA-FEATURES.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

11 KiB

Estructura de Features Frontend

Versión: 1.1.0 Última Actualización: 2025-11-29 Aplica a: apps/frontend/src/features/


Resumen

El frontend de GAMILIT organiza la funcionalidad en "features" - módulos autocontenidos que agrupan componentes, hooks, stores y servicios relacionados con un dominio específico.


Features Disponibles (12 total)

Feature Ubicación Descripción
admin features/admin/ Panel administrativo
assignments features/assignments/ Tareas asignadas a estudiantes
auth features/auth/ Login, registro, recuperación de contraseña
content features/content/ Gestión de contenido educativo
exercises features/exercises/ Visualización y resolución de ejercicios
gamification features/gamification/ Logros, rangos, ML Coins, leaderboard
mechanics features/mechanics/ 23 mecánicas de ejercicios organizadas por módulo
missions features/missions/ Misiones diarias y semanales
notifications features/notifications/ Centro de notificaciones
progress features/progress/ Seguimiento de progreso del estudiante
social features/social/ Aulas, equipos, retos (en apps/)
teacher features/teacher/ Portal del docente (en apps/)

Estructura Estándar de una Feature

features/ejemplo/
├── components/              # Componentes React específicos
│   ├── EjemploCard.tsx
│   ├── EjemploList.tsx
│   ├── EjemploForm.tsx
│   └── index.ts            # Barrel exports
├── hooks/                   # Custom hooks
│   ├── useEjemplo.ts
│   ├── useEjemploMutation.ts
│   └── index.ts
├── services/                # API calls
│   ├── ejemplo.service.ts
│   └── index.ts
├── stores/                  # Zustand stores (si aplica)
│   ├── ejemplo.store.ts
│   └── index.ts
├── types/                   # TypeScript types/interfaces
│   ├── ejemplo.types.ts
│   └── index.ts
├── utils/                   # Utilidades específicas
│   └── ejemplo.utils.ts
├── pages/                   # Páginas de la feature (si tiene rutas)
│   └── EjemploPage.tsx
└── index.ts                 # Barrel export principal

Ejemplos de Features

auth/

features/auth/
├── components/
│   ├── LoginForm.tsx
│   ├── RegisterForm.tsx
│   ├── ForgotPasswordForm.tsx
│   └── PasswordStrengthIndicator.tsx
├── hooks/
│   ├── useAuth.ts           # Estado de autenticación
│   ├── useLogin.ts          # Mutación de login
│   └── useRegister.ts       # Mutación de registro
├── services/
│   └── auth.service.ts      # Llamadas a API
├── stores/
│   └── auth.store.ts        # Zustand store para auth
├── types/
│   ├── auth.types.ts        # LoginDto, UserResponse, etc.
│   └── index.ts
└── index.ts

gamification/

features/gamification/
├── components/
│   ├── AchievementCard.tsx
│   ├── AchievementList.tsx
│   ├── RankBadge.tsx
│   ├── XpProgressBar.tsx
│   ├── MlCoinsDisplay.tsx
│   ├── LeaderboardTable.tsx
│   └── ComodinCard.tsx
├── hooks/
│   ├── useUserStats.ts
│   ├── useAchievements.ts
│   ├── useLeaderboard.ts
│   ├── useComodines.ts
│   └── usePurchaseComodin.ts
├── services/
│   ├── gamification.service.ts
│   ├── achievements.service.ts
│   └── leaderboard.service.ts
├── types/
│   ├── user-stats.types.ts
│   ├── achievement.types.ts
│   ├── rank.types.ts
│   └── comodin.types.ts
└── index.ts

exercises/

features/exercises/
├── components/
│   ├── ExerciseRenderer.tsx     # Renderiza según tipo
│   ├── ExerciseProgress.tsx
│   ├── FeedbackDisplay.tsx
│   └── mechanics/               # Componentes por mecánica
│       ├── TimelineExercise.tsx
│       ├── FillInBlankExercise.tsx
│       ├── TrueFalseExercise.tsx
│       ├── WordSearchExercise.tsx
│       └── ... (23 tipos)
├── hooks/
│   ├── useExercise.ts
│   ├── useSubmitAnswer.ts
│   └── useExerciseTimer.ts
├── services/
│   └── exercises.service.ts
└── types/
    ├── exercise.types.ts
    └── answer.types.ts

mechanics/ (NUEVO v1.1)

Feature que contiene las 23 mecánicas de ejercicios organizadas por módulo curricular.

features/mechanics/
├── index.ts                     # Barrel export de todas las mecánicas
├── shared/                      # Componentes compartidos entre mecánicas
│   ├── FeedbackModal.tsx
│   ├── TimerDisplay.tsx
│   └── ScoreDisplay.tsx
├── auxiliar/                    # Mecánicas auxiliares
│   ├── CrucigramaExercise/
│   ├── SopaLetrasExercise/
│   └── ...
├── module1/                     # Mecánicas del Módulo 1
│   ├── TimelineExercise/
│   ├── FillInBlankExercise/
│   ├── TrueFalseExercise/
│   └── ...
├── module2/                     # Mecánicas del Módulo 2
│   ├── CauseEffectMatching/
│   ├── DetectiveTextual/
│   └── ...
├── module3/                     # Mecánicas del Módulo 3
├── module4/                     # Mecánicas del Módulo 4
└── module5/                     # Mecánicas del Módulo 5

Nota: Cada mecánica tiene su propia carpeta con:

  • Componente principal (*.tsx)
  • Types locales (types.ts)
  • Estilos específicos (si aplica)

missions/ (NUEVO v1.1)

Feature para misiones diarias y semanales.

features/missions/
├── store/
│   └── missionsStore.ts         # Zustand store para misiones
├── MIGRATION-GUIDE.md           # Guía de migración desde API deprecated
└── (componentes migrados desde gamification/missions/)

Nota: Los types de Mission están en @features/gamification/missions/types/missionsTypes.ts (SSOT).

assignments/ (NUEVO v1.1 - P1-002)

Feature para tareas asignadas a estudiantes.

features/assignments/
└── store/
    └── studentAssignmentsStore.ts  # Zustand store para assignments de estudiante

API: @services/api/studentAssignmentsAPI.ts Página: @apps/student/pages/AssignmentsPage.tsx


Patrones de Componentes

Componente con Hook de Datos

// features/gamification/components/AchievementList.tsx
import { useAchievements } from '../hooks/useAchievements';
import { AchievementCard } from './AchievementCard';

export const AchievementList: React.FC = () => {
  const { data: achievements, isLoading, error } = useAchievements();

  if (isLoading) return <LoadingSpinner />;
  if (error) return <ErrorMessage error={error} />;

  return (
    <div className="grid grid-cols-2 gap-4">
      {achievements?.map((achievement) => (
        <AchievementCard key={achievement.id} achievement={achievement} />
      ))}
    </div>
  );
};

Componente Presentacional

// features/gamification/components/RankBadge.tsx
import { MayaRank } from '../types/rank.types';

interface RankBadgeProps {
  rank: MayaRank;
  size?: 'sm' | 'md' | 'lg';
  showLabel?: boolean;
}

export const RankBadge: React.FC<RankBadgeProps> = ({
  rank,
  size = 'md',
  showLabel = true,
}) => {
  const sizeClasses = {
    sm: 'w-8 h-8',
    md: 'w-12 h-12',
    lg: 'w-16 h-16',
  };

  return (
    <div className="flex items-center gap-2">
      <img
        src={rank.iconUrl}
        alt={rank.name}
        className={sizeClasses[size]}
      />
      {showLabel && <span className="font-medium">{rank.name}</span>}
    </div>
  );
};

Barrel Exports

feature/index.ts

// features/gamification/index.ts

// Components
export { AchievementCard } from './components/AchievementCard';
export { AchievementList } from './components/AchievementList';
export { RankBadge } from './components/RankBadge';
export { XpProgressBar } from './components/XpProgressBar';
export { MlCoinsDisplay } from './components/MlCoinsDisplay';

// Hooks
export { useUserStats } from './hooks/useUserStats';
export { useAchievements } from './hooks/useAchievements';
export { useLeaderboard } from './hooks/useLeaderboard';

// Types
export type { UserStats, Achievement, MayaRank } from './types';

Uso en otros lugares

// Importar desde la feature
import { RankBadge, useUserStats } from '@/features/gamification';

// NO importar archivos internos directamente
// import { RankBadge } from '@/features/gamification/components/RankBadge'; ❌

Comunicación Entre Features

Usando Stores Compartidos

// En gamification: actualizar stats después de logro
const { refetchStats } = useUserStats();
await grantAchievement(achievementId);
refetchStats();

Usando Eventos

// features/exercises/hooks/useSubmitAnswer.ts
import { useQueryClient } from '@tanstack/react-query';

export const useSubmitAnswer = () => {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: submitAnswer,
    onSuccess: (result) => {
      // Invalidar queries de otras features
      queryClient.invalidateQueries({ queryKey: ['user-stats'] });
      queryClient.invalidateQueries({ queryKey: ['achievements'] });
    },
  });
};

Páginas y Rutas

Las páginas de cada feature se registran en el router principal:

// src/router/index.tsx
import { DashboardPage } from '@/features/dashboard/pages/DashboardPage';
import { ExercisePage } from '@/features/exercises/pages/ExercisePage';
import { AchievementsPage } from '@/features/gamification/pages/AchievementsPage';

const routes = [
  { path: '/dashboard', element: <DashboardPage /> },
  { path: '/exercises/:id', element: <ExercisePage /> },
  { path: '/achievements', element: <AchievementsPage /> },
];

Buenas Prácticas

  1. Feature = Dominio: Una feature por dominio de negocio
  2. Autocontenida: Cada feature debe funcionar independientemente
  3. Barrel exports: Usar index.ts para exponer API pública
  4. No imports cruzados internos: Usar exports públicos entre features
  5. Colocalizar tests: __tests__/ junto a lo que prueban
  6. Types propios: Cada feature define sus propios tipos
  7. Hooks para lógica: Extraer lógica a custom hooks

Ver También


Changelog

Versión Fecha Cambios
1.1.0 2025-11-29 Añadidas features: mechanics, missions, assignments
1.0.0 2025-11-28 Versión inicial