Festivera Platform

Manual Técnico

Hardware · NFC · Red · Servidor · Troubleshooting
Solo personal técnico Hostinger + Supabase Septiembre 2026
Este manual es de uso exclusivo del equipo técnico de Festivera.

📋 Contenido

  1. Arquitectura del sistema
  2. Catálogo de hardware
  3. Configuración NFC y pulseras
  4. Requisitos de red en el evento
  5. Servidor y despliegue
  6. Supabase — estructura de datos
  7. Diagnóstico y troubleshooting
  8. Protocolo de emergencia en vivo

1. Arquitectura del sistema

Stack tecnológico

FrontendHTML/CSS/JS vanilla (sin framework)
HostingHostinger LiteSpeed — app.festivera.com
Base de datosSupabase (PostgreSQL) — gpswnzcfyhxzldijgewa.supabase.co
API backendPHP 8.x en Hostinger (carpeta api/)
Pagos COBold (webhook en api/bold-webhook.php)
EmailResend API (transaccional + marketing)
FacturaciónDIAN UBL 2.1 — XAdES-B-B, PHP (api/billing/dian/)

Flujo de datos principal

# Compra de boleta
Usuario → frontend (dashboard.html)
  → Bold (pago)
  → bold-webhook.php (confirmación)
  → Supabase orders + tickets + cashless_wallets (INSERT)
  → Resend API (email confirmación con QR)

# Acceso en portería
Portero → validador.html (escanea QR)
  → Supabase tickets (UPDATE estado = 'usado')
  → Respuesta visual verde/rojo

# Consumo cashless
Cajero → cajero.html (tap pulsera NFC)
  → Supabase cashless_wallets (deducción saldo)
  → cashless_transactions (INSERT log)

2. Catálogo de hardware

DispositivoFunciónCantidad recomendada
Lector NFC de escritorio USBPunto de venta / cajero1 por punto de venta
Tablet Android (10")Panel cajero, validador, guardarropa1 por operador
Smartphone AndroidRecargas NFC portátiles1 por recargador
Chip NFC Festivera (pulsera)Wallet cashless del asistente1 por asistente
Router WiFi 5GHzRed del evento1 por cada 150 personas
Switch PoERed cableada para puntos fijos1 por zona
Impresora térmica QRBoletas físicas in-situOpcional (1 por ingreso)
Los chips NFC Festivera son de uso exclusivo de la plataforma. Siempre referirse a ellos como "Chip NFC Festivera" o "Chip NFC certificado". Nunca mencionar al público las especificaciones técnicas del chip.

3. Configuración NFC y pulseras

Escritura de pulseras (producción masiva)

  1. 1Conecta el lector NFC USB al equipo de producción.
  2. 2Abre app.festivera.com/recargar.html (panel de recargas) con las credenciales de operador.
  3. 3Selecciona el evento correspondiente en el selector de evento.
  4. 4El sistema lee el UID del chip al acercar la pulsera al lector. Confirma el UID en pantalla antes de asignar.
  5. 5Haz clic en "Asociar pulsera" — el sistema crea un registro en cashless_wallets con saldo inicial $0.
  6. 6Repite para cada pulsera del evento.
Para eventos masivos (+500 pulseras), exporta el lote de UIDs desde el lector y usa el endpoint api/bulk-register-wallets.php con el CSV. Consulta la documentación de la API interna.

Lectura NFC en cajero / validador

Los paneles de cajero y validador usan Web NFC API (Chrome Android) con fallback a BarcodeDetector + jsQR para dispositivos sin NFC o usando QR. El estándar es:

  1. 1BarcodeDetector (cámara) como método primario de QR.
  2. 2jsQR como fallback si BarcodeDetector no está disponible.
  3. 3NFC (Web NFC API) para pulseras físicas.
  4. 4Entrada manual de código como último recurso.

Compatibilidad NFC

DispositivoWeb NFCAlternativa
Android Chrome 89+✅ Nativo
iPhone / Safari❌ No soportadoQR con cámara
Chrome desktop + lector USB❌ No Web NFCLector envía como teclado
Firefox AndroidQR con cámara

4. Requisitos de red en el evento

Topología recomendada

Internet (4G/Fibra backup)
    │
    ├── Router principal (WiFi 5GHz)
    │       ├── Red "FestiveraOPS" (operadores, protegida)
    │       │       ├── Tablets cajero
    │       │       ├── Tablets validador
    │       │       └── Tablets guardarropa
    │       └── Red "FestiveraGUEST" (opcional, aislada)
    │
    └── Switch PoE (si hay puntos fijos)
            ├── Impresoras QR
            └── Puntos de recarga fija

Configuración WiFi recomendada

ParámetroValor recomendado
Banda5 GHz (menos interferencia en eventos)
Canal36, 40, 44 o 48 (auto si el router lo soporta)
SeguridadWPA2-PSK o WPA3
SSID operadoresOculto (no broadcast)
Ancho de bandaMínimo 10 Mbps subida / 20 Mbps bajada
IP fija para servidoresSí (para impresoras y lectores USB fijos)
Nunca uses la red WiFi del evento abierta al público para los dispositivos de operación. La red de operadores debe estar aislada y con contraseña distinta.

Plan de contingencia — sin internet

Si el internet falla durante el evento:

  1. 1Activar hotspot 4G del coordinador técnico como backup inmediato.
  2. 2El validador puede operar con las últimas entradas escaneadas en caché local (IndexedDB) durante hasta 30 minutos.
  3. 3El cajero debe pausarse hasta recuperar conectividad — no procesar transacciones cashless offline sin confirmación de saldo en Supabase.
  4. 4Al restaurar conexión, el sistema sincroniza automáticamente los registros pendientes.

5. Servidor y despliegue

Acceso FTP Hostinger

Credenciales FTP

Host212.85.28.245
Puerto21 (con PASV)
Usuariou931838093.app.festivera.com
Raízpublic_html/
ProtocoloFTP con PASV (curl --ftp-pasv)

Subir un archivo al servidor

# Subir un archivo PHP a la raíz
curl --ftp-pasv \
  -u "u931838093.app.festivera.com:CONTRASEÑA" \
  -T archivo.php \
  ftp://212.85.28.245/public_html/api/archivo.php

# Subir admin.html al frontend
curl --ftp-pasv \
  -u "u931838093.app.festivera.com:CONTRASEÑA" \
  -T admin.html \
  ftp://212.85.28.245/public_html/admin.html

# Verificar tamaño en servidor (MLST)
curl --ftp-pasv \
  -u "u931838093.app.festivera.com:CONTRASEÑA" \
  "ftp://212.85.28.245/public_html/admin.html" \
  -I 2>&1 | grep -i size

Estructura de directorios en Hostinger

public_html/
├── admin.html              # Panel superadmin
├── dashboard.html          # Panel organizador
├── cajero.html             # POS cashless
├── validador.html          # Portería
├── recargar.html           # Recargas pulseras
├── guardarropa-op.html     # Guardarropa
├── docs/                   # Manuales de usuario
│   ├── index.html
│   ├── manual-organizador.html
│   ├── manual-operador.html
│   ├── manual-administrador.html
│   ├── manual-tecnico.html
│   └── manual-general.html
├── api/
│   ├── bold-webhook.php
│   ├── billing-dispatch.php
│   ├── dian-admin.php      # Token: Fstvr2025Wh
│   ├── create-daily-campaigns.php
│   ├── process-email-jobs.php
│   └── billing/dian/
│       ├── Certificate.php
│       ├── DianApi.php
│       ├── DianBilling.php
│       └── UblBuilder.php
└── dian-data/              # FUERA de public_html si es posible
    └── certs/tms.p12       # Certificado DIAN

Crons activos en Hostinger

CronFrecuenciaPropósito
create-daily-campaigns.phpCada 2 horasDetecta eventos nuevos, crea campañas de email automáticas
process-email-jobs.phpCada minutoProcesa la cola de emails pendientes vía Resend

6. Supabase — estructura de datos

Conexión desde PHP

$supabase_url = "https://gpswnzcfyhxzldijgewa.supabase.co/rest/v1";
$headers = [
    "apikey: {SERVICE_KEY}",
    "Authorization: Bearer {SERVICE_KEY}",
    "Content-Type: application/json"
];

# GET con filtro
GET /rest/v1/api_settings?service=eq.dian&select=config

# POST insert
POST /rest/v1/dian_invoices
Body: {"event_id":1,"order_id":2,"amount":50000,...}

# PATCH update
PATCH /rest/v1/dian_invoices?id=eq.42
Body: {"status":"aceptada","cufe":"abc123..."}

Tablas críticas

TablaRLSAcceso service_role
profiles✅ Full
events✅ Full
orders✅ Full
cashless_wallets✅ Full
cashless_transactions✅ Full
dian_invoicesDeshabilitado (fix pendiente)✅ Post-fix
api_settingsNo✅ Full
email_campaignsNo✅ Full
El archivo fix-dian-invoices-grant.sql debe ejecutarse en Supabase SQL editor antes de que el panel de Facturas en admin.html funcione correctamente. Ver festivera-platform/sql/fix-dian-invoices-grant.sql.

7. Diagnóstico y troubleshooting

El lector NFC no responde

  1. 1Confirma que el navegador es Chrome para Android (Web NFC solo funciona ahí).
  2. 2Ve a Configuración Android → NFC y verifica que esté activado.
  3. 3El sitio debe estar en https:// — Web NFC requiere contexto seguro.
  4. 4En Chrome, la primera vez que se usa NFC, el navegador pide permiso. Acepta el popup.
  5. 5Si el chip no se lee, prueba acercarlo por distintas zonas del dispositivo (el lector NFC varía por modelo de teléfono).

Error "permission denied for table dian_invoices"

  1. 1Ve a Supabase Dashboard → SQL Editor.
  2. 2Ejecuta: ALTER TABLE public.dian_invoices DISABLE ROW LEVEL SECURITY;
  3. 3Confirma con: SELECT count(*) FROM public.dian_invoices;

DIAN InternalServiceFault

SíntomaCausa probableSolución
InternalServiceFault en send-test-setSoftware "Festivera" "En proceso" en DIAN habLlamar 01 8000 912 478, dar TestSetId + NIT
Certificate errorCert .p12 vencido o mal cargadoSubir nuevo .p12 vía admin.html → DIAN → "Subir certificado"
ZIP inválidoNombre de ZIP incorrectoVerificar DianApi.php usa fv{NIT}{num}.zip
Firma XAdES rechazadaTransform C14N faltanteVerificar Certificate.php tiene exc-C14N explícito (ya corregido)

Email no llega al asistente

  1. 1Verifica que el cron process-email-jobs.php esté activo en Hostinger cPanel → Cron Jobs.
  2. 2Revisa la tabla email_campaigns en Supabase: el registro debe estar en estado "completado", no "error".
  3. 3Verifica la API key de Resend en Supabase api_settings where service='resend'.
  4. 4Revisa el dashboard de Resend (resend.com) → Logs para ver si el email fue aceptado o rebotó.

Pulsera con saldo incorrecto

  1. 1Busca el UID de la pulsera en Supabase cashless_wallets.
  2. 2Revisa el historial completo en cashless_transactions filtrando por wallet_id.
  3. 3Si hay discrepancia, actualiza el saldo vía Supabase SQL: UPDATE cashless_wallets SET balance=X WHERE uid='...'.
  4. 4Documenta el ajuste en el log de incidencias del evento.

8. Protocolo de emergencia en vivo

Escenario: el sistema cae en pleno evento

  1. 1Verificar conexión: abrir app.festivera.com desde otro dispositivo. Si carga, el problema es local (WiFi o dispositivo).
  2. 2Cambiar a datos móviles: desactivar WiFi en el dispositivo con problemas y usar 4G directamente.
  3. 3Hotspot de emergencia: el coordinador técnico activa hotspot 4G y reconecta todos los dispositivos.
  4. 4Modo degradado: el validador puede usar capturas de pantalla de los QR válidos para continuar la entrada manualmente.
  5. 5Cashless en pausa: si no hay Supabase disponible, pausar puntos de venta hasta restaurar conexión. No procesar cashless sin confirmación.
  6. 6Escalar: contactar soporte Festivera en hola@festivera.com con captura del error exacto.
Para situaciones de emergencia, el equipo técnico debe siempre tener a mano: (1) hotspot 4G dedicado para operaciones, (2) contraseña FTP, (3) acceso al dashboard de Supabase desde su propio dispositivo.