# Floutic Backend API

API central de Floutic construida con FastAPI, PostgreSQL, Stripe y GoHighLevel.

## 🚀 Características Implementadas

- ✅ **Autenticación JWT** con refresh tokens, rate limiting y Redis cache
- ✅ **Gestión unificada de perfiles** (empresa/experto/admin) con validación completa y slugs SEO automáticos normalizados para expertos (fallback retroactivo para slugs antiguos)
- ✅ **Perfiles opcionales de admin** para página "Quiénes Somos" con campos completos (nombre, rol, biografía, redes sociales, visibilidad)
- ✅ **Subida de imágenes de perfil** para expertos y admin (JPEG, PNG, WebP, max 2MB)
  - Validación mejorada con Pillow para asegurar que el archivo sea realmente una imagen
  - Optimización automática: redimensionado de imágenes > 1024px, compresión de calidad
  - Conversión automática de transparencia a RGB con fondo blanco
  - Servicio centralizado `ProfileImageService` para validación, almacenamiento y normalización
- ✅ **Sistema de verificación de perfiles** - Los administradores verifican perfiles de empresas y expertos antes de permitir funcionalidades avanzadas
- ✅ **Restricción de creación de proyectos** - Solo empresas con perfil verificado pueden crear proyectos (validación en `get_current_company_user`)
- ✅ **Configuración de cuenta** con cambio seguro de contraseña, email y username
- ✅ **Sistema de proyectos** con matching inteligente, aplicaciones y selección
- ✅ **Chat interno completo** con archivos, edición, eliminación y descarga
- ✅ **Sistema de notificaciones** completo con WebSocket y endpoints REST
- ✅ **Notificaciones en tiempo real** vía WebSocket con gestión de conexiones
- ✅ **Pagos Escrow** con Stripe Connect y disputas (PaymentIntent inicial al seleccionar experto, sincronización automática `pending → held → released`, transferencias al experto con deferred payout scheduler y comisiones para Floutic)
- ✅ **Sistema de reseñas** y reputación con estadísticas (incluye visualización de avatares de revisores para mayor credibilidad)
- ✅ **Sistema de hitos secuenciales** con entregas, revisiones y pagos parciales
- ✅ **Gestión de entregas** por expertos con formularios completos
- ✅ **Sistema de revisión** por empresas (aprobar, rechazar, solicitar revisión)
- ✅ **Lógica de rechazos** con cancelación automática tras 3 rechazos
- ✅ **Búsqueda de expertos** con filtros avanzados
- ✅ **Panel de administración** con dashboard Kanban unificado
- ✅ **Gestión de propuestas** con selección de expertos (replicando hitos propuestos al aceptar al experto)
- ✅ **Servicio de email** con templates HTML y notificaciones transaccionales (bienvenida, match, proyectos, hitos, pagos, reseñas, disputas, mensajes)
- ✅ **Integraciones** (GHL, n8n, Stripe) con webhooks
- ✅ **Hardening HTTP** con CSP dinámica (nonce), Trusted Host, sesiones HttpOnly y rate limiting global basado en Redis
- ✅ **Revocación de tokens** con blacklist persistente en Redis (logout clásico y seguro invalidan access/refresh tokens)
- ✅ **Optimización de rendimiento** con Redis cache (20-100x más rápido)
- ✅ **Tests completos** - 1008 tests pasando, 5 skipped (tests de concurrencia que requieren PostgreSQL), 45 warnings controlados. La suite completa requiere Redis activo y desactivar rate limiting global (`RATE_LIMIT_PER_MINUTE=0`, `LOGIN_RATE_LIMIT_MAX_ATTEMPTS_PER_USER=0`, `LOGIN_RATE_LIMIT_MAX_ATTEMPTS_PER_IP=0`)
- ✅ **Sistema de roles múltiples** - Los usuarios pueden tener múltiples roles (`roles` array) con un `active_role` que determina el dashboard y permisos. Los administradores pueden gestionar roles de usuarios.
- ✅ **57 tests críticos nuevos implementados** (Enero 2025):
  - 9 tests de race conditions y concurrencia (5 requieren PostgreSQL)
  - 7 tests de rollback de transacciones
  - 4 tests de validaciones de negocio críticas en pagos
  - 5 tests de edge cases en milestones
  - 3 flujos end-to-end completos (proyecto, disputa, Stripe Connect)
  - 7 tests de performance (4 básicos + 3 avanzados)
  - 7 tests de expiración de tokens y refresh token
  - 6 tests de transiciones de estado de proyectos
  - 9 tests de edge cases adicionales (proyectos y reviews)
  - Incluye suites específicas para validar plantillas de email y notificaciones (`tests/unit/test_services.py`, `tests/test_notification_manager.py`)
- ✅ **Tests de integración GHL v2.2** - 63/63 pasando (100%):
  - `test_ghl_integration.py`: 11 tests (sincronización básica)
  - `test_ghl_sync.py`: 9 tests (sincronización en endpoints admin)
  - `test_ghl_sync_complete_fields.py`: 4 tests (sincronización de campos completos)
  - `test_ghl_contact_status.py`: 6 tests (estado del contacto dinámico)
  - `test_ghl_lead_score.py`: 4 tests (cálculo y sincronización de lead_score)
  - `test_ghl_project_tags.py`: 5 tests (etiquetas de proyecto)
  - `test_ghl_lead_score_integration.py`: 8 tests (integración en nivel y reputación)
  - `test_webhooks.py`: 6 tests (webhooks bidireccionales)
  - `test_admin_advanced.py`: 1 test (actualización de nivel de experto)
  - `test_admin_verification_working.py`: 3 tests (verificación básica)
- ✅ **Tests de validación de proyectos** - 5/5 pasando (100%)
- ✅ **Tests de verificación admin** - 15/15 pasando (100%)
- ✅ **Tests de seguridad** - Tests completos de seguridad headers, CORS, rate limiting, sesiones concurrentes
  - `test_security_headers_cors.py` - Headers de seguridad y CORS
  - `test_rate_limiting_brute_force.py` - Rate limiting global y por usuario/IP
  - `test_concurrent_sessions.py` - Límite de sesiones concurrentes por usuario
- ✅ **Validación robusta** - Campos obligatorios mínimos para facilitar registro
- ✅ **Sistema de datos fiscales para facturación legal** - Solicitud de datos fiscales completos cuando empresas crean su primer proyecto o expertos son asignados a su primer proyecto. Incluye validaciones, endpoints dedicados, modal bloqueante en frontend y **notificaciones proactivas** (`FISCAL_DATA_REQUIRED`) cuando se detecta que faltan datos fiscales. 15 tests backend implementados (100% pasando, incluye tests de notificaciones)

## 🆕 Nuevas Funcionalidades - Flujo de Contratación Curado

- ✅ **Sistema de proyectos curados** con validación administrativa
- ✅ **Tres tipos de contratación:** privada, curada y desde perfil
- ✅ **Estados de proyecto avanzados** con flujo completo
- ✅ **Curación administrativa** para selección de expertos
- ✅ **Sistema de propuestas** con hitos definidos por expertos
- ✅ **Validación de contenido** antes de publicación
- ✅ **Workflows administrativos** automatizados
- ✅ **Sistema de disputas** con mediación
- ✅ **Endpoints de validación** para administradores
- ✅ **Solicitud de presupuesto** desde perfil de experto

## 🎯 Sistema de Invitación de Expertos - Implementado

- ✅ **Endpoint de invitación** `/api/admin/projects/{id}/invite-experts`
- ✅ **Sistema dual de invitaciones**:
  - **Invitaciones formales** en tabla `project_invitations` (método actual)
  - **Campo legacy** `invited_experts` (JSON array) mantenido para compatibilidad
- ✅ **Validación de expertos** con verificación de roles
- ✅ **Schema actualizado** `ProjectListItemResponse` con campo `invited_experts`
- ✅ **Endpoint de admin** `/api/admin/projects/{id}` devuelve `ProjectResponse` completo
- ✅ **Validación de permisos** solo para administradores
- ✅ **Respuesta detallada** con IDs de expertos invitados y confirmación
- ✅ **Verificación dual** - Los endpoints verifican tanto `project_invitations` como `invited_experts` para máxima compatibilidad

## 🛠️ Stack Tecnológico

- **FastAPI** - Framework web moderno y rápido
- **PostgreSQL** - Base de datos relacional
- **SQLAlchemy** - ORM con soporte async
- **Pydantic** - Validación de datos
- **Stripe** - Procesamiento de pagos
- **Redis** - Cache y sesiones
- **Docker** - Containerización

## 📋 Requisitos

- Docker Desktop (incluye Docker y Docker Compose)

## 🚀 Instalación (Docker, único modo soportado)

```bash
# Desde la raíz del repo
./start-dev.sh

# O manualmente
docker compose up -d backend
```

- API Docs (host): `http://localhost:18080/docs`
- Health: `docker compose exec backend curl http://localhost:8000/health`

## 🐳 Docker

### Ejecutar con Docker Compose

```bash
docker compose up -d backend
```

### Construir imagen

```bash
docker build -t floutic-backend .
```

## 📚 API Endpoints Implementados

### Autenticación ✅
- `POST /api/auth/register` - Registro de usuario con email de bienvenida
- `POST /api/auth/login` - Iniciar sesión con JWT
- `POST /api/auth/refresh` - Renovar token de acceso (rota el refresh token previo automáticamente)
- `POST /api/auth/logout` - Cerrar sesión (enviar `Authorization: Bearer` + JSON opcional `{"refresh_token": "..."}` para revocar ambos tokens)
- `GET /api/auth/verify` - Verificar token

### Autenticación Segura ✅ (Recomendado)
- `POST /api/auth/login_secure` - Login seguro con HttpOnly cookies, CSRF protection y session_id único
- `POST /api/auth/refresh_secure` - Renovar tokens con validación de session_id
- `POST /api/auth/logout_secure` - Logout seguro con invalidación de tokens
- `GET /api/auth/verify_secure` - Verificar sesión válida, devuelve tokens y valida session_id

**Características de seguridad:**
- ✅ Cookies HttpOnly con `SameSite=Strict` para aislar ventanas privadas
- ✅ Sistema de `session_id` único por ventana para máximo aislamiento
- ✅ **Validación obligatoria de `session_id`**: Todas las peticiones a `refresh_secure` y `verify_secure` requieren el header `X-Session-ID` que coincide con el `session_id` del token
- ✅ Protección CSRF con tokens
- ✅ Cache Redis para optimización de rendimiento
- ✅ Blacklist de tokens en Redis (logout seguro/refresh rotativo evitan reutilización de cookies robadas)
- ✅ Rate limiting de login (usuario e IP) respaldado por Redis
- ✅ Cabeceras de seguridad (CSP con nonce, HSTS, COOP/COEP) y Trusted Host automático en producción

## ⚠️ Puntos pendientes conocidos
- Falta verificación de email del usuario (el registro envía notificación pero no confirma ownership).
- Recordatorios automáticos de perfil incompleto pendientes; actualmente se gestionan desde administración.

### Usuarios ✅
- `GET /api/users/me` - Obtener información del usuario actual
- `PUT /api/users/me` - Actualizar username del usuario actual
- `POST /api/users/me/change-password` - Cambiar contraseña (requiere contraseña actual)
- `PUT /api/users/me/email` - Actualizar email (requiere contraseña actual para confirmar)

### Perfiles ✅
- `GET /api/profiles/{id}` - Ver perfil público
- `GET /api/profiles/experts/slug/{slug}` - Obtener perfil público de experto por slug SEO (acepta slugs legacy sin guiones y los normaliza automáticamente)
- `GET /api/profiles/me/profile` - Mi perfil completo
- `POST /api/profiles/` - Crear perfil
- `PUT /api/profiles/{id}` - Actualizar perfil
- `POST /api/profiles/upload` - Subir documento
- `GET /api/profiles/experts` - Buscar expertos con filtros
- Los administradores también pueden crear un perfil interno (`profile_type="admin"`) para nutrir la futura página de “Quiénes somos”. Genera slug `admin-{id}` automáticamente y no dispara integración con GHL.

### Proyectos ✅
- `GET /api/projects/` - Listar proyectos con filtros
- `POST /api/projects/` - Crear proyecto con hitos (requiere perfil de empresa verificado)
  - **Campo `skills_required`**: Ahora es opcional (puede ser lista vacía) para mejorar UX
- `GET /api/projects/{id}` - Ver proyecto
- `PUT /api/projects/{id}` - Actualizar proyecto
- `DELETE /api/projects/{id}` - Eliminar proyecto
- `POST /api/projects/{id}/apply` - Aplicar a proyecto
  - Disponible para expertos invitados a proyectos `published_curated`, `bidding`, `published`
  - También habilitado para proyectos `pending_publication` cuando el experto tiene invitación formal en `project_invitations` o está en `invited_experts` (compatibilidad)
  - Proyectos `published_private` aceptan aplicaciones del `target_expert_id`
  - **Verificación dual**: El endpoint verifica tanto invitaciones formales (`project_invitations`) como el campo legacy (`invited_experts`)
- `POST /api/projects/{id}/select/{expert_id}` - Seleccionar experto (crea hitos del proyecto a partir de la propuesta si aún no existen)
- **Restricción de acceso:** Solo empresas con perfil verificado (`is_verified=True`) pueden crear proyectos. El endpoint devuelve `403 Forbidden` si el perfil no existe o no está verificado.

### Hitos (Milestones) ✅
- `POST /api/milestones/` - Crear hito
- `GET /api/milestones/project/{id}` - Listar hitos de proyecto
- `GET /api/milestones/{id}` - Ver hito específico
- `PUT /api/milestones/{id}` - Actualizar hito
- `DELETE /api/milestones/{id}` - Eliminar hito
- `POST /api/milestones/{id}/complete` - Completar hito (experto)
- `POST /api/milestones/{id}/approve` - Aprobar hito (empresa)
- `POST /api/milestones/{id}/reject` - Rechazar hito (empresa)

### Reseñas (Reviews) ✅
- `POST /api/reviews/` - Crear reseña
- `GET /api/reviews/project/{id}` - Reseñas de proyecto
- `GET /api/reviews/user/{id}` - Reseñas de usuario
- `GET /api/reviews/stats/{id}` - Estadísticas de reseñas
- `PUT /api/reviews/{id}` - Actualizar reseña
- `POST /api/reviews/{id}/respond` - Responder a reseña
- `POST /api/reviews/{id}/publish` - Publicar reseña (admin)
- `POST /api/reviews/{id}/hide` - Ocultar reseña (admin)
- `DELETE /api/reviews/{id}` - Eliminar reseña (admin)

- `POST /api/payments/initiate` - Crear PaymentIntent del proyecto/hito
- `POST /api/payments/release` - Liberar pago retenido (Stripe capture)
- `POST /api/payments/release-and-charge-next` - Liberar pago actual, capturar y transferir neto al experto vía Connect (o diferir si balance insuficiente) y crear el PaymentIntent del siguiente hito
- `POST /api/payments/sync-status` - Sincronizar estado con Stripe (marca `held`, actualiza `held_at` y `stripe_charge_id`, prepara el hito)
- `POST /api/payments/refund` - Crear reembolso
- `GET /api/payments/history` - Historial de pagos del usuario
- `GET /api/payments/project/{project_id}` - Pagos por proyecto
- `GET /api/payments/{id}` - Ver pago específico
- `POST /api/payments/webhooks/stripe` - Webhook Stripe
- `GET /api/stripe-connect/status` - Verificar estado de cuenta Connect del experto
- `POST /api/stripe-connect/account-link` - Generar enlace de onboarding Express
- `POST /api/stripe-connect/account-update-link` - Generar enlace para actualizar información de cuenta Connect (con fallback automático a onboarding si no está permitido)

> **Flujo actualizado:** al seleccionar experto se genera el PaymentIntent del primer hito con estado `pending`. Una vez autorizado el cargo inicial, el frontend sincroniza el intent (`/sync-status`) y el pago queda en depósito (`held`). Al aprobar un hito, `/release-and-charge-next` captura dicho pago y crea el intent del siguiente hito, manteniendo el ciclo de escrow.

### Chat ✅
- `GET /api/chat/{project_id}` - Obtener mensajes
- `POST /api/chat/{project_id}` - Enviar mensaje
- `PUT /api/chat/{project_id}/messages/{message_id}` - Editar mensaje
- `DELETE /api/chat/{project_id}/messages/{message_id}` - Eliminar mensaje
- `POST /api/chat/{project_id}/files` - Subir archivo
- `POST /api/chat/{project_id}/mark-read` - Marcar como leído

### Notificaciones y Emails ✅
- `GET /api/notifications/` - Consultar notificaciones
- `POST /api/notifications/mark-read` - Marcar notificación como leída
- `POST /api/notifications/mark-all-read` - Marcar todas como leídas
- `POST /api/notifications/test` - Probar notificaciones (persistencia en BD + WebSocket si hay conexiones activas)
- **Disparadores automáticos clave:**
  - Creación de perfil (empresa o experto) → alerta a administradores para iniciar verificación (movido desde registro)
  - Proyecto pasa a `pending_publication` (submit o request-budget) → aviso a admins para validar
  - Creación de disputas → notificación a admin + contraparte, con email de respaldo
- **Webhooks personalizados por usuario:**
  - `GET /api/users/me/webhook` / `PUT /api/users/me/webhook` - Configurar URL HTTPS, habilitar/deshabilitar y método de autenticación (JWT o none).
  - `GET /api/users/me/webhook/secret` - Obtener el secreto actual (para configurar JWT en n8n).
  - `POST /api/users/me/webhook/secret` - Regenerar el secreto usado para JWT.
  - `POST /api/notifications/webhook/test` - Disparar evento de prueba desde el dashboard.
  - **Método HTTP:** POST
  - **Autenticación:** JWT (compatible con n8n HTTP Trigger con JWT Auth) o sin autenticación (none).
  - **Configuración n8n:** Key Type: Secret, Algorithm: HS256, Secret: (el secreto del usuario)

  📖 **Documentación completa:** Ver [docs/WEBHOOKS.md](docs/WEBHOOKS.md) para:
  - Todos los tipos de webhooks disponibles (16 tipos)
  - Ejemplos de payloads JSON para cada tipo
  - Guía paso a paso de configuración en n8n
  - Troubleshooting y referencias
- **Emails automáticos** (via `app/services/email_service.py`):
  - **Bienvenida:**
    - Email de bienvenida genérico (`welcome.html`)
    - Email de bienvenida para empresas (`welcome_company.html`) - Incluye invitación a sesión Discovery y preparación
    - Email de bienvenida para expertos (`welcome_expert.html`) - Incluye proceso de verificación oficial
  - **Match y selección:**
    - Match confirmado para empresas (`match_confirmed_company.html`) - Presentación del experto asignado y próximos pasos
    - Match confirmado para expertos (`match_confirmed_expert.html`) - Información del cliente y proyecto, buenas prácticas
    - Selección de experto (`expert_selected.html`)
    - Invitaciones de proyecto para expertos (`expert_invited.html`)
  - **Proyectos:**
    - Nuevas propuestas recibidas por empresas (`project_application.html`)
    - Proyectos aprobados o rechazados (`project_approved.html`, `project_rejected.html`)
  - **Hitos y entregas:**
    - Entregas de hitos completados (empresa) (`milestone_completed.html`)
    - Aprobación de hitos (experto) (`milestone_approved.html`)
    - Rechazo de hitos (experto) (`milestone_rejected.html`)
  - **Pagos:**
    - Pagos liberados (experto) (`payment_released.html`)
    - Pagos recibidos (experto) (`payment_received.html`)
  - **Reseñas y feedback:**
    - Solicitud de reseña post-proyecto (`request_review.html`) - Se envía automáticamente cuando un proyecto se completa, incluye valoración interna y reseña pública
    - Reseña recibida (`review_received.html`) - Notificación cuando alguien deja una reseña
  - **Otros:**
    - Disputas creadas y resueltas (`dispute_notification.html`)
    - Mensajes nuevos en el chat (`message_received.html`)
    - Verificación de email (`verify_email.html`)
    - Recuperación de contraseña (`password_reset.html`)

### Administración ✅
- `GET /api/admin/users` - Listar usuarios con filtros (rol, estado, verificación, búsqueda)
- `PUT /api/admin/users/{id}/status` - Activar/desactivar usuario
- `PUT /api/admin/users/{id}/verify` - Verificar usuario/perfil
- `PUT /api/admin/users/{id}/unverify` - Desverificar usuario/perfil
- `DELETE /api/admin/users/{id}` - Eliminar usuario
- `GET /api/admin/projects` - Listar proyectos con filtros
- `PUT /api/admin/projects/{id}/status` - Cambiar estado de proyecto
- `GET /api/admin/payments` - Listar pagos con filtros
- `POST /api/admin/payments/{id}/refund` - Procesar reembolso
- `POST /api/admin/profiles/expert/{user_id}` - Crear perfil de experto para un usuario existente (genera slug único normalizado automáticamente)
- `POST /api/admin/profiles/company/{user_id}` - Crear perfil de empresa para un usuario existente

### Gestión de Usuarios ✅ ✨ NUEVO
- `GET /api/users/me` - Obtener información del usuario actual
- `PUT /api/users/me` - Actualizar usuario actual (username, is_active)
- `POST /api/users/me/change-password` - Cambiar contraseña
- `PUT /api/users/me/email` - Actualizar email (requiere contraseña)

### Webhooks ✅ ✨ NUEVO
- `POST /api/webhooks/ghl` - Recibir webhooks de GoHighLevel
  - Eventos: ContactCreate, ContactUpdate, ContactTagUpdate, ContactDndUpdate
  - Eventos: OpportunityCreate, OpportunityUpdate

### Integración GoHighLevel ✅ (63 tests pasando - 100% - v2.2)

**Nuevas Funcionalidades v2.2:**
- ✅ **Lead Score dinámico (0-100)** - Calculado automáticamente y sincronizado con GHL
- ✅ **Estado del contacto dinámico** - Calculado según proyectos, verificación, hitos
- ✅ **5 nuevas etiquetas de proyecto** - Borrador, validación, invitado, propuesta, asignado
- ✅ **Sincronización de campos básicos** - Email, teléfono, nombre, ubicación
- ✅ **Integración en nivel y reputación** - Lead_score usado para sugerir nivel y en scoring
- `POST /api/integrations/ghl/contact` - Sincronizar contacto con GHL (admin)
- `POST /api/integrations/ghl/opportunity` - Crear oportunidad en GHL (admin)
- `POST /api/integrations/ghl/tag` - Añadir tags a contacto en GHL (admin)
- `GET /api/integrations/ghl/status/{contact_id}` - Estado de contacto en GHL (admin)
- `GET /api/integrations/ghl/sync-logs` - Historial de sincronizaciones (admin)
- `GET /api/admin/users/{user_id}/ghl-tags` - Etiquetas GHL esperadas vs. actuales (admin)
- `GET /api/admin/users/{user_id}/ghl-diagnosis` - Diagnóstico completo de sincronización (admin)
- `POST /api/admin/users/{user_id}/ghl-sync-tags` - Forzar sincronización manual de tags (admin)
- `GET /api/admin/users/{user_id}/suggest-level` - Sugerir nivel de experto basado en lead_score (admin)
- `GET /api/admin/users/{user_id}/reputation` - Métricas de reputación incluyendo lead_score (admin)

### Utilidades de testing
- `POST /api/v1/testing/reset-e2e` - Reinicia la base de datos al estado demo base, eliminando únicamente artefactos creados durante las suites Playwright. Protegido por `ENABLE_TEST_RESET_ENDPOINT`/`TEST_RESET_TOKEN`.

## 🔧 Configuración

### Variables de entorno

```bash
# Database
DATABASE_URL=postgresql+asyncpg://user:pass@localhost:5432/floutic
REDIS_URL=redis://localhost:6379/0

# Authentication
JWT_SECRET=your-super-secret-jwt-key
JWT_ALGORITHM=HS256
JWT_ACCESS_EXPIRE_MINUTES=15
JWT_REFRESH_EXPIRE_DAYS=7

# External APIs
STRIPE_SECRET_KEY=sk_test_xxx
STRIPE_WEBHOOK_SECRET=whsec_xxx
STRIPE_CONNECT_RETURN_URL=https://app.floutic.com/dashboard/experto
STRIPE_CONNECT_REFRESH_URL=https://app.floutic.com/dashboard/experto?retryStripeOnboarding=true
STRIPE_CONNECT_ACCOUNT_COUNTRY=ES
GHL_API_KEY=your_ghl_api_key
GHL_WEBHOOK_SECRET=your_ghl_webhook_secret

# n8n
N8N_WEBHOOK_URL=https://your-n8n-instance.com/webhook
N8N_API_KEY=your_n8n_api_key

# Security
CORS_ORIGINS=https://floutic.com,https://www.floutic.com
RATE_LIMIT_PER_MINUTE=60
MAX_CONCURRENT_SESSIONS=3
LOGIN_RATE_LIMIT_MAX_ATTEMPTS_PER_USER=5
LOGIN_RATE_LIMIT_MAX_ATTEMPTS_PER_IP=20
LOGIN_RATE_LIMIT_WINDOW_SECONDS=60
SESSION_COOKIE_SECURE=false
SESSION_COOKIE_HTTPONLY=true
SESSION_COOKIE_SAMESITE=strict
ENABLE_TEST_RESET_ENDPOINT=false
TEST_RESET_TOKEN=

# Environment
ENVIRONMENT=development
LOG_LEVEL=INFO
DEBUG=true
```

### Entorno de pruebas
- Establece `ENVIRONMENT=test` para que `app/database.py` utilice `NullPool` y evite conflictos de event loop con SQLAlchemy durante las suites asíncronas.
- En Docker Compose ya se fuerza este valor en los comandos; mantén `ENVIRONMENT=test` dentro del contenedor.

## 🧪 Testing

### Tests Implementados ✅
- ✅ **Tests básicos** de importación y configuración
- ✅ **Tests del servicio de email** con templates
- ✅ **Tests de endpoints** principales (auth, profiles, projects)
- ✅ **Tests de modelos** de base de datos
- ✅ **Tests de schemas** de validación
- ✅ **Tests de integración** para flujos completos

### Ejecutar Tests

```bash
# Suite completa dentro del contenedor (recomendado)
docker compose exec backend bash -c "cd /app && ENVIRONMENT=test pytest"

# Tests con cobertura
docker compose exec backend bash -c "cd /app && ENVIRONMENT=test pytest --cov=app"

# Tests específicos
docker compose exec backend bash -c "cd /app && ENVIRONMENT=test pytest tests/endpoints/test_expert_selection.py -v"
docker compose exec backend bash -c "cd /app && ENVIRONMENT=test pytest tests/endpoints/test_profiles.py -v"
docker compose exec backend bash -c "cd /app && ENVIRONMENT=test pytest tests/unit/test_services.py tests/test_notification_manager.py"
```

### Estado Actual (Actualizado - Enero 2025)
- `pytest --collect-only` → **757+ tests** descubiertos en la suite.
- ✅ **57 tests críticos nuevos implementados** cubriendo:
  - Race conditions y concurrencia (9 tests)
  - Rollback de transacciones (7 tests)
  - Validaciones de negocio críticas (4 tests)
  - Edge cases (14 tests: 5 milestones + 9 proyectos/reviews)
  - Flujos end-to-end completos (3 flujos)
  - Performance (7 tests)
  - Seguridad y autenticación (7 tests)
  - Transiciones de estado (6 tests)
- ✅ **Tests de autenticación segura habilitados**: Se habilitaron 7 tests previamente omitidos en `test_auth_secure_fixed.py` que ahora incluyen correctamente el header `X-Session-ID`
- Puedes ejecutar toda la batería con `./scripts/test_backend.sh`, que levanta Redis y ejecuta `pytest` dentro del contenedor backend con los límites de rate limiting desactivados.
- Para la suite completa en Docker: iniciar Redis (`docker compose up -d redis`) y ejecutar `docker compose exec backend bash -c "cd /app && RATE_LIMIT_PER_MINUTE=0 LOGIN_RATE_LIMIT_MAX_ATTEMPTS_PER_USER=0 LOGIN_RATE_LIMIT_MAX_ATTEMPTS_PER_IP=0 REDIS_URL=redis://redis:6379/0 ENVIRONMENT=test pytest"`.
- Los overrides de dependencias (`get_db`, `get_redis_cache`, `get_current_admin_user`) están fijados para pytest y se limpian entre tests; si Redis no está disponible, varias pruebas fallarán con `RedisCache no ha sido inicializado`.
- ⚠️ **Nota importante**: Algunos tests de concurrencia se saltan automáticamente en SQLite y requieren PostgreSQL para validar comportamiento real de concurrencia.

## 📊 Monitoreo

### Health Check
- `GET /health` - Estado de la aplicación

### Métricas
- `GET /api/admin/metrics` - Métricas del sistema (solo admin)

## 🔒 Seguridad

- **JWT** con expiración de 15 minutos
- **Refresh tokens** con expiración de 7 días
- **Rate limiting** 5 intentos/minuto para login
- **Hash bcrypt** con salt rounds 12
- **CORS** restringido a dominios específicos
- **Validación** de datos con Pydantic

## 🚀 Despliegue

### Producción

1. Configurar variables de entorno de producción
2. Configurar HTTPS
3. Configurar base de datos de producción
4. Configurar Redis de producción
5. Configurar Stripe en modo live

### Docker

```bash
# Construir imagen
docker build -t floutic-backend .

# Ejecutar contenedor
docker run -p 8000:8000 --env-file .env floutic-backend
```

## 📝 Documentación

- **Swagger UI**: `http://localhost:18080/docs`
- **ReDoc**: `http://localhost:18080/redoc`

## 🤝 Contribución

1. Fork el proyecto
2. Crear rama feature (`git checkout -b feature/AmazingFeature`)
3. Commit cambios (`git commit -m 'Add some AmazingFeature'`)
4. Push a la rama (`git push origin feature/AmazingFeature`)
5. Abrir Pull Request

## 📄 Licencia

Este proyecto está bajo la Licencia MIT - ver el archivo [LICENSE](LICENSE) para detalles.

## 🆘 Soporte

Para soporte, contacta a [soporte@floutic.com](mailto:soporte@floutic.com)
