# Don Confiao Backend - Contexto del Proyecto ## Tipo de Proyecto Backend Django con Django REST Framework ## Estructura del Proyecto ``` don_confiao_backend/ ├── requirements.txt # Dependencias Python ├── docker-compose.dev.yml # Docker Compose para desarrollo ├── docker-compose.staging.yml # Docker Compose para staging (testing producción local) ├── docker-compose.prod.yml # Docker Compose para producción ├── django.Dockerfile # Dockerfile Django ├── .env.development # Variables de entorno desarrollo ├── .env.staging # Variables de entorno staging ├── .env.production.example # Ejemplo variables de entorno producción ├── .env_example # Ejemplo de variables de entorno ├── README.rst # Documentación básica ├── Rakefile # Tareas rake ├── doc/ # Documentación adicional │ └── requests.org └── tienda_ilusion/ # Proyecto Django ├── manage.py ├── db.sqlite3 # Base de datos SQLite (desarrollo) ├── don_confiao/ # App principal │ ├── models.py # Modelos: Customer, Product, Sale, SaleLine, Payment, ReconciliationJar, AdminCode │ ├── views.py │ ├── api_views.py │ ├── serializers.py │ ├── forms.py │ ├── admin.py │ ├── urls.py │ ├── export_csv.py │ ├── tests/ # Tests │ └── migrations/ ├── users/ # App de usuarios │ ├── models.py │ ├── views.py │ ├── serializers.py │ ├── urls.py │ └── tests/ └── config/ # Configuración Django ├── settings/ # Settings por ambiente │ ├── __init__.py # Detección automática de ambiente │ ├── base.py # Configuración compartida │ ├── development.py # Configuración desarrollo │ ├── staging.py # Configuración staging │ └── production.py # Configuración producción ├── urls.py ├── wsgi.py └── asgi.py ``` ## Dependencias Principales - Django==5.0.6 - djangorestframework - django-cors-headers - djangorestframework-simplejwt - sabatron-tryton-rpc-client==7.4.0 (integración con Tryton ERP) - psycopg2-binary (driver PostgreSQL para producción) - gunicorn (servidor WSGI para producción) - python-decouple (gestión de variables de entorno) ## Modelos Principales (don_confiao/models.py) - **Customer**: Clientes (name, address, email, phone, external_id) - **Product**: Productos (name, price, measuring_unit, categories) - **ProductCategory**: Categorías de productos - **Sale**: Ventas (customer, date, phone, description, payment_method, reconciliation) - **SaleLine**: Líneas de venta (sale, product, quantity, unit_price, description) - **Payment**: Pagos (date_time, type_payment, amount, reconciliation_jar) - **PaymentSale**: Relación muchos a muchos entre Payment y Sale - **ReconciliationJar**: Arqueo de caja (is_valid, date_time, reconcilier, cash_taken, cash_discrepancy) - **AdminCode**: Códigos de administrador ## Autenticación - JWT con djangorestframework-simplejwt - ACCESS_TOKEN_LIFETIME: 30 minutos - REFRESH_TOKEN_LIFETIME: 1 día ## API Endpoints - REST API en don_confiao/api_views.py y users/ - URLs en don_confiao/urls.py y users/urls.py ## Ejecución con Docker Compose El proyecto se ejecuta con docker-compose. Todos los comandos `manage.py` deben ejecutarse dentro del contenedor: ### Desarrollo (Development) ```bash # Ejecutar tests docker compose -f docker-compose.dev.yml run --rm django python manage.py test # Migraciones docker compose -f docker-compose.dev.yml run --rm django python manage.py makemigrations docker compose -f docker-compose.dev.yml run --rm django python manage.py migrate # Servidor desarrollo docker compose -f docker-compose.dev.yml up # Shell Django docker compose -f docker-compose.dev.yml run --rm django python manage.py shell # Crear superuser docker compose -f docker-compose.dev.yml run --rm django python manage.py createsuperuser ``` ### Staging (Testing Producción Local) ```bash # Iniciar servicios (PostgreSQL + Django con Gunicorn) # Ya incluye el archivo .env.staging, listo para usar docker compose -f docker-compose.staging.yml up -d # Migraciones docker compose -f docker-compose.staging.yml run --rm django python manage.py migrate # Colectar archivos estáticos docker compose -f docker-compose.staging.yml run --rm django python manage.py collectstatic --noinput # Crear superuser docker compose -f docker-compose.staging.yml run --rm django python manage.py createsuperuser # Ver logs docker compose -f docker-compose.staging.yml logs -f django # Detener servicios docker compose -f docker-compose.staging.yml down ``` ### Producción (Production) ```bash # Primero, copiar .env.production.example a .env.production y configurar variables cp .env.production.example .env.production # Editar .env.production con valores reales # Iniciar servicios (PostgreSQL + Django con Gunicorn) docker compose -f docker-compose.prod.yml up -d # Migraciones docker compose -f docker-compose.prod.yml run --rm django python manage.py migrate # Colectar archivos estáticos docker compose -f docker-compose.prod.yml run --rm django python manage.py collectstatic --noinput # Crear superuser docker compose -f docker-compose.prod.yml run --rm django python manage.py createsuperuser # Ver logs docker compose -f docker-compose.prod.yml logs -f django # Detener servicios docker compose -f docker-compose.prod.yml down ``` Nota: El volumen monta `tienda_ilusion/` en `/app/`, por lo que el path correcto es `python manage.py` (no `python tienda_ilusion/manage.py`). ## Tests - Framework: Django unittest - Directorio: don_confiao/tests/ - Ejecutar: `docker-compose -f docker-compose.dev.yml run --rm django python manage.py test` ## Comandos Útiles (dentro del contenedor) - Migraciones: `docker-compose -f docker-compose.dev.yml run --rm django python manage.py makemigrations && docker-compose -f docker-compose.dev.yml run --rm django python manage.py migrate` - Servidor desarrollo: `docker-compose -f docker-compose.dev.yml up` - Shell Django: `docker-compose -f docker-compose.dev.yml run --rm django python manage.py shell` - Superuser: `docker-compose -f docker-compose.dev.yml run --rm django python manage.py createsuperuser` ## Configuración de Ambientes El proyecto soporta tres ambientes diferentes mediante la variable `DJANGO_ENV`: ### Development (desarrollo local) - **Variable de ambiente**: `DJANGO_ENV=development` - **Archivo de configuración**: `.env.development` - **Base de datos**: SQLite (db.sqlite3) - **DEBUG**: True - **CORS**: Permisivo para desarrollo local - **Docker Compose**: `docker-compose.dev.yml` ### Staging (testing de producción local) - **Variable de ambiente**: `DJANGO_ENV=staging` - **Archivo de configuración**: `.env.staging` - **Base de datos**: PostgreSQL (tienda_ilusion_staging) - **DEBUG**: False (simula producción) - **CORS**: Permisivo para localhost (sin SSL redirect) - **Docker Compose**: `docker-compose.staging.yml` - **Servidor**: Gunicorn con 4 workers - **Puerto PostgreSQL**: 5433 (para no conflictuar con producción) ### Production (producción) - **Variable de ambiente**: `DJANGO_ENV=production` - **Archivo de configuración**: `.env.production` (crear desde `.env.production.example`) - **Base de datos**: PostgreSQL - **DEBUG**: False - **Seguridad**: HTTPS, HSTS, secure cookies, CSRF protections - **Docker Compose**: `docker-compose.prod.yml` - **Servidor**: Gunicorn con 4 workers ### Cambiar entre ambientes La detección de ambiente es automática mediante la variable `DJANGO_ENV`. Docker Compose configura esta variable automáticamente según el archivo usado: - `docker-compose.dev.yml` → usa `.env.development` → carga `settings/development.py` - `docker-compose.staging.yml` → usa `.env.staging` → carga `settings/staging.py` - `docker-compose.prod.yml` → usa `.env.production` → carga `settings/production.py` ### Variables de entorno requeridas **Desarrollo** (`.env.development`): - `DJANGO_ENV=development` - `DEBUG=True` - `TRYTON_HOST`, `TRYTON_DATABASE`, `TRYTON_USERNAME`, `TRYTON_PASSWORD` **Staging** (`.env.staging`): - `DJANGO_ENV=staging` - `DEBUG=False` - `SECRET_KEY` (para staging local, puede ser una key fija) - `ALLOWED_HOSTS=localhost,127.0.0.1,0.0.0.0` - `CORS_ALLOWED_ORIGINS` (URLs localhost separadas por comas) - `DB_NAME=tienda_ilusion_staging`, `DB_USER`, `DB_PASSWORD`, `DB_HOST=postgres`, `DB_PORT=5432` - `TRYTON_HOST`, `TRYTON_DATABASE`, `TRYTON_USERNAME`, `TRYTON_PASSWORD` **Producción** (`.env.production`): - `DJANGO_ENV=production` - `DEBUG=False` - `SECRET_KEY` (generar una nueva y segura) - `ALLOWED_HOSTS` (dominios separados por comas) - `CORS_ALLOWED_ORIGINS` (URLs separadas por comas) - `CSRF_TRUSTED_ORIGINS` (URLs separadas por comas) - `DB_NAME`, `DB_USER`, `DB_PASSWORD`, `DB_HOST`, `DB_PORT` - `EMAIL_HOST`, `EMAIL_PORT`, `EMAIL_HOST_USER`, `EMAIL_HOST_PASSWORD` - `TRYTON_HOST`, `TRYTON_DATABASE`, `TRYTON_USERNAME`, `TRYTON_PASSWORD` Ver `.env.production.example` para todos los detalles. ## Scripts Útiles El proyecto incluye scripts para facilitar operaciones comunes: ### Health Check Verifica el estado de todos los servicios: ```bash # Verificar ambiente de desarrollo ./scripts/health-check.sh dev # Verificar ambiente de producción ./scripts/health-check.sh prod ``` ### Backup de Base de Datos (Producción) Crea un backup comprimido de la base de datos PostgreSQL: ```bash ./scripts/backup-db.sh ``` Los backups se guardan en `backups/` y se mantienen por 7 días automáticamente. ### Restore de Base de Datos (Producción) Restaura un backup de la base de datos: ```bash ./scripts/restore-backup.sh ``` **ADVERTENCIA**: Esto reemplazará la base de datos actual. Se crea un backup de seguridad antes de restaurar. ## Troubleshooting ### Errores Comunes #### 1. Error: "database 'tienda_ilusion_user' does not exist" **Síntoma**: Aparece en los logs de PostgreSQL ``` FATAL: database "tienda_ilusion_user" does not exist ``` **Causa**: Este es un comportamiento normal de PostgreSQL. Cuando te conectas sin especificar una base de datos, PostgreSQL intenta conectarse a una base con el mismo nombre del usuario. **Solución**: Este error NO afecta el funcionamiento de Django. Para verificar que la base de datos correcta existe: ```bash docker exec tienda_ilusion_postgres_prod psql -U tienda_ilusion_user -d tienda_ilusion_prod -c '\l' ``` #### 2. Error: "required variable DB_PASSWORD is missing a value" **Síntoma**: Docker Compose falla al iniciar con error de variable faltante **Causa**: El archivo `.env.production` no existe o tiene valores placeholder **Solución**: 1. Copiar el archivo de ejemplo: `cp .env.production.example .env.production` 2. Editar `.env.production` y reemplazar todos los valores `CHANGE-ME-...` con valores reales 3. Generar SECRET_KEY segura: ```bash python -c 'from django.core.management.utils import get_random_secret_key; print(get_random_secret_key())' ``` #### 3. Error: "ModuleNotFoundError" o importación fallida **Síntoma**: Django no puede importar módulos después de cambiar configuración **Causa**: Dependencias no instaladas o contenedor con caché viejo **Solución**: ```bash # Reconstruir contenedores docker-compose -f docker-compose.dev.yml build --no-cache docker-compose -f docker-compose.dev.yml up # Para producción docker-compose -f docker-compose.prod.yml build --no-cache docker-compose -f docker-compose.prod.yml up -d ``` #### 4. Error: "django.db.utils.OperationalError: could not connect to server" **Síntoma**: Django no puede conectarse a PostgreSQL **Causa**: PostgreSQL aún no está listo cuando Django intenta conectar **Solución**: El healthcheck en `docker-compose.prod.yml` maneja esto automáticamente. Si el problema persiste: ```bash # Verificar que PostgreSQL esté corriendo docker ps | grep postgres # Ver logs de PostgreSQL docker logs tienda_ilusion_postgres_prod # Reiniciar servicios en orden docker-compose -f docker-compose.prod.yml restart postgres docker-compose -f docker-compose.prod.yml restart django ``` #### 5. Error: "CSRF verification failed" **Síntoma**: Errores CSRF en producción **Causa**: `CSRF_TRUSTED_ORIGINS` no configurado correctamente **Solución**: En `.env.production`, asegurar que `CSRF_TRUSTED_ORIGINS` incluya el protocolo: ```bash CSRF_TRUSTED_ORIGINS=https://tudominio.com,https://www.tudominio.com ``` #### 6. Static files no se sirven en producción **Síntoma**: CSS/JS no cargan, errores 404 para archivos estáticos **Causa**: `collectstatic` no ejecutado o configuración de nginx incorrecta **Solución**: ```bash # Ejecutar collectstatic docker-compose -f docker-compose.prod.yml exec django python manage.py collectstatic --noinput # Verificar que los archivos existen docker exec tienda_ilusion_django_prod ls -la /app/staticfiles ``` #### 7. Migraciones pendientes después de deployment **Síntoma**: Errores de base de datos o tablas faltantes **Causa**: Migraciones no aplicadas en producción **Solución**: ```bash # Ver estado de migraciones docker-compose -f docker-compose.prod.yml exec django python manage.py showmigrations # Aplicar migraciones pendientes docker-compose -f docker-compose.prod.yml exec django python manage.py migrate ``` ### Comandos de Diagnóstico ```bash # Ver todos los contenedores docker ps -a # Ver logs en tiempo real docker-compose -f docker-compose.prod.yml logs -f # Ver logs solo de Django docker logs -f tienda_ilusion_django_prod # Ver logs solo de PostgreSQL docker logs -f tienda_ilusion_postgres_prod # Ejecutar shell en contenedor Django docker-compose -f docker-compose.prod.yml exec django bash # Ejecutar Django shell docker-compose -f docker-compose.prod.yml exec django python manage.py shell # Conectar a PostgreSQL docker exec -it tienda_ilusion_postgres_prod psql -U tienda_ilusion_user -d tienda_ilusion_prod # Verificar variables de entorno en contenedor docker-compose -f docker-compose.prod.yml exec django env | grep DJANGO ``` ### Performance y Optimización Si experimentas problemas de rendimiento: 1. **Verificar recursos del contenedor**: ```bash docker stats ``` 2. **Ajustar workers de Gunicorn** (editar `docker-compose.prod.yml`): ```yaml command: gunicorn config.wsgi:application --bind 0.0.0.0:8000 --workers 8 --timeout 120 ``` Regla general: `workers = (2 x CPU cores) + 1` 3. **Habilitar persistent connections**: Ya configurado en `settings/production.py` con `CONN_MAX_AGE = 600` 4. **Considerar agregar Redis para caché**: Descomentar sección de Redis en `settings/production.py` ### Seguridad Antes de ir a producción, verificar: - [ ] `DEBUG=False` en `.env.production` - [ ] `SECRET_KEY` único y seguro generado - [ ] `ALLOWED_HOSTS` configurado con dominios reales - [ ] `CORS_ALLOWED_ORIGINS` limitado a orígenes confiables - [ ] `CSRF_TRUSTED_ORIGINS` configurado correctamente - [ ] Contraseñas de base de datos seguras - [ ] `.env.production` NO commiteado a git - [ ] HTTPS habilitado (certificados SSL/TLS configurados) - [ ] Firewall configurado (solo puertos necesarios abiertos) - [ ] Backups automáticos configurados ## Integraciones - **Tryton ERP**: Integración mediante sabatron-tryton-rpc-client para sincronización de clientes, productos y ventas