Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/andrespaul123/micole-flutter/llms.txt

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

Mi Cole is organised around a strict feature-first architecture: every functional area of the app lives in its own self-contained directory under lib/feature/, carrying its own model, repository, view-model, and screens. Shared infrastructure — the HTTP client, secure storage, router, layout shell, and utility helpers — lives under lib/core/. This separation makes it straightforward to add, remove, or test a feature without touching the rest of the app.

Directory Structure

lib/
├── main.dart                          # App entry point, MultiProvider setup

├── core/
│   ├── dio/
│   │   └── dio_client.dart            # Dio singleton + auth interceptor
│   ├── router/
│   │   └── app_router.dart            # GoRouter definition + redirectToLogin()
│   ├── storage/
│   │   └── secure_storage.dart        # JWT session persistence (mobile + web)
│   ├── layout/
│   │   ├── main_layout.dart           # Shell: AppBar + BottomNavigationBar
│   │   └── home_dashboard.dart        # Role-aware home screen
│   ├── utils/
│   │   └── api_error_handler.dart     # DioException → human-readable message
│   └── widgest/                       # Shared UI widgets (AuthCard, AuthInput, …)

└── feature/
    ├── login/                         # Authentication
    │   ├── users.dart                 # Users model (id, name, email, token, roles)
    │   ├── auth_repository.dart       # POST /auth/login, /auth/register, /auth/logout
    │   ├── auth_viewmodel.dart        # AuthViewModel (ChangeNotifier)
    │   └── screens/
    │       ├── login_screen.dart
    │       └── register_screen.dart

    ├── tenant/                        # Super-admin: school management
    ├── subject/                       # Director: subjects (materias)
    ├── curso/                         # Director: grade levels (cursos)
    ├── paralelo/                      # Director: class sections (paralelos)
    ├── periodo_academico/             # Director: academic periods
    ├── periodo_evaluacion/            # Director: evaluation periods
    ├── asignacion_horario/            # Director: teacher–subject–schedule mapping
    ├── inscripcion/                   # Director: student enrollment
    ├── circulares/                    # Director: school-wide announcements
    ├── modulos/                       # Super-admin: per-tenant module flags

    ├── profesor/                      # Teacher management
    ├── estudiante/                    # Student management + student-facing features
    │   ├── estudiante_horario/        # Student timetable
    │   ├── estudiante_materias/       # Student subject list + detail
    │   ├── estudiante_agenda/         # Student tasks & exams
    │   │   └── entrega_tarea/         # Task submission flow
    │   └── estudiante_biblioteca/     # Resource library
    ├── padre/                         # Parent management + parent-facing features
    ├── padre_agenda/                  # Parent: child's agenda view
    ├── padre_asistencia/              # Parent: child's attendance view
    ├── padre_anecdotario/             # Parent: child's anecdote view
    ├── padre_nota/                    # Parent: child's grades view

    ├── agenda/                        # Teacher: agenda / task creation
    ├── anecdotario/                   # Teacher: anecdotal records
    ├── asistencia/                    # Teacher: attendance recording
    ├── libro_calificaciones/          # Teacher: grade book
    └── criterio/                      # Teacher: grading criteria

Feature Module Pattern

Every feature follows the same four-layer convention, illustrated here with the login feature:
feature/login/
├── users.dart              ← Model:      plain Dart class, fromJson factory
├── auth_repository.dart    ← Repository: Dio calls, returns model objects
├── auth_viewmodel.dart     ← ViewModel:  ChangeNotifier, calls repo, holds state
└── screens/
    ├── login_screen.dart   ← Screen:     reads ViewModel via Provider.of / Consumer
    └── register_screen.dart
LayerResponsibility
ModelImmutable data class. Parses API JSON via a fromJson factory.
RepositoryRaw API calls using the shared Dio instance. Returns typed model objects.
ViewModelChangeNotifier that calls the repository, manages loading/error state, and calls notifyListeners().
ScreenFlutter Widget that reads the ViewModel with Provider.of<T>(context) and dispatches actions back to it.

Data Flow

Interactions travel in one direction through the stack:
User Action (Widget)


ViewModel.method()          ← ChangeNotifier, calls notifyListeners()


Repository.apiCall()        ← returns typed model


DioClient (interceptor)     ← injects Bearer token, logs request


REST API  (HTTP/HTTPS)

      ▼  (response)
Repository parses JSON


ViewModel updates state


Widget rebuilds via Consumer / Provider.of
State never flows upward. Screens never call Dio directly, and repositories never hold UI state.

MultiProvider Setup

main.dart creates a single Dio instance and passes it to every repository. All ChangeNotifier view-models are registered as ChangeNotifierProvider entries in a flat MultiProvider tree, so any widget in the app can access any view-model without prop-drilling.
// lib/main.dart (simplified)

final dio = DioClient.create();
final authViewModel = AuthViewModel(repository: AuthRepository(dio));
await authViewModel.loadSession();

runApp(
  MultiProvider(
    providers: [
      ChangeNotifierProvider.value(value: authViewModel),          // Auth
      ChangeNotifierProvider(create: (_) => TenantViewModel(...)), // Tenants
      ChangeNotifierProvider(create: (_) => SubjectViewModel(...)),
      ChangeNotifierProvider(create: (_) => CursoViewModel(...)),
      ChangeNotifierProvider(create: (_) => ParaleloViewModel(...)),
      ChangeNotifierProvider(create: (_) => ProfesorViewModel(...)),
      ChangeNotifierProvider(create: (_) => EstudianteViewModel(...)),
      ChangeNotifierProvider(create: (_) => PadreFamiliaViewModel(...)),
      ChangeNotifierProvider(create: (_) => AcademicPeriodViewModel(...)
          ..loadPeriodoActivo()),                                   // eager load
      ChangeNotifierProvider(create: (_) => PeriodoEvaluacionViewModel(...)),
      ChangeNotifierProvider(create: (_) => AsignacionViewModel(...)),
      ChangeNotifierProvider(create: (_) => CircularViewModel(...)),
      ChangeNotifierProvider(create: (_) => InscripcionViewModel(...)),
      ChangeNotifierProvider(create: (_) => EstudiantesClaseViewModel(...)),
      ChangeNotifierProvider(create: (_) => AnecdotarioViewModel(...)),
      ChangeNotifierProvider(create: (_) => AsistenciaViewModel(...)),
      ChangeNotifierProvider(create: (_) => AgendaViewModel(...)),
      ChangeNotifierProvider(create: (_) => ModuleViewModel(...)),
      ChangeNotifierProvider(create: (_) => CriterioViewModel(...)),
      ChangeNotifierProvider(create: (_) => LibroCalificacionesViewModel(...)),
      ChangeNotifierProvider(create: (_) => PadreAgendaViewModel(...)),
      ChangeNotifierProvider(create: (_) => PadreAsistenciaViewModel(...)),
      ChangeNotifierProvider(create: (_) => PadreAnecdotarioViewModel(...)),
      ChangeNotifierProvider(create: (_) => EstudianteHorarioViewModel(...)),
      ChangeNotifierProvider(create: (_) => EstudianteMateriaViewModel(...)),
      ChangeNotifierProvider(create: (_) => PadreNotaViewModel(...)),
      ChangeNotifierProvider(create: (_) => EstudianteAgendaViewModel(...)),
      ChangeNotifierProvider(create: (_) => EntregaTareaViewModel(...)),
    ],
    child: MyApp(router: router),
  ),
);
AcademicPeriodViewModel calls ..loadPeriodoActivo() immediately after creation so the active academic period is available to all other view-models before the first screen renders.

Core Modules

DioClientlib/core/dio/dio_client.dart

The DioClient.create() static factory produces a configured Dio instance with:
  • A baseUrl pointing to POST /api/…
  • Default Content-Type: application/json and Accept: application/json headers
  • A 10 s connect timeout, 10 s send timeout, and 15 s receive timeout
  • An InterceptorsWrapper that reads the stored token and attaches Authorization: Bearer <token> to every outbound request
  • A 401 error handler that clears storage and calls redirectToLogin()

SecureStoragelib/core/storage/secure_storage.dart

A platform-aware static class. On mobile it delegates to FlutterSecureStorage with AndroidOptions(encryptedSharedPreferences: true). On web (kIsWeb == true) it uses SharedPreferences. Stores four keys: token, role, name, email.

AppRouterlib/core/router/app_router.dart

createRouter(authViewModel) builds a GoRouter with:
  • refreshListenable: authViewModel — the router re-evaluates the redirect callback whenever AuthViewModel calls notifyListeners()
  • A global redirect that sends unauthenticated users to /login and authenticated users away from /login//register to /home
  • A top-level ShellRoute that wraps all authenticated screens in MainLayout (AppBar + bottom navigation)
  • A module-level late GoRouter _routerInstance that exposes redirectToLogin() to the Dio interceptor without needing a BuildContext

MainLayoutlib/core/layout/

The persistent shell rendered by the ShellRoute. Displays a role-aware bottom navigation bar and an AppBar. The HomeDashboard widget inside the shell reads AuthViewModel.role to show the correct set of navigation tiles.

Dependencies

Full dependency table from pubspec.yaml:
PackageVersionPurpose
flutterSDKUI framework
flutter_localizationsSDKInternationalisation support
go_router^14.0.0Declarative routing with guards
provider^6.1.5+1InheritedWidget-based state management
dio^5.9.2HTTP client with interceptors
flutter_secure_storage^10.0.0Encrypted key-value store (mobile)
shared_preferences^2.5.3Key-value store (web fallback)
http^1.6.0Auxiliary HTTP utilities
file_picker^8.0.0File selection for uploads
url_launcher^6.3.0Open URLs / deep links
cupertino_icons^1.0.8iOS-style icon set

Build docs developers (and LLMs) love