chore: añadir CLAUDE.md con convenciones del ecosistema
All checks were successful
DEPLOY_MULTI_BRACH/pipeline/head This commit looks good
All checks were successful
DEPLOY_MULTI_BRACH/pipeline/head This commit looks good
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
103
CLAUDE.md
Normal file
103
CLAUDE.md
Normal file
@@ -0,0 +1,103 @@
|
||||
# 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
|
||||
- `dev`: validación previa a producción
|
||||
- `master`: producción estable
|
||||
- Merges siempre con `--no-ff`
|
||||
|
||||
## 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.
|
||||
Reference in New Issue
Block a user