Controladores y ViewComponents
Un módulo con interfaz de backend expone sus pantallas mediante controladores MVC y, para fragmentos reutilizables, ViewComponents. Crono aporta controladores base que ya traen resueltos la localización, el registro, el acceso a los servicios comunes y las notificaciones, de modo que el controlador del módulo se centra en su lógica.
Controladores base
En lugar de heredar directamente de Controller, un controlador de módulo hereda de un controlador base de Crono según el área en la que vive. Por ejemplo, los controladores del módulo de facturación (área de contabilidad del backend) heredan de un controlador de área que a su vez desciende del controlador base de Crono:
public class BoletaVentaLoteController : ContabilidadController
{
private readonly IBoletaVentaLoteServicio _boletaVentaLoteServicio;
public BoletaVentaLoteController(IBoletaVentaLoteServicio boletaVentaLoteServicio)
{
_boletaVentaLoteServicio = boletaVentaLoteServicio;
}
}
Las dependencias se inyectan por constructor (ver Inyección de dependencias). El controlador base pone a disposición, entre otros, el registrador, el localizador (T) y los servicios comunes, además de ayudantes de notificación al usuario (información, advertencia, éxito, error) y de renderizado de vistas parciales a cadena.
Acciones y verbos HTTP
Las acciones usan los atributos estándar de ASP.NET Core ([HttpGet], [HttpPost]) y devuelven IActionResult. El patrón habitual separa la pantalla (que devuelve la vista con su modelo) del endpoint de datos que alimenta la grilla:
[HttpGet]
[Permiso(FacturacionPermisos.ComprobanteElectronico.GenerarMasivamente)]
public IActionResult Lista()
{
FiltroBusquedaBoletaVentaLoteModelo modelo = new();
return View(modelo);
}
[HttpPost]
[Permiso(FacturacionPermisos.ComprobanteElectronico.GenerarMasivamente)]
public async Task<IActionResult> ListaBoletasVentasLotes(GrillaComando comando,
FiltroBusquedaBoletaVentaLoteModelo filtro)
{
// ... consulta paginada/ordenada y devolución del resultado de grilla
}
Seguridad: el atributo [Permiso]
Cada acción se protege declarando el permiso requerido con [Permiso(...)], apuntando a una constante de permiso del módulo (ver Seguridad). Así el sistema de autorización evalúa si el usuario actual (por rol y organización) puede ejecutar la acción antes de entrar al método:
[Permiso(FacturacionPermisos.ComprobanteElectronico.GenerarMasivamente)]
public IActionResult Index() => RedirectToAction(nameof(Lista));
Los permisos del módulo se declaran en su Permisos.cs y se registran automáticamente al instalar.
Áreas y enrutado
Los controladores de backend viven en un área (por ejemplo Admin o el área de contabilidad). El enrutado por convención de Crono resuelve Area/Controlador/Accion, por lo que la ruta de configuración de un módulo se declara con esos valores:
public RutaInformacion ObtenerRutaConfiguracion()
=> new("Configurar", "FacturacionConfiguracion", new { area = "Admin" });
ViewComponents
Para fragmentos de interfaz reutilizables (una tarjeta, un resumen, un bloque que se inyecta en una zona), un módulo usa ViewComponents de ASP.NET Core. Se resuelven por DI igual que los controladores, por lo que pueden inyectar los servicios del módulo, y se renderizan desde una vista o se conectan a una zona mediante una micro‑aplicación cuando deben aparecer en páginas del núcleo (ver Widgets).
@await Component.InvokeAsync("MiResumenFacturacion", new { prestamoId = Model.Id })
Mantén los controladores delgados: la lógica de negocio va en los servicios del módulo (IComprobantePagoServicio, IBoletaVentaLoteServicio, …), y el controlador solo orquesta la entrada/salida HTTP y arma el modelo de la vista.