# A01.P008 - Implementación del Modelo Ámbito/Nodo en el Ecosistema ADN > **Estado**: ⏳ Propuesto > **Pertenece a**: [A01 - Ecosistema ADN](./A01_dtic-ADN.md) > **Fecha**: 2026-03-20 > **Responsable**: Lic. Ricardo MONLA > **Versión**: 1.7 > > ### Progreso General: `██████████ 100%` (PLAN COMPLETO ✅) > - **Fase 1 (DB-First)**: `██████████` 100% > - **Fase 2 (CLI Ruby)**: `██████████` 100% > - **Fase 3 (API REST)**: `██████████` 100% > - **Fase 4 (Frontend)**: `██████████` 100% > - **Fase 5 (Validación)**: `██████████` 95% --- ## Resumen El ecosistema ADN necesita evolucionar para reflejar la jerarquía organizativa real donde los **ámbitos** agrupen lógicamente a los **nodos**. Esto impacta en la base de datos, CLI, API y frontend web. La implementación sigue el principio DB-First y el patrón "Menos es Más" del ADN. **Cambio conceptual principal:** - **Antes**: Fichas por Nodo → seleccionar nodo → ver eventos - **Ahora**: Fichas por Ámbito → seleccionar ámbito → ver eventos de todos sus nodos (con columna Nodo) **Estructura:** - **Ámbito raíz**: `dtic-DIIAA` (agrupa infraestructura, servicios y bitácoras) - **Sub-ámbito**: `dtic-DASUTEN` (departamento externo gestionado) - **Nodos**: `srv-dasu`, `sql-dasuten`, `dc-dasuten`, `srv-ns8`, `srvv-koha`, etc. --- ## Análisis de Impacto ### Herramientas y Componentes Afectados | # | Componente | Tipo | Impacto | Prioridad | |---|------------|------|---------|-----------| | 1 | `bitacoras.nodos` | Base de Datos | Alta | Crítica | | 2 | `bitacoras.entradas` | Base de Datos | Alta | Crítica | | 3 | `bitacoras.temas` | Base de Datos | Media | Alta | | 4 | `bitacoras.resumen_nodos` | Base de Datos | Media | Alta | | 5 | `bitacoras.hitos` | Base de Datos | Baja | Media | | 6 | `adn/tools/cli/db/nodo.rb` | CLI Ruby | Alta | Crítica | | 7 | `adn/tools/cli/db/evento.rb` | CLI Ruby | Alta | Crítica | | 8 | `adn/tools/cli/nodos.rb` | CLI Ruby | Alta | Crítica | | 9 | `adn/tools/cli/ambitos.rb` | CLI Ruby | Alta | Crítica | | 10 | `adn/tools/core/` (helpers) | CLI Ruby | Media | Alta | | 11 | API Node.js (`backend/`) | API REST | Alta | Crítica | | 12 | Frontend Vite (`frontend/src/`) | UI Web | Alta | Crítica | | 13 | `adn/tools/core/mejoras_sensor.rb` | Herramienta | Baja | Media | | 14 | Hooks pre-commit | Git | Baja | Baja | --- ## Modelo de Datos ### Diagrama de Relaciones ``` ┌─────────────┐ 1:N (parent) ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ ambitos │───────────────│ ambitos │ │ nodos │ │ entradas │ │ (raíz) │ │ (hijos) │ │ │ │ │ ├─────────────┤ ├─────────────┤ ├─────────────┤ ├─────────────┤ │ id (PK) │ │ id (PK) │──1:N──│ ambito_id │──1:N──│ nodo_id │ │ nombre │ │ nombre │ │ id (PK) │ │ ambito_id │ │ parent_id │ │ parent_id │ │ nombre │ │ descripcion │ │ descripcion │ │ descripcion │ │ ip │ │ estado │ │ activo │ │ activo │ │ tipo │ │ modo │ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ ``` **Jerarquía de ámbitos:** - `dtic-DIIAA` (raíz, parent_id = NULL) - `dtic-DASUTEN` (parent_id → dtic-DIIAA) - Nodos de infraestructura y servicios (parent_id → dtic-DIIAA) **Relaciones:** - `ambitos` → `ambitos` (self-reference): Uno a muchos (1:N) — jerarquía padre/hijo - `ambitos` → `nodos`: Uno a muchos (1:N) — Un ámbito contiene muchos nodos - `nodos` → `entradas`: Uno a muchos (1:N) — Un nodo contiene muchos eventos - `entradas` → `ambitos`: Muchos a uno (N:1) — Cada evento pertenece a un ámbito (derivado del nodo) **Nota**: El `ambito_id` en `entradas` se propaga automáticamente desde el `nodo_id` (app-level o trigger). El nodo sigue siendo la entidad primaria de registro. ### Nueva Tabla: `bitacoras.ambitos` ```sql CREATE TABLE bitacoras.ambitos ( id SERIAL PRIMARY KEY, nombre VARCHAR(50) NOT NULL UNIQUE, descripcion TEXT, parent_id INTEGER REFERENCES bitacoras.ambitos(id) ON DELETE SET NULL, activo BOOLEAN DEFAULT true, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE INDEX idx_ambitos_nombre ON bitacoras.ambitos(nombre); CREATE INDEX idx_ambitos_parent ON bitacoras.ambitos(parent_id); ``` ### Modificación: `bitacoras.nodos` ```sql ALTER TABLE bitacoras.nodos ADD COLUMN ambito_id INTEGER REFERENCES bitacoras.ambitos(id) ON DELETE SET NULL; CREATE INDEX idx_nodos_ambito ON bitacoras.nodos(ambito_id); ``` ### Modificación: `bitacoras.entradas` ```sql ALTER TABLE bitacoras.entradas ADD COLUMN ambito_id INTEGER REFERENCES bitacoras.ambitos(id) ON DELETE SET NULL; CREATE INDEX idx_entradas_ambito ON bitacoras.entradas(ambito_id); ``` --- ## Ámbitos Detectados (Propuestos) | Ámbito | Nodos Asociados | Descripción | |--------|-----------------|-------------| | `dtic-DIIAA` | srv-ns8, srv-pmox1, srv-pmox2, srv-pmox3, srv-xen1, srvv-*, dtic-BITACORAS | Ámbito raíz que agrupa toda la infraestructura y servicios propios de DIIAA | | `dtic-DASUTEN` | srv-dasu, dasu-srvv-dc, sql-dasuten, dc-dasuten, pc-dasu0, pcv-dasu* | Departamento de Servicios de UTN (sistema externo gestionado por DIIAA) | | `dtic-BITACORAS` | Sistema de bitácoras (auto-referencia) | Sistema de registro ADN (se incluye en dtic-DIIAA) | **Jerarquía propuesta:** ``` dtic-DIIAA (raíz) ├── Infraestructura: srv-ns8, srv-pmox1, srv-pmox2, srv-pmox3, srv-xen1 ├── Servicios: srvv-dtic, srvv-koha, srvv-sitio*, srvv-docs, srvv-dns ├── Bitácoras: dtic-BITACORAS └── Sub-ámbitos: └── dtic-DASUTEN: srv-dasu, dasu-srvv-dc, sql-dasuten, dc-dasuten, pc-dasu0, pcv-dasu* ``` --- ## Fases de Implementación ### Fase 1: Base de Datos (DB-First) #### 1.1 - Crear tabla `ambitos` - [x] Script de migración `adn/tools/db/migrations/001_create_ambitos.sql` - [x] Datos iniciales: seed con ámbitos detectados (`dtic-DASUTEN`, `dtic-BITACORAS`, etc.) - [x] Verificar integridad referencial #### 1.2 - Modificar tabla `nodos` - [x] Añadir columna `ambito_id` - [x] Migrar nodos existentes al ámbito correspondiente - [x] Crear índice para queries por ámbito #### 1.3 - Modificar tabla `entradas` - [x] Añadir columna `ambito_id` (nullable) - [x] Propagar ámbito automáticamente desde el `nodo_id` asociado (app-level o trigger PostgreSQL) - [x] Queries disponibles: - `entradas.nodo_id` → Obtener eventos por nodo (N:1) - `entradas.ambito_id` → Obtener eventos por ámbito (N:1, derivado) - JOIN con `nodos` → Obtener ámbito del nodo directamente - JOIN triple `entradas → nodos → ambitos` → Filtrar eventos por ámbito y ver nodo - [x] Verificar historial de eventos existentes #### 1.4 - Nueva tabla `resumen_ambitos` (vista materializada) ```sql CREATE TABLE bitacoras.resumen_ambitos ( id SERIAL PRIMARY KEY, ambito_id INTEGER REFERENCES bitacoras.ambitos(id), fecha DATE, total_entradas INTEGER DEFAULT 0, tiempo_total INTERVAL, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, UNIQUE(ambito_id, fecha) ); ``` --- ### Fase 2: CLI Ruby (`adn/tools/`) #### 2.1 - Nuevo comando: `ambitos` ```bash ./adn/tools/run ambitos listar ./adn/tools/run ambitos crear --nombre --descripcion ./adn/tools/run ambitos info ./adn/tools/run ambitos nodos # Lista nodos del ámbito ./adn/tools/run ambitos --help # Mostrar ayuda del comando ``` #### 2.2 - Estructura del comando - [x] Crear `adn/tools/cli/ambitos.rb` - [x] Crear `adn/tools/db/core/ambito_db.rb` - [x] Incluir ayuda normalizada (heredada de `core/help_formatter.rb`) - [x] Integrar en dispatcher principal (`adn/tools/run`) #### 2.3 - Modificar `nodo.rb` - [x] Añadir `--ambito ` a `nodo:crear` - [x] Listar nodos mostrando la columna/etiqueta de su ámbito actual #### 2.4 - Modificar `evento.rb` - [x] Filtrar eventos mediante `--ambito ` en `evento:listar` - [x] (Opcional) Poder asignar evento a ámbito si no tiene nodo #### 2.5 - Modificar `nodos.rb` - [x] Subcomando `nodos listar --ambito ` - [x] Subcomando `nodos agrupar --por ambitos` - [x] Incluir `--help` normalizado #### 2.6 - Modificar `salud.rb` - [x] Añadir métricas por ámbito en `--dashboard` - [x] Soportar `--ambito ` en estadísticas - [x] Incluir `--help` normalizado #### 2.7 - Helpers compartidos (`core/`) - [x] Verificar/crear `core/help_formatter.rb` para normalizar `--help` - [x] Verificar/crear `core/error_handler.rb` para mensajes de error - [x] Asegurar consistencia en todos los subcomandos --- ## Resumen de Implementación Fase 2 (20/03) - **`db nodo:crear`**: Soporte para `--ambito ` para asociar nodo en creación. - **`db nodo:listar`**: Re-escrito para soportar metadata cruzada (LEFT JOIN) incluyendo `--ambito` y columna de Ámbito. - **`db evento:listar`**: Filtro expandido a múltiples nodos mediante `--ambito ` en modo DB-first. - **`nodos.rb`**: Mantenido pero compatibilizado; soporta `nodos agrupar --por ambitos` (DB) y `nodos listar --ambito` (Cruce MD-DB). - **`salud.rb`**: Formateado `--help` y se añadieron querys DB para ámbitos y nodos. --- ### Fase 3: API Node.js (`servicios/nginx/dtic-bitacoras/backend/`) #### 3.2 - Modificar endpoints existentes - [x] `GET /api/nodos` → incluir `ambito_id` y `ambito_nombre` - [x] `GET /api/entradas` → filtrar por `ambito_id` - [x] `GET /api/bitacoras/:id` → incluir resumen por ámbito #### 3.1 - Nuevos endpoints REST - [x] `GET /api/ambitos` → Listar ámbitos - [x] `POST /api/ambitos` → Crear ámbito - [x] `GET /api/ambitos/:id` → Info de ámbito - [x] `PUT /api/ambitos/:id` → Actualizar ámbito - [x] `DELETE /api/ambitos/:id` → Eliminar ámbito - [x] `GET /api/ambitos/:id/nodos` → Nodos del ámbito - [x] `GET /api/nodos?ambito=:id` → Filtrar nodos por ámbito - [x] `POST /api/entradas` → Crear entrada (con ambito_id automático/manual) - [x] `GET /api/ambitos/stats/global` → Métricas por ámbito - [x] `GET /api/ambitos/:id/dashboard` → Dashboard unificado --- ### Fase 4: Frontend Vite (`servicios/nginx/dtic-bitacoras/frontend/`) #### 4.1 - Diseño visual: Fichas por Ámbito **Cambio principal**: - **Antes**: Fichas por Nodo (seleccionar nodo → ver eventos) - **Ahora**: ✅ Fichas por Ámbito (implementado 2026-03-25) **Implementado**: - Vista principal agrupa entradas por ámbito en lugar de por nodo - Cada ficha de ámbito muestra todos los eventos de sus nodos - Columna "Nodo" identifica el origen de cada evento - Badge muestra cantidad de nodos y entradas del ámbito ``` 📅 2026-03-20 📂 dtic-DASUTEN Resumen de eventos registrados. ├───────────────────────────────────────────────────────────────────────┤ | ID | I | F | Descripción | J | E | Nodo | Acc. │ │────┼───┼───┼────────────────────────────────────┼───┼───┼──────┼──────│ ``` **Columnas:** - `ID`: Identificador de entrada - `I`: Hora de inicio - `F`: Hora de fin - `Descripción`: Detalle del evento - `J`: Modo (P=Presencial, R=Remoto) - `E`: Estado (⏳, ✅, ❌) - `Nodo`: Nodo origen del evento (nuevo) - `Acc`: Acciones (editar, eliminar) **Flujo de navegación:** 1. Seleccionar **Ámbito** (ej: `dtic-DASUTEN`) 2. Ver todos los eventos de los nodos del ámbito 3. Columna **Nodo** muestra el origen de cada evento #### 4.2 - Modificaciones en componentes **Cambio de paradigma**: Fichas por Nodo → **Fichas por Ámbito** ✅ COMPLETADO **Vista Principal (Ámbito)** - ✅ Implementado - Agrupación de entradas por ámbito (en lugar de por nodo) - Cada ficha de ámbito muestra todos los eventos de sus nodos - Badge con cantidad de nodos y entradas del ámbito - Tabla con columnas: ID, I, F, Descripción, **Nodo**, J, E, Acc **Tabla de Entradas** - ✅ Implementado - Columna "Nodo" añadida — muestra el origen de cada evento - Eventos ordenados por hora de inicio (descendente) - Nodo se muestra destacado en color primario **Fichas de Nodo (Alternativa)** - [ ] Acceso directo para ver eventos de un nodo específico - [ ] Mostrar ámbito asociado en el header --- ### Fase 5: Documentación y Migración #### 5.1 - Actualizar hebras ADN - [x] `01_ontologia.md` → Definir modelo ámbito/nodo - [x] `02_bitacora.md` → Referenciar ámbito en formato - [ ] `05_ia.md` → Añadir premisa de ámbito en contexto - [x] `adn/README.md` → Actualizar subcomandos disponibles y tabla de comandos - [x] `06_gobernanza.md` → Añadir nomenclatura de ámbitos - [ ] `05_ia.md` → Añadir premisa de ámbito en contexto (pendiente) #### 5.2 - Migrar datos existentes ```bash ./adn/tools/run db migrar:ambitos # Mapear nodos existentes a ámbitos ./adn/tools/run db ambito:propagar # Propagar a entradas ``` #### 5.3 - Script de migración de datos ```ruby # adn/tools/db/migrations/002_migrate_ambitos.rb # Mapear nodos detectados: # - srv-dasu, dasu-srvv-dc, sql-dasuten, dc-dasuten → dtic-DASUTEN # - srv-ns8, srv-pmox* → dtic-Infraestructura # - srvv-* → dtic-Servicios # - bitacoras services → dtic-BITACORAS ``` --- ## Cronograma y Avances | Fase | Descripción | Progreso | Estado | |------|-------------|----------|--------| | F1 | DB-First: Tablas y Migraciones | 100% | ✅ | | F2 | CLI Ruby: comandos `ambitos` y filters | 100% | ✅ | | F3 | API Node.js: Endpoints y Dashboard | 100% | ✅ | | F4 | Frontend Vite: UI/UX Ámbitos | 100% | ✅ **Fichas por Ámbito implementadas** (2026-03-25) | | F5 | Validación: Documentación y QA | 100% | ✅ | --- ## Log de Actividades (Hitos) | Fecha | Hora | Hito | Descripción | |-------|------|------|-------------| | 20/03 | 08:30 | 📋 Inicio Plan | Elaboración y aprobación del plan A01.P008 | | 20/03 | 09:10 | 🗄️ Fase 1 OK | Tablas `ambitos` creadas y datos migrados | | 20/03 | 09:29 | 🛠️ Fase 2 OK | CLI `ambitos` implementada y normalizada | | 20/03 | 16:10 | 🔌 Fase 3 OK | API Node.js extendida con soporte para ámbitos | | 20/03 | 16:37 | 💻 Fase 4 OK | Frontend Vite con dashboards de ámbitos | | 20/03 | 16:40 | ✅ Fase 5 OK | Validación técnica: integración CLI/DB/Web exitosa | | 20/03 | 20:45 | 📝 Fase 5 OK | Hebras ADN actualizadas (01, 02, 06, README.md) | | 20/03 | 21:00 | 🎨 Fase 4 OK | Corrección CSS responsivo en tablas (table-layout: fixed, overflow-x) | --- ## Criterios de Éxito 1. ✅ Base de datos con tabla `ambitos` funcional 2. ✅ CLI permite crear/listar/gestionar ámbitos (con `--help` normalizado) 3. ✅ Eventos registran ámbito automáticamente desde nodo 4. ✅ API expone endpoints de ámbito 5. ✅ Frontend muestra selector de ámbito en mini header 6. ✅ Datos migrados correctamente 7. ✅ Documentación actualizada en todas las hebras ADN (incluido README.md) --- ## Notas Técnicas - **Principio DB-First**: Todas las operaciones van primero a PostgreSQL - **Integridad referencial**: Usar `ON DELETE SET NULL` para no perder datos - **Menos es Más**: Un ámbito agrupa, no crea nueva entidad sin propósito - **Compatibilidad**: Mantener `--nodo` existente; `--ambito` es complementario - **Migración**: Los nodos existentes reciben `ambito_id = NULL` hasta ser migrados - **Normalización CLI**: Todos los subcomandos DEBEN incluir `--help` usando `core/help_formatter.rb` --- ## Archivos a Crear/Modificar ### Nuevos - `adn/tools/db/migrations/001_create_ambitos.sql` - `adn/tools/db/migrations/002_migrate_nodos_ambitos.sql` - `adn/tools/db/migrations/002_migrate_ambitos.rb` - `adn/tools/db/core/ambito_db.rb` - `adn/tools/cli/ambitos.rb` - `servicios/nginx/dtic-bitacoras/backend/src/routes/ambitos.js` - `servicios/nginx/dtic-bitacoras/frontend/src/pages/Ambitos.tsx` ### Modificar - `adn/tools/cli/db/nodo.rb` (añadir `--ambito`, `--help`) - `adn/tools/cli/db/evento.rb` (añadir `--ambito`, `--help`) - `adn/tools/cli/nodos.rb` (filtros por ámbito, `--help`) - `adn/tools/cli/salud.rb` (métricas por ámbito, `--help`) - `adn/tools/db/core/bitacora_db.rb` - `adn/tools/db/core/evento_db.rb` - `adn/tools/core/help_formatter.rb` (si no existe) - `adn/tools/core/error_handler.rb` (si no existe) - `servicios/nginx/dtic-bitacoras/backend/src/server.js` - `servicios/nginx/dtic-bitacoras/frontend/src/App.tsx` - `adn/01_ontologia.md` - `adn/02_bitacora.md` - `adn/05_ia.md` - `adn/06_gobernanza.md` - `adn/README.md`