03‐Conceptos Fundamentales - UTOQINGAPP/Arquitectura-CMI GitHub Wiki

3. Conceptos Fundamentales

La Arquitectura CMI se basa en una estructura jerárquica compuesta por Capas, Módulos, Contenedores y Enrutadores.
Estos elementos son la base de la organización y deben aplicarse de forma estricta para garantizar la coherencia, el orden y la escalabilidad del proyecto.

A continuación, se definen cada uno de estos conceptos esenciales.


3.1 Capas

Las Capas en la Arquitectura CMI representan la división estructural más rígida y fundamental.
Esta separación no es arbitraria, sino el resultado de una necesidad clara: mantener el orden a nivel macro en cualquier proyecto, sin importar su tamaño o complejidad.

En muchas arquitecturas flexibles, es común que las responsabilidades se mezclen con el tiempo, especialmente bajo presión de crecimiento o cambios rápidos.
Este desorden puede empezar de forma imperceptible —una función de lógica dentro de la interfaz, una configuración incrustada en el núcleo de la aplicación— pero a medida que el proyecto evoluciona, estas pequeñas decisiones generan una estructura difícil de mantener, escalar y entender.

CMI resuelve este problema desde el inicio estableciendo un sistema de capas fijas e inalterables que separan claramente:

  • La configuración técnica global (configs/).
  • La lógica de negocio y datos (core/).
  • Los puntos de entrada o presentación:
    • interface/ en backend (API, CLI, events) y en frontend (presentación e interacción con el usuario).

¿Por qué CMI impone capas estrictas?

  • Para evitar personalizaciones estructurales subjetivas.
  • Para mantener una organización coherente sin importar el equipo o la escala del proyecto.
  • Para asegurar que cada cambio ocurre dentro de su contexto correcto, minimizando riesgos estructurales.

Esta rigidez no es una limitación, sino una herramienta que protege la salud del proyecto a largo plazo.


Consecuencias de ignorar la separación de capas

  • Dificultad para localizar o modificar funciones específicas.
  • Aumento del acoplamiento.
  • Crecimiento desordenado donde lógica, configuración e interfaz se entrelazan.
  • Refactorizaciones costosas en etapas avanzadas.

⚠️ Ignorar la jerarquía de capas no es una mala práctica: es una ruptura directa de la arquitectura CMI.


3.2 Módulos

Los Módulos en CMI son la respuesta al crecimiento descontrolado dentro de una misma Capa.

Aunque las Capas dividen el proyecto a nivel macro, dentro de cada una el código tiende a expandirse rápidamente.
Los Módulos aíslan funcionalidades específicas dentro de cada Capa, asignando espacios definidos a cada bloque de código.


¿Por qué existen los Módulos en CMI?

  • Para dividir lógicamente cada área funcional dentro de cada Capa.
  • Para aplicar el principio de separación de responsabilidades también a nivel de organización de carpetas.
  • Para facilitar el crecimiento independiente de cada funcionalidad.
  • Para evitar los "cajones de sastre" (todo mezclado en una sola carpeta).

Diferencia con otras arquitecturas

  • En otras arquitecturas los módulos se crean a criterio del equipo → riesgo de inconsistencias.
  • En CMI los módulos son fijos (Módulos Estándar).
  • Los módulos adicionales sólo se crean si existe necesidad funcional justificada.

Errores comunes al gestionar módulos

  • No usar módulos → desorden dentro de las capas.
  • Crear módulos por costumbre sin necesidad real.
  • Duplicar funcionalidades entre módulos.
  • Omitir los enrutadores dentro de los módulos → ruptura del encapsulamiento.

¿Cuándo crear un módulo adicional?

  • Sólo cuando exista una necesidad clara de aislamiento funcional que no pueda resolverse mediante contenedores dentro de un módulo existente.
  • Crear módulos por comodidad es un error grave en CMI.

3.3 Contenedores

Los Contenedores son herramientas esenciales para mantener el orden a nivel micro dentro de cada Módulo.

Su función es organizar los tipos de archivos según sus responsabilidades.


¿Por qué son esenciales los contenedores en CMI?

  • Permiten localizar fácilmente los archivos.
  • Refuerzan la cohesión funcional.
  • Evitan carpetas arbitrarias.
  • Preparan la estructura para el crecimiento futuro.
  • Facilitan mantenibilidad y escalabilidad, incluso en equipos grandes.

Tipos de Contenedores en CMI

Contenedores Estándar (de uso obligatorio):

Contenedor Descripción
services/ Contratos de servicios (interfaces).
adapters/ Adaptadores entre entidades y almacenamiento o integración externa.
origins/ Acceso a orígenes de datos (bases de datos, APIs, etc.).
consumers/ Exposición pública de lógica consumible.
handlers/ Manejadores de solicitudes (HTTP, CLI, Events).
commands/ Comandos CLI (solo backend).
middlewares/ Validadores HTTP.
guards/ Validaciones de acceso (permiso/autenticación).

Contenedores de Dominio (obligatorios dentro de rules/):

  • data/ → Agrupa entidades, contratos de datos, value objects.
  • Dentro de data/ se organizan subdominios por carpetas (por ejemplo: user/, token/, recovery/).

Contenedores Adicionales (opcional, sólo si es necesario):

  • cli/, shared/, etc., dependiendo de necesidades específicas.

Contenedores Genéricos (estructuras internas adicionales):

  • components/, dialogs/, logic/ (en shared/).
  • container/, group/, category/, part/, internal/, view/ (en cualquier contenedor según contexto).

Recursividad en Contenedores

  • Se permite profundización cuando es necesaria.
  • Siempre debe ser controlada y justificada.
  • El abuso de la recursividad genera estructuras difíciles de leer.

Errores comunes al trabajar con contenedores

  • Ignorar los contenedores estándar.
  • Crear carpetas personalizadas donde ya existe un contenedor estándar.
  • Mezclar tipos de archivos (por ejemplo: poner adaptadores dentro de services/).
  • Abusar de la recursividad sin necesidad.
  • No crear el enrutador correspondiente.

❗ Crear estructuras personalizadas fuera del patrón aprobado desorganiza el sistema y debilita su escalabilidad.


3.4 Enrutadores

Los Enrutadores son el núcleo del encapsulamiento estructural en CMI.

Toda interacción entre Capas, Módulos o Contenedores debe pasar por sus respectivos Enrutadores.

El enrutador:

  • Controla la visibilidad de los elementos.
  • Evita accesos directos a archivos internos.
  • Refuerza el bajo acoplamiento.

¿Por qué son fundamentales los enrutadores?

  • Control de acceso: Bloquean importaciones directas de archivos internos.
  • Encapsulamiento real: Exponen sólo lo diseñado para ser visible.
  • Mantenibilidad: Cambios internos no afectan al resto del sistema mientras el enrutador mantenga el contrato.
  • Claridad de dependencias: Toda importación visible pasa por los enrutadores.
  • Refuerzo jerárquico: Definen los límites formales de acceso por nivel.

Tipos de Enrutadores en CMI

Enrutadores Normales

  • Se utilizan en todos los niveles (capas, módulos, contenedores).
  • Son el único punto de acceso público para su contexto.

Enrutadores Compuestos

En algunos casos dentro de la arquitectura CMI, un archivo puede asumir simultáneamente la función de raíz estructural y funcional de su propia estructura.
Este patrón se denomina Enrutador Compuesto.

Un Enrutador Compuesto:

  • Se encuentra dentro de una estructura (por ejemplo: layouts/, pages/, overlays/, dialogs/, flows/, authentication/, http/, cli/, events/, etc.).
  • Gestiona la construcción, configuración, lógica y dependencias internas de su estructura.
  • Expone públicamente los elementos internos que necesitan ser accesibles desde el exterior.

Se aplica cuando:

  • Existe un punto central de inicialización funcional (visual, lógica o de infraestructura).
  • Toda la lógica principal se mantiene centralizada dentro del archivo raíz.
  • Puede incluir navegación, subestructuras o vistas internas, siempre encapsuladas bajo su lógica principal.

Errores comunes al gestionar enrutadores

  • Omitir enrutadores obligatorios.
  • Exportar todos los elementos internos sin control.
  • Acceso directo no autorizado a archivos internos.
  • No actualizar enrutadores al modificar contenido.
  • Incluir lógica o visualización dentro de enrutadores normales (excepto en enrutadores compuestos donde está permitido).

3.5 Relación Jerárquica de CMI

Capa
  └── Módulo
        └── Contenedor
              └── Elementos: servicios, adaptadores, lógica, componentes, vistas, etc.

3.6 Ejemplo Visual de Estructura

Backend:

lib/
├── configs/
│   ├── env/
│   ├── constants/
│   ├── logger/
│   └── configs.dart                # Enrutador de Configs
│
├── core/
│   ├── rules/
│   │   ├── data/
│   │   ├── services/
│   │   ├── consumers/
│   │   └── rules.dart              # Enrutador de Rules
│   │
│   ├── uses/
│   │   ├── consumers/
│   │   ├── adapters/
│   │   ├── services/
│   │   ├── origins/
│   │   └── uses.dart                # Enrutador de Use
│   │
│   └── core.dart                   # Enrutador de Core
│
├── interface/
│   ├── http/
│   │   ├── routes/
│   │   ├── handlers/
│   │   └── http.dart               # Enrutador del módulo HTTP
│   │
│   ├── cli/
│   │   ├── commands/
│   │   └── cli.dart                # Enrutador del módulo CLI
│   │
│   ├── events/
│   │   ├── listeners/
│   │   └── events.dart             # Enrutador del módulo Events
│   │
│   ├── shared/
│   │   ├── middlewares/
│   │   └── shared.dart             # Enrutador del módulo Shared
│   │
│   └── interface.dart              # Enrutador de Interface
│
└── main.dart

Frontend:

lib/
├── configs/
│   └── configs.dart        # Enrutador de Configs
├── core/
│   ├── rules/
│   │   └── services/
│   │       └── socket_service_rule.dart
│   └── use/
├── interface/
│   ├── layouts/
│   │   └── authentication/
│   │       ├── components/
│   │       └── views/
│   └── shared/
└── main.dart