🌲 Explicación Detallada del Tree

Guía completa de cada carpeta y archivo de tu proyecto KENDI

📂 Tu Estructura Actual
lib/ ├── core/ # Componentes compartidos globalmente │ ├── constants/ │ │ └── education_systems/ # Niveles educativos por país │ │ ├── bo.json # Bolivia │ │ ├── br.json # Brasil │ │ ├── main.txt │ │ └── py.json # Paraguay │ ├── models/ # Modelos de datos básicos │ │ ├── country_model.dart │ │ └── grade_model.dart │ ├── router/ # Navegación de la app │ │ ├── app_router.dart │ │ └── routes/ │ │ ├── admin_routes.dart │ │ ├── auth_routes.dart │ │ ├── student_routes.dart │ │ └── teacher_routes.dart │ ├── services/ │ │ └── education_system_service.dart │ ├── themes/ # Vacío (para estilos globales) │ └── utils/ # Vacío (para helpers) │ ├── features/ # Módulos funcionales (Clean Architecture) │ ├── auth/ # ✅ COMPLETO │ ├── competitions/ # ❌ VACÍO │ ├── home/ │ ├── kendi_dashboard/ # ✅ COMPLETO (CRUD Menús) │ ├── student_dashboard/ # ⚠️ SOLO UI │ ├── supervisor_dashboard/ # ❌ VACÍO │ └── teacher_dashboard/ # ❌ VACÍO │ ├── shared/ # Widgets/componentes reutilizables │ ├── constants/ │ │ └── icons_catalog.dart │ ├── models/ │ │ └── kendi_icon_model.dart │ └── widgets/ │ └── icon_selector_widget.dart │ ├── firebase_options.dart # Config de Firebase └── main.dart # Punto de entrada
🔷 1. CORE - Núcleo Compartido
💡 ¿Qué es CORE?
Todo lo que es fundamental y se usa en TODA la aplicación. No pertenece a ningún feature específico.
📁 core/constants/education_systems/
lib/core/constants/education_systems/
Aquí están definidos los 18 niveles educativos para cada país (Bolivia, Brasil, Paraguay). Son archivos JSON estáticos que no se modifican.
📄 bo.json
Bolivia: Define los 18 niveles del sistema educativo boliviano.
[ { "id": "maternal", "nombre": "Maternal", "edad_min": 3, "edad_max": 3, "categoria": "inicial" }, { "id": "prejardin", "nombre": "Prejardín", "edad_min": 3, "edad_max": 4, "categoria": "inicial" } // ... hasta 18 niveles ]
📄 py.json y br.json
Misma estructura pero adaptada a Paraguay y Brasil respectivamente.
✅ Esto ya funciona: Estos niveles se usan en todo el sistema para validar que el contenido se asigna al nivel correcto.
📁 core/models/
lib/core/models/
Modelos de datos fundamentales que representan conceptos básicos del sistema.
📄 country_model.dart
Modelo de País: Representa un país (BO, BR, PY).
class CountryModel { final String id; // 'bo', 'py', 'br' final String nombre; // 'Bolivia' final String codigo; // 'BO' final String bandera; // '🇧🇴' // Métodos: toJson(), fromJson(), toEntity() }
📄 grade_model.dart
Modelo de Grado/Nivel: Representa uno de los 18 niveles educativos.
class GradeModel { final String id; // 'preescolar' final String nombre; // 'Preescolar' final int edadMin; // 5 final int edadMax; // 6 final String categoria; // 'inicial' // Métodos: toJson(), fromJson() }
🔗 Cómo se relacionan:

El education_system_service lee los JSON (bo.json, py.json) y los convierte en objetos GradeModel para usarlos en toda la app.

📁 core/router/
lib/core/router/
Sistema de navegación de toda la aplicación. Define cómo el usuario navega entre pantallas.
📄 app_router.dart
Router Principal: Configura toda la navegación. Probablemente usa go_router o auto_route.
class AppRouter { static final router = GoRouter( routes: [ ...authRoutes, // Login, Register, etc. ...studentRoutes, // Dashboard estudiante ...teacherRoutes, // Dashboard docente ...adminRoutes, // Panel admin ], redirect: (context, state) { // Lógica de autenticación // Si no está logueado → /login // Si es estudiante → /student/dashboard // Si es docente → /teacher/dashboard } ); }
📂 routes/ (Subcarpeta)
📄 auth_routes.dart
Define las rutas de autenticación:
final authRoutes = [ GoRoute( path: '/login', builder: (context, state) => LoginPage(), ), GoRoute( path: '/register', builder: (context, state) => SelectUserTypePage(), ), GoRoute( path: '/register/student', builder: (context, state) => RegisterStudentPage(), ), // etc... ];
📄 student_routes.dart
Rutas del estudiante:
final studentRoutes = [ GoRoute( path: '/student/dashboard', builder: (context, state) => StudentDashboardPage(), ), GoRoute( path: '/student/menu/:menuId', builder: (context, state) { final menuId = state.params['menuId']; return MenuDetailPage(menuId: menuId); }, ), ];
📄 teacher_routes.dart y admin_routes.dart
Misma idea pero para docentes y admins.
💡 Ventaja: Separar rutas por rol permite agregar guards de autenticación específicos. Por ejemplo, solo usuarios con rol "teacher" pueden acceder a /teacher/*.
📁 core/services/
lib/core/services/
📄 education_system_service.dart
Servicio de Sistemas Educativos: Lee los JSON de education_systems y proporciona métodos para obtener niveles.
class EducationSystemService { List<GradeModel> _grades = []; // Lee el JSON según el país Future<void> loadGrades(String countryCode) async { // Lee bo.json, py.json o br.json final json = await rootBundle.loadString( 'lib/core/constants/education_systems/$countryCode.json' ); // Convierte a List _grades = (jsonDecode(json) as List) .map((e) => GradeModel.fromJson(e)) .toList(); } // Obtiene todos los niveles List<GradeModel> getAllGrades() => _grades; // Obtiene niveles por categoría List<GradeModel> getGradesByCategory(String category) { return _grades.where((g) => g.categoria == category).toList(); } // Busca un nivel por ID GradeModel? getGradeById(String id) { return _grades.firstWhere((g) => g.id == id); } }
✅ Uso en la app:
Cuando el usuario selecciona su país al registrarse, se carga el JSON correspondiente. Luego, en todo el sistema se usan estos niveles para validar y mostrar opciones.
📁 core/themes/ y core/utils/
lib/core/themes/ y lib/core/utils/
Actualmente vacías. Aquí irían:
  • themes/: Temas de colores, tipografías, estilos globales (ThemeData)
  • utils/: Funciones helper, extensiones, constantes globales, validators, formatters
🎯 2. FEATURES - Módulos Funcionales
💡 Clean Architecture:
Cada feature se divide en 3 capas:
  • data/ - Conexión con APIs, Firebase, bases de datos
  • domain/ - Lógica de negocio pura (sin dependencias de Flutter/Firebase)
  • presentation/ - UI + Gestión de estado (BLoC)
📁 features/auth/ ✅ COMPLETO
lib/features/auth/
Módulo de autenticación. Maneja login, registro (múltiples tipos), recuperación de contraseña, verificación.
📂 data/
📂 datasources/
Probablemente tiene AuthRemoteDataSource que se conecta a Firebase Auth:
class AuthRemoteDataSource { final FirebaseAuth _auth; Future<UserModel> login(String email, String password) async { final credential = await _auth.signInWithEmailAndPassword( email: email, password: password ); return UserModel.fromFirebase(credential.user); } // register(), logout(), resetPassword(), etc. }
📂 models/
UserModel - Modelo que representa un usuario con métodos toJson(), fromJson(), toEntity()
📂 repositories/
AuthRepositoryImpl - Implementación del repositorio que usa el datasource
📂 domain/
📂 entities/
User - Entidad pura (sin dependencias de Firebase):
class User { final String id; final String email; final String name; final String role; // 'student', 'teacher', 'admin' final String? gradeId; User({required this.id, ...}); }
📂 repositories/
AuthRepository - Interfaz (contrato):
abstract class AuthRepository { Future<User> login(String email, String password); Future<User> register(RegisterData data); Future<void> logout(); }
📂 usecases/
Casos de uso individuales (una acción = un usecase):
  • LoginUseCase
  • RegisterStudentUseCase
  • RegisterTeacherUseCase
  • ForgotPasswordUseCase
  • VerifyCodeUseCase
📂 presentation/
📂 bloc/
Gestión de estado con BLoC:
  • auth_bloc.dart - Lógica
  • auth_event.dart - Eventos (LoginPressed, RegisterPressed)
  • auth_state.dart - Estados (Initial, Loading, Success, Error)
📂 pages/
Las pantallas:
  • login_page.dart - Login
  • forgot_password_page.dart - Recuperar contraseña
  • select_user_type_page.dart - Elegir tipo de usuario
  • select_grade_page.dart - Elegir nivel educativo
  • verify_code_page.dart - Verificar código
  • register/register_student_page.dart - Registro estudiante
  • register/register_teacher_page.dart - Registro docente
  • etc...
📂 widgets/
Widgets específicos del registro:
  • student/student_step1_form.dart - Paso 1 del registro estudiante
  • student/student_step2_form.dart - Paso 2
  • teacher/teacher_step1_form.dart - Paso 1 del registro docente
  • teacher/teacher_step2_form.dart - Paso 2
  • teacher/teacher_step3_form.dart - Paso 3
  • teacher/teacher_step4_form.dart - Paso 4
✅ Resultado: Sistema de autenticación completo y funcional con múltiples tipos de usuario y registro por pasos.
📁 features/kendi_dashboard/ ✅ COMPLETO
lib/features/kendi_dashboard/
EL MÁS IMPORTANTE: Gestión de Menús y Submenús. Aquí el docente crea la navegación (COLORES, NÚMEROS, etc.).
📂 data/
📄 menu_remote_datasource.dart
Conexión con Firebase para CRUD de menús:
class MenuRemoteDataSource { final FirebaseFirestore _firestore; Future<void> createMenu(MenuModel menu) async { await _firestore .collection('menus') .doc(menu.id) .set(menu.toJson()); } Future<List<MenuModel>> getMenusByLevel(String nivel) async { final snapshot = await _firestore .collection('menus') .where('nivel', isEqualTo: nivel) .get(); return snapshot.docs .map((doc) => MenuModel.fromJson(doc.data())) .toList(); } // updateMenu(), deleteMenu(), createSubmenu(), etc. }
📄 menu_model.dart
Modelo de menú:
class MenuModel { final String id; final String nivel; final String nombre; // "COLORES" final String icono; // "🌈" final String? descripcion; final List<SubmenuModel> submenus; Map<String, dynamic> toJson() => {...}; factory MenuModel.fromJson(Map<String, dynamic> json) => ...; }
📄 submenu_model.dart
Modelo de submenú:
class SubmenuModel { final String id; final String menuId; final String nombre; // "Primarios" final int orden; }
📂 domain/ y presentation/

Similar estructura a auth con entidades, repositorios, usecases, bloc, pages.

📂 presentation/pages/
Pantallas principales:
  • select_level_page.dart - Seleccionar uno de los 18 niveles
  • menus_grid_page.dart - Ver todos los menús del nivel
  • create_menu_page.dart - Crear menú nuevo
  • create_submenu_page.dart - Crear submenú
✅ Resultado: El docente puede crear menús (COLORES, NÚMEROS) y submenús (Primarios, Secundarios) para cada nivel educativo.
⚠️ LO QUE FALTA: Los menús están vacíos. No hay contenido asignado todavía. Eso lo haremos con el módulo de Bancos y Asignaciones.
📁 features/student_dashboard/ ⚠️ SOLO UI
lib/features/student_dashboard/
Dashboard del estudiante. Tiene widgets visuales pero sin lógica de negocio.
📂 presentation/pages/
student_dashboard_page.dart - Pantalla principal del estudiante
📂 presentation/widgets/
Widgets de UI:
  • student_header.dart - Header con foto y nombre
  • achievement_card.dart - Tarjeta de logro
  • progress_by_subject_card.dart - Progreso por materia
  • quick_actions_row.dart - Botones de acciones rápidas
  • top_of_class_card.dart - Ranking de clase
⚠️ PROBLEMA: Las carpetas data/ y domain/ están vacías. Los widgets probablemente muestran datos hardcodeados. Falta implementar la lógica real.
📁 Otros Features ❌ VACÍOS
  • competitions/ - Solo estructura, sin implementación
  • home/ - Probablemente pantalla inicial básica
  • supervisor_dashboard/ - Vacío completamente
  • teacher_dashboard/ - Vacío completamente
🔄 3. SHARED - Componentes Reutilizables
📁 shared/
lib/shared/
Widgets, modelos y constantes que se usan en MÚLTIPLES features.
📄 constants/icons_catalog.dart
Catálogo de iconos disponibles para menús:
class IconsCatalog { static final Map<String, String> icons = { 'colores': '🌈', 'numeros': '🔢', 'animales': '🐶', 'letras': '🔤', 'musica': '🎵', // etc... }; }
📄 models/kendi_icon_model.dart
Modelo para representar un icono:
class KendiIconModel { final String id; final String nombre; final String icono; // emoji o icon code final String? categoria; }
📄 widgets/icon_selector_widget.dart
Widget reutilizable para seleccionar un icono:
class IconSelectorWidget extends StatelessWidget { final Function(String) onIconSelected; // Muestra un grid con todos los iconos del catálogo // Al hacer click, llama onIconSelected(iconId) @override Widget build(BuildContext context) { return GridView.builder( itemCount: IconsCatalog.icons.length, itemBuilder: (context, index) { final icon = IconsCatalog.icons.values.elementAt(index); return GestureDetector( onTap: () => onIconSelected(icon), child: Text(icon, style: TextStyle(fontSize: 40)), ); }, ); } }
💡 Uso: Este widget se usa en create_menu_page cuando el docente necesita elegir un icono para su menú.
🚀 4. Archivos en la Raíz
📄 main.dart
lib/main.dart
Punto de entrada de la aplicación. Aquí se inicializa todo:
void main() async { WidgetsFlutterBinding.ensureInitialized(); // Inicializa Firebase await Firebase.initializeApp( options: DefaultFirebaseOptions.currentPlatform, ); // Inicializa servicios (ej: EducationSystemService) await setupServices(); // Corre la app runApp(const MyApp()); } class MyApp extends StatelessWidget { @override Widget build(BuildContext context) { return MaterialApp.router( title: 'KENDI', routerConfig: AppRouter.router, // El router que definimos en core/ theme: ThemeData(...), ); } }
📄 firebase_options.dart
lib/firebase_options.dart
Configuración de Firebase. Generado automáticamente por FlutterFire CLI.
// Auto-generado por: flutterfire configure class DefaultFirebaseOptions { static FirebaseOptions get currentPlatform { if (Platform.isAndroid) return android; if (Platform.isIOS) return ios; if (kIsWeb) return web; throw UnsupportedError('Platform not supported'); } static const FirebaseOptions android = FirebaseOptions( apiKey: '...', appId: '...', messagingSenderId: '...', projectId: 'kendi-app', // etc... ); }
📊 RESUMEN VISUAL
🔗 Cómo se Relaciona Todo:
FLUJO TÍPICO:
1. Usuario abre la app → main.dart inicializa Firebase
2. AppRouter verifica si está logueado
3. Si no → Redirige a /login (auth feature)
4. Usuario se loguea → AuthBloc maneja el estado
5. AuthRemoteDataSource llama a Firebase Auth
6. Si es estudiante → Redirige a /student/dashboard
7. Dashboard carga los menús de su nivel usando EducationSystemService
8. Estudiante hace click en un menú → Carga actividades (FALTA IMPLEMENTAR)
✅ AHORA YA SABES:
  • Qué hace cada carpeta y archivo
  • Cómo se organiza el código (Clean Architecture)
  • Qué está implementado y qué falta
  • Cómo fluye la información entre capas
  • Dónde agregar nuevos módulos (Bancos, Asignaciones)
🎯 SIGUIENTE PASO:

Ahora que entiendes tu estructura actual, vamos a diseñar cómo agregar el módulo de Bancos de Contenido siguiendo exactamente el mismo patrón que kendi_dashboard.

🎉 ¡Perfecto!

Ahora conoces tu código a la perfección

Estás listo para implementar los módulos que faltan 💪