Subir archivos a "/"
This commit is contained in:
@@ -0,0 +1,876 @@
|
||||
# Seguimiento de Impuestos GLM
|
||||
|
||||
> Aplicación interna de GomezLee Marketing para centralizar el calendario tributario regional, administrar responsables y automatizar recordatorios por Gmail, Google Chat y Google Calendar.
|
||||
|
||||
---
|
||||
|
||||
## INFORMACIÓN GENERAL
|
||||
|
||||
| Campo | Detalle |
|
||||
|---|---|
|
||||
| **Proyecto** | Seguimiento de Impuestos GLM |
|
||||
| **Área** | Administración / Nómina |
|
||||
| **Estado** | Producción · mantenimiento continuo |
|
||||
| **Developer principal** | Isaac Aracena |
|
||||
| **IT Manager** | Luis Matos |
|
||||
| **Fecha de inicio** | 2026-07-24 |
|
||||
| **Fecha de versión actual** | 2026-08-07 |
|
||||
| **Ciclo Shape Up** | No registrado |
|
||||
| **Board de ejecución** | Kan.bn · enlace pendiente de registrar |
|
||||
| **PRD del proyecto** | Pendiente de enlazar |
|
||||
| **Repositorio** | `https://git.digitalcompass.agency/Isaac_Aracena/seguimiento-impuestos` |
|
||||
| **Aplicación** | `https://digitalcompass.agency/calendario-impuestos/` |
|
||||
|
||||
---
|
||||
|
||||
## OBJETIVO
|
||||
|
||||
### Problema que resuelve
|
||||
|
||||
El seguimiento de obligaciones tributarias de GLM se realizaba a partir de calendarios y archivos separados, lo que dificultaba consultar fechas límite, mantener responsables actualizados y asegurar que cada persona recibiera los avisos correspondientes según país y área.
|
||||
|
||||
Los cambios de contactos también requerían intervención técnica cuando los destinatarios estaban definidos directamente en automatizaciones.
|
||||
|
||||
### Solución implementada
|
||||
|
||||
**Seguimiento de Impuestos GLM** centraliza en una sola aplicación:
|
||||
|
||||
- Calendario tributario regional.
|
||||
- Obligaciones históricas y futuras.
|
||||
- País, categoría y fecha límite de cada obligación.
|
||||
- Contactos responsables por país y área.
|
||||
- Búsqueda automatizada de empleados en BambooHR.
|
||||
- Alta manual y edición de contactos.
|
||||
- Recordatorios por Gmail y Google Chat.
|
||||
- Sincronización de obligaciones con Google Calendar.
|
||||
- Historial de notificaciones enviadas.
|
||||
- Registro del usuario que crea nuevas obligaciones.
|
||||
- Bloqueo de eventos que ya generaron avisos.
|
||||
|
||||
La aplicación utiliza Supabase como fuente central de datos y n8n como capa de automatización.
|
||||
|
||||
### Usuarios / Beneficiarios
|
||||
|
||||
- Equipo de Administración.
|
||||
- Equipo de Nómina.
|
||||
- Responsables administrativos por país.
|
||||
- Responsables regionales.
|
||||
- Dirección y personal que necesita visibilidad del calendario tributario.
|
||||
- Equipo de IT de GomezLee Marketing.
|
||||
|
||||
---
|
||||
|
||||
## ARQUITECTURA
|
||||
|
||||
### Diagrama de flujo
|
||||
|
||||
```text
|
||||
┌─────────────────────────────┐
|
||||
│ Usuario autorizado GLM │
|
||||
└──────────────┬──────────────┘
|
||||
│
|
||||
v
|
||||
┌─────────────────────────────┐
|
||||
│ React + Vite │
|
||||
│ /calendario-impuestos/ │
|
||||
└───────┬─────────┬───────────┘
|
||||
│ │
|
||||
Google OAuth │ │ REST / RPC
|
||||
en popup │ v
|
||||
│ ┌───────────────────────┐
|
||||
└──>│ Supabase Auth/Postgres│
|
||||
└──────┬───────┬────────┘
|
||||
│ │
|
||||
┌──────────────────┘ └──────────────────┐
|
||||
│ │
|
||||
v v
|
||||
┌───────────────────────┐ ┌──────────────────────┐
|
||||
│ Obligaciones/contactos│ │ Access / logs / sync │
|
||||
└───────┬───────────────┘ └──────────────────────┘
|
||||
│
|
||||
┌───────────┼────────────────────────────┐
|
||||
│ │ │
|
||||
v v v
|
||||
┌────────────────┐ ┌──────────────────┐ ┌─────────────────────────┐
|
||||
│ n8n BambooHR │ │ n8n Calendar │ │ n8n Recordatorios │
|
||||
│ búsqueda │ │ create/update/del│ │ diario 8:00 AM │
|
||||
└───────┬────────┘ └────────┬─────────┘ └──────────┬──────────────┘
|
||||
│ │ │
|
||||
v v ┌─────┴─────┐
|
||||
┌───────────────┐ ┌─────────────────┐ v v
|
||||
│ BambooHR API │ │ Google Calendar │ Gmail Google Chat
|
||||
└───────────────┘ └─────────────────┘
|
||||
```
|
||||
|
||||
### Stack tecnológico
|
||||
|
||||
| Componente | Tecnología | Propósito |
|
||||
|---|---|---|
|
||||
| Frontend | React 19 | Interfaz de usuario |
|
||||
| Lenguaje | TypeScript | Lógica tipada |
|
||||
| Build | Vite 8 | Desarrollo y compilación |
|
||||
| Estilos | Tailwind CSS 4 | Diseño visual |
|
||||
| Autenticación | Supabase Auth + Google OAuth | Inicio de sesión corporativo |
|
||||
| Base de datos | Supabase / PostgreSQL | Persistencia y reglas de negocio |
|
||||
| API de datos | PostgREST / RPC | Comunicación frontend/n8n ↔ Supabase |
|
||||
| Automatización | n8n | Orquestación de integraciones |
|
||||
| RRHH | BambooHR API | Fuente de datos de empleados |
|
||||
| Correo | Gmail OAuth | Recordatorios HTML |
|
||||
| Chat | Google Chat API | Mensajes directos de recordatorio |
|
||||
| Calendario | Google Calendar API | Creación, actualización y eliminación de eventos |
|
||||
| Hosting | Servidor GLM / Digital Compass | Publicación del frontend y servicios |
|
||||
|
||||
### Integraciones externas
|
||||
|
||||
| Sistema | Tipo de integración | Datos que fluyen |
|
||||
|---|---|---|
|
||||
| Supabase Auth | Google OAuth | Usuario autenticado y sesión |
|
||||
| Supabase REST / RPC | HTTPS | Países, obligaciones, contactos, accesos, logs y sincronización |
|
||||
| BambooHR | API REST | Nombre, país, área, cargo, correo, departamento, división, ubicación y estado |
|
||||
| n8n | Webhook / Schedule Trigger | Automatizaciones de contactos, recordatorios y calendario |
|
||||
| Gmail | OAuth | Correos HTML de recordatorio |
|
||||
| Google Chat | OAuth / REST API | Mensajes directos a contactos |
|
||||
| Google Calendar | OAuth / REST API | Eventos e invitados por obligación |
|
||||
|
||||
---
|
||||
|
||||
## REGLAS DE NEGOCIO
|
||||
|
||||
### 1. Regla de recordatorios
|
||||
|
||||
La fórmula principal es:
|
||||
|
||||
> **Miércoles estrictamente anterior y el mismo día de la fecha límite.**
|
||||
|
||||
| Día de vencimiento | Aviso previo | Aviso del vencimiento |
|
||||
|---|---|---|
|
||||
| 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 |
|
||||
|
||||
Si una obligación vence un miércoles, el aviso previo corresponde al miércoles de la semana anterior.
|
||||
|
||||
### 2. Horario
|
||||
|
||||
- El workflow diario de recordatorios se ejecuta a las **8:00 a. m.**
|
||||
- Zona horaria operativa: `America/Santo_Domingo`.
|
||||
- Los eventos de Google Calendar se crean para la fecha límite de **8:00 a. m. a 9:00 a. m.**
|
||||
|
||||
### 3. Enrutamiento de contactos
|
||||
|
||||
- Un contacto de **Regional** recibe todas las obligaciones.
|
||||
- Un contacto **Regional + Nómina** recibe obligaciones de Nómina de todos los países.
|
||||
- Un contacto **Regional + Administración** recibe obligaciones administrativas de todos los países.
|
||||
- Un contacto asociado a un país recibe únicamente las obligaciones aplicables a su país y categoría.
|
||||
- Solo participan contactos activos y con el canal correspondiente habilitado.
|
||||
|
||||
### 4. Categorías
|
||||
|
||||
Las categorías operativas son:
|
||||
|
||||
- `Nómina`
|
||||
- `Administración`
|
||||
|
||||
El país es obligatorio al crear una obligación.
|
||||
|
||||
### 5. Fechas pasadas
|
||||
|
||||
- No se permite crear una obligación nueva con fecha anterior al día actual.
|
||||
- Tampoco se permite mover una obligación futura a una fecha ya vencida.
|
||||
- Los registros históricos migrados se conservan para consulta.
|
||||
|
||||
### 6. Edición y eliminación
|
||||
|
||||
- Una obligación puede editarse o eliminarse mientras no haya generado un aviso.
|
||||
- Después del primer aviso registrado, queda bloqueada.
|
||||
- Una obligación bloqueada permanece visible en modo de solo lectura.
|
||||
|
||||
### 7. Más de tres obligaciones en un día
|
||||
|
||||
Cuando una celda del calendario contiene más elementos de los que se muestran inicialmente, la opción **Ver todos** permite consultar el resto.
|
||||
|
||||
### 8. Creador de la obligación
|
||||
|
||||
Para obligaciones nuevas se registran:
|
||||
|
||||
- `created_by_name`
|
||||
- `created_by_email`
|
||||
|
||||
Los valores se toman del usuario autenticado con Google/Supabase. Los registros históricos anteriores a esta mejora pueden permanecer sin creador.
|
||||
|
||||
### 9. Contactos mediante BambooHR
|
||||
|
||||
La búsqueda automática:
|
||||
|
||||
- Exige nombre y apellido.
|
||||
- Normaliza tildes y caracteres.
|
||||
- Compara coincidencias exactas y aproximadas.
|
||||
- Tolera diferencias menores de escritura.
|
||||
- Prioriza empleados activos.
|
||||
- Puede devolver varias coincidencias para selección manual.
|
||||
- Propone país, área, cargo, correo y datos organizacionales.
|
||||
- Permite modificar toda la información antes y después de guardar.
|
||||
- Siempre conserva la opción de agregar un contacto manualmente.
|
||||
|
||||
### 10. Google Calendar
|
||||
|
||||
Al crear una obligación:
|
||||
|
||||
- Se crea un evento para la fecha límite.
|
||||
- Se agregan como invitados los contactos aplicables con Calendar habilitado.
|
||||
- La descripción muestra la fecha límite en formato `DD-MM-YYYY`.
|
||||
- Si la obligación se modifica antes de quedar bloqueada, el mismo evento se actualiza.
|
||||
- Si se elimina antes del primer aviso, el evento se elimina.
|
||||
- La relación entre obligación y evento se conserva en Supabase.
|
||||
|
||||
### 11. Prevención de duplicados
|
||||
|
||||
Cada correo y mensaje de Google Chat se registra en `tax_notification_log`.
|
||||
|
||||
La combinación de obligación, contacto, fecha/tipo de aviso y canal evita repetir un envío ya registrado correctamente.
|
||||
|
||||
---
|
||||
|
||||
## BASE DE DATOS
|
||||
|
||||
### Tablas principales
|
||||
|
||||
| Tabla | Propósito |
|
||||
|---|---|
|
||||
| `tax_calendar_access` | Correos autorizados para utilizar la app |
|
||||
| `tax_countries` | Catálogo de países |
|
||||
| `tax_obligations` | Obligaciones tributarias e información del creador |
|
||||
| `tax_contacts` | Contactos, área, país, origen BambooHR y canales |
|
||||
| `tax_notification_log` | Historial de Gmail y Google Chat |
|
||||
| `tax_google_calendar_events` | Relación entre obligaciones y eventos de Google Calendar |
|
||||
|
||||
### Funciones / RPC principales
|
||||
|
||||
| Función | Propósito |
|
||||
|---|---|
|
||||
| `has_tax_calendar_access` | Verifica acceso del usuario autenticado |
|
||||
| `tax_previous_wednesday` | Calcula el miércoles estrictamente anterior |
|
||||
| `tax_due_reminders` | Obtiene recordatorios pendientes y destinatarios |
|
||||
| `tax_record_notification` | Registra el resultado de Gmail / Google Chat |
|
||||
| `tax_obligation_delivery_status` | Consulta si una obligación ya generó avisos |
|
||||
| `tax_prevent_sent_obligation_changes` | Impide modificar/eliminar obligaciones bloqueadas |
|
||||
| `tax_validate_future_obligation` | Impide nuevas obligaciones en fechas pasadas |
|
||||
| `tax_google_calendar_payload` | Obtiene obligación e invitados aplicables |
|
||||
| `tax_record_google_calendar_sync` | Guarda el estado de sincronización con Calendar |
|
||||
| `tax_capture_obligation_creator` | Guarda nombre y correo del creador |
|
||||
|
||||
### Instalación nueva
|
||||
|
||||
Para una instalación nueva, usar:
|
||||
|
||||
```text
|
||||
supabase/Seguimiento-de-Impuestos-GLM.sql
|
||||
```
|
||||
|
||||
### Actualizaciones incrementales utilizadas
|
||||
|
||||
El repositorio mantiene parches para instalaciones existentes:
|
||||
|
||||
```text
|
||||
supabase/actualizacion_eventos_bloqueados.sql
|
||||
supabase/actualizacion_final_calendario_y_nomina.sql
|
||||
supabase/actualizacion_bamboohr_google_calendar.sql
|
||||
supabase/actualizacion_google_chat_sin_whatsapp.sql
|
||||
supabase/actualizacion_creador_obligaciones.sql
|
||||
```
|
||||
|
||||
> No ejecutar parches de forma indiscriminada. En una instalación existente se debe aplicar únicamente lo que todavía no haya sido ejecutado.
|
||||
|
||||
---
|
||||
|
||||
## CONFIGURACIÓN Y SETUP
|
||||
|
||||
### Prerrequisitos
|
||||
|
||||
- Node.js y npm.
|
||||
- Acceso al Supabase empresarial de GLM.
|
||||
- Google OAuth habilitado en Supabase.
|
||||
- n8n operativo.
|
||||
- Credencial `BambooHR GLM Full Access`.
|
||||
- Credencial Gmail OAuth en n8n.
|
||||
- Credencial Google Chat OAuth2 API en n8n.
|
||||
- Credencial Google Calendar OAuth2 API en n8n.
|
||||
- Acceso al servidor donde se publica `/calendario-impuestos/`.
|
||||
- Usuario autorizado en `tax_calendar_access`.
|
||||
|
||||
### Variables de entorno del frontend
|
||||
|
||||
Copiar:
|
||||
|
||||
```powershell
|
||||
Copy-Item .env.example .env
|
||||
```
|
||||
|
||||
Variables documentadas:
|
||||
|
||||
| Variable | Descripción |
|
||||
|---|---|
|
||||
| `VITE_SUPABASE_URL` | URL pública de Supabase |
|
||||
| `VITE_SUPABASE_PUBLISHABLE_KEY` | Llave pública/publishable del frontend |
|
||||
| `VITE_SUPABASE_ANON_KEY` | Alternativa compatible si se utiliza anon key |
|
||||
| `VITE_TAX_WEBHOOK_URL` | Webhook del workflow de recordatorios |
|
||||
| `VITE_BAMBOOHR_CONTACT_WEBHOOK_URL` | Webhook para búsqueda de contactos |
|
||||
| `VITE_GOOGLE_CALENDAR_WEBHOOK_URL` | Webhook de sincronización con Calendar |
|
||||
|
||||
Ejemplo:
|
||||
|
||||
```env
|
||||
VITE_SUPABASE_URL=https://dbit.digitalcompass.agency
|
||||
VITE_SUPABASE_PUBLISHABLE_KEY=REEMPLAZAR
|
||||
VITE_TAX_WEBHOOK_URL=https://agenteit.digitalcompass.agency/webhook/seguimiento-impuestos
|
||||
VITE_BAMBOOHR_CONTACT_WEBHOOK_URL=https://agenteit.digitalcompass.agency/webhook/seguimiento-impuestos-bamboohr-contacto
|
||||
VITE_GOOGLE_CALENDAR_WEBHOOK_URL=https://agenteit.digitalcompass.agency/webhook/seguimiento-impuestos-google-calendar
|
||||
```
|
||||
|
||||
> Nunca colocar `service_role`, contraseñas, Client Secrets o tokens privados en variables `VITE_*`.
|
||||
|
||||
### Autenticación
|
||||
|
||||
La app utiliza Google OAuth sobre Supabase Auth.
|
||||
|
||||
El login se realiza mediante una **ventana emergente (popup)** para evitar que la aplicación principal navegue fuera de su bundle durante el proceso OAuth.
|
||||
|
||||
La URL base de producción es:
|
||||
|
||||
```text
|
||||
https://digitalcompass.agency/calendario-impuestos/
|
||||
```
|
||||
|
||||
No se utiliza una página callback dedicada dentro del frontend.
|
||||
|
||||
### Vite
|
||||
|
||||
Configuración relevante:
|
||||
|
||||
```ts
|
||||
base: "/calendario-impuestos/"
|
||||
```
|
||||
|
||||
Desarrollo y preview:
|
||||
|
||||
```text
|
||||
http://localhost:3000/calendario-impuestos/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## INSTALACIÓN LOCAL
|
||||
|
||||
### 1. Clonar
|
||||
|
||||
```powershell
|
||||
git clone https://git.digitalcompass.agency/Isaac_Aracena/seguimiento-impuestos.git
|
||||
cd seguimiento-impuestos
|
||||
```
|
||||
|
||||
### 2. Instalar dependencias
|
||||
|
||||
```powershell
|
||||
npm install
|
||||
```
|
||||
|
||||
### 3. Crear `.env`
|
||||
|
||||
```powershell
|
||||
Copy-Item .env.example .env
|
||||
```
|
||||
|
||||
Completar únicamente con valores autorizados.
|
||||
|
||||
### 4. Ejecutar en desarrollo
|
||||
|
||||
```powershell
|
||||
npm run dev
|
||||
```
|
||||
|
||||
Abrir:
|
||||
|
||||
```text
|
||||
http://localhost:3000/calendario-impuestos/
|
||||
```
|
||||
|
||||
### 5. Validaciones
|
||||
|
||||
```powershell
|
||||
npm run typecheck
|
||||
npm run lint
|
||||
npm run format:check
|
||||
```
|
||||
|
||||
### 6. Generar producción
|
||||
|
||||
```powershell
|
||||
npm run build
|
||||
```
|
||||
|
||||
### 7. Probar build
|
||||
|
||||
```powershell
|
||||
npm run preview
|
||||
```
|
||||
|
||||
El directorio generado es:
|
||||
|
||||
```text
|
||||
dist/
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## DESPLIEGUE
|
||||
|
||||
Producción:
|
||||
|
||||
```text
|
||||
https://digitalcompass.agency/calendario-impuestos/
|
||||
```
|
||||
|
||||
Flujo recomendado:
|
||||
|
||||
1. Ejecutar `npm install`.
|
||||
2. Ejecutar validaciones.
|
||||
3. Ejecutar `npm run build`.
|
||||
4. Probar el `dist` antes de publicarlo.
|
||||
5. Reemplazar en el servidor el contenido anterior por el contenido del `dist` validado.
|
||||
6. Confirmar login, calendario, lista y contactos.
|
||||
|
||||
El repositorio conserva `dist/` porque es el artefacto utilizado para el despliegue de esta aplicación.
|
||||
|
||||
---
|
||||
|
||||
## CONFIGURACIÓN DE N8N
|
||||
|
||||
El sistema utiliza **tres workflows operativos**.
|
||||
|
||||
### 1. Seguimiento de Impuestos GLM — Recordatorios Gmail y Google Chat
|
||||
|
||||
Archivo canónico:
|
||||
|
||||
```text
|
||||
n8n/Seguimiento-de-Impuestos-GLM-Recordatorios-Actualizado.json
|
||||
```
|
||||
|
||||
Funciones:
|
||||
|
||||
- Schedule diario a las 8:00 a. m.
|
||||
- Ejecución manual.
|
||||
- Webhook de ejecución controlada.
|
||||
- Consulta `tax_due_reminders`.
|
||||
- Construcción de correo HTML GLM.
|
||||
- Envío Gmail.
|
||||
- Apertura/reutilización de DM de Google Chat.
|
||||
- Envío de Google Chat.
|
||||
- Registro de resultados en Supabase.
|
||||
|
||||
Credenciales requeridas:
|
||||
|
||||
- Gmail OAuth.
|
||||
- Google Chat OAuth2 API.
|
||||
- Acceso seguro a Supabase para las operaciones de backend.
|
||||
|
||||
### 2. Seguimiento de Impuestos GLM — Buscar contacto en BambooHR
|
||||
|
||||
Archivo:
|
||||
|
||||
```text
|
||||
n8n/Seguimiento-de-Impuestos-GLM-BambooHR-Contactos.json
|
||||
```
|
||||
|
||||
Production URL:
|
||||
|
||||
```text
|
||||
https://agenteit.digitalcompass.agency/webhook/seguimiento-impuestos-bamboohr-contacto
|
||||
```
|
||||
|
||||
Flujo:
|
||||
|
||||
1. Recibe `full_name`.
|
||||
2. Valida que haya al menos nombre y apellido.
|
||||
3. Obtiene el reporte de empleados de BambooHR.
|
||||
4. Normaliza nombres.
|
||||
5. Calcula coincidencias exactas/aproximadas.
|
||||
6. Resuelve país y área.
|
||||
7. Devuelve hasta ocho candidatos ordenados por calidad.
|
||||
|
||||
### 3. Seguimiento de Impuestos GLM — Google Calendar
|
||||
|
||||
Archivo:
|
||||
|
||||
```text
|
||||
n8n/Seguimiento-de-Impuestos-GLM-Google-Calendar.json
|
||||
```
|
||||
|
||||
Production URL:
|
||||
|
||||
```text
|
||||
https://agenteit.digitalcompass.agency/webhook/seguimiento-impuestos-google-calendar
|
||||
```
|
||||
|
||||
Funciones:
|
||||
|
||||
- Crear evento.
|
||||
- Actualizar evento.
|
||||
- Eliminar evento.
|
||||
- Mantener invitados sincronizados.
|
||||
- Registrar la relación en `tax_google_calendar_events`.
|
||||
|
||||
Credencial requerida:
|
||||
|
||||
- Google Calendar OAuth2 API.
|
||||
|
||||
---
|
||||
|
||||
## CÓMO FUNCIONA
|
||||
|
||||
### Flujo diario de recordatorios
|
||||
|
||||
1. A las 8:00 a. m. n8n inicia el workflow.
|
||||
2. Se determina la fecha de ejecución.
|
||||
3. `tax_due_reminders` devuelve obligaciones y contactos pendientes.
|
||||
4. n8n construye el contenido de Gmail y Google Chat.
|
||||
5. Gmail envía el correo HTML a cada destinatario habilitado.
|
||||
6. Google Chat crea/reutiliza el DM y envía el mensaje.
|
||||
7. Cada resultado se registra en `tax_notification_log`.
|
||||
8. Un envío ya registrado correctamente no vuelve a emitirse.
|
||||
|
||||
### Flujo de alta de contacto con BambooHR
|
||||
|
||||
1. El usuario selecciona **Agregar contacto**.
|
||||
2. Puede elegir **Buscar en BambooHR** o **Agregar manualmente**.
|
||||
3. Si usa BambooHR, escribe el nombre completo.
|
||||
4. La app bloquea temporalmente la interacción durante la consulta.
|
||||
5. Si hay una coincidencia útil, presenta los datos encontrados.
|
||||
6. Si hay varias, el usuario elige.
|
||||
7. Si no hay una coincidencia adecuada, puede continuar manualmente.
|
||||
8. Antes de guardar puede corregir cualquier dato.
|
||||
9. El contacto queda almacenado en Supabase.
|
||||
|
||||
### Flujo de Google Calendar
|
||||
|
||||
1. El usuario crea una obligación futura.
|
||||
2. La obligación se guarda en Supabase con el usuario creador.
|
||||
3. El frontend llama al webhook de Google Calendar.
|
||||
4. n8n obtiene obligación e invitados aplicables.
|
||||
5. Crea el evento de 8:00 a. m. a 9:00 a. m.
|
||||
6. Guarda el ID de Calendar en Supabase.
|
||||
7. Cambios posteriores actualizan el mismo evento mientras sea editable.
|
||||
8. Una eliminación previa al primer aviso elimina también el evento.
|
||||
|
||||
### Flujo de bloqueo
|
||||
|
||||
1. Gmail o Google Chat registra el primer aviso.
|
||||
2. Supabase detecta que la obligación ya fue notificada.
|
||||
3. La obligación queda disponible en modo de consulta.
|
||||
4. Ya no puede modificarse ni eliminarse.
|
||||
|
||||
---
|
||||
|
||||
## SCHEDULES / TRIGGERS
|
||||
|
||||
| Trigger | Frecuencia | Descripción |
|
||||
|---|---|---|
|
||||
| Schedule `0 8 * * *` | Diario, 8:00 a. m. | Procesa recordatorios pendientes |
|
||||
| Manual Trigger | Bajo demanda | Pruebas controladas de recordatorios |
|
||||
| `POST /webhook/seguimiento-impuestos` | Bajo demanda | Ejecución controlada del workflow principal |
|
||||
| `POST /webhook/seguimiento-impuestos-bamboohr-contacto` | Bajo demanda | Búsqueda de empleados |
|
||||
| `POST /webhook/seguimiento-impuestos-google-calendar` | Al crear/editar/eliminar | Sincronización de Google Calendar |
|
||||
|
||||
---
|
||||
|
||||
## TESTING
|
||||
|
||||
### Casos de prueba mínimos
|
||||
|
||||
| Caso | Input | Output esperado | Estado |
|
||||
|---|---|---|---|
|
||||
| Login autorizado | Correo activo en `tax_calendar_access` | Acceso a la app | OK |
|
||||
| Login no autorizado | Correo sin acceso | Pantalla de acceso restringido | OK |
|
||||
| OAuth | Login Google | Sesión vuelve al frontend sin cargar una versión antigua | OK |
|
||||
| Crear obligación futura | Fecha válida + país + categoría | Registro creado | OK |
|
||||
| Crear en fecha pasada | Fecha anterior a hoy | Operación bloqueada | OK |
|
||||
| Editar antes del aviso | Obligación sin notificaciones | Actualización permitida | OK |
|
||||
| Eliminar antes del aviso | Obligación sin notificaciones | Eliminación permitida | OK |
|
||||
| Editar después del aviso | Obligación notificada | Solo lectura | OK |
|
||||
| Creador | Nueva obligación autenticada | Nombre/correo guardados | OK |
|
||||
| BambooHR exacto | Nombre existente | Datos propuestos | OK |
|
||||
| BambooHR múltiples | Nombre ambiguo | Lista de candidatos | OK |
|
||||
| BambooHR sin match | Nombre sin coincidencia | Registro manual disponible | OK |
|
||||
| Gmail | Recordatorio pendiente | Correo HTML GLM | OK |
|
||||
| Google Chat | Contacto habilitado | DM con recordatorio | OK |
|
||||
| Calendar crear | Nueva obligación | Evento + invitados | OK |
|
||||
| Calendar actualizar | Editar obligación | Mismo evento actualizado | OK |
|
||||
| Calendar eliminar | Eliminar obligación editable | Evento eliminado | OK |
|
||||
| Duplicado | Reejecutar aviso ya registrado | No repetir envío exitoso | OK |
|
||||
|
||||
---
|
||||
|
||||
## ERRORES CONOCIDOS Y TROUBLESHOOTING
|
||||
|
||||
| Error | Causa probable | Solución |
|
||||
|---|---|---|
|
||||
| `Servicio no disponible` | `.env` incompleto al compilar | Revisar variables `VITE_SUPABASE_*` y reconstruir |
|
||||
| Popup de Google no abre | Bloqueo de popups del navegador | Permitir ventanas emergentes para la app |
|
||||
| Acceso restringido | Correo no habilitado | Revisar `tax_calendar_access` |
|
||||
| BambooHR no responde | Credencial/API/timeout | Revisar ejecución y credencial en n8n |
|
||||
| BambooHR no encuentra persona | Diferencia fuerte o dato faltante | Probar nombre completo o usar alta manual |
|
||||
| Gmail falla | Credencial OAuth | Reconectar Gmail en n8n |
|
||||
| Google Chat falla | Permisos/scopes/Chat API | Revisar credencial y Google Chat API |
|
||||
| Calendar 401/403 | Credencial o permisos | Reconectar Google Calendar OAuth |
|
||||
| Calendar no actualiza | Sync ID ausente | Revisar `tax_google_calendar_events` |
|
||||
| Recordatorios vacíos | No hay alertas para la fecha o ya fueron enviadas | Revisar `tax_due_reminders` y `tax_notification_log` |
|
||||
| Evento bloqueado | Ya existe un aviso enviado | Comportamiento esperado |
|
||||
|
||||
---
|
||||
|
||||
## MONITOREO
|
||||
|
||||
### n8n
|
||||
|
||||
Revisar:
|
||||
|
||||
- **Executions** de los tres workflows.
|
||||
- Fallos de Gmail.
|
||||
- Fallos de Google Chat.
|
||||
- Fallos de Google Calendar.
|
||||
- Errores/timeout de BambooHR.
|
||||
|
||||
### Supabase
|
||||
|
||||
Revisar:
|
||||
|
||||
- `tax_notification_log` para envíos.
|
||||
- `tax_google_calendar_events` para sincronización.
|
||||
- `tax_contacts` para contactos activos/canales.
|
||||
- `tax_obligations` para fechas y creador.
|
||||
- `tax_calendar_access` para accesos.
|
||||
|
||||
### Condición normal
|
||||
|
||||
- El workflow de 8:00 a. m. termina en verde.
|
||||
- Solo se procesan recordatorios pendientes.
|
||||
- Gmail y Google Chat quedan registrados.
|
||||
- Calendar permanece sincronizado con las obligaciones.
|
||||
- Los eventos ya notificados quedan protegidos.
|
||||
|
||||
---
|
||||
|
||||
## ESTRUCTURA DEL REPOSITORIO
|
||||
|
||||
```text
|
||||
seguimiento-impuestos/
|
||||
├── README.md
|
||||
├── AGENTS.md
|
||||
├── .env.example
|
||||
├── .gitignore
|
||||
├── package.json
|
||||
├── package-lock.json
|
||||
├── vite.config.ts
|
||||
├── tsconfig.json
|
||||
├── eslint.config.js
|
||||
├── index.html
|
||||
│
|
||||
├── public/
|
||||
│ ├── favicon.ico
|
||||
│ ├── favicon-32.png
|
||||
│ ├── favicon-192.png
|
||||
│ ├── apple-touch-icon.png
|
||||
│ └── glm-logo-completo.png
|
||||
│
|
||||
├── src/
|
||||
│ ├── App.tsx
|
||||
│ ├── TaxApp.tsx
|
||||
│ ├── main.tsx
|
||||
│ ├── styles.css
|
||||
│ ├── auth/
|
||||
│ │ └── AuthGate.tsx
|
||||
│ ├── assets/
|
||||
│ │ └── glm-logo.png
|
||||
│ └── lib/
|
||||
│ ├── supabase-auth.ts
|
||||
│ ├── supabase-data.ts
|
||||
│ └── tax-utils.ts
|
||||
│
|
||||
├── n8n/
|
||||
│ ├── CONFIGURACION.md
|
||||
│ ├── Seguimiento-de-Impuestos-GLM-Recordatorios-Actualizado.json
|
||||
│ ├── Seguimiento-de-Impuestos-GLM-BambooHR-Contactos.json
|
||||
│ ├── Seguimiento-de-Impuestos-GLM-Google-Calendar.json
|
||||
│ └── Seguimiento-de-Impuestos-GLM.json
|
||||
│
|
||||
├── supabase/
|
||||
│ ├── README.md
|
||||
│ ├── Seguimiento-de-Impuestos-GLM.sql
|
||||
│ ├── seguimiento_impuestos_auth.sql
|
||||
│ ├── actualizacion_eventos_bloqueados.sql
|
||||
│ ├── actualizacion_final_calendario_y_nomina.sql
|
||||
│ ├── actualizacion_bamboohr_google_calendar.sql
|
||||
│ ├── actualizacion_google_chat_sin_whatsapp.sql
|
||||
│ └── actualizacion_creador_obligaciones.sql
|
||||
│
|
||||
└── dist/
|
||||
└── build validado para producción
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## CHANGELOG
|
||||
|
||||
### 2026-08-07 — v1.3
|
||||
|
||||
- Registro de nombre y correo del creador de nuevas obligaciones.
|
||||
- Eliminación del ejemplo de una empleada real en el buscador de BambooHR.
|
||||
- Fecha límite de Google Calendar mostrada en formato `DD-MM-YYYY`.
|
||||
- README actualizado al estado operativo actual.
|
||||
|
||||
### 2026-07-31 — v1.2
|
||||
|
||||
- Estabilización del inicio de sesión con Google mediante popup OAuth.
|
||||
- La ventana principal permanece cargada durante la autenticación.
|
||||
- Corrección del problema en el que podía mostrarse temporalmente un bundle anterior después del login.
|
||||
|
||||
### 2026-07-29 — v1.1
|
||||
|
||||
- Sustitución de WhatsApp por Google Chat.
|
||||
- Integración de Google Calendar.
|
||||
- Automatización de contactos mediante BambooHR.
|
||||
- Bloqueo de creación de obligaciones en fechas pasadas.
|
||||
- Gestión de contactos manual y automática.
|
||||
|
||||
### 2026-07-24 — v1.0
|
||||
|
||||
- Limpieza del prototipo inicial.
|
||||
- Migración del calendario histórico a Supabase.
|
||||
- Integración de Google OAuth y control de acceso.
|
||||
- Calendario, lista y contactos.
|
||||
- Regla de miércoles anterior y fecha límite.
|
||||
- Primer workflow de recordatorios.
|
||||
|
||||
---
|
||||
|
||||
## DECISIONS LOG
|
||||
|
||||
### DEC-001 — Supabase como fuente única de verdad
|
||||
|
||||
- **Fecha:** 2026-07-24
|
||||
- **Contexto:** El calendario y contactos necesitaban persistencia y administración multiusuario.
|
||||
- **Opciones consideradas:** Datos estáticos en frontend vs Supabase.
|
||||
- **Decisión:** Supabase/PostgreSQL.
|
||||
- **Razón:** Centraliza datos, reglas, RLS, accesos y trazabilidad.
|
||||
|
||||
### DEC-002 — Lógica determinística para recordatorios
|
||||
|
||||
- **Fecha:** 2026-07-24
|
||||
- **Contexto:** La regla de fechas es exacta.
|
||||
- **Opciones consideradas:** Gemini vs cálculo determinístico.
|
||||
- **Decisión:** Funciones de fecha en PostgreSQL/n8n.
|
||||
- **Razón:** Evita interpretaciones probabilísticas para una regla crítica.
|
||||
|
||||
### DEC-003 — Contactos administrables desde la app
|
||||
|
||||
- **Fecha:** 2026-07-29
|
||||
- **Contexto:** No se quería editar n8n para cada cambio de destinatario.
|
||||
- **Opciones consideradas:** Contactos hardcodeados vs Supabase.
|
||||
- **Decisión:** Persistir contactos en `tax_contacts`.
|
||||
- **Razón:** Permite mantenimiento funcional sin tocar workflows.
|
||||
|
||||
### DEC-004 — BambooHR como fuente asistida, no autoritativa
|
||||
|
||||
- **Fecha:** 2026-07-29
|
||||
- **Contexto:** BambooHR puede tener datos faltantes o desactualizados.
|
||||
- **Decisión:** Autocompletar desde BambooHR, pero permitir edición y alta manual.
|
||||
- **Razón:** Mantiene automatización sin perder control humano.
|
||||
|
||||
### DEC-005 — Gmail + Google Chat + Google Calendar
|
||||
|
||||
- **Fecha:** 2026-07-29
|
||||
- **Contexto:** Se descartó WhatsApp como canal operativo.
|
||||
- **Decisión:** Usar Gmail y Google Chat para avisos, y Google Calendar para agenda.
|
||||
- **Razón:** Integración directa con Google Workspace corporativo.
|
||||
|
||||
### DEC-006 — Bloqueo después del primer aviso
|
||||
|
||||
- **Fecha:** 2026-07-29
|
||||
- **Contexto:** Editar una obligación ya notificada genera inconsistencias.
|
||||
- **Decisión:** Modo de solo lectura después del primer envío.
|
||||
- **Razón:** Preserva trazabilidad e integridad del mensaje ya enviado.
|
||||
|
||||
### DEC-007 — OAuth en popup
|
||||
|
||||
- **Fecha:** 2026-07-31
|
||||
- **Contexto:** Al regresar de Google podía mostrarse temporalmente una versión anterior del frontend.
|
||||
- **Decisión:** Ejecutar OAuth en una ventana separada y conservar el bundle principal.
|
||||
- **Razón:** Evita restauraciones inconsistentes del documento principal durante el login.
|
||||
|
||||
### DEC-008 — Registro del creador
|
||||
|
||||
- **Fecha:** 2026-08-07
|
||||
- **Contexto:** Era necesario saber quién agregó cada nueva obligación.
|
||||
- **Decisión:** Guardar nombre y correo desde la sesión autenticada.
|
||||
- **Razón:** Mejora trazabilidad sin afectar registros históricos.
|
||||
|
||||
---
|
||||
|
||||
## CONTACTOS DEL PROYECTO
|
||||
|
||||
| Rol | Nombre | Contacto |
|
||||
|---|---|---|
|
||||
| Solicitante funcional | Ada Rodríguez | `asrodriguez@gomezleemarketing.com` |
|
||||
| IT Manager | Luis Matos | `lmatos@gomezleemarketing.com` |
|
||||
| Developer principal | Isaac Aracena | `iaracena@gomezleemarketing.com` |
|
||||
|
||||
---
|
||||
|
||||
## DEFINITION OF DONE
|
||||
|
||||
- [x] Calendario histórico migrado a Supabase.
|
||||
- [x] Autenticación Google implementada.
|
||||
- [x] Acceso controlado desde `tax_calendar_access`.
|
||||
- [x] Calendario, lista y contactos operativos.
|
||||
- [x] País obligatorio.
|
||||
- [x] Categorías Nómina / Administración.
|
||||
- [x] Bloqueo de fechas pasadas.
|
||||
- [x] Edición/eliminación antes del primer aviso.
|
||||
- [x] Bloqueo después del primer aviso.
|
||||
- [x] Búsqueda de contactos mediante BambooHR.
|
||||
- [x] Alta manual y edición de contactos.
|
||||
- [x] Gmail HTML con branding GLM.
|
||||
- [x] Google Chat.
|
||||
- [x] Google Calendar create/update/delete.
|
||||
- [x] Prevención de recordatorios duplicados.
|
||||
- [x] Registro del creador de obligaciones nuevas.
|
||||
- [x] Workflows n8n exportados.
|
||||
- [x] Scripts SQL versionados.
|
||||
- [x] `.env.example` documentado.
|
||||
- [x] `dist` validado antes de despliegue.
|
||||
- [x] Código y build versionados en Gitea.
|
||||
- [x] README actualizado.
|
||||
- [ ] Registrar enlace definitivo del board Kan.bn.
|
||||
- [ ] Registrar enlace definitivo del PRD.
|
||||
- [ ] Registrar aprobación funcional formal del cierre.
|
||||
|
||||
---
|
||||
|
||||
## SEGURIDAD
|
||||
|
||||
- Nunca commitear `.env`.
|
||||
- Nunca colocar `service_role` en el frontend.
|
||||
- Nunca publicar Client Secrets ni tokens OAuth.
|
||||
- Los valores `VITE_*` deben ser únicamente públicos.
|
||||
- Mantener RLS y funciones de autorización activas.
|
||||
- Los permisos de acceso deben administrarse mediante `tax_calendar_access`.
|
||||
- Las credenciales privadas de n8n deben residir en Credentials/Vault.
|
||||
- Antes de commitear exports de n8n, revisar que no contengan llaves privadas embebidas.
|
||||
- Si una llave privada fue expuesta en un commit, rotarla y actualizar la credencial correspondiente.
|
||||
|
||||
---
|
||||
|
||||
Documento mantenido por el equipo **GLM IT**.
|
||||
Reference in New Issue
Block a user