From 55acc28a2c49788670fec9ca7a4738bf86e63fe9 Mon Sep 17 00:00:00 2001 From: Isaac_Aracena Date: Mon, 27 Jul 2026 15:38:30 +0000 Subject: [PATCH] Actualizar README.md --- README.md | 751 +++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 709 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index fcdc9af..6d49879 100644 --- a/README.md +++ b/README.md @@ -1,88 +1,755 @@ # Seguimiento de Impuestos GLM -Aplicación interna para mantener el calendario tributario regional, administrar destinatarios y alimentar el flujo automático de recordatorios por Gmail y WhatsApp. +> Aplicación interna que centraliza el calendario tributario regional de GomezLee Marketing y automatiza el envío de recordatorios por correo y WhatsApp. -## Incluye +--- -- Login con Google y control de acceso desde Supabase. -- Calendario histórico 2026 migrado a PostgreSQL/Supabase. -- Creación, consulta, edición y eliminación lógica de obligaciones antes de su primer aviso. -- Bloqueo automático de edición y eliminación después del primer recordatorio enviado. -- País obligatorio y categorías limitadas a **Nómina** y **Administración**. -- Regla de alertas: **miércoles estrictamente anterior y el mismo día**, incluidos sábados y domingos. -- Contactos almacenados en Supabase y administrables desde la app. -- Países visibles aunque todavía no tengan contactos. -- Filtro buscable por país y búsqueda por nombre en Contactos. -- Búsqueda por nombre o país en Lista. -- Webhook de producción configurado para n8n. -- Workflow de n8n para Gmail + WhatsApp con correo HTML GLM. +## INFORMACIÓN GENERAL -## 1. Crear la base de datos +| Campo | Detalle | +|---|---| +| **Proyecto** | Seguimiento de Impuestos GLM | +| **Área** | Administración | +| **Estado** | Listo para producción | +| **Developer principal** | Isaac Aracena | +| **IT Manager** | Luis Matos | +| **Fecha de inicio** | 2026-07-24 | +| **Fecha de cierre** | 2026-07-27 | +| **Ciclo Shape Up** | No registrado | +| **Board de ejecución** | Pendiente de agregar enlace de Kan.bn | +| **PRD del proyecto** | Documentación funcional incluida en este repositorio | +| **Repositorio** | `https://git.digitalcompass.agency/Isaac_Aracena/seguimiento-impuestos` | +| **Aplicación** | `https://home.digitalcompass.agency/` | -Ejecuta completo: +--- + +## OBJETIVO + +### Problema que resuelve + +El seguimiento de las obligaciones tributarias de los diferentes países de GLM se realizaba mediante calendarios y archivos separados. Esto dificultaba consultar las fechas límite, identificar a los responsables y garantizar que los avisos fueran enviados a tiempo. + +Además, agregar o cambiar destinatarios requería modificar manualmente los flujos de automatización. + +### Solución implementada + +Seguimiento de Impuestos GLM centraliza en una sola aplicación: + +- El calendario tributario regional. +- Las obligaciones de Nómina y Administración. +- Los países y fechas límite. +- Los contactos responsables. +- Los canales habilitados para cada contacto. +- El historial de notificaciones enviadas. + +La aplicación permite administrar obligaciones y contactos desde una interfaz web. Un flujo de n8n consulta diariamente la información almacenada en Supabase y envía los recordatorios correspondientes por Gmail y WhatsApp. + +### Usuarios y beneficiarios + +- Equipo de Administración. +- Equipo de Nómina. +- Responsables tributarios de cada país. +- Contactos regionales. +- Dirección de Recursos Humanos. +- Equipo de IT de GomezLee Marketing. + +--- + +## ARQUITECTURA + +### Diagrama general + +```text +Usuario autorizado + | + v +Frontend React + Vite + | + +------> Supabase Auth + | + +------> Supabase PostgreSQL + | + v + Obligaciones y contactos + | + v + n8n — Ejecución 8:00 AM + | + v + RPC tax_due_reminders + | + +--------+--------+ + | | + v v + Gmail HTML WhatsApp + | | + +--------+--------+ + | + v + tax_notification_log +``` + +### Stack tecnológico + +| Componente | Tecnología | Propósito | +|---|---|---| +| Frontend | React 19 | Interfaz de usuario | +| Lenguaje | TypeScript | Tipado y lógica de la aplicación | +| Bundler | Vite | Desarrollo y compilación | +| Estilos | Tailwind CSS | Diseño visual | +| Autenticación | Supabase Auth + Google OAuth | Control de acceso | +| Base de datos | Supabase / PostgreSQL | Obligaciones, países, contactos y bitácora | +| API de datos | Supabase REST / PostgREST | Comunicación entre frontend, n8n y base de datos | +| Automatización | n8n | Orquestación de recordatorios | +| Correo | Gmail OAuth | Envío de correos HTML | +| Mensajería | WhatsApp GLM | Envío de avisos por WhatsApp | +| Hosting | EasyPanel / servidor GLM | Despliegue de la aplicación y servicios | + +### Integraciones externas + +| Sistema | Tipo de integración | Datos que fluyen | +|---|---|---| +| Supabase Auth | Google OAuth | Inicio de sesión y sesión del usuario | +| Supabase REST | API REST / RPC | Obligaciones, contactos, países y notificaciones | +| n8n | Webhook y Schedule Trigger | Ejecución manual, diaria y notificación de cambios | +| Gmail | OAuth | Correos de recordatorio | +| WhatsApp GLM | API REST | Mensajes de recordatorio | +| Google Workspace | OAuth | Identidad corporativa de los usuarios | + +--- + +## REGLAS DE NEGOCIO + +### Regla de recordatorios + +La fórmula principal es: + +> **Miércoles estrictamente anterior y el mismo día de la fecha límite.** + +Ejemplos: + +| Fecha límite | Primer aviso | Segundo aviso | +|---|---|---| +| Lunes | Miércoles anterior | Lunes | +| Martes | Miércoles anterior | Martes | +| Miércoles | Miércoles de la semana anterior | Miércoles | +| Jueves | Miércoles anterior | Jueves | +| Viernes | Miércoles anterior | Viernes | +| Sábado | Miércoles anterior | Sábado | +| Domingo | Miércoles anterior | Domingo | + +El miércoles calculado debe ser estrictamente anterior. Si la obligación vence un miércoles, el primer aviso corresponde al miércoles de la semana anterior. + +### Enrutamiento de contactos + +- Los contactos de área **Regional** reciben todas las obligaciones de todos los países. +- Los contactos regionales de **Nómina** reciben las obligaciones de Nómina de todos los países. +- Los contactos regionales de **Administración** reciben las obligaciones administrativas de todos los países. +- Los contactos de un país específico reciben solamente las obligaciones de su país y categoría. +- Solo se utilizan contactos activos. +- El correo se envía únicamente cuando el canal de correo está habilitado. +- WhatsApp se envía únicamente cuando el canal de WhatsApp está habilitado. +- Los números deben guardarse con código internacional. + +### Obligaciones tributarias + +- El país es obligatorio. +- Las únicas categorías disponibles son: + - Nómina. + - Administración. +- Una obligación puede editarse o eliminarse mientras no tenga avisos enviados. +- Después del primer correo o WhatsApp registrado, la obligación queda bloqueada. +- Las obligaciones bloqueadas permanecen disponibles en modo de solo lectura. +- Cuando un día tiene más de tres obligaciones, la opción **Ver todos** permite consultar la lista completa. + +### Prevención de duplicados + +Cada notificación enviada se registra en `tax_notification_log`. + +La combinación de obligación, contacto, canal y tipo de aviso evita que el mismo recordatorio sea enviado dos veces. + +--- + +## BASE DE DATOS + +### Tablas + +La aplicación utiliza cinco tablas: + +| Tabla | Propósito | +|---|---| +| `tax_calendar_access` | Correos autorizados para ingresar | +| `tax_countries` | Catálogo de países | +| `tax_obligations` | Obligaciones y eventos tributarios | +| `tax_contacts` | Contactos responsables y canales habilitados | +| `tax_notification_log` | Bitácora de correos y WhatsApp enviados | + +### Funciones principales + +| Función | Propósito | +|---|---| +| `has_tax_calendar_access` | Valida si el correo puede utilizar la aplicación | +| `tax_previous_wednesday` | Calcula el miércoles estrictamente anterior | +| `tax_due_reminders` | Devuelve los recordatorios y destinatarios pendientes | +| `tax_record_notification` | Registra un envío exitoso | +| `tax_obligation_delivery_status` | Consulta si una obligación ya fue notificada | +| `tax_prevent_sent_obligation_changes` | Bloquea cambios después del primer aviso | + +### Instalación completa + +Para una instalación nueva, ejecutar en Supabase: ```text supabase/Seguimiento-de-Impuestos-GLM.sql ``` -El script crea tablas, RLS, funciones, bitácora anti-duplicados, bloqueo de eventos notificados, accesos iniciales, contactos y las 294 obligaciones históricas de 2026. +El script incluye: -Si ya habías ejecutado una versión anterior del script completo, ejecuta solamente: +- Tablas. +- Índices. +- Triggers. +- Funciones RPC. +- Políticas RLS. +- Accesos iniciales. +- Países. +- Contactos. +- Obligaciones históricas de 2026. +- Prevención de notificaciones duplicadas. + +### Actualizaciones incrementales + +Para bases que ya tenían una versión anterior: ```text supabase/actualizacion_eventos_bloqueados.sql +supabase/actualizacion_final_calendario_y_nomina.sql ``` -## 2. Configurar frontend +No ejecutar actualizaciones incrementales si ya se utilizó el script completo más reciente. -Copia `.env.example` como `.env` y completa la llave pública de Supabase. La `service_role` nunca debe ponerse en Vite. +--- -```bash +## CONFIGURACIÓN Y SETUP + +### Prerrequisitos + +- Node.js instalado. +- npm instalado. +- Acceso al Supabase empresarial. +- Acceso a Google Cloud y Supabase Auth. +- Acceso a n8n. +- Credencial de Gmail configurada en n8n. +- Acceso a la API de WhatsApp de GLM. +- Acceso al hosting de EasyPanel. +- Correo autorizado para ingresar a la aplicación. + +### Variables del frontend + +Copiar el archivo de ejemplo: + +```powershell +Copy-Item .env.example .env +``` + +Configurar: + +```env +VITE_SUPABASE_URL=https://dbit.digitalcompass.agency +VITE_SUPABASE_PUBLISHABLE_KEY=REEMPLAZAR_CON_LA_LLAVE_PUBLICA +VITE_TAX_WEBHOOK_URL=https://agenteit.digitalcompass.agency/webhook/seguimiento-impuestos +``` + +También puede utilizarse: + +```env +VITE_SUPABASE_ANON_KEY=REEMPLAZAR_CON_LA_ANON_KEY +``` + +Nunca colocar la llave `service_role` dentro del frontend. + +### Variables y credenciales de n8n + +| Configuración | Descripción | +|---|---| +| Supabase URL | URL del Supabase empresarial | +| Supabase Service Role | Llave privada para ejecutar RPC y registrar envíos | +| Gmail Credential | Cuenta que envía los recordatorios | +| WhatsApp Base URL | Endpoint del servicio de WhatsApp | +| WhatsApp Instance | Instancia `botsoporte` | +| WhatsApp API Key | Credencial privada del servicio | +| GLM Tax App URL | `https://home.digitalcompass.agency/` | +| GLM Logo URL | Logo público utilizado en el correo HTML | + +Las llaves privadas deben administrarse en n8n o en el vault de credenciales de GLM. + +> **Nunca commitear `.env`, llaves privadas, tokens, contraseñas o credenciales reales al repositorio.** + +### Supabase Auth + +La URL autorizada para regresar a la aplicación después del login es: + +```text +https://home.digitalcompass.agency/ +``` + +En el servicio de Supabase Auth debe agregarse: + +```env +ADDITIONAL_REDIRECT_URLS=https://home.digitalcompass.agency/ +``` + +El callback de Google OAuth hacia Supabase permanece en: + +```text +https://dbit.digitalcompass.agency/auth/v1/callback +``` + +--- + +## INSTALACIÓN LOCAL + +### 1. Clonar el repositorio + +```powershell +git clone https://git.digitalcompass.agency/Isaac_Aracena/seguimiento-impuestos.git +cd seguimiento-impuestos +``` + +### 2. Instalar dependencias + +```powershell npm install +``` + +### 3. Crear el archivo de entorno + +```powershell +Copy-Item .env.example .env +``` + +Editar `.env` con la configuración pública correspondiente. + +### 4. Ejecutar en desarrollo + +```powershell npm run dev ``` -URL local: +Aplicación local: ```text -http://localhost:5173/calendario-impuestos/ +http://localhost:5173/ ``` -Build: +### 5. Validar el proyecto -```bash +```powershell +npm run typecheck +npm run lint +npm run format:check +``` + +### 6. Generar el build + +```powershell npm run build +``` + +### 7. Probar el build + +```powershell npm run preview ``` -## 3. Configurar n8n +--- -Importa: +## DESPLIEGUE + +La aplicación se publica directamente en la raíz del subdominio: + +```text +https://home.digitalcompass.agency/ +``` + +La configuración de Vite utiliza: + +```ts +base: "/" +``` + +Proceso general: + +```powershell +npm install +npm run build +``` + +El contenido generado en `dist/` debe desplegarse en el servicio correspondiente de EasyPanel. + +Después del despliegue: + +1. Abrir la aplicación. +2. Iniciar sesión con Google. +3. Confirmar que Supabase redirige a la raíz del subdominio. +4. Verificar que carguen obligaciones, países y contactos. +5. Crear un registro de prueba. +6. Confirmar su almacenamiento en Supabase. + +--- + +## CONFIGURACIÓN DE N8N + +Importar el archivo: ```text n8n/Seguimiento-de-Impuestos-GLM.json ``` -Luego sigue `n8n/CONFIGURACION.md`. El único ajuste dentro del canvas es seleccionar la credencial de Gmail; las demás claves se leen de variables de entorno. +Después de importarlo: -## Enrutamiento +1. Seleccionar la credencial en **Gmail - Enviar recordatorio**. +2. Configurar la conexión privada con Supabase. +3. Configurar el endpoint y la API key de WhatsApp. +4. Verificar la zona horaria `America/Santo_Domingo`. +5. Ejecutar una prueba manual. +6. Confirmar el correo recibido. +7. Confirmar el WhatsApp recibido. +8. Verificar el registro en `tax_notification_log`. +9. Activar el workflow. -- **Regional** recibe todas las obligaciones. -- **Nómina** recibe únicamente obligaciones de Nómina de su país. -- **Administración** recibe únicamente obligaciones de Administración de su país. -- El flujo consulta los contactos en Supabase en cada ejecución; agregar un contacto en la app no requiere modificar n8n. +--- -## Despliegue +## CÓMO FUNCIONA -Vite conserva la base: +### Flujo diario -```ts -base: "/calendario-impuestos/"; +1. El Schedule Trigger inicia el workflow a las 8:00 a. m. +2. n8n obtiene la fecha correspondiente a la ejecución. +3. El nodo de Supabase llama la RPC `tax_due_reminders`. +4. Supabase identifica las obligaciones que deben notificarse. +5. Supabase cruza cada obligación con los contactos aplicables. +6. n8n genera el correo HTML con el branding de GLM. +7. n8n genera el mensaje de WhatsApp. +8. Gmail envía los correos habilitados. +9. La API de WhatsApp envía los mensajes habilitados. +10. Cada envío exitoso se registra en Supabase. +11. Los registros enviados quedan protegidos contra duplicados. + +### Cambios desde la aplicación + +Cuando el usuario: + +- Crea una obligación. +- Actualiza una obligación. +- Elimina una obligación. +- Crea un contacto. +- Actualiza un contacto. +- Desactiva un contacto. + +La información se guarda directamente en Supabase. + +El flujo de n8n consulta siempre la información vigente, por lo que no es necesario modificar manualmente el workflow cuando cambien los contactos. + +### Schedules y triggers + +| Trigger | Frecuencia | Descripción | +|---|---|---| +| Schedule Trigger | Diario, 8:00 a. m. | Envía los recordatorios correspondientes | +| Manual Trigger | Bajo demanda | Permite realizar pruebas desde n8n | +| Webhook `seguimiento-impuestos` | Bajo demanda | Recibe acciones del frontend o ejecuciones controladas | + +### Prueba con una fecha específica + +```json +{ + "action": "run_now", + "run_date": "2026-07-24" +} ``` -## Actualización final de calendario y Nómina +--- -- Cuando un día tiene más de tres obligaciones, el enlace **Ver todos** abre una vista con la lista completa; desde allí se puede abrir cada obligación. -- El script `supabase/actualizacion_final_calendario_y_nomina.sql` agrega a Mati Soto Valenzuela e Iveth Herrera como contactos regionales especializados en Nómina. -- Los contactos regionales con área `nomina` reciben obligaciones de Nómina de todos los países. Los contactos con área `regional` continúan recibiendo todas las categorías. -- El número de Mati se guarda como `18094037571`, agregando el prefijo internacional `1` requerido para WhatsApp. +## TESTING + +### Casos de prueba mínimos + +| Caso | Input | Resultado esperado | Estado | +|---|---|---|---| +| Login autorizado | Correo incluido en `tax_calendar_access` | Acceso concedido | Validado | +| Login no autorizado | Correo no incluido | Acceso denegado | Validado | +| Crear obligación | Fecha, descripción, categoría y país | Registro visible en calendario | Validado | +| País vacío | Obligación sin país | Formulario no permite guardar | Validado | +| Categoría inválida | Valor diferente a Nómina o Administración | Registro rechazado | Validado | +| Editar sin aviso | Obligación sin notificaciones | Cambios permitidos | Validado | +| Editar con aviso | Obligación ya notificada | Modo de solo lectura | Validado | +| Eliminar sin aviso | Obligación sin notificaciones | Eliminación permitida | Validado | +| Eliminar con aviso | Obligación ya notificada | Eliminación bloqueada | Validado | +| Más de tres obligaciones | Día con cuatro o más registros | Opción Ver todos disponible | Validado | +| Contacto regional | Área Regional activa | Recibe todas las obligaciones | Validado | +| Contacto regional de Nómina | País Regional y área Nómina | Recibe Nómina de todos los países | Validado | +| Correo deshabilitado | `email_enabled = false` | No se genera correo | Validado | +| WhatsApp deshabilitado | `whatsapp_enabled = false` | No se genera WhatsApp | Validado | +| Aviso duplicado | Mismo contacto, obligación, canal y tipo | Segundo envío bloqueado | Validado | +| API de WhatsApp caída | Error HTTP | Ejecución registrada como fallida | Pendiente de prueba controlada | +| Gmail no disponible | Error de credencial o servicio | Nodo falla y queda visible en Executions | Pendiente de prueba controlada | + +--- + +## ERRORES CONOCIDOS Y TROUBLESHOOTING + +| Error | Causa probable | Solución | +|---|---|---| +| El login vuelve a Supabase | Redirect URL incorrecta | Agregar `https://home.digitalcompass.agency/` a `ADDITIONAL_REDIRECT_URLS` | +| Pantalla en blanco después del deploy | Base de Vite incorrecta | Confirmar `base: "/"` y reconstruir | +| 401 Unauthorized en Supabase | Llave incorrecta o expirada | Revisar la llave pública o `service_role` según el componente | +| No cargan obligaciones | Error en URL, RLS o sesión | Revisar consola del navegador y políticas RLS | +| No llegan correos | Credencial de Gmail no seleccionada | Abrir el nodo Gmail y seleccionar la credencial | +| No llega WhatsApp | API key, número o instancia incorrectos | Revisar encabezado `apikey`, instancia y código internacional | +| Recordatorio duplicado | Bitácora no registrada correctamente | Revisar los nodos `Supabase - Registrar correo/WhatsApp` | +| Obligación editable después del aviso | Trigger de protección no instalado | Ejecutar el script actualizado de Supabase | +| Contacto no recibe avisos | País, área, canal o estado incorrecto | Revisar el contacto desde la app | +| Webhook no responde | Workflow inactivo o URL incorrecta | Revisar activación y Production URL en n8n | +| Error al compilar | Dependencias incompletas | Eliminar `node_modules`, ejecutar `npm install` y reconstruir | + +--- + +## MONITOREO + +### n8n + +Revisar periódicamente: + +- **Executions**. +- Ejecuciones fallidas. +- Respuesta de Gmail. +- Respuesta de WhatsApp. +- Respuesta de los nodos de registro en Supabase. + +Una ejecución normal debe finalizar sin nodos rojos y registrar cada canal enviado. + +### Supabase + +Revisar: + +- Nuevas obligaciones. +- Contactos activos. +- Estado de acceso de usuarios. +- Registros recientes en `tax_notification_log`. +- Duplicados o errores de datos. +- Obligaciones bloqueadas después del primer envío. + +### Resultado esperado + +Cada día a las 8:00 a. m.: + +- Se consultan las obligaciones pendientes. +- Se identifican los contactos aplicables. +- Se envían los canales habilitados. +- Se registra cada envío exitoso. +- No se repiten avisos ya enviados. + +--- + +## ESTRUCTURA DEL REPOSITORIO + +```text +seguimiento-impuestos/ +|-- README.md +|-- AGENTS.md +|-- package.json +|-- package-lock.json +|-- vite.config.ts +|-- tsconfig.json +|-- eslint.config.js +|-- index.html +|-- .env.example +|-- .gitignore +| +|-- public/ +| |-- favicon.ico +| |-- favicon-32.png +| |-- favicon-192.png +| └-- apple-touch-icon.png +| +|-- src/ +| |-- App.tsx +| |-- TaxApp.tsx +| |-- main.tsx +| |-- styles.css +| | +| |-- assets/ +| | └-- glm-logo.png +| | +| |-- auth/ +| | └-- AuthGate.tsx +| | +| └-- lib/ +| |-- supabase-auth.ts +| |-- supabase-data.ts +| └-- tax-utils.ts +| +|-- supabase/ +| |-- README.md +| |-- Seguimiento-de-Impuestos-GLM.sql +| |-- seguimiento_impuestos_auth.sql +| |-- actualizacion_eventos_bloqueados.sql +| └-- actualizacion_final_calendario_y_nomina.sql +| +|-- n8n/ +| |-- CONFIGURACION.md +| └-- Seguimiento-de-Impuestos-GLM.json +| +└-- dist/ + └-- Build generado para producción +``` + +`node_modules/`, `.env` y demás archivos sensibles o generados no deben subirse al repositorio. + +--- + +## CHANGELOG + +### 2026-07-27 — v1.0.0 + +- Aplicación preparada para producción. +- Migración del calendario histórico 2026 a Supabase. +- Login con Google y control de accesos. +- Gestión de obligaciones por país y categoría. +- Gestión dinámica de contactos. +- Filtros por país y nombre. +- Búsqueda en la vista Lista. +- Recordatorios por Gmail y WhatsApp. +- Correo HTML con identidad visual GLM. +- Prevención de envíos duplicados. +- Bloqueo de obligaciones después del primer aviso. +- Vista completa para días con más de tres obligaciones. +- Despliegue configurado en la raíz del subdominio. +- Flujo n8n con ejecución diaria a las 8:00 a. m. + +### 2026-07-25 — v0.9.0 + +- Integración del frontend con Supabase. +- Creación de las tablas principales. +- Migración de obligaciones históricas. +- Creación del flujo inicial de n8n. +- Incorporación de contactos regionales y por país. + +### 2026-07-24 — v0.1.0 + +- Limpieza del prototipo generado por Lovable. +- Eliminación de archivos y dependencias innecesarias. +- Estandarización del proyecto con React, Vite y TypeScript. +- Aplicación inicial del branding de GLM. + +--- + +## DECISIONS LOG + +### DEC-001 — Supabase como fuente única de datos + +- **Fecha:** 2026-07-24 +- **Contexto:** El prototipo almacenaba el calendario directamente en el frontend. +- **Opciones consideradas:** Mantener datos estáticos o migrarlos a Supabase. +- **Decisión:** Utilizar Supabase/PostgreSQL. +- **Razón:** Permite persistencia, administración multiusuario, integración con n8n y trazabilidad. + +### DEC-002 — Lógica determinística para las fechas + +- **Fecha:** 2026-07-24 +- **Contexto:** Se consideró utilizar Gemini para decidir cuándo enviar los avisos. +- **Opciones consideradas:** IA generativa o funciones de fechas en PostgreSQL. +- **Decisión:** Utilizar funciones determinísticas. +- **Razón:** La regla es exacta y no debe depender de interpretaciones probabilísticas. + +### DEC-003 — Contactos administrados desde la aplicación + +- **Fecha:** 2026-07-25 +- **Contexto:** Cada cambio de destinatario obligaba a editar n8n. +- **Opciones consideradas:** Contactos hardcodeados o contactos en Supabase. +- **Decisión:** Guardar contactos en `tax_contacts`. +- **Razón:** Los usuarios pueden mantener destinatarios sin modificar el workflow. + +### DEC-004 — Bloqueo después del primer envío + +- **Fecha:** 2026-07-26 +- **Contexto:** Modificar una obligación después de notificarla podía generar inconsistencias. +- **Opciones consideradas:** Permitir cambios siempre o bloquear después del envío. +- **Decisión:** Bloquear edición y eliminación después del primer aviso. +- **Razón:** Preserva la integridad del historial y evita discrepancias con mensajes ya enviados. + +### DEC-005 — Despliegue en subdominio + +- **Fecha:** 2026-07-27 +- **Contexto:** La app inicialmente utilizaba `/calendario-impuestos/` como base. +- **Opciones consideradas:** Ruta interna o subdominio independiente. +- **Decisión:** Publicar en `https://home.digitalcompass.agency/`. +- **Razón:** Simplifica navegación, OAuth, despliegue y mantenimiento. + +--- + +## CONTACTOS DEL PROYECTO + +| Rol | Nombre | Contacto | +|---|---|---| +| Solicitante funcional | Ada | Pendiente de documentar | +| IT Manager | Luis Matos | `lmatos@gomezleemarketing.com` | +| Developer principal | Isaac Aracena | `iaracena@gomezleemarketing.com` | +| Contacto regional de Nómina | Mati Soto Valenzuela | `msoto@gomezleemarketing.com` | +| Contacto regional de Nómina | Iveth Herrera | `iherrera@gomezleemarketing.com` | + +--- + +## DEFINITION OF DONE + +- [x] Calendario histórico migrado a Supabase. +- [x] Aplicación integrada con la base de datos. +- [x] Login con Google implementado. +- [x] Accesos administrables desde Supabase. +- [x] Obligaciones administrables desde la aplicación. +- [x] Contactos administrables desde la aplicación. +- [x] País obligatorio. +- [x] Categorías limitadas a Nómina y Administración. +- [x] Filtros y búsquedas implementados. +- [x] Regla del miércoles anterior implementada. +- [x] Aviso del mismo día implementado. +- [x] Correos HTML con branding GLM. +- [x] Envíos por WhatsApp. +- [x] Prevención de duplicados. +- [x] Bloqueo después del primer aviso. +- [x] Vista para días con más de tres obligaciones. +- [x] Workflow exportado en `/n8n`. +- [x] Scripts SQL almacenados en `/supabase`. +- [x] Variables públicas documentadas en `.env.example`. +- [x] Proyecto subido a Gitea. +- [x] Manual de uso elaborado. +- [ ] Ejecutar monitoreo controlado durante los primeros días en producción. +- [ ] Registrar el enlace definitivo del board de Kan.bn. +- [ ] Documentar la aprobación funcional final. + +--- + +## SEGURIDAD + +- No subir el archivo `.env`. +- No almacenar la llave `service_role` en React. +- No publicar la API key de WhatsApp. +- No almacenar contraseñas o tokens en el README. +- Utilizar únicamente llaves públicas en variables `VITE_*`. +- Mantener RLS activo en las tablas. +- Restringir los accesos mediante `tax_calendar_access`. +- Revisar periódicamente los usuarios autorizados. +- Rotar credenciales cuando una persona deje de necesitar acceso. + +--- + +## DOCUMENTACIÓN ADICIONAL + +- `AGENTS.md`: reglas para agentes y asistentes de programación. +- `supabase/README.md`: instrucciones específicas de la base de datos. +- `n8n/CONFIGURACION.md`: configuración del workflow. +- `supabase/Seguimiento-de-Impuestos-GLM.sql`: instalación completa. +- `n8n/Seguimiento-de-Impuestos-GLM.json`: workflow importable. + +--- + +Documento mantenido por el equipo **GLM IT**. \ No newline at end of file