Skip to content

Runbook Operativo del Sistema — ITECEL ADM ​

Última actualización: 2026-09-28
Estado: Documento Vivo / Operaciones
Propósito: Procedimientos paso a paso para el operador del sistema. Libre de credenciales o secretos; enfocado en la ejecución segura de despliegues, migraciones, diagnóstico de mensajería y verificaciones forenses.


Índice de Procedimientos ​

  1. Superficies y Ritual de Despliegue (Vercel, Supabase y Cloudflare Pages)
  2. Checklist Anti-Deadlock para DDL en Producción
  3. Protocolo de Diagnóstico Forense de Correos y Supresión en Resend
  4. Checklist de Verificación Forense Post-Sync (Table Editor)
  5. Despliegue del Visor de Documentación W-2 (Cloudflare Pages + Zero Trust)

1. Superficies y Ritual de Despliegue ​

Premisa Fundamental (R1 / ADR-011): Las Tres Superficies del Sistema ​

El ecosistema de ITECEL ADM opera sobre tres superficies de despliegue claramente diferenciadas:

  1. Frontend Web de la Aplicación (Vercel): El comando git push hacia la rama principal de GitHub activa el build automático en Vercel, el cual compila y publica únicamente el frontend web (src/, public/) en adm.itecelgs.com.
  2. Backend y Base de Datos (Supabase): Vercel NO despliega Edge Functions de Supabase ni ejecuta scripts de migración SQL en la base de datos. Cualquier cambio de backend requiere el ritual manual correspondiente en el Dashboard de Supabase.
  3. Visor de Documentación Técnica (Cloudflare Pages): La wiki técnica desacoplada (wiki/) se compila y publica en Cloudflare Pages (wiki-adm.itecelgs.com), protegida perimetralmente con Cloudflare Zero Trust (One-Time PIN por email). Consulta la sección 5 y docs/RUNBOOK-W2-DESPLEGUE-WIKI.md.

Procedimiento A: Despliegue de Edge Functions (Supabase) ​

Cuando un turno incluya cambios o nuevas funciones en supabase/functions/:

  1. Ingreso al Panel:

    • Iniciar sesión en el Dashboard de Supabase.
    • Navegar al proyecto correspondiente de producción.
    • Seleccionar en el menú lateral: Edge Functions.
  2. Edición o Creación:

    • Si la función ya existe: hacer clic sobre la función en la lista y seleccionar Edit Function o Deploy New Version.
    • Si es una función nueva: hacer clic en Create Function, asignando el nombre exacto de la carpeta en el repositorio (ej. send-email-resend, send-otp).
  3. Copia de Código Fuente:

    • Copiar el contenido exacto del archivo index.ts (y cualquier archivo complementario en su carpeta) desde el repositorio local.
    • Pegar en el editor integrado de la función en Supabase.
  4. Variables de Entorno y Secretos:

    • Verificar en la pestaña Secrets de Edge Functions que existan las claves requeridas (ej. RESEND_API_KEY, SUPABASE_SERVICE_ROLE_KEY, APP_URL).
    • Jamás quemar estas variables en el código TypeScript.
  5. Despliegue (Deploy):

    • Presionar el botón Deploy / Save.
    • Esperar a que el indicador de estado cambie a verde (Active).
  6. Smoke Test de Función:

    • Realizar una llamada de prueba o verificar la primera invocación desde la aplicación web con la consola de red abierta (Network Tab).
    • Revisar la pestaña Logs de la Edge Function para confirmar código de respuesta HTTP 200 OK y ausencia de excepciones en tiempo de ejecución.

Procedimiento B: Despliegue de SQL de Esquema (SQL Editor) ​

Cuando un turno incluya modificaciones de esquema, tablas, índices, RLS o funciones PL/pgSQL:

  1. Inspección Previa del Esquema Real (Regla 1 de Gobernanza SQL):

    • No asumir columnas o tipos de datos basándose únicamente en migraciones locales.
    • Si se va a alterar una función existente, obtener previamente su definición real en producción:
      sql
      SELECT pg_get_functiondef('nombre_funcion(tipos)'::regprocedure);
  2. Apertura de Sesión en SQL Editor:

    • En el Dashboard de Supabase, ir a SQL Editor.
    • Crear una nueva pestaña (New query) con un nombre descriptivo de la tarea (ej. migracion_licencias_2026_09).
  3. Estructura Segura del Script (Transaccionalidad):

    • Todo script de DDL o DML debe estar contenido en un bloque transaccional:
      sql
      BEGIN;
      -- Sentencias de migración
      COMMIT;
    • Si el cambio es experimental o requiere prueba preliminar, utilizar ROLLBACK; antes del commit definitivo.
  4. Ejecución y Verificación de Retorno:

    • Ejecutar el script (Run).
    • Confirmar que el panel inferior muestre Success. No rows returned o los resultados esperados.
    • En caso de error (42710, 42501, 23503, etc.), la transacción habrá hecho rollback automático. Reportar la causa exacta con el código de error de Postgres.

2. Checklist Anti-Deadlock para DDL en Producción ​

Las operaciones de Definición de Datos (ALTER TABLE, ADD CONSTRAINT, etc.) solicitan bloqueos exclusivos. Para evitar interrupciones o congelamiento del servicio en horas productivas, seguir estrictamente este checklist:

  • [ ] Ventana Operativa Adecuada:
    Ejecutar preferentemente fuera de los picos de uso del condominio (ej. evitar días 1 al 5 de mes en horario matutino donde administradores generan cobros masivos).
  • [ ] Inspección de Conexiones Activas:
    Verificar que no existan consultas lentas o transacciones colgadas bloqueando las tablas involucradas:
    sql
    SELECT pid, now() - xact_start AS duracion, query, state
    FROM pg_stat_activity
    WHERE state != 'idle' 
      AND query NOT ILIKE '%pg_stat_activity%'
    ORDER BY duracion DESC;
  • [ ] Definición de Lock Timeout Preventivo:
    Establecer siempre un timeout corto para la sesión actual. Si otra transacción retiene el bloqueo por más de 2 segundos, el script aborta inmediatamente sin formar una cola de deadlocks:
    sql
    SET lock_timeout = '2s';
  • [ ] Creación Concurrente de Índices:
    Jamás ejecutar CREATE INDEX en tablas grandes sin concurrencia. Utilizar siempre:
    sql
    CREATE INDEX CONCURRENTLY IF NOT EXISTS idx_nombre ON tabla(columna);
  • [ ] Adición Segura de Columnas:
    Agregar columnas con valor por defecto NULL, o si llevan DEFAULT, asegurar que no bloqueen escrituras concurrentes (Postgres 11+ maneja defaults constantes sin reescritura de tabla).
  • [ ] Validación Post-DDL:
    Comprobar que las tablas sigan respondiendo a consultas ordinarias de lectura inmediatamente después del cambio.

3. Protocolo de Diagnóstico Forense de Correos ​

Flujo Completo de la Cadena de Notificaciones ​

[ Interfaz React (UI) ]
         │
         ▼ (Llamada HTTP POST / Supabase Client)
[ Edge Function (send-email-resend / send-otp) ]
         │
         ▼ (API Key Bearer HTTPS)
[ Resend API (api.resend.com/emails) ]
         │
         ▼ (Protocolo SMTP / DNS SPF-DKIM-DMARC)
[ Servidor Receptor (Google / Outlook / Corporativo) ]
         │
         ▼
[ Bandeja de Entrada del Residente / Administrador ]

Diagnóstico Paso a Paso ante Fallo de Entrega ​

Paso 1: Evidencia en Frontend (Network & Console) ​

  1. Abrir las Herramientas de Desarrollador del navegador (F12 / Ctrl+Shift+I).
  2. En la pestaña Network, filtrar por functions/v1/ o el nombre del endpoint.
  3. Revisar el código de respuesta HTTP:
    • 401 / 403: Error de autorización o token inválido.
    • 500: Excepción interna en la Edge Function.
    • 200: La función procesó la solicitud; el error está aguas abajo.
  4. Inspeccionar el payload de respuesta JSON (Response Tab).

Paso 2: Evidencia en Edge Functions (Logs de Supabase) ​

  1. Ir al Dashboard de Supabase → Edge Functions → seleccionar la función involucrada.
  2. Abrir la pestaña Logs.
  3. Buscar el timestamp del intento de envío.
  4. Verificar si la llamada a resend.emails.send() devolvió un ID de mensaje (resend_id) o un código de error de la API de Resend (ej. rate_limit_exceeded, missing_required_field).

Paso 3: Evidencia en el Dashboard de Resend ​

  1. Iniciar sesión en el portal de Resend.
  2. Ir a la sección Emails.
  3. Localizar el correo destinatario en la lista de envíos recientes.
  4. Observar el estado reportado por Resend:
    • Delivered: El servidor receptor aceptó el correo.
    • Bounced: El correo fue rechazado por el servidor de destino (dirección inexistente, buzón lleno).
    • Complained: El usuario marcó el mensaje como spam.
    • Suppressed: El correo no fue enviado porque la dirección está en la lista de supresión.

Paso 4: Manejo de la Lista de Supresión (Suppression List) ​

  • Causa: Resend bloquea automáticamente direcciones que generaron un Hard Bounce previo para proteger la reputación del dominio itecelgs.com.
  • Regla Estricta (ADR-009): Queda terminantemente prohibido probar envíos con direcciones inventadas (asdf@test.com, correo_falso@...).
  • Desbloqueo de Casillas Válidas:
    1. En Resend, ir a Audiences / Suppressions (o pestaña Suppressions dentro de Settings/Domains).
    2. Buscar la dirección de correo afectada.
    3. Si la casilla es de un cliente real que ya reactivó o corrigió su buzón: hacer clic en Remove from suppression list.
    4. Realizar un nuevo envío de prueba desde la aplicación.

4. Checklist de Verificación Forense Post-Sync ​

Después de ejecutar cualquier sincronización masiva, migración de licencias, o carga de datos:

  • [ ] Acceso a Table Editor:
    Abrir Supabase Dashboard → Table Editor sobre las tablas afectadas (condos, condo_licenses, app_users, housing_units, expenses, quotes).
  • [ ] Paridad de Conteo:
    Comparar el número de filas esperadas contra el conteo real en base de datos.
  • [ ] Auditoría de Timestamps (created_at / updated_at):
    Filtrar por las filas modificadas en los últimos 15 minutos para asegurar que los registros corresponden a la ejecución actual.
  • [ ] Integridad de Claves Foráneas (FKs):
    Verificar que condo_id coincida exactamente con el condominio objetivo y no existan registros huérfanos con NULL en campos obligatorios.
  • [ ] Separación Identidad vs Descriptivo (ADR-002):
    Confirmar que las modificaciones institucionales en condos no hayan sobreescrito correos personales en app_users o viceversa.
  • [ ] Revisión del Registro de Auditoría:
    Consultar la tabla audit_log para confirmar que las mutaciones registraron el user_id verificado (o system en procesos batch) y no valores nulos o quemados.

5. Despliegue del Visor de Documentación W-2 (Cloudflare Pages + Zero Trust) ​

Iniciativa: Wiki + Guía de Usuario y Chatbot (Fase W-2)
Guía Operativa Detallada: Para el procedimiento paso a paso completo de conexión a GitHub, build command (cd wiki && npm install && npm run docs:build), configuración de subdominio wiki-adm.itecelgs.com y políticas de Cloudflare Zero Trust con OTP, consultar:
👉 [docs/RUNBOOK-W2-DESPLEGUE-WIKI.md](file:///c:/Users/Admin/ITECEL-adm/ITECEL-ADM/docs/RUNBOOK-W2-DESPLEGUE-WIKI.md)

Resumen Rápido para el Operador: ​

  1. Plataforma: Cloudflare Pages (conectado al repositorio privado zjuanf5-ai/ITECEL-ADM, rama main).
  2. Build Settings: Root /, Build Command cd wiki && npm install && npm run docs:build, Output directory wiki/.vitepress/dist, NODE_VERSION=20.
  3. Dominio: wiki-adm.itecelgs.com (sin tocar el DNS de adm.itecelgs.com).
  4. Seguridad Obligatoria: Cloudflare Zero Trust (Access Application Self-hosted) con política One-Time PIN restringida exclusivamente a los correos del equipo.
  5. Estado: Preparado en repositorio; ejecución manual pendiente del operador.

Wiki Técnica Oficial — ITECEL ADM