Sistema de venta de tickets para eventos de Fuego Austral π₯
DocumentaciΓ³n de dominio y reglas de negocio (casos de uso, modelos, integraciones): ver la carpeta docs/.
- π DocumentaciΓ³n de producto (
/docs) - π CaracterΓsticas
- π οΈ Desarrollo Local
- π οΈ Herramientas de Desarrollo
- π Deploy
- πͺ Agregar un Nuevo Evento
- ποΈ Arquitectura
- π οΈ TecnologΓas
- π§ Troubleshooting
- π Soporte
- ποΈ GestiΓ³n de eventos - Crear y administrar eventos de manera sencilla
- π³ Pagos integrados - MercadoPago checkout online e Instore (QR/Postnet) en caja v2
- πͺ Caja v2 - MΓΊltiples puntos de venta por evento, stock unificado, reportes
- π Logros - Insignias desbloqueables segΓΊn historial de compras
- π AutenticaciΓ³n - Login con Google OAuth2
- π§ Notificaciones - Sistema de emails automΓ‘ticos
- βοΈ Deploy automΓ‘tico - CI/CD con GitHub Actions
- π Python 3.13 - Γltima versiΓ³n de Python con mejoras de rendimiento
- PostgreSQL (v16.8 en producciΓ³n, v15.6+ en desarrollo. En cualquier momento migramos todo a 17) π
- Python 3.13 (ΓΊltima versiΓ³n) π
- Git para clonar el repositorio π¦
Crea un archivo .env basado en el template:
cp env.example .envπ Configura las variables de base de datos en tu archivo
.env:
DB_HOST- Host de tu base de datos PostgreSQLDB_USER- Usuario de la base de datosDB_DATABASE- Nombre de la base de datosDB_PASSWORD- ContraseΓ±a de la base de datos
- Crear entorno virtual π
python3.13 -m venv venv
source venv/bin/activateπ‘ Tip: Para salir del entorno virtual ejecuta
deactivate
- Instalar dependencias π¦
(venv)$ pip install -r requirements.txt
(venv)$ pip install -r requirements-dev.txt- Configurar settings locales βοΈ
(venv)$ cp deprepagos/local_settings.py.example deprepagos/local_settings.py- Iniciar PostgreSQL π
# macOS
brew services start postgresql@17
# Ubuntu/Debian
sudo systemctl start postgresql- Crear base de datos ποΈ
(venv)$ createdb deprepagos_development- Aplicar migraciones π
(venv)$ python manage.py migrate- Crear usuario administrador π€
(venv)$ python manage.py createsuperuserSi necesitas migrar datos desde PostgreSQL 15 (producciΓ³n) a PostgreSQL 17 (local), usa nuestro script automatizado:
-
Configurar variables de entorno en tu archivo
.env:DB_HOST=tu_host_de_produccion DB_USER=tu_usuario DB_DATABASE=tu_database DB_PASSWORD=tu_password
-
Ejecutar migraciΓ³n completa:
./migrate_db.sh all
-
O ejecutar paso a paso:
./migrate_db.sh dump # Hacer dump desde producciΓ³n ./migrate_db.sh create # Crear nuevo schema ./migrate_db.sh restore # Restaurar datos
dump- Hacer dump desde PostgreSQL 15 (producciΓ³n)create- Crear nuevo schema en PostgreSQL 17 (local)restore- Restaurar dump en el nuevo schemaall- Ejecutar todo el proceso completohelp- Mostrar ayuda
DespuΓ©s de la migraciΓ³n, actualiza tu local_settings.py:
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql',
'NAME': 'postgres',
'USER': 'tu_usuario',
'PASSWORD': 'tu_password',
'HOST': 'localhost',
'PORT': '5432',
'OPTIONS': {
'options': '-c search_path=ticketera_new,public'
}
}
}π‘ Tip: El script crea un schema llamado
ticketera_newpara mantener los datos separados del schemapublic
-
Crear usuario de prueba en MercadoPago π§ͺ
-
Configurar variables:
MERCADOPAGO_PUBLIC_KEYMERCADOPAGO_ACCESS_TOKENMERCADOPAGO_WEBHOOK_SECRETMERCADOPAGO_COLLECTOR_USER_ID(caja v2: stores/POS MP Instore)
-
Configurar webhook apuntando a
{tu_url_local}/webhooks/mercadopagoπ
π Para exponer tu servidor local: Usa Cloudflare Tunnel o ngrok
- Crear proyecto en Google Cloud Platform βοΈ
- Habilitar Google+ API π‘
- Crear credenciales OAuth 2.0 π
- Configurar variables:
GOOGLE_CLIENT_IDGOOGLE_CLIENT_SECRET
- Agregar URI de redirecciΓ³n:
{tu_url_local}/accounts/google/login/callback/π
Usa Mailtrap para testing de emails π¬
- Crear cuenta en Mailtrap
- Obtener credenciales SMTP de Email Testing > Inboxes > SMTP
- Configurar en tu
.env
(venv)$ python manage.py runserverΒ‘Listo! π Tu aplicaciΓ³n estarΓ‘ disponible en http://127.0.0.1:8000
El proyecto incluye un script automatizado para migrar datos entre diferentes versiones de PostgreSQL:
migrate_db.sh- Script principal de migraciΓ³nenv.example- Template de variables de entorno
# Configurar variables de entorno
cp env.example .env
# Editar .env con tus datos
# Ejecutar migraciΓ³n completa
./migrate_db.sh all- β
Carga automΓ‘tica de variables desde
.env - β Compatibilidad con PostgreSQL 15 β 16+
- β
CreaciΓ³n automΓ‘tica de base de datos
ticketera_local - β Dump optimizado con opciones avanzadas
- β Limpieza automΓ‘tica de archivos temporales
- β Manejo de foreign keys circulares
- β Mensajes informativos con colores
- β Manejo de errores robusto
./migrate_db.sh help # Mostrar ayuda
./migrate_db.sh check # Verificar dependencias del sistema
./migrate_db.sh dump # Hacer dump desde producciΓ³n
./migrate_db.sh create # Crear base de datos ticketera_local
./migrate_db.sh restore # Restaurar datos
./migrate_db.sh cleanup # Limpiar archivos de dump
./migrate_db.sh drop-db # Eliminar base de datos ticketera_local
./migrate_db.sh test-local # Verificar conexiΓ³n local
./migrate_db.sh test-remote # Verificar conexiΓ³n remota
./migrate_db.sh test-all # Verificar ambas conexiones
./migrate_db.sh all # Proceso completoEl script verifica automΓ‘ticamente que tengas todas las dependencias necesarias:
- β PostgreSQL 16+ (local)
- β Homebrew (para instalaciΓ³n)
- β Archivo .env (configuraciΓ³n)
Si faltan dependencias, el script te darΓ‘ instrucciones especΓficas de instalaciΓ³n.
El script utiliza opciones avanzadas de pg_dump para mayor eficiencia:
--disable-triggers- Evita problemas con foreign keys circulares--no-owner --no-privileges- Ignora permisos especΓficos del sistema--exclude-schema- Excluye schemas del sistema y de Supabase- Limpieza automΓ‘tica - Elimina archivos de dump anteriores antes de crear nuevos
- EliminaciΓ³n robusta de BD - Termina conexiones activas antes de eliminar la base de datos
- Manejo de conflictos - Ignora errores de schemas/tablas existentes durante la restauraciΓ³n
- EstadΓsticas de archivos - Muestra el tamaΓ±o de cada archivo creado
β οΈ IMPORTANTE: Todos los deploys se realizan exclusivamente por CI/CD (GitHub Actions). No se hacen deploys manuales.
# 1. Crear feature branch desde dev
git checkout dev
git pull origin dev
git checkout -b feature/nueva-funcionalidad
# 2. Hacer cambios y commit
git add .
git commit -m "feat: agregar nueva funcionalidad"
# 3. Push y crear PR a dev
git push origin feature/nueva-funcionalidad
# Crear PR en GitHub: feature/nueva-funcionalidad β devβ‘ Deploy automΓ‘tico a dev: Al mergear el PR a
dev, GitHub Actions despliega automΓ‘ticamente
- π§ͺ Probar la funcionalidad en
https://dev.fuegoaustral.org - β Verificar que todo funciona correctamente
- π Revisar logs y mΓ©tricas
# 1. Crear PR de dev a main
# En GitHub: Crear PR dev β main
# 2. Revisar y mergear
# DespuΓ©s de revisiΓ³n, mergear el PR
# 3. Deploy automΓ‘tico a producciΓ³n
# GitHub Actions despliega automΓ‘ticamente a prodπ Deploy automΓ‘tico a prod: Al mergear
devβmain, se despliega automΓ‘ticamente a producciΓ³n
- β
Push a
feature/*branches - β
PRs a
devbranch - β
PRs de
devamain
- π« Push directo a
dev(excepto hotfixes crΓticos o que estes vibrando expresion radical β¨ y sepas lo que estas haciendo. Mandale cumbia rey) - π« Push directo a
main(NUNCA) - π« Deploys manuales con Zappa
En caso de emergencia crΓtica:
# 1. Crear hotfix desde main
git checkout main
git pull origin main
git checkout -b hotfix/fix-critico
# 2. Aplicar fix y commit
git add .
git commit -m "hotfix: fix crΓtico urgente"
# 3. Push y crear PR directo a main
git push origin hotfix/fix-critico
# Crear PR: hotfix/fix-critico β main
# 4. OBLIGATORIO: Backport a dev despuΓ©s
git checkout dev
git cherry-pick <commit-hash>
git push origin dev
β οΈ Solo usar en emergencias: El deploy normal es 100% automΓ‘tico
# Construir imagen Docker
docker build . -t ticketera-zappashell
# Crear alias para facilitar el uso
alias zappashell='docker run -ti -e AWS_PROFILE=ticketera -v "$(pwd):/var/task" -v ~/.aws/:/root/.aws --rm ticketera-zappashell'
# Usar el shell (solo emergencias)
zappashell
zappashell> zappa update prodLos archivos estΓ‘ticos se manejan automΓ‘ticamente en el pipeline:
# Esto se ejecuta automΓ‘ticamente en CI/CD
python manage.py collectstatic --settings=deprepagos.settings_prodπ DocumentaciΓ³n completa: Google Doc
π‘ Tip: Comparte este documento con el equipo de comunicaciΓ³n y diseΓ±o cuando prepares un nuevo evento
πΊοΈ Vista de pΓ‘jaro del sistema: cΓ³mo se conectan usuarios, infra de AWS, integraciones externas y CI/CD.
flowchart LR
%% =========================
%% Actores
%% =========================
subgraph Users["π₯ Usuarios"]
Buyer["ποΈ Comprador<br/><i>browser</i>"]
Staff["π‘οΈ Staff / Admin<br/><i>/admin</i>"]
end
%% =========================
%% CI/CD
%% =========================
subgraph CICD["π CI/CD"]
GH["GitHub<br/><i>main / dev</i>"]
GHA["GitHub Actions<br/><i>deploy-dev / deploy-prod</i>"]
Zappa["π¦ Zappa<br/><i>package + deploy</i>"]
GH --> GHA --> Zappa
end
%% =========================
%% AWS
%% =========================
subgraph AWS["βοΈ AWS β us-east-1"]
R53["π Route 53 / ACM<br/><i>eventos.fuegoaustral.org<br/>dev.fuegoaustral.org</i>"]
APIGW["πͺ API Gateway<br/><i>HTTPS</i>"]
subgraph Lambda["Ξ» AWS Lambda β Python 3.13"]
Django["π Django 4.2<br/><i>tickets Β· events Β·<br/>user_profile Β· caja Β· logros Β· espaciozen</i>"]
Crons["β° Cron Handlers<br/><i>payment_check Β· email_crons</i>"]
end
EB["ποΈ EventBridge<br/><i>schedules</i>"]
S3Static["πͺ£ S3 Β· faprivate<br/><i>static + media</i>"]
RDS[("π RDS PostgreSQL 16.8")]
CW["π CloudWatch Logs"]
APIGW --> Django
EB -->|"rate(5 min)"| Crons
EB -->|"cron 17:00 UTC"| Crons
Django --> RDS
Crons --> RDS
Django --> S3Static
Django --> CW
Crons --> CW
end
%% =========================
%% Integraciones externas
%% =========================
subgraph Ext["π Integraciones Externas"]
MP["π³ MercadoPago<br/><i>checkout + webhook + Instore caja</i>"]
Google["π Google OAuth2<br/><i>django-allauth</i>"]
SMTP["π§ SMTP<br/><i>transactional email</i>"]
Twilio["π± Twilio Verify<br/><i>phone OTP</i>"]
Chatwoot["π¬ Chatwoot<br/><i>support widget</i>"]
end
%% =========================
%% Conexiones principales
%% =========================
Buyer -->|HTTPS| R53 --> APIGW
Staff -->|HTTPS| R53
Django <-->|create preference| MP
MP -->|POST /webhooks/mercadopago| APIGW
Django <-->|OAuth2| Google
Django -->|send| SMTP
Django <-->|verify| Twilio
Buyer <-.->|chat| Chatwoot
Zappa -. deploy .-> Lambda
Zappa -. upload .-> S3Static
%% =========================
%% Estilos
%% =========================
classDef aws fill:#FFF4E5,stroke:#FF9900,stroke-width:1px,color:#222;
classDef ext fill:#EAF4FF,stroke:#1E88E5,stroke-width:1px,color:#222;
classDef cicd fill:#F3E5F5,stroke:#8E24AA,stroke-width:1px,color:#222;
classDef users fill:#E8F5E9,stroke:#43A047,stroke-width:1px,color:#222;
classDef db fill:#FFEBEE,stroke:#E53935,stroke-width:1px,color:#222;
class R53,APIGW,Lambda,Django,Crons,EB,S3Static,CW aws;
class RDS db;
class MP,Google,SMTP,Twilio,Chatwoot ext;
class GH,GHA,Zappa cicd;
class Buyer,Staff users;
| Capa | TecnologΓa | Detalle |
|---|---|---|
| π¨ Frontend | Django Templates + Bootstrap 5 + CKEditor 5 | SSR clΓ‘sico, sin SPA |
| π Backend | Django 4.2 / Python 3.13 | Apps: tickets, events, user_profile, caja, logros, espaciozen |
| πͺ Edge | API Gateway + ACM + Route 53 | TLS y dominios eventos.fuegoaustral.org / dev.fuegoaustral.org |
| β‘ Compute | AWS Lambda (Zappa, slim_handler) |
1024 MB Β· timeout 300s Β· keep_warm activo |
| π Datos | Amazon RDS PostgreSQL 16.8 | Schema ΓΊnico Β· migraciones Django |
| ποΈ Storage | S3 faprivate |
EstΓ‘ticos + uploads vΓa django_s3_storage |
| π Observabilidad | CloudWatch Logs + django-auditlog |
zappa tail para streaming |
| β° Jobs | EventBridge β Lambda | Ver tabla de cron jobs β |
| π Auth | django-allauth + Google OAuth2 |
Email obligatorio, verificaciΓ³n mandatory |
| π³ Pagos | MercadoPago Checkout Pro + Instore (caja v2) | Webhook firmado en /webhooks/mercadopago |
| Job | Schedule | FunciΓ³n |
|---|---|---|
π° check_pending_payments |
rate(5 minutes) |
Reconcilia pagos pendientes contra MercadoPago |
π¬ send_pending_actions_emails |
cron(0 17 * * ? *) |
Recordatorios diarios de acciones pendientes |
sequenceDiagram
autonumber
actor U as ποΈ Comprador
participant D as π Django (Lambda)
participant DB as π PostgreSQL
participant MP as π³ MercadoPago
participant E as π§ SMTP
U->>D: GET /evento/:slug
D->>DB: SELECT evento + tickets disponibles
D-->>U: HTML con formulario de compra
U->>D: POST /comprar (datos + cantidad)
D->>DB: INSERT Order (status=pending)
D->>MP: create_preference()
MP-->>D: init_point (URL checkout)
D-->>U: 302 β init_point
U->>MP: completa pago en MercadoPago
MP-->>U: redirect a /payment/success
par Webhook async
MP->>D: POST /webhooks/mercadopago (firmado)
D->>MP: GET /v1/payments/:id (verificar)
D->>DB: UPDATE Order (status=paid) + emitir tickets
D->>E: enviar tickets por email
and Cron de respaldo (cada 5 min)
D->>MP: poll pagos pendientes
D->>DB: reconciliar estados
end
| Entorno | Branch | URL | Lambda alias | DB |
|---|---|---|---|---|
| π§ͺ dev | dev |
https://dev.fuegoaustral.org |
deprepagos-dev |
RDS dev |
| π prod | main |
https://eventos.fuegoaustral.org |
deprepagos-prod |
RDS prod |
π Diagrama ASCII (fallback para terminales sin renderizado Mermaid)
ββββββββββββββββββββββββββββββββββββββββββββββ
β π₯ Usuarios β
β Comprador Β· Staff (/admin) β
βββββββββββββββββββββ¬βββββββββββββββββββββββββ
β HTTPS
βΌ
ββββββββββββββββββββββββββββββββββββββββββββββ
β π Route 53 + ACM β πͺ API Gateway β
βββββββββββββββββββββ¬βββββββββββββββββββββββββ
βΌ
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β βοΈ AWS Lambda (Python 3.13, Zappa) β
β ββββββββββββββββββββββββββββββ βββββββββββββββββββββββββββββ β
β β π Django 4.2 β β β° Cron Handlers β β
β β tickets Β· events Β· β β payment_check (5 min) β β
β β user_profile Β· caja Β· logros Β· espaciozen β β email_crons (17:00) β β
β βββββββ¬βββββββ¬βββββββ¬ββββββββββ ββββββββββββββ¬βββββββββββββββ β
ββββββββββΌβββββββΌβββββββΌββββββββββββββββββββββββββββΌβββββββββββββββββ
β β β β
βΌ βΌ βΌ βΌ
ββββββββββββ βββββββββββ ββββββββββββββ ββββββββββββββββ
β π RDS β β πͺ£ S3 β β π CW Logs β β ποΈ EventBridgeβ
β PG 16.8 β βfaprivateβ β β β schedules β
ββββββββββββ βββββββββββ ββββββββββββββ ββββββββββββββββ
β²
β
βββββββββββββββββββββββββββ΄βββββββββββββββββββββββββββ
β π Integraciones Externas β
β π³ MercadoPago Β· π Google OAuth2 Β· π§ SMTP β
β π± Twilio Verify Β· π¬ Chatwoot β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββ
π CI/CD: GitHub β GH Actions β Zappa β Lambda + S3
- Backend: Django 4.2 + Python 3.13 π
- Base de Datos: PostgreSQL 16.8 (producciΓ³n) / 15.6 (desarrollo) π
- Deploy: AWS Lambda + Zappa βοΈ
- CI/CD: GitHub Actions π
- Pagos: MercadoPago π³
- Auth: Google OAuth2 π
- Emails: Django + SMTP π§
- Herramientas: Scripts de migraciΓ³n automatizados π§
# Si psql no se encuentra
export PATH="/opt/homebrew/Cellar/postgresql@17/17.6/bin:$PATH"
# Si hay problemas de permisos
sudo chown -R $(whoami) /opt/homebrew/var/postgresql@17# Verificar conexiΓ³n a PostgreSQL
/opt/homebrew/Cellar/postgresql@17/17.6/bin/psql -d postgres -c "SELECT version();"
# Reiniciar PostgreSQL
brew services restart postgresql@17
# Ver logs de PostgreSQL
tail -f /opt/homebrew/var/log/postgresql@17.log# Verificar dependencias del sistema
./migrate_db.sh check
# Verificar conexiones
./migrate_db.sh test-all
# Verificar variables de entorno
./migrate_db.sh help
# Verificar conexiΓ³n a base de datos remota manualmente
/opt/homebrew/Cellar/postgresql@16/16.10/bin/psql -h $DB_HOST -U $DB_USER -d $DB_DATABASE -c "SELECT 1;"# Verificar AWS credentials
aws sts get-caller-identity
# Verificar Zappa
source venv/bin/activate && zappa status dev
# Ver logs de Lambda
zappa tail dev# Verificar estado del proyecto
python manage.py check
# Verificar migraciones pendientes
python manage.py showmigrations
# Crear migraciones
python manage.py makemigrations
# Aplicar migraciones
python manage.py migrate
# Cargar datos de prueba
python manage.py loaddata fixtures/initial_data.jsonΒΏNecesitas ayuda? π€
- π§ Email: contacto@fuegoaustral.org
- π Issues: GitHub Issues
Hecho con β€οΈ por el equipo de Fuego Austral π₯