Compare commits

57 Commits

Author SHA1 Message Date
juanjo
c4db3639c3 Merge pre-dev: docs flujo ramas
All checks were successful
DEPLOY_MULTI_BRACH/pipeline/head This commit looks good
2026-04-17 01:15:19 +02:00
juanjo
c692ce2a61 sync
All checks were successful
DEPLOY_MULTI_BRACH/pipeline/head This commit looks good
2026-04-17 01:15:05 +02:00
juanjo
152e9c14ef Merge: docs flujo ramas 2026-04-17 01:15:05 +02:00
juanjo
99de5f06b5 docs: corregir flujo de ramas en CLAUDE.md (pre-dev → dev → master)
All checks were successful
DEPLOY_MULTI_BRACH/pipeline/head This commit looks good
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 01:15:04 +02:00
juanjo
379ce825f6 Merge pre-dev: fix api_hub_dispatcher → api_config
All checks were successful
DEPLOY_MULTI_BRACH/pipeline/head This commit looks good
2026-04-17 01:13:56 +02:00
juanjo
d7a84a4dfa Merge master: fix api_hub_dispatcher → api_config
All checks were successful
DEPLOY_MULTI_BRACH/pipeline/head This commit looks good
2026-04-17 01:13:54 +02:00
juanjo
fbc5f0f6c4 fix: reemplazar referencias a api_hub_dispatcher por api_config
All checks were successful
DEPLOY_MULTI_BRACH/pipeline/head This commit looks good
ROOT_URLCONF, WSGI_APPLICATION, DJANGO_SETTINGS_MODULE apuntaban al
módulo renombrado — causaba ModuleNotFoundError al arrancar en Docker.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 01:13:52 +02:00
juanjo
abe67a7f20 Merge pre-dev: fix env_file docker-compose
All checks were successful
DEPLOY_MULTI_BRACH/pipeline/head This commit looks good
2026-04-17 01:06:34 +02:00
juanjo
cac00a4f8c Merge master: fix env_file docker-compose
All checks were successful
DEPLOY_MULTI_BRACH/pipeline/head This commit looks good
2026-04-17 01:06:31 +02:00
juanjo
a17f00bad2 fix: env_file .env (relativo a deployments/) en docker-compose
All checks were successful
DEPLOY_MULTI_BRACH/pipeline/head This commit looks good
Jenkins copia el secret a deployments/.env — el path debe ser .env
relativo al docker-compose.yml, no ../.env a la raíz del workspace.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 01:06:28 +02:00
juanjo
5367ba7313 Merge pre-dev: fix env_file path docker-compose
All checks were successful
DEPLOY_MULTI_BRACH/pipeline/head This commit looks good
2026-04-17 01:05:40 +02:00
juanjo
b8c3e03348 fix: corregir env_file path en docker-compose (../.env → .env)
All checks were successful
DEPLOY_MULTI_BRACH/pipeline/head This commit looks good
Jenkins copia el secret a deployments/.env — el path debe ser relativo
al docker-compose.yml, no a la raíz del workspace.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 01:05:37 +02:00
juanjo
23cd4bf8b4 Merge pre-dev: gunicorn + wait-for-db + healthcheck
Some checks failed
DEPLOY_MULTI_BRACH/pipeline/head There was a failure building this commit
2026-04-17 00:39:30 +02:00
juanjo
b43ca9d919 Merge branch 'dev' of https://git.v-encore-lab.com/Proyecto-SaaS/django-core-base into dev 2026-04-17 00:39:30 +02:00
juanjo
252e176e9d Merge master: gunicorn + wait-for-db + healthcheck
All checks were successful
DEPLOY_MULTI_BRACH/pipeline/head This commit looks good
2026-04-17 00:39:27 +02:00
juanjo
41fc2a0aa0 fix: gunicorn + wait-for-db + healthcheck en docker-compose
Some checks failed
DEPLOY_MULTI_BRACH/pipeline/head There was a failure building this commit
- entrypoint.sh: sustituye runserver por gunicorn (workers=2, timeout=120)
- entrypoint.sh: espera a PostgreSQL antes de migrar cuando DB_HOST está definido
- docker-compose.yml: unifica nombre de servicio db, añade healthcheck robusto,
  corrige env_file path a ../.env

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 00:39:21 +02:00
juanjo
001bf13d26 chore: añadir CLAUDE.md con convenciones del ecosistema
All checks were successful
DEPLOY_MULTI_BRACH/pipeline/head This commit looks good
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 00:12:18 +02:00
juanjo
47f23a73e1 docs: README completo con despliegue, BD y mantenimiento
All checks were successful
DEPLOY_MULTI_BRACH/pipeline/head This commit looks good
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 00:02:21 +02:00
juanjo
04c37f669c revert: restaurar nombre api_config (revertir renombrado erróneo)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 00:02:21 +02:00
juanjo
92a00ec75f refactor: renombrar proyecto principal api_config → api_hub_dispatcher
- Renombrar carpeta app/api_config/ → app/api_hub_dispatcher/
- Actualizar DJANGO_SETTINGS_MODULE en asgi.py, wsgi.py, manage.py
- Actualizar ROOT_URLCONF y WSGI_APPLICATION en settings.py

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-17 00:02:21 +02:00
juanjo
adaf20bd8e Merge pre-dev: revert api_config 2026-04-16 23:31:29 +02:00
juanjo
30c540b6f9 revert: restaurar nombre api_config (revertir renombrado erróneo)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 23:31:08 +02:00
juanjo
95e036108d Merge pre-dev: renombrar api_config → api_hub_dispatcher 2026-04-16 23:28:44 +02:00
juanjo
778753afd6 refactor: renombrar proyecto principal api_config → api_hub_dispatcher
- Renombrar carpeta app/api_config/ → app/api_hub_dispatcher/
- Actualizar DJANGO_SETTINGS_MODULE en asgi.py, wsgi.py, manage.py
- Actualizar ROOT_URLCONF y WSGI_APPLICATION en settings.py

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-16 23:28:43 +02:00
b91f5d09e5 Merge pull request 'dev' (#43) from dev into master
All checks were successful
DEPLOY_MULTI_BRACH/pipeline/head This commit looks good
Reviewed-on: #43
2026-04-16 17:32:46 +00:00
1e1348bc1a Merge pull request 'dev' (#41) from dev into master
All checks were successful
DEPLOY_MULTI_BRACH/pipeline/head This commit looks good
Reviewed-on: #41
2026-04-16 15:34:48 +00:00
juanjo
384f47df5e Merge branch 'master' of https://git.v-encore-lab.com/Proyecto-SaaS/django-core-base
All checks were successful
DEPLOY_MULTI_BRACH/pipeline/head This commit looks good
2026-04-16 17:29:18 +02:00
juanjo
94faedecae Merge pre-dev: fix serialización LogService 2026-04-16 17:28:48 +02:00
juanjo
2684e251f7 Merge dev: fix serialización LogService 2026-04-16 17:28:48 +02:00
3f95e92318 Merge pull request 'dev' (#39) from dev into master
All checks were successful
DEPLOY_MULTI_BRACH/pipeline/head This commit looks good
Reviewed-on: #39
2026-04-16 15:11:49 +00:00
juanjo
0c18ffc2f9 Merge pre-dev: fix ruta data/ y LogService resiliente 2026-04-16 17:07:23 +02:00
juanjo
03663aacb4 Merge dev: fix ruta data/ y LogService resiliente 2026-04-16 17:07:23 +02:00
77b722d739 Merge pull request 'dev' (#37) from dev into master
All checks were successful
DEPLOY_MULTI_BRACH/pipeline/head This commit looks good
Reviewed-on: #37
2026-04-16 14:57:37 +00:00
juanjo
5d2a6469aa Merge pre-dev: feat app general con LogService 2026-04-16 16:51:00 +02:00
juanjo
156b5ad77d Merge dev: feat app general con LogService 2026-04-16 16:51:00 +02:00
e2ae400889 Merge pull request 'dev' (#35) from dev into master
All checks were successful
DEPLOY_MULTI_BRACH/pipeline/head This commit looks good
Reviewed-on: #35
2026-04-16 14:37:32 +00:00
juanjo
4425141cb3 Merge dev: refactor mover BD SQLite a carpeta data/
All checks were successful
DEPLOY_MULTI_BRACH/pipeline/head This commit looks good
2026-04-16 16:34:16 +02:00
juanjo
29db0eb0a2 Merge pre-dev: refactor mover BD SQLite a carpeta data/ 2026-04-16 16:34:00 +02:00
0a73b91e12 Merge pull request 'fix: corregir name en common/apps.py' (#33) from dev into master
All checks were successful
DEPLOY_MULTI_BRACH/pipeline/head This commit looks good
2026-04-16 14:13:02 +00:00
508f3f028d Merge pull request 'refactor: reorganizar estructura app/api_config' (#31) from dev into master
All checks were successful
DEPLOY_MULTI_BRACH/pipeline/head This commit looks good
2026-04-16 14:02:19 +00:00
bc82249a29 Merge pull request 'Merge dev into master' (#29) from dev into master
All checks were successful
DEPLOY_MULTI_BRACH/pipeline/head This commit looks good
2026-04-16 13:51:32 +00:00
f3514d399e Merge pull request 'dev' (#27) from dev into master
All checks were successful
DEPLOY_MULTI_BRACH/pipeline/head This commit looks good
Reviewed-on: #27
2026-04-14 23:44:35 +00:00
0ac0a859b9 Merge pull request 'dev' (#24) from dev into master
All checks were successful
DEPLOY_MULTI_BRACH/pipeline/head This commit looks good
Reviewed-on: #24
2026-04-14 21:52:57 +00:00
7a9a1686fa Merge pull request 'dev' (#21) from dev into master
Some checks failed
DEPLOY_MULTI_BRACH/pipeline/head There was a failure building this commit
Reviewed-on: #21
2026-04-14 21:28:08 +00:00
5a7209badb Merge pull request 'dev' (#16) from dev into master
All checks were successful
DEPLOY_MULTI_BRACH/pipeline/head This commit looks good
Reviewed-on: #16
2026-04-12 20:57:46 +00:00
32e3184b59 Merge pull request 'dev' (#11) from dev into master
All checks were successful
DEPLOY_MULTI_BRACH/pipeline/head This commit looks good
Reviewed-on: #11
2026-04-12 13:42:46 +00:00
083375c5f0 Merge pull request 'dev' (#9) from dev into master
All checks were successful
DEPLOY_MULTI_BRACH/pipeline/head This commit looks good
Reviewed-on: #9
2026-04-12 12:10:27 +00:00
6f84db00cd Merge pull request 'dev' (#7) from dev into master
All checks were successful
DEPLOY_MULTI_BRACH/pipeline/head This commit looks good
Reviewed-on: #7
2026-04-12 02:53:09 +00:00
b60ecccad4 Merge pull request 'dev' (#28) from dev into master
Some checks failed
DEPLOY_MULTI_BRACH/pipeline/head There was a failure building this commit
Reviewed-on: #28
2026-04-11 23:02:30 +02:00
c4e8675fe8 Merge pull request 'dev' (#23) from dev into master
Reviewed-on: #23
2026-04-11 20:48:19 +02:00
04fb83447f Merge pull request 'dev' (#16) from dev into master
Reviewed-on: https://gitea.185.187.169.109.nip.io/Proyecto-SaaS/django-core-base/pulls/16
2026-04-11 18:39:48 +02:00
bdda074fa1 Merge pull request 'dev' (#14) from dev into master
Reviewed-on: https://gitea.185.187.169.109.nip.io/Proyecto-SaaS/django-core-base/pulls/14
2026-04-11 18:23:51 +02:00
64afc3aedb Merge pull request 'dev' (#11) from dev into master
Reviewed-on: https://gitea.185.187.169.109.nip.io/Proyecto-SaaS/django-core-base/pulls/11
2026-04-11 18:04:09 +02:00
156e1aa27c Merge pull request 'dev' (#9) from dev into master
Reviewed-on: https://gitea.185.187.169.109.nip.io/Proyecto-SaaS/django-core-base/pulls/9
2026-04-11 15:21:01 +02:00
16b7f956b3 Merge pull request 'dev' (#7) from dev into master
Reviewed-on: https://gitea.185.187.169.109.nip.io/Proyecto-SaaS/django-core-base/pulls/7
2026-04-11 15:13:03 +02:00
34faf2157e Merge pull request 'dev' (#5) from dev into master
Reviewed-on: https://gitea.185.187.169.109.nip.io/Proyecto-SaaS/django-core-base/pulls/5
2026-04-11 15:07:07 +02:00
2a6723aedf Merge pull request 'dev' (#3) from dev into master
Reviewed-on: https://gitea.185.187.169.109.nip.io/Proyecto-SaaS/django-core-base/pulls/3
2026-04-11 14:57:47 +02:00
5 changed files with 442 additions and 74 deletions

110
CLAUDE.md Normal file
View File

@@ -0,0 +1,110 @@
# Convenciones del Ecosistema V-Encore Lab
## Ecosistema de microservicios
| Repo | Rol | Puerto |
|------|-----|--------|
| `django-core-base` | Hub orquestador principal | 8000 |
| `api_backoffice` | Consulta y gestión de BD | 8001 |
| `api_comunicaciones` | Emails, notificaciones, webhooks | 8002 |
| `api_documentacion` | Generación y gestión de documentos | 8003 |
| `web_interno` | Panel de gestión (React + Ant Design) | 3000 |
## Stack Django
- Django 5.0 + DRF + SimpleJWT
- Apps bajo `app/`. Prefijo `/api/` en todas las URLs salvo `admin/`.
- Patrón 3 capas: **URL → View → Action**
- SQL con `connection.cursor()` y placeholders (`%s`). Nunca concatenar strings.
## Patrón de vistas — 4 bloques obligatorios
```python
from general.utilidades.acciones import LogService
class MiVista(APIView):
authentication_classes = [JWTAuthentication]
permission_classes = [IsAuthenticated]
def post(self, request):
path = '/mi-app/mi-endpoint/'
# Bloque 1 — Inicio Log
log_id = LogService.gestionar_log(self, request, path=path)
try:
# Bloque 2 — Data Cleaning
data = request.data
LogService.gestionar_log(self, request, log_id=log_id,
path=path, body_request=data, status_code=100)
params = {'campo': data.get('campo')}
except Exception as error:
response = {'error': str(error)}
LogService.gestionar_log(self, request, log_id=log_id,
path=path, body_response=response, status_code=400)
return JsonResponse(response, status=400)
try:
# Bloque 3 — Action Call
resultado = mi_accion(params)
# Bloque 4 — Cierre Log
LogService.gestionar_log(self, request, log_id=log_id,
path=path, body_response=resultado, status_code=200)
return JsonResponse(resultado, status=200)
except Exception as error:
response = {'error': str(error)}
LogService.gestionar_log(self, request, log_id=log_id,
path=path, body_response=response, status_code=500)
return JsonResponse(response, status=500)
```
## LogService — reglas
- Siempre llamar como `LogService.gestionar_log(self, request, ...)` — pasar `self` de la vista.
- Primera llamada (sin `log_id`): crea el registro, devuelve el `log_id`.
- Llamadas siguientes: actualizar con `log_id=log_id`.
- `body_request` y `body_response` se serializan con `DjangoJSONEncoder` — soporta `datetime.date`, `Decimal`, etc.
- `status_code` como entero. Usar `is not None` para comprobar (0 es válido).
## Base de datos
- `DB_HOST` definido → PostgreSQL
- `DB_HOST` no definido → SQLite en `app/data/db.sqlite3`
- Migraciones siempre desde `app/`: `cd app && python manage.py migrate`
- SQL INSERT con psycopg2: usar `INSERT ... RETURNING id` + `cursor.fetchone()`. **Nunca `cursor.lastrowid`**.
- Booleans en psycopg2: pasar `True`/`False`, no `1`/`0`.
## Flujo de ramas
```
pre-dev → dev → master
```
- `pre-dev`: desarrollo activo — aquí entran todos los cambios
- `dev`: validación previa a producción
- `master`: producción estable
- Merges siempre con `--no-ff`
- **NUNCA** propagar en sentido inverso (master → dev o dev → pre-dev)
- Secuencia correcta:
```bash
git checkout pre-dev && git merge <mi-cambio> --no-ff
git checkout dev && git merge pre-dev --no-ff && git push origin dev
git checkout master && git merge dev --no-ff && git push origin master
```
## Estructura de app Django
```
app/
├── api_config/ # settings.py, urls.py, wsgi.py
├── general/ # LogService, utils — NO tiene modelos propios
├── backend_admin/ # Modelo Log (audit_logs), admin panel
├── common/ # Modelos y utilidades compartidas entre apps
├── <feature_app>/ # Una app por dominio de negocio
├── data/ # SQLite (gitignored, solo .gitkeep versionado)
└── manage.py
```
## Fixtures
- `loaddata` ignora `auto_now_add=True` — incluir fechas explícitas en el JSON o falla con NOT NULL en PostgreSQL.

329
README.md
View File

@@ -1,73 +1,312 @@
# django-core-base
# django-core-base · API Hub Orquestador
// V-Encore Lab: Sistema Automatizado v1.0.4
> V-Encore Lab — Microservicio principal. Actúa como orquestador y punto de entrada central del ecosistema SaaS.
> Puerto por defecto: **8000**
## 🚀 Inicio Rápido (Desarrollo Local)
---
## Tabla de contenidos
1. [Requisitos previos](#requisitos-previos)
2. [Inicio rápido — Desarrollo local](#inicio-rápido--desarrollo-local)
3. [Variables de entorno](#variables-de-entorno)
4. [Base de datos](#base-de-datos)
5. [Docker — Producción](#docker--producción)
6. [Estructura del proyecto](#estructura-del-proyecto)
7. [Endpoints principales](#endpoints-principales)
8. [Patrón LogService](#patrón-logservice)
9. [Flujo de ramas](#flujo-de-ramas)
10. [Mantenimiento](#mantenimiento)
---
## Requisitos previos
| Herramienta | Versión mínima |
|-------------|---------------|
| Python | 3.11 |
| pip | 23+ |
| Docker | 24+ |
| Docker Compose | v2 |
| Git | 2.40+ |
---
## Inicio rápido — Desarrollo local
### 1. Clonar y Configurar
```bash
# 1. Clonar
git clone https://git.v-encore-lab.com/Proyecto-SaaS/django-core-base.git
cd django-core-base
cp .env.example .env
```
### 2. Instalar Dependencias
```bash
# 2. Entorno virtual
python -m venv .venv
source .venv/bin/activate # Linux/Mac
.venv\Scripts\activate # Windows
# 3. Dependencias
pip install -r deployments/requirements.txt
```
### 3. Migraciones de Base de Datos
```bash
# Crear y aplicar migraciones para todos los modelos
python manage.py makemigrations
# 4. Variables de entorno
cp .env.example .env
# Editar .env según el entorno (ver sección Variables de entorno)
# 5. Migraciones (SQLite en local)
cd app
python manage.py migrate
# Opcional: Crear superusuario
# 6. Superusuario (primera vez)
python manage.py createsuperuser
# 7. Servidor de desarrollo
python manage.py runserver 0.0.0.0:8000
```
Accesos:
- API: http://localhost:8000/api/
- Admin: http://localhost:8000/admin/
---
## Variables de entorno
Copia `.env.example` a `.env` y ajusta los valores:
| Variable | Descripción | Ejemplo / Default |
|----------------|--------------------------------------------------|----------------------------|
| `SECRET_KEY` | Clave secreta Django | `django-insecure-...` |
| `DEBUG` | Modo debug | `True` (dev) / `False` (prod) |
| `ALLOWED_HOSTS`| Hosts permitidos (separados por coma) | `localhost,127.0.0.1` |
| `DB_HOST` | Host PostgreSQL. **Si no se define → SQLite** | `localhost` / vacío |
| `DB_PORT` | Puerto PostgreSQL | `5432` |
| `DB_NAME` | Nombre de la base de datos | `vencorelab` |
| `DB_USER` | Usuario PostgreSQL | `postgres` |
| `DB_PASSWORD` | Contraseña PostgreSQL | `postgres` |
---
## Base de datos
### Desarrollo local — SQLite
Si `DB_HOST` **no** está definido en `.env`, Django usa automáticamente SQLite:
```
app/data/db.sqlite3
```
```bash
cd app
python manage.py migrate # crea app/data/db.sqlite3
python manage.py createsuperuser
```
### 4. Correr el Servidor
```bash
python manage.py runserver
La carpeta `app/data/` está en `.gitignore` (solo se versiona `.gitkeep`).
### Producción — PostgreSQL
Define `DB_HOST` en `.env` para activar el driver PostgreSQL:
```env
DB_HOST=localhost
DB_PORT=5432
DB_NAME=vencorelab
DB_USER=postgres
DB_PASSWORD=supersecret
```
Abrir http://localhost:8000
## 🐳 Docker (Producción/Desarrollo)
```bash
docker-compose up --build
cd app
python manage.py migrate
```
Acceder a:
- App: http://localhost:8000
- Admin: http://localhost:8000/admin/
- DB: localhost:5432 (Postgres)
## 📋 Comandos Django Comunes
### Comandos útiles de migración
```bash
# Verificar configuración
python manage.py check
cd app
# Recopilar static files
python manage.py collectstatic --noinput
# Ver migraciones pendientes
python manage.py showmigrations
# Test
python manage.py test
# Crear migraciones de una app
python manage.py makemigrations <app_name>
# Aplicar todas las migraciones
python manage.py migrate
# Revertir migraciones de una app al estado inicial
python manage.py migrate <app_name> zero
```
## 🔧 Estructura del Proyecto
---
```
├── apps/ # Aplicaciones Django
│ ├── backend_admin/
│ ├── common/
│ └── promociones/
├── core/ # Configuración principal
├── deployments/ # Docker, requirements prod
└── manage.py
## Docker — Producción
```bash
# Construir e iniciar
docker-compose up --build -d
# Ver logs
docker-compose logs -f
# Parar
docker-compose down
# Parar y eliminar volúmenes (¡cuidado en producción!)
docker-compose down -v
```
## .env Variables
Ver `.env.example` para configuración.
El contenedor expone el puerto **8000**.
Para producción con PostgreSQL, asegúrate de que `.env` tenga `DB_HOST` apuntando al host correcto (puede ser el nombre del servicio en la red Docker).
---
## Estructura del proyecto
```
django-core-base/
├── app/
│ ├── api_config/ # Configuración Django (settings, urls, wsgi)
│ ├── general/ # App transversal
│ │ └── utilidades/
│ │ ├── acciones.py # LogService — auditoría centralizada
│ │ └── utils.py # Utilidades HTTP (get_client_ip, etc.)
│ ├── backend_admin/ # App admin: modelo Log, endpoints de gestión
│ ├── common/ # Modelos y utilidades compartidas
│ ├── promociones/ # App de ejemplo
│ ├── automatizados/ # Endpoints para Jenkins/automatizaciones
│ ├── data/ # Directorio de la BD SQLite (gitignored)
│ │ └── .gitkeep
│ └── manage.py
├── deployments/
│ ├── requirements.txt
│ └── Dockerfile
├── docker-compose.yml
├── .env.example
└── README.md
```
---
## Endpoints principales
| Método | Ruta | Descripción | Auth |
|--------|-------------------------------|-----------------------------------|--------------|
| POST | `/api/token/` | Obtener JWT (login) | No |
| POST | `/api/token/refresh/` | Renovar access token | No |
| GET | `/admin/` | Panel de administración Django | Session |
| POST | `/api/promociones/obtener/` | Consultar promociones | JWT Bearer |
| GET | `/api/general/health/` | Health check | No |
Autenticación: `Authorization: Bearer <access_token>`
---
## Patrón LogService
Todas las vistas deben usar `LogService` para auditoría:
```python
from general.utilidades.acciones import LogService
class MiVista(APIView):
authentication_classes = [JWTAuthentication]
permission_classes = [IsAuthenticated]
def post(self, request):
path = '/mi-app/mi-endpoint/'
# Bloque 1 — Inicio log
log_id = LogService.gestionar_log(self, request, path=path)
try:
# Bloque 2 — Limpieza de datos
data = request.data
LogService.gestionar_log(self, request, log_id=log_id,
path=path, body_request=data, status_code=100)
params = {'campo': data.get('campo')}
except Exception as error:
response = {'error': str(error)}
LogService.gestionar_log(self, request, log_id=log_id,
path=path, body_response=response, status_code=400)
return JsonResponse(response, status=400)
try:
# Bloque 3 — Acción
resultado = mi_accion(params)
LogService.gestionar_log(self, request, log_id=log_id,
path=path, body_response=resultado, status_code=200)
return JsonResponse(resultado, status=200)
except Exception as error:
response = {'error': str(error)}
LogService.gestionar_log(self, request, log_id=log_id,
path=path, body_response=response, status_code=500)
return JsonResponse(response, status=500)
```
`LogService` registra automáticamente en la tabla `audit_logs` el usuario, IP, path, request/response y status code.
---
## Flujo de ramas
```
pre-dev → dev → master
```
- `pre-dev`: desarrollo activo, integración de features
- `dev`: validación previa a producción
- `master`: rama de producción estable
```bash
# Crear feature
git checkout pre-dev
git checkout -b feature/mi-feature
# Mergear a pre-dev
git checkout pre-dev
git merge feature/mi-feature --no-ff
# Promover a dev
git checkout dev
git merge pre-dev --no-ff
# Promover a master
git checkout master
git merge dev --no-ff
```
---
## Mantenimiento
```bash
# Limpiar sesiones expiradas
cd app && python manage.py clearsessions
# Ver estado de la BD
cd app && python manage.py dbshell
# Backup SQLite (desarrollo)
cp app/data/db.sqlite3 app/data/db.sqlite3.bak
# Backup PostgreSQL (producción)
pg_dump -U postgres vencorelab > backup_$(date +%Y%m%d).sql
# Actualizar dependencias
pip list --outdated
pip install -U <paquete>
pip freeze > deployments/requirements.txt
# Reiniciar contenedor Docker
docker-compose restart web
# Ver logs del contenedor
docker-compose logs -f web --tail=100
```
---
> **V-Encore Lab** — Sistema Automatizado v1.0
> Repositorio: `Proyecto-SaaS/django-core-base`

View File

@@ -18,7 +18,7 @@ class Admin:
# 1. Autenticación
user = authenticate(username=username, password=password)
if user is not None:
# 2. Generación de JWT (Access & Refresh)
refresh = RefreshToken.for_user(user)

View File

@@ -1,45 +1,41 @@
version: '3.8'
services:
gitea-db:
image: postgres:15
# Usará el nombre de tu .env (django_db_local)
container_name: ${DB_CONTAINER_NAME:-django_db_dev}
restart: always
db:
image: postgres:15-alpine
container_name: ${DB_CONTAINER_NAME:-django_core_db}
restart: unless-stopped
environment:
POSTGRES_DB: ${DB_NAME:-gitea}
POSTGRES_USER: ${DB_USER:-gitea}
POSTGRES_PASSWORD: ${DB_PASSWORD:-gitea}
POSTGRES_DB: ${DB_NAME:-django_core_db}
POSTGRES_USER: ${DB_USER:-postgres}
POSTGRES_PASSWORD: ${DB_PASSWORD:-postgres}
volumes:
- postgres_data:/var/lib/postgresql/data
# --- ESTO ES LO QUE FALTA ---
ports:
- "${DATABASE_EXPOSE_PORT:-5432}:5432"
# ----------------------------
healthcheck:
test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-gitea} -d ${DB_NAME:-gitea}"]
test: ["CMD-SHELL", "pg_isready -U ${DB_USER:-postgres} -d ${DB_NAME:-django_core_db}"]
interval: 5s
timeout: 5s
retries: 5
retries: 10
start_period: 10s
web:
build:
context: ..
dockerfile: deployments/Dockerfile
container_name: ${APP_CONTAINER_NAME:-django_app_dev}
restart: always
container_name: ${APP_CONTAINER_NAME:-django_core_app}
restart: unless-stopped
env_file:
- .env
environment:
- DEBUG=${DEBUG_MODE:-1}
# IMPORTANTE: Este nombre debe coincidir con el nombre del servicio arriba (gitea-db)
- DB_HOST=gitea-db
- DB_HOST=db
- DB_PORT=5432
ports:
- "${PORT:-8000}:8000"
depends_on:
gitea-db:
db:
condition: service_healthy
volumes:
postgres_data:
postgres_data:

View File

@@ -3,16 +3,39 @@
# Salir inmediatamente si un comando falla
set -e
# --- Esperar a PostgreSQL si estamos en modo BD remota ---
if [ -n "$DB_HOST" ]; then
echo "--> Esperando a PostgreSQL en $DB_HOST:${DB_PORT:-5432}..."
until python -c "
import sys, psycopg2, os
try:
psycopg2.connect(
host=os.environ['DB_HOST'],
port=os.environ.get('DB_PORT', 5432),
user=os.environ['DB_USER'],
password=os.environ['DB_PASSWORD'],
dbname=os.environ['DB_NAME']
)
sys.exit(0)
except Exception:
sys.exit(1)
" 2>/dev/null; do
echo " PostgreSQL no disponible, reintentando en 2s..."
sleep 2
done
echo "--> PostgreSQL listo."
fi
echo "--> Ejecutando migraciones..."
# Esto asegura que si hay cambios en models.py, se generen y apliquen las tablas
python manage.py makemigrations --noinput
python manage.py migrate --noinput
echo "--> Cargando datos de prueba..."
# Este comando busca archivos JSON en las carpetas 'fixtures' de tus apps
# Usamos || true para que si el archivo no existe o ya están cargados, el contenedor no se detenga
python manage.py loaddata semillas || echo "Aviso: No se pudieron cargar las semillas (fichero no encontrado o error de formato)."
echo "--> Cargando semillas (si existen)..."
python manage.py loaddata semillas 2>/dev/null || echo " Sin semillas, continuando."
echo "--> Arrancando el servidor Django..."
# Usamos exec para que Django sea el proceso principal (PID 1) y reciba señales de Docker
exec python manage.py runserver 0.0.0.0:8000
echo "--> Arrancando servidor con Gunicorn..."
exec gunicorn api_config.wsgi:application \
--bind 0.0.0.0:8000 \
--workers 2 \
--timeout 120 \
--access-logfile - \
--error-logfile -