Seguimiento de Impuestos GLM

Aplicación interna que centraliza el calendario tributario regional de GomezLee Marketing y automatiza el envío de recordatorios por correo y WhatsApp.


INFORMACIÓN GENERAL

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

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

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:

supabase/Seguimiento-de-Impuestos-GLM.sql

El script incluye:

  • 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:

supabase/actualizacion_eventos_bloqueados.sql
supabase/actualizacion_final_calendario_y_nomina.sql

No ejecutar actualizaciones incrementales si ya se utilizó el script completo más reciente.


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:

Copy-Item .env.example .env

Configurar:

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:

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:

https://home.digitalcompass.agency/

En el servicio de Supabase Auth debe agregarse:

ADDITIONAL_REDIRECT_URLS=https://home.digitalcompass.agency/

El callback de Google OAuth hacia Supabase permanece en:

https://dbit.digitalcompass.agency/auth/v1/callback

INSTALACIÓN LOCAL

1. Clonar el repositorio

git clone https://git.digitalcompass.agency/Isaac_Aracena/seguimiento-impuestos.git
cd seguimiento-impuestos

2. Instalar dependencias

npm install

3. Crear el archivo de entorno

Copy-Item .env.example .env

Editar .env con la configuración pública correspondiente.

4. Ejecutar en desarrollo

npm run dev

Aplicación local:

http://localhost:5173/

5. Validar el proyecto

npm run typecheck
npm run lint
npm run format:check

6. Generar el build

npm run build

7. Probar el build

npm run preview

DESPLIEGUE

La aplicación se publica directamente en la raíz del subdominio:

https://home.digitalcompass.agency/

La configuración de Vite utiliza:

base: "/"

Proceso general:

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:

n8n/Seguimiento-de-Impuestos-GLM.json

Después de importarlo:

  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.

CÓMO FUNCIONA

Flujo diario

  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

{
  "action": "run_now",
  "run_date": "2026-07-24"
}

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

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

  • Calendario histórico migrado a Supabase.
  • Aplicación integrada con la base de datos.
  • Login con Google implementado.
  • Accesos administrables desde Supabase.
  • Obligaciones administrables desde la aplicación.
  • Contactos administrables desde la aplicación.
  • País obligatorio.
  • Categorías limitadas a Nómina y Administración.
  • Filtros y búsquedas implementados.
  • Regla del miércoles anterior implementada.
  • Aviso del mismo día implementado.
  • Correos HTML con branding GLM.
  • Envíos por WhatsApp.
  • Prevención de duplicados.
  • Bloqueo después del primer aviso.
  • Vista para días con más de tres obligaciones.
  • Workflow exportado en /n8n.
  • Scripts SQL almacenados en /supabase.
  • Variables públicas documentadas en .env.example.
  • Proyecto subido a Gitea.
  • 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.

S
Description
Aplicación para gestionar obligaciones tributarias y automatizar recordatorios por correo y WhatsApp.
Readme 801 KiB
Languages
PLpgSQL 50.9%
TypeScript 45.8%
CSS 1.4%
HTML 1.1%
JavaScript 0.8%