Nuevo README

This commit is contained in:
2026-07-28 11:45:30 -04:00
parent 9e10699faa
commit 2b74335e03
+110 -286
View File
@@ -1,326 +1,150 @@
# GLM ID Card Generator # GLM ID Card Generator
> Herramienta web que permite al equipo de RRHH generar carnets corporativos GLM listos para imprimir en formato CR80 o enviar digitalmente, con verificacion de autenticidad via QR conectado a BambooHR en tiempo real. ## ¿Qué hace este proyecto?
Sistema de generación de ID corporativas para el departamento de RRHH de GomezLee Marketing (GLM), que opera en 14 países. El sistema permite:
1. **Generar IDs** (frente y reverso) de empleados de forma individual o por lote (Excel/CSV).
2. **Editar fotos con IA**: usa Google Gemini para vestir al empleado con un uniforme Columbia, bordar el logo de GLM en el pecho derecho y reemplazar el fondo por blanco.
3. **Códigos QR**: cada ID incluye un QR único que redirige a `https://digitalcompass.agency/empleado?id=X` para verificar en tiempo real el estatus del empleado contra BambooHR.
4. **Exportación a PNG**: descarga los ID como PNG listos para impresión CR80 o envío por WhatsApp.
5. **Verificación pública**: cualquier persona puede escanear el QR y ver la foto, nombre, puesto, país y estatus del empleado.
### Arquitectura
- **Frontend Generator**: React + Vite (`glm-card-generator/`)
- **Frontend Verificación QR**: React + Vite (`glm-card-qr/`)
- **Workflow de IA**: n8n con Google Gemini para edición de fotos
- **Base de datos**: Supabase (PostgreSQL)
- **Almacenamiento**: Supabase Storage + Google Drive
- **Verificación**: BambooHR API
--- ---
## Informacion General ## Instalación y ejecución
| Campo | Detalle | ### Requisitos
|---|---|
| Proyecto | GLM ID Card Generator |
| Area | RRHH — 14 paises |
| Estado | En Progreso |
| Developer Principal | Eidan Then |
| IT Manager | Luis Matos |
| Fecha de Inicio | 2026-06-16 |
| Fecha de Cierre Estimada | 2026-07-28 |
| Ciclo Shape Up | Ciclo 2 — Semana 1 de 6 |
| Board de Ejecucion | https://pmit.digitalcompass.agency/boards/v8iyihdd7u2v |
| PRD del Proyecto | https://docs.google.com/document/d/1SZMEcx5BZGf6CtDk5ZEb08Nx1xMBeyVd9zoqMDFhHgI/edit?usp=sharing |
--- - Node.js >= 18
- npm
## Objetivo ### 1. Clonar el repositorio
### Problema que resuelve
Hoy RRHH depende del area de diseno para generar cada carnet corporativo, lo que toma entre 1 y 3 dias habiles por colaborador. No existe estandar centralizado entre paises ni mecanismo para verificar la autenticidad o el estado activo de un carnet en campo.
### Solucion implementada
Un archivo HTML que RRHH abre en cualquier navegador. El operador selecciona el cliente de un desplegable precargado, ingresa los datos del colaborador, sube su foto y descarga dos PNG — frente y reverso — listos para imprimir en CR80 o enviar por WhatsApp. El reverso incluye un QR unico que al escanearse consulta BambooHR en tiempo real y devuelve el estado del colaborador. Para produccion masiva, el operador sube un CSV y el sistema genera todos los carnets en lote dentro de un ZIP.
### Usuarios y beneficiarios
- Operador: Equipo de RRHH en los 14 paises de GLM
- Verificador: Supervisores, clientes y auditores que escanean el QR en campo
- Beneficiario: Colaboradores que reciben su carnet impreso o digital
---
## Arquitectura
### Diagrama de flujo
```
MODO INDIVIDUAL
[RRHH abre glm_id_card.html] → [Selecciona cliente / sube logo] → [Ingresa datos + foto]
→ [Sistema genera QR unico con URL de verificacion] → [Vista previa en tiempo real]
→ [Descarga Frente PNG + Reverso PNG con QR]
MODO BATCH
[RRHH sube CSV] → [Sistema lee cada fila] → [Genera carnet completo por colaborador]
→ [Descarga ZIP con todos los PNG]
VERIFICACION QR
[Escaneo del QR en campo] → [verify.gomezlee.com/carnet/{ID}]
→ [Endpoint Cloud Run consulta BambooHR API]
→ [Devuelve pagina: Nombre, Puesto, Cliente, Estado (Activo / Inactivo / Terminado)]
```
### Stack tecnologico
| Componente | Tecnologia | Proposito |
|---|---|---|
| Frontend / Generador | HTML5 + CSS3 + JavaScript | Interfaz interactiva del generador — sin frameworks externos |
| Exportacion PNG | html2canvas (libreria JS) | Convierte el DOM del carnet a PNG de alta resolucion para impresion CR80 |
| Generacion de QR | QRCode.js (libreria JS) | Genera el QR unico por colaborador con la URL del endpoint de verificacion |
| Procesamiento batch | JavaScript + FileReader API | Lee el CSV y genera carnets en lote sin intervencion manual por fila |
| Endpoint de verificacion | Python + Google Cloud Run | Recibe el ID del QR, consulta BambooHR y devuelve pagina de estado del colaborador |
| Integracion BambooHR | BambooHR API REST | Fuente de verdad para nombre, puesto, pais, cliente y estado del colaborador |
| Version control | Gitea | Repositorio del generador y del endpoint |
### Integraciones externas
| Sistema | Tipo de integracion | Datos que fluyen |
|---|---|---|
| BambooHR | API REST | Nombre, puesto, pais, cliente asignado, estado del empleado (activo / inactivo / terminado) |
| Google Cloud Run | Endpoint HTTP publico | Recibe ID del colaborador desde el QR y devuelve pagina de verificacion |
| CSV local | Archivo de entrada | Nombre, puesto, pais, cliente, id_colaborador, ruta_foto (opcional) |
---
## Configuracion y Setup
### Prerequisitos
- [ ] Acceso a BambooHR API (API Key del subdominio GLM)
- [ ] Proyecto configurado en Google Cloud con Cloud Run habilitado
- [ ] Variable de entorno `BAMBOOHR_API_KEY` configurada en Cloud Run
- [ ] Variable de entorno `BAMBOOHR_SUBDOMAIN` configurada en Cloud Run
- [ ] Dominio `verify.gomezlee.com` apuntando al servicio de Cloud Run
- [ ] Lista de clientes precargados definida y aprobada por RRHH (nombre + logo PNG)
### Variables de entorno
| Variable | Descripcion | Donde se obtiene |
|---|---|---|
| `BAMBOOHR_API_KEY` | API Key de BambooHR | BambooHR → Admin → API Keys |
| `BAMBOOHR_SUBDOMAIN` | Subdominio de la cuenta GLM en BambooHR | URL de BambooHR: {subdominio}.bamboohr.com |
| `VERIFY_BASE_URL` | URL base del endpoint de verificacion | Ej: https://verify.gomezlee.com |
> Las credenciales nunca se commitean al repo. Todas las keys van en el vault de credenciales GLM o en los secrets de Google Cloud Run.
### Instalacion — Endpoint de verificacion
```bash ```bash
# Clonar el repo git clone <repo-url>
git clone https://gitea.glm.com/glm-it/glm-id-card-generator cd GLM ID Card Generator
# Instalar dependencias del endpoint
cd endpoint/
pip install -r requirements.txt --break-system-packages
# Configurar variables de entorno locales para pruebas
cp .env.example .env
# Editar .env con las credenciales reales
# Correr el endpoint en local
python main.py
# Deploy a Google Cloud Run
gcloud run deploy glm-id-card-verify \
--source . \
--region us-central1 \
--allow-unauthenticated
``` ```
### Distribucion del generador HTML ### 2. Configurar variables de entorno
El archivo `glm_id_card.html` se distribuye directamente a RRHH via email o carpeta compartida. No requiere instalacion. El operador lo abre en Chrome o Edge.
---
## Como funciona
### Flujo paso a paso — Modo individual
1. El operador abre `glm_id_card.html` en Chrome o Edge
2. Selecciona el cliente del desplegable precargado (o sube un logo nuevo)
3. Ingresa nombre completo, puesto, pais e ID del colaborador
4. Sube la foto del colaborador — aparece recortada en circulo en el frente
5. El sistema genera automaticamente el QR con la URL `verify.gomezlee.com/carnet/{ID}`
6. El operador visualiza la vista previa en tiempo real del frente y el reverso
7. Descarga el Frente PNG y el Reverso PNG por separado
8. Envia los PNG al colaborador o los imprime en formato CR80
### Flujo paso a paso — Modo batch
1. El operador prepara el CSV segun el formato requerido (ver seccion Formato CSV)
2. Sube el CSV al generador
3. El sistema procesa cada fila, genera el carnet completo y produce un ZIP
4. El ZIP contiene los archivos nombrados como `{nombre_colaborador}_frente.png` y `{nombre_colaborador}_reverso.png`
### Flujo de verificacion QR
1. Supervisor o cliente escanea el QR del reverso del carnet con cualquier telefono
2. El QR abre `verify.gomezlee.com/carnet/{ID_COLABORADOR}` en el navegador del telefono
3. El endpoint consulta BambooHR con el ID del colaborador
4. Se devuelve una pagina web con: nombre, puesto, cliente, pais y estado del colaborador
5. Si el colaborador esta activo: pagina verde con sus datos completos
6. Si el colaborador esta inactivo o terminado: pagina roja con mensaje "Carnet no vigente"
### Formato CSV para batch
| Columna | Requerida | Descripcion |
|---|---|---|
| `nombre_completo` | Si | Nombre completo del colaborador |
| `puesto` | Si | Puesto o cargo |
| `pais` | Si | Pais de operacion |
| `cliente` | Si | Nombre del cliente (debe coincidir exactamente con la lista precargada) |
| `id_colaborador` | Si | ID del colaborador en BambooHR |
| `ruta_foto` | No | URL publica de la foto. Si se omite, el circulo de foto queda vacio |
### Schedules y triggers
| Trigger | Descripcion |
|---|---|
| Manual — abre el HTML | El operador genera carnets cuando RRHH lo necesita |
| Escaneo del QR | El endpoint se dispara on-demand cada vez que alguien escanea un carnet en campo |
---
## Testing
### Como probar el sistema
```bash ```bash
# Test unitario del endpoint # Para el generador de IDs
cd endpoint/ cp glm-card-generator/.env.example glm-card-generator/.env
python -m pytest tests/
# Test de integracion — verificacion real contra BambooHR # Para el visor QR
python tests/test_bamboohr_integration.py cp glm-card-qr/.env.example glm-card-qr/.env
# Test manual del generador HTML
# 1. Abrir glm_id_card.html en Chrome
# 2. Llenar todos los campos con datos de prueba
# 3. Exportar PNG y verificar dimensiones: 1012 x 638 px a 96 dpi display (equivalente a 300 dpi en CR80)
# 4. Imprimir en hoja CR80 y verificar calidad
# 5. Escanear el QR generado y confirmar que abre el endpoint correctamente
``` ```
### Casos de prueba minimos Editar los archivos `.env` con los valores correspondientes.
| Caso | Input | Output esperado | Estado | ### 3. Instalar dependencias y ejecutar
|---|---|---|---|
| Carnet individual completo | Todos los campos + foto + cliente seleccionado | PNG frente y reverso descargados correctamente | Pendiente |
| Carnet sin foto | Todos los campos sin foto | PNG generado con circulo vacio en frente | Pendiente |
| Batch CSV valido | CSV con 20 colaboradores | ZIP con 40 PNG (frente + reverso por colaborador) en menos de 2 minutos | Pendiente |
| QR colaborador activo | ID valido en BambooHR, estado activo | Pagina verde con datos completos del colaborador | Pendiente |
| QR colaborador inactivo | ID valido en BambooHR, estado inactivo | Pagina roja con mensaje "Carnet no vigente" | Pendiente |
| QR ID inexistente | ID que no existe en BambooHR | Mensaje de error claro, sin crash del endpoint | Pendiente |
| Cliente nuevo con logo manual | Logo subido manualmente sin seleccionar del desplegable | Logo aparece correctamente en el reverso del PNG | Pendiente |
| BambooHR API caida | Timeout del endpoint al consultar BambooHR | Mensaje de error legible, endpoint no crashea | Pendiente |
--- **Generador de IDs:**
## Errores conocidos y troubleshooting
| Error | Causa probable | Solucion |
|---|---|---|
| QR no abre la pagina de verificacion | Dominio verify.gomezlee.com no apunta a Cloud Run | Verificar DNS y configuracion del servicio en Google Cloud Run |
| PNG exportado se ve diferente al preview | html2canvas no soporta alguna propiedad CSS usada | Revisar consola del navegador, simplificar el estilo CSS del elemento afectado |
| Endpoint devuelve 401 | API Key de BambooHR vencida o incorrecta | Renovar la API Key en BambooHR y actualizar el secret en Google Cloud Run |
| Batch no genera todos los carnets | Fila del CSV con campo obligatorio vacio | Revisar el CSV — todas las columnas requeridas deben tener valor en cada fila |
| Logo del cliente no aparece en el PNG | Logo en formato no soportado o con CORS bloqueado | Usar PNG con fondo transparente, minimo 300px de ancho, hosteado en el mismo dominio o con CORS abierto |
| Endpoint lento al responder | BambooHR API con latencia alta | El endpoint tiene cache de 5 minutos por ID — si es la primera consulta puede tardar hasta 3 segundos |
---
## Monitoreo
- **Google Cloud Run Logs:** Revisar logs del servicio `glm-id-card-verify` en Google Cloud Console para errores del endpoint
- **BambooHR API:** Si el endpoint falla consistentemente, verificar el estado de la API de BambooHR y los limites de rate limit
- **Output esperado:** El endpoint debe responder en menos de 3 segundos. Si supera ese tiempo de forma sistematica, revisar la implementacion del cache.
---
## Estructura del repositorio
```bash
cd glm-card-generator
npm install
npm run dev
``` ```
/glm-id-card-generator
├── README.md <- Este archivo Abre en: `http://localhost:5173/empleado-id/`
├── glm_id_card.html <- Generador de carnets (distribuir a RRHH)
├── /assets **Visor QR:**
│ ├── /logos-clientes <- Logos PNG de clientes precargados (aprobados por RRHH)
│ └── glm-logo.png <- Logo GLM para el generador ```bash
├── /endpoint cd glm-card-qr
│ ├── main.py <- Punto de entrada del servicio de verificacion npm install
│ ├── requirements.txt <- Dependencias Python del endpoint npm run dev
│ ├── .env.example <- Variables de entorno de ejemplo (sin valores reales) ```
│ ├── Dockerfile <- Para deploy en Google Cloud Run
│ └── /tests Abre en: `http://localhost:5173/empleado`
│ ├── test_endpoint.py <- Tests unitarios del endpoint
│ └── test_bamboohr_integration.py <- Tests de integracion con BambooHR API ### 4. Build para producción
├── /batch
│ └── ejemplo_colaboradores.csv <- CSV de ejemplo con el formato requerido para batch ```bash
├── /docs # Generador
│ ├── guia-uso-rrhh.pdf <- Guia de uso para operadores de RRHH cd glm-card-generator
│ └── architecture.png <- Diagrama de arquitectura del sistema npm run build
├── CHANGELOG.md <- Historial de cambios # El output está en glm-card-generator/dist/
└── DECISIONS.md <- Log de decisiones tecnicas
# Visor QR
cd glm-card-qr
npm run build
# El output está en glm-card-qr/dist/
``` ```
--- ---
## CHANGELOG ## Variables de entorno
``` ### `glm-card-generator/.env.example`
[2026-07-28] v1.0 — Launch inicial en produccion
```env
VITE_SUPABASE_ANON_KEY=J5JS7HG...
VITE_SUPABASE_URL=https://tudominio
VITE_WEBHOOK_TOKEN=6d4g56d4fgd...
VITE_N8N_WEBHOOK_URL=https://tudominio/webhook/carnet
``` ```
--- ### `glm-card-qr/.env.example`
## DECISIONS LOG ```env
VITE_SUPABASE_URL=https://tudominio
VITE_SUPABASE_ANON_KEY=J5JS7HG...
```
### DEC-001 — Generador como HTML local vs. app web hosteada ### Descripción de variables
- Fecha: 2026-06-16 | Variable | Descripción |
- Contexto: Se evaluo si el generador debia ser una app web hosteada en Google Cloud o un archivo HTML distribuido localmente a RRHH. |---|---|
- Opciones consideradas: App web hosteada (requiere autenticacion, servidor, mantenimiento) vs. HTML local (distribucion simple, sin dependencias de red para generar el carnet). | `VITE_SUPABASE_URL` | URL del proyecto Supabase |
- Decision: HTML local distribuido a RRHH en Fase 1. | `VITE_SUPABASE_ANON_KEY` | Clave anónima de Supabase |
- Razon: El equipo de RRHH opera en 14 paises con distintos niveles de conectividad. El HTML local garantiza que el generador funciona sin internet. Solo el endpoint de verificacion QR requiere conexion. | `VITE_WEBHOOK_TOKEN` | Token de autenticación para el webhook de n8n |
| `VITE_N8N_WEBHOOK_URL` | URL del webhook en n8n (`/webhook/carnet`) |
### DEC-002 — Verificacion QR via BambooHR en tiempo real vs. base de datos propia
- Fecha: 2026-06-16
- Contexto: Se evaluo mantener una base de datos propia en Supabase con el estado de cada carnet vs. consultar BambooHR directamente al momento del escaneo.
- Opciones consideradas: Base de datos propia (requiere sincronizacion manual o automatica con BambooHR) vs. BambooHR como fuente de verdad (estado siempre actualizado, sin base de datos adicional).
- Decision: BambooHR como fuente de verdad con consulta en tiempo real.
- Razon: Elimina el riesgo de datos desincronizados. Cuando RRHH da de baja a un colaborador en BambooHR, el QR lo refleja de inmediato sin ningun paso adicional.
--- ---
## Contactos del proyecto ## Explicación del workflow de n8n
| Rol | Nombre | Contacto | **Archivo**: `n8n-workflow/GLM ID Card Generator.json`
|---|---|---|
| Product Owner | Maximo Gomez | [email/WhatsApp] |
| IT Manager | Luis Matos | [email/WhatsApp] |
| Developer Principal | Eidan Then | [email/WhatsApp] |
--- El workflow **"GLM ID Card Generator"** se ejecuta cuando el frontend envía una foto de empleado al webhook `POST /webhook/carnet` autenticado con el token en el header.
## Definition of Done ### Flujo
Checklist antes de mover a Completado en Kan.bn: 1. **Webhook** — Recibe la solicitud POST con la foto del empleado (y opcionalmente un array de empleados para lote).
2. **IF: "Es un binario y employeeId?"** — Determina si es un envío individual (tiene `employeeId` y foto binaria) o por lote.
3. **IF: "Es un binario?"** — Verifica si el body contiene `empleados` (array de empleados en modo lote).
4. **Split Out** + **Loop Over Items** — En modo lote, separa el array y procesa cada empleado uno por uno.
5. **Download file** (Google Drive) — Descarga la foto del empleado desde Google Drive (según URL recibida).
6. **Descargar logo GLM** (HTTP Request) — Obtiene el logo de GLM desde Supabase Storage.
7. **Edit an image (Google Gemini)** — Edita la foto del empleado con IA:
- Modelo: `gemini-3-pro-image` o `gemini-3.1-flash-image`
- Viste a la persona con un uniforme Columbia (camisa de botones color `#2d3748`)
- Borda el logo de GLM en el pecho derecho
- Reemplaza el fondo por blanco sólido
8. **Extract from File** — Extrae el binario de la imagen editada.
9. **Guardar foto** (Google Drive) — Guarda la foto editada en la carpeta "Fotos Temporal Carnet Empleados".
10. **Hacer url publica** (Google Drive) — Comparte la imagen públicamente.
11. **Actualizar foto del empleado** (Supabase) — Actualiza el registro del empleado en la tabla `empleados_glm` con la `photo_url` y marca `photo_uploaded = FALSE`.
12. **Merge** — Combina los resultados.
13. **Respond to Webhook** — Devuelve la URL de la foto editada al frontend.
- [ ] Todos los criterios de exito cumplidos y verificados ### Credenciales usadas
- [ ] PNG exportado validado fisicamente en impresion CR80
- [ ] Modo batch probado con CSV de al menos 20 colaboradores
- [ ] QR escaneado y verificacion confirmada contra BambooHR en ambiente real
- [ ] Endpoint de verificacion desplegado en Google Cloud Run y accesible publicamente
- [ ] Generador probado en Chrome y Edge en al menos 2 paises
- [ ] Lista de clientes precargados cargada y validada con RRHH
- [ ] Codigo commiteado y pusheado a Gitea
- [ ] README completo y actualizado
- [ ] Variables de entorno documentadas en `.env.example`
- [ ] Prueba de usuario real con al menos un miembro del equipo RRHH
- [ ] Luis Matos valido el output tecnico
- [ ] Maximo aprobo el resultado final
--- | Tipo | Nombre |
|---|---|
_Documento mantenido por el equipo GLM IT · Ultima actualizacion: 2026-06-05_ | HTTP Header Auth | GLM ID Generator |
| Google Drive OAuth2 | Eidan - Google Drive account |
| Google Gemini API | Eidan - Google Gemini(PaLM) Api account |
| Supabase API | Sofia test - Supabase account |