Nota: este documento es un punto de partida (borrador). La intención es capturar el contexto actual, decisiones tentativas y preguntas abiertas para iterar después.
El objetivo es establecer un sistema centralizado para la administración de múltiples tipos de programas de lealtad, con el usuario como eje principal. Cada usuario dispondrá de un identificador único (su tarjeta universal). Adicionalmente, contará billetera digital (wallet), que contendrá las tarjetas individuales asociadas a cada establecimiento comercial (y/o marca).
Las campañas pueden ser permanentes o temporales, todo debe ser totalmente configurable, tanto a nivel de CPG como de Comercio.
- Programas basados en puntos: Los clientes acumulan unidades de valor (puntos) con cada adquisición, las cuales son canjeables por descuentos, productos sin costo o servicios privilegiados. La sencillez de este modelo motiva la continuidad de compra para la obtención de mayores recompensas.
- Programas de estructura jerárquica (niveles): La progresión del cliente a través de distintos escalones se determina por el volumen de compras o el logro de metas específicas (como el monto total gastado). Cada nivel superior confiere beneficios adicionales y exclusivos, incentivando un mayor gasto para acceder a retribuciones de categoría superior.
- Programas de beneficios exclusivos y personalizados: Este esquema, a diferencia de los puntos o niveles, se enfoca en ofrecer ventajas únicas y adaptadas a los clientes con mayor fidelidad, tales como acceso prioritario a eventos, lanzamientos de productos especiales o atención personalizada. Dicha estrategia fomenta la percepción de valor y aprecio por parte del cliente.
Los programas de lealtad se pueden cuantificar de dos maneras:
- Por interacciones o frecuencia: Se mide mediante el número de acciones o participaciones (por ejemplo, sellos).
- Por tamaño de la operación o valor: Se mide a través de la cantidad o valor de la transacción (por ejemplo, puntos).
Sistema de lealtad para el tendero, facilitado por T-Conecta (Qoa).
- Qoa entrega un QR a la tienda (vía T-Conecta).
- La tienda imprime el QR y lo coloca en mostrador.
- El cliente escanea el QR y se abre WhatsApp con un mensaje tipo: “Quiero crear mi tarjeta de puntos de [Tienda]”.
- Qoa responde por WhatsApp y entrega un link a una página donde el cliente ve su tarjeta (puntos/estampas) + un CTA para comprar cierto producto (PLI) y ganar su primera estampa.
- El cliente compra; la tienda escanea el QR de la tarjeta del cliente y el código de barras del producto.
- Qoa envía recordatorios con cierta periodicidad para completar estampas.
- Qoa retroalimenta a la tienda con ventas generadas + CTA para incrementar orden de productos (PLI).
- Qoa retroalimenta a comercial/marketing con el ROI del programa.
- Aumentar ventas del tendero (alta adopción en canal tradicional).
- Generar data no solo del tendero, sino del cliente final (habilitar microsegmentación a futuro).
- “Tarjeta de estampas/puntos” como semilla de un producto más complejo (storefront digital / conversacional).
- Reducir dependencia operativa de T-Conecta (idealmente solo el escaneo); definir workarounds si el escaneo es lento (p. ej. evidencias con códigos alfanuméricos por WhatsApp).
- Diferenciación vs intermediarios (Beez, Arca, etc.): ellos intermedian entre CPGs y canal tradicional; nosotros entre CPGs y cliente final a través del canal tradicional.
- ¿Esquema de puntos, estampas o combinación? El sistema debe ser capas de operar ambos, al crear una campaña se define el esquema.
- ¿Qué ofrecemos como premio al cliente final? (alinear con Comercial). Esto debe ser configurable por campaña.
- ¿Qué tan “automático” es el escaneo en tienda (UX y tiempos reales)? ¿Qué hacemos si falla? Este es un punto crítico a validar en la POC, debemos de brindar toda la tecnología para que nos puean integrar fácilmente, debemos tener un buen control de errores y tiempos de respuesta. esto debe ir directo a la documentación técnica.
- ¿Cuáles son los “PLI” iniciales (productos), cuántos CPGs y bajo qué reglas de campaña? Todo esto son parametros configurables en la creación de campañas, aun no tengo claro la estructura final de las campañas, como se introducen los PLI, sobretodo
- ¿Qué métricas mínimas definen éxito del piloto (retención, conversión, repetición, incremento de venta, etc.)?
La documentación vive en /docs. Los READMEs de cada carpeta explican qué llenar:
- docs/01-overview/README.md
- docs/02-architecture/README.md
- docs/03-apis/README.md
- docs/04-data/README.md
- docs/05-security/README.md
- docs/06-ops/README.md
- docs/07-engineering/README.md
- docs/adr/README.md
Este proyecto está configurado para GitHub Codespaces, lo que permite desarrollar en un entorno completamente configurado en la nube. El Codespace incluye:
- ✅ Bun runtime pre-instalado
- ✅ PostgreSQL 16 y Redis 7 configurados automáticamente
- ✅ Extensiones de VS Code recomendadas
- ✅ Hot-reload para desarrollo rápido
Para empezar:
- Haz clic en el badge de arriba (el botón aparecerá en inglés como "Open in GitHub Codespaces")
- Espera a que el entorno se configure (2-3 minutos)
- Ejecuta
bun run deven la terminal - Accede a la aplicación en el puerto 3000 cuando VS Code te notifique
Ver .devcontainer/README.md para más detalles sobre el entorno de Codespaces.
El runtime carga las variables definidas en src/.env.local automáticamente (Bun soporta .env* sin dependencias adicionales). El archivo incluido en el repo trae valores de ejemplo para:
PORT,NODE_ENVpara la app HTTP.POSTGRES_*yDATABASE_URLpara la base de datos interna.REDIS_*yREDIS_URLpara la caché/eventos.
Actualiza esos valores antes de desplegar en otros entornos; no compartas secretos reales en control de versiones.
-
Construye e inicia toda la pila (API Bun + Postgres + Redis):
docker compose up --build
-
La app expone
http://localhost:3000/healthy la UI de OpenAPI en/openapi. -
Para apagar los servicios y conservar los datos de Postgres/Redis en volúmenes locales:
docker compose down
Los servicios usan las credenciales definidas en src/.env.local. Ajusta puertos/volúmenes editando docker-compose.yml.
Cuando quieras aprovechar hot-reload de bun run dev pero mantener la misma base de datos/caché de Docker:
-
Levanta únicamente las dependencias:
docker compose up -d postgres redis
-
Usa las variables de
src/.env.development(Bun ya carga.env.developmentcuandobun run devestableceBUN_ENV=development). Asegúrate de quePOSTGRES_HOSTyREDIS_HOSTapunten a127.0.0.1, tal como viene en ese archivo. -
Ejecuta la app local:
cd src bun install bun run dev -
Cuando termines, detén los contenedores (los volúmenes persisten):
docker compose stop postgres redis
Desde src/:
bun install
bun run dev # recarga en caliente para desarrollo
bun test spec # ejecuta las pruebas existentesLos comandos anteriores respetan el principio de “Bun-first” (sin npm, node, ni ts-node).
Siempre que se cree o modifique un endpoint:
- Actualiza/crea sus tests en
src/spec/. - Sincroniza la definición en
/Users/iddar/Developer/projects/qoa/docs/03-apis/openapi.yaml.
-
Define/actualiza las tablas en
src/db/schema/*.ts(p. ej.tenants). -
Genera el SQL versionado y los snapshots JSON:
cd src bun run db:generateEsto produce archivos en
src/drizzle/(ej.0000_red_shockwave.sql) siguiendo la guía oficial de Drizzle migrations. -
Aplica las migraciones al Postgres que tengas configurado mediante
DATABASE_URL(usa.env.localo.env.developmentsegún el flujo):cd src bun run db:migrate -
En entornos Docker, ejecuta las migraciones dentro del contenedor de la app antes de exponer tráfico:
docker compose run --rm app bun run db:migrate
Todas las migraciones y snapshots (src/drizzle/meta) se deben versionar en Git para garantizar reproducibilidad.
La aplicación usa el driver nativo de Bun (drizzle-orm/bun-sql + SQL de Bun), así que no requiere adaptadores como postgres o pg.