Backend – controladores y helpers en comunes
Cuándo usar: Al crear una nueva pantalla/entidad (controlador en backend), al generar controladores con las utilidades de orm, o cuando crees funciones de utilidad (fecha a string, normalizar RUT, etc.).
1. Una página → un controlador
- Por cada página o pantalla de la aplicación (ej. listado de productos, órdenes maestro-detalle) debe existir un controlador (o endpoints asociados) en el backend que atienda la lógica y los datos de esa pantalla.
- El controlador expone los endpoints CRUD de la entidad (GET/POST /api/entidad, GET/PUT/DELETE /api/entidad/:id) y/o lógica específica que la página necesite.
- No crear páginas en el frontend que llamen a APIs que no tengan un controlador definido en el backend.
- Al añadir una nueva pantalla: (1) crear o tener el controlador y los endpoints; (2) añadir la entrada en la respuesta del endpoint de rutas (
/routes) con path, component y props.endpoint.
2. Reutilizar lógica: no repetir por controlador
- Una página = un controlador no implica duplicar lógica. Si varias páginas necesitan los mismos datos (ej. movimientos, productos, clientes), la obtención y transformación de esos datos debe vivir en una capa compartida: servicio, módulo de negocio o comunes.
- Cada controlador consume esa lógica compartida y se encarga de cómo se usan los datos en esa pantalla: qué filtros aplicar, qué formato devolver, qué agregaciones o permisos aplicar para ese endpoint.
- Ejemplo: Página A y página B necesitan "movimientos". Crear un servicio (o función en un módulo compartido) que obtenga los movimientos; el controlador de la página A lo llama y devuelve movimientos con un formato/filtros para A; el controlador de la página B lo llama y devuelve movimientos con formato/filtros para B. No implementar la obtención de movimientos dos veces.
- Resumen: lógica de datos reutilizable en servicios/comunes; cada controlador orquesta y adapta la respuesta a lo que su página necesita.
3. Helpers y utilidades – siempre en comunes
Tipos de funciones que van en comunes: conversión de fechas (date/datetime → "YYYY-MM-DD"), normalizar RUT, formateo de números o strings, validadores o sanitizadores pequeños reutilizables. Ejemplos de nombres: _fecha_a_str, _normalize_rut. Documentar con docstring.
Protocolo obligatorio:
- Revisar primero si ya existe en comunes – Buscar en
comunes/, common/, utils/comunes.py o equivalente. Si existe una función que haga lo mismo o muy similar, usarla; no crear otra.
- Si no existe, crearla en comunes – Añadir la función en el lugar adecuado dentro de comunes. Documentar. Así se usa en todo el proyecto (controladores, servicios) sin duplicar código.
- No duplicar en cada controlador – Donde haga falta, importar desde comunes y usar la función (ej.
from comunes.xxx import _fecha_a_str).
Flujo ejemplo: Usuario pide "convertir fecha del ORM a string YYYY-MM-DD". Buscar en comunes si ya hay fecha_a_str o _fecha_a_str. Si no hay, crearla en comunes y usarla desde el controlador. Si ya hay, indicar que existe y cómo importarla.
4. Lo que NO debe crearse
- No crear
_query_builder_to_orm_objects ni funciones equivalentes que conviertan resultados de QueryBuilder.get() (lista de diccionarios) en objetos ORM usando set_dict, _exists o instanciar el modelo y cargar el dict a mano. Usar QueryBuilder/ORM tal como los define pybernate.
5. Cómo generar un controlador (flujo manual con IPython)
En este proyecto, los controladores de backend se generan manualmente usando utilidades de orm. El agente no debe ejecutar estos comandos, sino explicar al usuario los pasos y pedirle que los ejecute en su terminal.
Pasos para el usuario
Abrir la terminal en la carpeta del backend, por ejemplo:
cd flujappi2-back-main (o el directorio raíz del backend en tu entorno).
Entrar a IPython:
Importar las utilidades de generación:
- En la consola de IPython:
from orm import gen_single_controller, reverse_engineer
Generar el controlador para una tabla/objeto concreto:
- Ejecutar:
gen_single_controller("{nombre_tabla}")
- Sustituir
"{nombre_tabla}" por el nombre real de la tabla/entidad para la que quieres el controlador.
Revisar el archivo generado:
- Verificar:
- Ubicación del archivo de controlador.
- Nombres de endpoints generados.
- Que respete las reglas de
pybernate_rules y endpoint_rules.
Instrucciones para el agente
- Cuando el usuario pida crear un nuevo controlador:
- No intentes escribirlo “desde cero” ignorando el generador.
- Indica explícitamente los pasos anteriores y solicita al usuario que:
- Abra la terminal en el backend.
- Entre a IPython.
- Ejecute
from orm import gen_single_controller, reverse_engineer.
- Ejecute
gen_single_controller("{nombre_tabla}") con el nombre correcto.
- Después de eso, puedes ayudar a:
- Revisar el código generado.
- Ajustar detalles según las reglas de arquitectura.
1---2name: controller-generation3description: Una página = un controlador; lógica de datos reutilizable en servicios/comunes (no repetir por controlador); helpers en comunes. Usar al crear controladores o funciones de utilidad reutilizables.4---56# Backend – controladores y helpers en comunes78**Cuándo usar:** Al crear una nueva pantalla/entidad (controlador en backend), al generar controladores con las utilidades de `orm`, o cuando crees funciones de utilidad (fecha a string, normalizar RUT, etc.).910---1112## 1. Una página → un controlador1314- Por cada **página** o pantalla de la aplicación (ej. listado de productos, órdenes maestro-detalle) debe existir un **controlador** (o endpoints asociados) en el **backend** que atienda la lógica y los datos de esa pantalla.15- El controlador expone los endpoints CRUD de la entidad (GET/POST /api/entidad, GET/PUT/DELETE /api/entidad/:id) y/o lógica específica que la página necesite.16- No crear páginas en el frontend que llamen a APIs que no tengan un controlador definido en el backend.17- Al añadir una nueva pantalla: (1) crear o tener el controlador y los endpoints; (2) añadir la entrada en la respuesta del endpoint de rutas (`/routes`) con path, component y props.endpoint.1819---2021## 2. Reutilizar lógica: no repetir por controlador2223- **Una página = un controlador** no implica duplicar lógica. Si varias páginas necesitan los mismos datos (ej. movimientos, productos, clientes), la **obtención y transformación de esos datos** debe vivir en una capa compartida: **servicio**, módulo de negocio o comunes.24- Cada **controlador** consume esa lógica compartida y se encarga de **cómo** se usan los datos en esa pantalla: qué filtros aplicar, qué formato devolver, qué agregaciones o permisos aplicar para ese endpoint.25- **Ejemplo:** Página A y página B necesitan "movimientos". Crear un servicio (o función en un módulo compartido) que obtenga los movimientos; el controlador de la página A lo llama y devuelve movimientos con un formato/filtros para A; el controlador de la página B lo llama y devuelve movimientos con formato/filtros para B. No implementar la obtención de movimientos dos veces.26- Resumen: **lógica de datos reutilizable en servicios/comunes; cada controlador orquesta y adapta la respuesta a lo que su página necesita.**2728---2930## 3. Helpers y utilidades – siempre en comunes3132**Tipos de funciones que van en comunes:** conversión de fechas (date/datetime → `"YYYY-MM-DD"`), normalizar RUT, formateo de números o strings, validadores o sanitizadores pequeños reutilizables. Ejemplos de nombres: `_fecha_a_str`, `_normalize_rut`. Documentar con **docstring**.3334**Protocolo obligatorio:**35361. **Revisar primero si ya existe en comunes** – Buscar en `comunes/`, `common/`, `utils/comunes.py` o equivalente. Si existe una función que haga lo mismo o muy similar, **usarla**; no crear otra.372. **Si no existe, crearla en comunes** – Añadir la función en el lugar adecuado dentro de comunes. Documentar. Así se usa en todo el proyecto (controladores, servicios) sin duplicar código.383. **No duplicar en cada controlador** – Donde haga falta, **importar desde comunes** y usar la función (ej. `from comunes.xxx import _fecha_a_str`).3940**Flujo ejemplo:** Usuario pide "convertir fecha del ORM a string YYYY-MM-DD". Buscar en comunes si ya hay `fecha_a_str` o `_fecha_a_str`. Si no hay, crearla en comunes y usarla desde el controlador. Si ya hay, indicar que existe y cómo importarla.4142---4344## 4. Lo que NO debe crearse4546- **No** crear `_query_builder_to_orm_objects` ni funciones equivalentes que conviertan resultados de `QueryBuilder.get()` (lista de diccionarios) en objetos ORM usando `set_dict`, `_exists` o instanciar el modelo y cargar el dict a mano. Usar QueryBuilder/ORM tal como los define pybernate.4748---4950## 5. Cómo generar un controlador (flujo manual con IPython)5152En este proyecto, los **controladores de backend se generan manualmente** usando utilidades de `orm`. El agente **no debe ejecutar estos comandos**, sino **explicar al usuario** los pasos y pedirle que los ejecute en su terminal.5354### Pasos para el usuario55561. **Abrir la terminal** en la carpeta del backend, por ejemplo:5758 - `cd flujappi2-back-main` (o el directorio raíz del backend en tu entorno).59602. **Entrar a IPython**:6162 - Ejecutar: `ipython`63643. **Importar las utilidades de generación**:6566 - En la consola de IPython:67 - `from orm import gen_single_controller, reverse_engineer`68694. **Generar el controlador para una tabla/objeto concreto**:7071 - Ejecutar:72 - `gen_single_controller("{nombre_tabla}")`73 - Sustituir `"{nombre_tabla}"` por el nombre real de la tabla/entidad para la que quieres el controlador.74755. **Revisar el archivo generado**:7677 - Verificar:78 - Ubicación del archivo de controlador.79 - Nombres de endpoints generados.80 - Que respete las reglas de `pybernate_rules` y `endpoint_rules`.8182### Instrucciones para el agente8384- Cuando el usuario pida **crear un nuevo controlador**:85 - **No** intentes escribirlo “desde cero” ignorando el generador.86 - Indica explícitamente los pasos anteriores y solicita al usuario que:87 - Abra la terminal en el backend.88 - Entre a IPython.89 - Ejecute `from orm import gen_single_controller, reverse_engineer`.90 - Ejecute `gen_single_controller("{nombre_tabla}")` con el nombre correcto.91- Después de eso, puedes ayudar a:92 - Revisar el código generado.93 - Ajustar detalles según las reglas de arquitectura.94