[Dashboard] P2601 actualizado — Estructura de Ámbitos y Planes (ADN)

- adn/tools/db/migrations/004_create_planes.sql (NUEVO)
  Migración para tabla 'planes' dentro de ámbitos
  Reemplaza concepto anterior de 'fases' por 'planes'
  Incluye vista resumen_planes para métricas

- servicios/nginx/dtic-bitacoras/tools/sync_dashboard_to_db.js
  Actualizado para usar Ámbito A04 (dtic-DASUTEN) en vez de 'P2601'
  Planes A04.P001 a A04.P006 en vez de 'fases 1-13'
  Migración automática de DB si tablas no existen
  27 hitos organizados por plan (Legacy + Workgroup + Backups)

- docs/ambito/dtic-DASUTEN/_hist/260415_dashboard_P2601_actualizacion.md
  Documentación completa de la actualización
  Incluye estructura de datos, métricas y referencias

**Estructura ADN aplicada:**
- Ámbito: A04 (dtic-DASUTEN)
- Planes: A04.P001 (Red) a A04.P006 (Backups)
- Hitos: 21 completados , 3 pausados ⏸️, 6 legacy 🛑

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Ricardo Monla
2026-04-15 20:10:35 -03:00
co-authored by Claude Opus 4.6
parent faa5d7ad9a
commit cafa07303b
3 changed files with 731 additions and 54 deletions
@@ -0,0 +1,61 @@
-- 004_create_planes.sql
-- Creación de tabla planes para estructura de Ámbitos y Planes (ADN)
-- Reemplaza el concepto anterior de "fases" por "planes" dentro de cada ámbito
DO $$
BEGIN
-- Crear tabla planes (dentro de un ámbito)
CREATE TABLE IF NOT EXISTS bitacoras.planes (
id SERIAL PRIMARY KEY,
ambito_id INTEGER REFERENCES bitacoras.ambitos(id) ON DELETE CASCADE,
codigo VARCHAR(20) NOT NULL, -- Ej: 'A04.P001'
titulo VARCHAR(200) NOT NULL,
descripcion TEXT,
estado VARCHAR(10) DEFAULT '', -- ⏳ Pendiente, ✅ Completado, ⏸️ Pausado, 🔴 Bloqueado
fecha_inicio DATE,
fecha_fin DATE,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
UNIQUE(ambito_id, codigo)
);
-- Índices para planes
CREATE INDEX IF NOT EXISTS idx_planes_ambito ON bitacoras.planes(ambito_id);
CREATE INDEX IF NOT EXISTS idx_planes_codigo ON bitacoras.planes(codigo);
CREATE INDEX IF NOT EXISTS idx_planes_estado ON bitacoras.planes(estado);
-- Modificar tabla hitos: añadir plan_id (reemplaza fase_id)
IF NOT EXISTS (
SELECT 1 FROM information_schema.columns
WHERE table_schema = 'bitacoras' AND table_name = 'hitos' AND column_name = 'plan_id'
) THEN
ALTER TABLE bitacoras.hitos
ADD COLUMN plan_id INTEGER REFERENCES bitacoras.planes(id) ON DELETE SET NULL;
CREATE INDEX IF NOT EXISTS idx_hitos_plan ON bitacoras.hitos(plan_id);
END IF;
-- Mantener fase_id por compatibilidad temporal (se deprecará en el futuro)
-- Los nuevos hitos deben usar plan_id
-- Crear vista resumen_planes para métricas
CREATE OR REPLACE VIEW bitacoras.resumen_planes AS
SELECT
p.id AS plan_id,
p.codigo,
p.titulo,
p.estado,
a.codigo AS ambito_codigo,
a.nombre AS ambito_nombre,
COUNT(h.id) AS total_hitos,
COUNT(CASE WHEN h.estado = '' THEN 1 END) AS hitos_completados,
COALESCE(SUM(h.horas_presencial), 0) AS total_horas_presencial,
COALESCE(SUM(h.horas_remoto), 0) AS total_horas_remoto,
MIN(h.fecha) AS fecha_inicio_real,
MAX(h.fecha) AS fecha_fin_real
FROM bitacoras.planes p
LEFT JOIN bitacoras.ambitos a ON p.ambito_id = a.id
LEFT JOIN bitacoras.hitos h ON p.id = h.plan_id
GROUP BY p.id, p.codigo, p.titulo, p.estado, a.codigo, a.nombre;
END $$;