# 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.

---

## Informacion General

| Campo | Detalle |
|---|---|
| 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 |

---

## Objetivo

### 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
# Clonar el repo
git clone https://gitea.glm.com/glm-it/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

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
# Test unitario del endpoint
cd endpoint/
python -m pytest tests/

# Test de integracion — verificacion real contra BambooHR
python tests/test_bamboohr_integration.py

# 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

| Caso | Input | Output esperado | Estado |
|---|---|---|---|
| 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 |

---

## 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

```
/glm-id-card-generator
├── README.md                        <- Este archivo
├── glm_id_card.html                 <- Generador de carnets (distribuir a RRHH)
├── /assets
│   ├── /logos-clientes              <- Logos PNG de clientes precargados (aprobados por RRHH)
│   └── glm-logo.png                 <- Logo GLM para el generador
├── /endpoint
│   ├── main.py                      <- Punto de entrada del servicio de verificacion
│   ├── requirements.txt             <- Dependencias Python del endpoint
│   ├── .env.example                 <- Variables de entorno de ejemplo (sin valores reales)
│   ├── Dockerfile                   <- Para deploy en Google Cloud Run
│   └── /tests
│       ├── test_endpoint.py         <- Tests unitarios del endpoint
│       └── test_bamboohr_integration.py <- Tests de integracion con BambooHR API
├── /batch
│   └── ejemplo_colaboradores.csv    <- CSV de ejemplo con el formato requerido para batch
├── /docs
│   ├── guia-uso-rrhh.pdf            <- Guia de uso para operadores de RRHH
│   └── architecture.png             <- Diagrama de arquitectura del sistema
├── CHANGELOG.md                     <- Historial de cambios
└── DECISIONS.md                     <- Log de decisiones tecnicas
```

---

## CHANGELOG

```
[2026-07-28] v1.0 — Launch inicial en produccion
```

---

## DECISIONS LOG

### DEC-001 — Generador como HTML local vs. app web hosteada

- Fecha: 2026-06-16
- 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).
- Decision: HTML local distribuido a RRHH en Fase 1.
- 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.

### 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

| Rol | Nombre | Contacto |
|---|---|---|
| Product Owner | Maximo Gomez | [email/WhatsApp] |
| IT Manager | Luis Matos | [email/WhatsApp] |
| Developer Principal | Eidan Then | [email/WhatsApp] |

---

## Definition of Done

Checklist antes de mover a Completado en Kan.bn:

- [ ] Todos los criterios de exito cumplidos y verificados
- [ ] 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

---

_Documento mantenido por el equipo GLM IT · Ultima actualizacion: 2026-06-05_