Saltar al contenido principal

API Endpoints

Documentación completa de los endpoints de la API de Floutic.

Autenticación

Autenticación Estándar (JWT)

  • POST /api/auth/register - Registro de usuario (envía email de verificación)
  • POST /api/auth/login - Login y token JWT
  • POST /api/auth/refresh - Renovar token (rota el refresh token automáticamente)
  • POST /api/auth/logout - Cerrar sesión (puede enviar refresh_token opcional)
  • GET /api/auth/verify - Verificar token
  • POST /api/auth/verify-email - Verificar email usando token de verificación
  • POST /api/auth/send-verification-email - Reenviar email de verificación (requiere autenticación, rate limit: 1 cada 2 minutos)

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
  • POST /api/auth/forgot-password - Solicitar recuperación de contraseña
  • POST /api/auth/reset-password - Restablecer contraseña con token seguro
  • GET /api/auth/verify_token - Verificar token con autenticación
  • POST /api/auth/verify-email - Verificar email usando token de verificación (no requiere autenticación)
  • POST /api/auth/send-verification-email - Reenviar email de verificación (requiere autenticación, rate limit: 1 cada 2 minutos)
  • POST /api/auth/add-role - Añadir un nuevo rol al usuario autenticado (empresa o experto)
  • POST /api/auth/switch-role - Cambiar el rol activo del usuario autenticado

Gestión de Roles Multiples:

  • Los usuarios pueden tener múltiples roles (empresa y/o experto)
  • Al registrarse, se pueden seleccionar uno o ambos roles
  • El rol activo determina qué dashboard y funcionalidades están disponibles
  • Se puede cambiar entre roles en cualquier momento desde el selector de roles

Características de seguridad:

  • Cookies HttpOnly con SameSite=Strict para aislar ventanas privadas
  • Sistema de session_id único por ventana
  • Validación obligatoria de session_id en todas las peticiones
  • Protección CSRF con tokens
  • Cache Redis para optimización
  • Blacklist de tokens en Redis

Usuarios

  • GET /api/users/me - Obtener información del usuario actual (incluye roles array y active_role)
  • PUT /api/users/me - Actualizar usuario actual (username, is_active)
  • POST /api/users/me/change-password - Cambiar contraseña (requiere contraseña actual)
  • PUT /api/users/me/email - Actualizar email (requiere contraseña actual). Nota: Al cambiar el email, se marca como no verificado y se envía automáticamente un email de verificación al nuevo correo. El usuario debe verificar el nuevo email para completar el cambio.
  • GET /api/users/{id} - Ver perfil público de usuario

Estructura de Usuario:

{
"id": 1,
"email": "usuario@ejemplo.com",
"username": "usuario",
"roles": ["empresa", "experto"], // Array de roles del usuario
"active_role": "empresa", // Rol actualmente activo
"role": "empresa" // Alias para compatibilidad (igual a active_role)
}

Webhooks de Usuario

  • GET /api/users/me/webhook - Obtener configuración de webhook
  • PUT /api/users/me/webhook - Configurar webhook (URL HTTPS, habilitar/deshabilitar, método de autenticación)
  • GET /api/users/me/webhook/secret - Obtener secreto JWT actual
  • POST /api/users/me/webhook/secret - Regenerar secreto JWT

Perfiles

  • GET /api/profiles/{id} - Ver perfil público
  • GET /api/profiles/experts/slug/{slug} - Obtener perfil público de experto por slug SEO
  • GET /api/profiles/me - Obtener mi perfil del rol activo actual
  • GET /api/profiles/me/profile - Mi perfil completo (alias de /me)
  • POST /api/profiles/ - Crear perfil (empresa/experto/admin) - Requiere que el tipo de perfil esté en los roles del usuario
  • PUT /api/profiles/{id} - Actualizar perfil

Nota sobre Perfiles Multi-Rol:

  • Cada usuario puede tener un perfil por cada rol que posea

  • Un usuario con roles ["empresa", "experto"] puede tener dos perfiles independientes

  • El endpoint /api/profiles/me devuelve el perfil correspondiente al active_role del usuario

  • Cada perfil tiene su propia verificación y estado independiente

  • POST /api/profiles/upload - Subir documento (verificación, portfolio, etc.)

  • POST /api/profiles/me/picture - Subir imagen de perfil (JPEG, PNG, WebP, max 2MB). Actualiza automáticamente el campo profile_picture del perfil. Disponible para expertos y admin.

    Nota técnica:

    • Usa el servicio centralizado ProfileImageService para validación, almacenamiento y normalización de rutas
    • La imagen se guarda en uploads/profiles/{user_id}/{filename} y la ruta en BD es /api/uploads/profiles/{user_id}/{filename}
    • Validación mejorada: Usa Pillow para validar que el archivo sea realmente una imagen válida
    • Optimización automática:
      • Imágenes mayores a 1024px se redimensionan automáticamente manteniendo aspect ratio
      • Optimización de calidad (JPEG: 85, PNG: optimizado, WebP: método 6)
      • Conversión automática de imágenes con transparencia a RGB con fondo blanco
    • Logging: Registra reducción de tamaño y dimensiones para debugging
  • GET /api/profiles/experts - Buscar expertos con filtros avanzados

  • PUT /api/profiles/{id}/fiscal-data - Actualizar datos fiscales

  • GET /api/profiles/me/fiscal-status - Verificar estado de datos fiscales

Perfiles de Admin

Los administradores pueden crear perfiles opcionales para aparecer en la página "Quiénes Somos":

  • POST /api/profiles/admin/me - Crear perfil de admin (solo para usuarios con rol admin). Todos los campos son opcionales.
  • PUT /api/profiles/admin/me - Actualizar perfil de admin
  • GET /api/profiles/admin/me - Obtener perfil de admin propio
  • GET /api/profiles/admin/slug/{slug} - Obtener perfil de admin por slug (endpoint público, sin autenticación). Usado para la página pública de perfil de miembro del equipo.
  • GET /api/profiles/team - Obtener equipo público (endpoint público, sin autenticación). Retorna todos los perfiles admin con is_visible_in_team=True, ordenados por display_order.

Campos disponibles para perfiles admin:

  • full_name (string, opcional) - Nombre completo para mostrar
  • team_role (string, opcional) - Rol en el equipo (CEO, CTO, Product Manager, etc.)
  • bio (string, opcional) - Biografía
  • profile_picture (string, opcional) - Ruta de la imagen de perfil
  • location (string, opcional) - Ubicación
  • linkedin_url (string, opcional) - URL de LinkedIn
  • twitter_url (string, opcional) - URL de Twitter
  • github_url (string, opcional) - URL de GitHub
  • instagram_url (string, opcional) - URL de Instagram
  • tiktok_url (string, opcional) - URL de TikTok
  • personal_website (string, opcional) - Sitio web personal
  • display_order (integer, opcional) - Orden de visualización en "quienes somos" (menor = primero)
  • is_visible_in_team (boolean, default: false) - Si aparece en la página pública "quienes somos"

Ejemplo de creación de perfil admin:

POST /api/profiles/admin/me
{
"full_name": "Juan Pérez",
"team_role": "CEO",
"bio": "Fundador y CEO de Floutic",
"location": "Madrid, España",
"linkedin_url": "https://linkedin.com/in/juanperez",
"twitter_url": "https://twitter.com/juanperez",
"github_url": "https://github.com/juanperez",
"instagram_url": "https://instagram.com/juanperez",
"tiktok_url": "https://tiktok.com/@juanperez",
"personal_website": "https://juanperez.com",
"display_order": 1,
"is_visible_in_team": true
}

Sistema de Invitaciones de Administradores

Los administradores pueden invitar a nuevos administradores mediante un sistema seguro de invitaciones por email:

Endpoints de Gestión (Requieren autenticación admin)

  • POST /api/admin/invitations - Crear invitación de administrador
  • GET /api/admin/invitations - Listar invitaciones (con filtros y paginación)
  • GET /api/admin/invitations/{invitation_id} - Obtener detalles de una invitación
  • DELETE /api/admin/invitations/{invitation_id} - Cancelar una invitación

Endpoint Público (Aceptar invitación)

  • POST /api/auth/accept-admin-invitation - Aceptar invitación y crear cuenta de administrador

Campos para crear invitación (POST /api/admin/invitations):

  • email (string, requerido) - Email del invitado
  • message (string, opcional) - Mensaje personalizado para el invitado
  • expires_hours (integer, opcional, default: 168) - Horas hasta la expiración (1-720, default 7 días)

Ejemplo de creación de invitación:

POST /api/admin/invitations
{
"email": "nuevo.admin@example.com",
"message": "Te invitamos a unirte al equipo de administradores de Floutic",
"expires_hours": 168
}

Respuesta de creación:

{
"id": 1,
"email": "nuevo.admin@example.com",
"invited_by": 5,
"inviter_username": "admin1",
"message": "Te invitamos a unirte al equipo...",
"expires_at": "2025-12-29T12:00:00Z",
"used": false,
"used_at": null,
"created_at": "2025-12-22T12:00:00Z"
}

Filtros para listar invitaciones (GET /api/admin/invitations):

  • page (integer, default: 1) - Número de página
  • size (integer, default: 20, max: 100) - Tamaño de página
  • status (string: "all"|"pending"|"used"|"expired", default: "all") - Filtrar por estado
  • search (string, opcional) - Buscar por email

Campos para aceptar invitación (POST /api/auth/accept-admin-invitation):

  • token (string, requerido) - Token de invitación (proporcionado en el email)
  • username (string, requerido) - Nombre de usuario (3-50 caracteres, solo letras, números y _)
  • password (string, requerido) - Contraseña (mínimo 8 caracteres)

Características del sistema de invitaciones:

  • Los tokens son únicos y se hashean antes de guardarse en la base de datos
  • Los tokens expiran después del tiempo especificado (default: 7 días)
  • Los tokens son de un solo uso (una vez aceptados, no pueden reutilizarse)
  • Se valida que no exista ya un usuario con el email o username antes de crear la cuenta
  • El nuevo administrador se crea automáticamente con email_verified=True y is_active=True
  • Se envía un email con el enlace de invitación que contiene el token

Proyectos

Listado y Búsqueda

  • GET /api/projects/public - Listar proyectos públicos (marketplace)
  • GET /api/projects/ - Listar proyectos (con filtros y paginación)
  • GET /api/projects/my - Mis proyectos (empresa o experto)
  • GET /api/projects/all - Todos los proyectos (admin)
  • GET /api/projects/{project_id} - Ver proyecto específico
  • GET /api/projects/{project_id}/applications - Aplicaciones de un proyecto

Gestión de Proyectos

  • POST /api/projects/ - Crear proyecto (requiere email verificado, perfil verificado y datos fiscales para primer proyecto)
  • PUT /api/projects/{project_id} - Actualizar proyecto
  • PATCH /api/projects/{project_id}/status - Cambiar estado de proyecto
  • DELETE /api/projects/{project_id} - Eliminar proyecto

Aplicaciones y Selección

  • POST /api/projects/{project_id}/apply - Aplicar a proyecto (experto)
  • GET /api/projects/{project_id}/my-application - Obtener mi propuesta para un proyecto (experto)
  • POST /api/projects/{project_id}/applications/{application_id}/request-revision - Solicitar cambios en una propuesta (empresa). Pasa la propuesta a needs_revision y guarda feedback.
  • PUT /api/projects/{project_id}/applications/{application_id} - Re-enviar propuesta modificada (experto). Solo permitido si está en needs_revision.
  • POST /api/projects/{project_id}/applications/{application_id}/reject - Rechazar propuesta (empresa)
  • POST /api/projects/{project_id}/select/{expert_id} - Seleccionar experto (requiere datos fiscales del experto si es primer proyecto). Nota: Solo permitido si el proyecto está en published_curated, published_private o bidding (y estados legacy published/open para compatibilidad). En draft o pending_publication responde 400 con un mensaje explicativo.
  • POST /api/projects/{project_id}/selection/cancel - Cancelar selección de experto

Validación y Curación

  • POST /api/projects/{project_id}/submit - Enviar proyecto para validación
  • POST /api/projects/{project_id}/validate - Validar proyecto (admin)
  • POST /api/projects/{project_id}/curate - Curación manual de expertos (admin)
  • POST /api/projects/{project_id}/auto-curate - Curación automática de expertos (admin)
  • GET /api/projects/{project_id}/curation-suggestions - Sugerencias de curación

Otros

  • POST /api/projects/{project_id}/request-budget - Solicitar presupuesto desde perfil de experto
  • POST /api/projects/{project_id}/dispute - Crear disputa en proyecto
  • GET /api/projects/{project_id}/dispute - Obtener la disputa más reciente del proyecto (empresa/experto/admin)

Contrato API de Disputas

Crear disputa (POST /api/projects/{project_id}/dispute)

Permisos: participante del proyecto (company_id o expert_id).

Request body (campos soportados):

{
"title": "Incumplimiento de entregables",
"reason": "Texto principal de la disputa",
"description": "Alternativa a reason",
"dispute_type": "delivery",
"priority": "high",
"evidence": "Evidencia textual o referencia",
"requested_resolution": "Mediación y ajuste de alcance",
"contact_preference": "email"
}

Reglas de validación relevantes:

  • Se requiere reason o description.
  • Solo se permite una disputa activa por proyecto (open o in_review).
  • No se permite crear disputa en proyectos completed o ya disputed.

Response (201):

{
"message": "Dispute created successfully. Admin will review the case.",
"dispute_id": 123
}

Obtener disputa del proyecto (GET /api/projects/{project_id}/dispute)

Response (200):

{
"id": 123,
"project_id": 77,
"payment_id": 55,
"raised_by": 9,
"status": "open",
"reason": "Texto de disputa",
"evidence": "...",
"requested_resolution": "...",
"resolution": null,
"resolution_action": null,
"resolved_by": null,
"created_at": "2026-02-11T15:45:00",
"resolved_at": null
}

Endpoints admin de disputas

  • GET /api/admin/disputes - Listado paginado
    • Query params: page, size, status, sort_by (created_at|status), sort_order (asc|desc), search
  • GET /api/admin/disputes/{dispute_id} - Detalle de disputa
  • PUT /api/admin/disputes/{dispute_id}/mediate - Pasar a mediación
    • Query params: notes (10..2000)
  • PUT /api/admin/disputes/{dispute_id}/resolve - Resolver disputa
    • Query params: resolution (10..2000), resolution_action

resolution_action soportadas y side effects principales:

  • resolve_favor_expert o release_to_expert → pago released (si estaba disputed|held|pending)
  • resolve_favor_company o refund_company → pago refunded (si estaba disputed|held|pending|released)

En resolución:

  • la disputa pasa a resolved,
  • el proyecto pasa de disputed a in_progress,
  • se registran trazas en project.admin_notes con prefijo [DISPUTE_EVENT],
  • se envían notificaciones a las partes.

Hitos (Milestones)

CRUD de Milestones

  • POST /api/milestones/ - Crear hito (empresa)
  • GET /api/milestones/project/{project_id} - Listar hitos de proyecto (paginado)
  • GET /api/milestones/{milestone_id} - Ver hito específico
  • PUT /api/milestones/{milestone_id} - Actualizar hito (solo pendientes)
  • DELETE /api/milestones/{milestone_id} - Eliminar hito (solo pendientes)

Entregas de Hitos

La gestión del flujo de trabajo de milestones (completar, aprobar, rechazar) se realiza a través del sistema de entregas:

  • POST /api/milestones/deliveries/ - Crear entrega de hito (experto)
  • GET /api/milestones/deliveries/milestone/{milestone_id} - Listar entregas de un hito
  • GET /api/milestones/deliveries/project/{project_id} - Listar entregas de un proyecto
  • GET /api/milestones/deliveries/expert/me - Listar entregas del experto actual
  • GET /api/milestones/deliveries/{delivery_id} - Ver entrega específica
  • PUT /api/milestones/deliveries/{delivery_id} - Actualizar entrega (solo si necesita revisión)
  • PUT /api/milestones/deliveries/{delivery_id}/review - Revisar entrega (aprobar/rechazar/solicitar revisión)

Reseñas (Reviews)

  • POST /api/reviews/ - Crear reseña
  • GET /api/reviews/user/{user_id} - Reseñas de un usuario (paginado)
  • GET /api/reviews/stats/{user_id} - Estadísticas de reseñas de un usuario
  • PUT /api/reviews/{review_id} - Actualizar reseña
  • PUT /api/reviews/{review_id}/respond - Responder a reseña
  • GET /api/reviews/project/{project_id} - Reseña de un proyecto
  • GET /api/reviews/project/{project_id}/reviewer/{reviewer_id} - Reseña específica por proyecto y revisor
  • GET /api/reviews/{review_id} - Ver reseña específica
  • DELETE /api/reviews/{review_id} - Eliminar reseña (admin)

Pagos

  • 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 PaymentIntent del siguiente hito
  • POST /api/payments/sync-status - Sincronizar estado con Stripe (marca held, actualiza held_at y stripe_charge_id)
  • 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
  • POST /api/payments/confirm-initial/{project_id} - Confirmar pago inicial del proyecto y activar proyecto
  • GET /api/payments/public-key - Obtener clave pública de Stripe (sin autenticación)
  • GET /api/payments/intent/{payment_intent_id} - Obtener detalles de un PaymentIntent desde Stripe
  • GET /api/payments/saved-methods - Listar métodos de pago guardados (empresa)
  • DELETE /api/payments/saved-methods/{payment_method_id} - Eliminar método de pago guardado
  • POST /api/payments/attach-method - Guardar método de pago tras transacción exitosa
  • POST /api/payments/retry-transfer/{payment_id} - Reintentar transferencia fallida (admin)
  • GET /api/payments/{payment_id}/receipt - Obtener URL del recibo de Stripe

Stripe Connect

  • 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
  • POST /api/stripe-connect/admin/disconnect/{user_id} - Desconectar cuenta Connect de un experto (admin)

Chat

  • GET /api/chat/{project_id} - Obtener mensajes del chat (paginado)
  • POST /api/chat/{project_id} - Enviar mensaje
  • PUT /api/chat/{project_id}/messages/{message_id} - Editar mensaje
  • GET /api/chat/{project_id}/messages/{message_id} - Obtener mensaje específico
  • DELETE /api/chat/{project_id}/messages/{message_id} - Eliminar mensaje
  • POST /api/chat/{project_id}/files - Subir archivo al chat
  • GET /api/chat/{project_id}/files/{message_id} - Descargar archivo del chat
  • POST /api/chat/{project_id}/mark-read - Marcar mensajes como leídos

Notificaciones

  • GET /api/notifications/ - Consultar notificaciones (paginado)
  • 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 + WebSocket)
  • POST /api/notifications/webhook/test - Disparar evento de prueba de webhook

WebSocket

  • WS /api/ws/notifications - Conexión WebSocket para notificaciones en tiempo real

Skills (Habilidades)

  • GET /api/skills/active - Obtener lista de skills activas (público)
  • GET /api/skills/{slug} - Obtener página de habilidad por slug (público)
  • GET /api/skills/{slug}/experts - Obtener expertos con una habilidad específica (paginado, público)

Dashboard de Experto

  • GET /api/expert/stats - Estadísticas del experto (aplicaciones, proyectos, ganancias)
  • GET /api/expert/applications - Aplicaciones del experto (paginado)
  • GET /api/expert/available-projects - Proyectos disponibles para el experto (paginado)
  • GET /api/expert/assigned-projects - Proyectos asignados al experto (paginado)
  • GET /api/expert/invitations - Invitaciones a proyectos (paginado)

DAC7 — Cumplimiento Normativo

Sistema de previsualización y revisión de datos fiscales para cumplimiento DAC7 (normativa española de declaración de ingresos de plataformas digitales).

Endpoints de Experto

  • GET /api/dac7/expert/dac7-summary - Obtener resumen DAC7 del experto para un año fiscal

    • Query params: year (requerido) — Año fiscal a consultar
    • Requiere: Rol experto + datos fiscales completos (fiscal_data_complete=true)
    • Respuesta 400: Si los datos fiscales no están completos
    • Respuesta: Dac7SummaryResponse con datos fiscales, resumen de ingresos y estado de revisión
  • POST /api/dac7/expert/dac7-review - Confirmar revisión DAC7 del experto

    • Body: { "period": 2026, "confirmed": true }
    • Requiere: Rol experto + datos fiscales completos + confirmed=true
    • Respuesta 400: Si confirmed=false o datos fiscales incompletos
    • Respuesta 409: Si ya fue revisado para el mismo período

Endpoints de Admin

  • POST /api/dac7/admin/notify-experts - Notificar a expertos con ingresos sobre revisión DAC7
    • Body: { "year": 2026, "review_deadline": "2027-01-15" }
    • Requiere: Rol admin
    • Comportamiento: Busca expertos con datos fiscales completos e ingresos > 0 en el año dado, envía email de notificación, actualiza dac7_review_status a notified
    • Respuesta: { "notified_count": N, "skipped_count": M }

Modelo de Datos (Profile)

Campos DAC7 agregados al modelo Profile:

CampoTipoDescripción
fiscal_typestringTipo fiscal: autonomo, empresa, individual
birth_datedateFecha de nacimiento
vat_numberstringNIF/CIF para empresas
irpf_rateintegerRetención IRPF: 0, 7 o 15%
commercial_registrystringRegistro mercantil (empresas)
fiscal_data_completebooleanIndica si todos los campos fiscales requeridos están completos
dac7_review_statusstringEstado revisión: pending_review, notified, reviewed
dac7_review_periodintegerAño del período revisado
dac7_reviewed_atdatetimeFecha de confirmación de revisión

Administración

Gestión de Usuarios

  • GET /api/admin/users - Listar usuarios con filtros (rol, estado, verificación, búsqueda)
  • GET /api/admin/users/{user_id} - Obtener usuario por ID
  • GET /api/admin/users/{user_id}/profile - Obtener el perfil completo del usuario (incluye campos admin como verification_notes). Si el usuario tiene múltiples perfiles, prioriza el del active_role.
  • PUT /api/admin/users/{user_id} - Actualizar usuario base
  • PUT /api/admin/users/{user_id}/verify - Verificar usuario/perfil
  • PUT /api/admin/users/{user_id}/unverify - Desverificar usuario/perfil
  • PUT /api/admin/users/{user_id}/pre-evaluation - Establecer pre-evaluación
  • POST /api/admin/users/{user_id}/recontact - Recontactar empresa
  • PUT /api/admin/users/{user_id}/reject - Rechazar perfil de usuario
  • PUT /api/admin/users/{user_id}/resubmit - Reenviar perfil para revisión
  • PUT /api/admin/users/{user_id}/status - Actualizar estado de usuario
  • POST /api/admin/users/{user_id}/deletion-request - Solicitar eliminación de usuario (añade emp-baja en GHL)
  • POST /api/admin/users/{user_id}/deletion-confirm - Confirmar eliminación de usuario (remueve emp-baja, añade emp-baja-confirmada en GHL)
  • DELETE /api/admin/users/{user_id} - Eliminar usuario definitivamente:
    • Empresas: Remueve emp-baja y emp-baja-confirmada, añade emp-eliminado en GHL
    • Expertos: Añade exp-eliminado en GHL
    • Registra evento user_deleted en ghl_sync_log
    • Si GHL falla, no bloquea la eliminación (solo registra warning)
  • PUT /api/admin/users/{user_id}/change-password - Cambiar contraseña de usuario
  • PUT /api/admin/users/{user_id}/suspend - Suspender usuario
  • PUT /api/admin/users/{user_id}/roles - Gestionar roles de usuario (añadir, eliminar, cambiar rol activo)

Gestión de Roles:

  • Permite añadir o eliminar roles de un usuario
  • Requiere que el usuario tenga al menos un rol
  • Si se elimina el rol activo, se asigna automáticamente el primer rol disponible
  • Los roles disponibles son: empresa, experto, admin

Gestión de Perfiles

  • POST /api/admin/profiles/expert/{user_id} - Crear perfil de experto (genera slug automático)
  • POST /api/admin/profiles/company/{user_id} - Crear perfil de empresa
  • GET /api/admin/profiles - Listar perfiles con filtros

Gestión de Proyectos

  • GET /api/admin/projects - Listar proyectos con filtros
  • GET /api/admin/projects/{project_id} - Obtener proyecto completo (admin)

Gestión de Pagos

  • GET /api/admin/payments - Listar pagos con filtros
  • GET /api/admin/payments/{payment_id} - Detalle de pago individual
  • POST /api/admin/payments/{id}/refund - Procesar reembolso
  • POST /api/admin/payments/reconcile - Reconciliar pagos stale con estado real de Stripe

Configuración de Comisiones

  • GET /api/admin/commission-config - Listar todas las configuraciones de comisión
  • PUT /api/admin/commission-config/bulk - Actualizar configuraciones en lote
  • GET /api/admin/commission-config/{level} - Obtener configuración por nivel de experto
  • PUT /api/admin/commission-config/{level} - Actualizar configuración por nivel

Integración GoHighLevel

  • GET /api/admin/users/{user_id}/ghl-tags - Etiquetas GHL esperadas vs. actuales
  • GET /api/admin/users/{user_id}/ghl-diagnosis - Diagnóstico completo de sincronización GHL
  • POST /api/admin/users/{user_id}/ghl-sync-tags - Forzar sincronización manual de tags
  • GET /api/admin/users/{user_id}/suggest-level - Sugerir nivel de experto basado en lead_score
  • GET /api/admin/users/{user_id}/reputation - Métricas de reputación incluyendo lead_score

Valoración Interna

  • PUT /api/admin/users/{user_id}/internal-rating - Actualizar valoración interna de un usuario
    • Parámetros: rating (1.0-5.0), reason (mínimo 10 caracteres)
    • Crea automáticamente un registro en el historial de cambios
    • Sincroniza con GoHighLevel si está habilitado
  • GET /api/admin/users/{user_id}/internal-rating-history - Obtener historial de cambios de valoración
    • Parámetros opcionales: limit (1-50, default: 10)
    • Devuelve: historial ordenado por fecha descendente con valoración anterior/nueva, razón, admin que lo cambió

Ejemplo de respuesta de historial:

{
"user_id": 123,
"history": [
{
"id": 5,
"old_rating": 3.0,
"new_rating": 4.5,
"reason": "Mejora en calidad de entregas",
"changed_by": "admin_username",
"changed_by_id": 1,
"created_at": "2024-12-12T10:30:00"
}
],
"total": 1
}

Métricas y Estadísticas

  • GET /api/admin/metrics - Métricas básicas del sistema (usuarios, proyectos, ingresos, top expertos/empresas)
  • GET /api/admin/metrics/growth - Métricas con cálculo de crecimiento por período

Parámetros de /api/admin/metrics/growth:

  • period (string, default: "30d") - Período de comparación: 7d, 30d, 90d, 1y

Respuesta de /api/admin/metrics/growth:

{
"period": "30d",
// Valores actuales
"total_revenue": 50000.0,
"active_projects": 15,
"total_users": 250,
"total_projects": 100,
"completion_rate": 65.5,
"average_project_value": 2500.0,
"expert_satisfaction": 4.5,
"company_satisfaction": 4.2,
"dispute_rate": 3.5,
// Crecimientos (porcentaje comparando período actual vs anterior)
"revenue_growth": 12.5,
"projects_growth": 8.0,
"users_growth": 5.5,
"completion_rate_growth": 2.0,
"average_project_value_growth": -1.5,
"expert_satisfaction_growth": 0.3,
"company_satisfaction_growth": 0.5,
"dispute_rate_growth": -0.5,
// Datos adicionales
"monthly_revenue": [
{ "month": "2025-02", "revenue": 3000.0, "projects": 2 },
{ "month": "2025-03", "revenue": 4000.0, "projects": 3 }
// ... últimos 12 meses en orden cronológico
],
"project_types": { "private": 30, "curated": 70 },
"project_statuses": {
"draft": 5,
"pending_publication": 3,
"published_private": 10,
"published_curated": 15,
"bidding": 8,
"assigned": 12,
"in_progress": 10,
"in_review": 5,
"completed": 25,
"disputed": 7
}
}

Cálculo de crecimiento:

  • Compara el período actual con el período inmediatamente anterior
  • Ejemplo: 30d compara últimos 30 días vs los 30 días anteriores
  • Si no hay datos en el período anterior, se muestra 100% si hay datos actuales, o 0% si no hay datos

Integraciones

GoHighLevel

  • 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)

Webhooks Externos

  • POST /api/webhooks/ghl - Recibir webhooks de GoHighLevel

Testing (Solo en desarrollo)

  • POST /api/v1/testing/reset-e2e - Reiniciar base de datos al estado demo (protegido por ENABLE_TEST_RESET_ENDPOINT)

Prácticas de Seguridad Backend

Prevención de Inyección SQL

  • Uso estricto de ORM: Preferir métodos nativos de SQLAlchemy (User.roles.contains("admin")) sobre SQL crudo.
  • Bind Parameters: Si es necesario usar text(), SIEMPRE utilizar .bindparams() para pasar valores.
  • Prohibido: Interpolación de strings (f-strings) dentro de consultas SQL.

Validación de Archivos (Uploads)

  • Magic Numbers: No confiamos en la extensión del archivo. Se utiliza python-magic para inspeccionar los primeros bytes del archivo y determinar su tipo MIME real.
  • Tipos Permitidos: Lista blanca estricta (Imágenes, PDF, DOCX, ZIP).
  • Bloqueo: Archivos ejecutables o scripts renombrados (ej. malware.sh.jpg) son rechazados automáticamente.

Protección de Datos en Logs

  • Scrubbing Automático: Un middleware intercepta errores 500 y ofusca automáticamente claves sensibles (password, token, secret, credit_card) en el cuerpo del request antes de enviarlo a los logs (OpenObserve).
  • Prevención: Evita que credenciales de usuario queden registradas en texto plano en caso de crash del servidor.

Manejo de Errores

La API utiliza un contrato de errores estandarizado para todas las respuestas fallidas (4xx, 5xx).

Los errores se devuelven en formato JSON con la siguiente estructura:

{
"detail": {
"code": "ERROR_CODE",
"message": "Mensaje legible para el usuario"
}
}

Para ver la lista completa de códigos de error y su significado, consulta la Documentación de Errores.

Documentación Interactiva

Para documentación completa e interactiva con ejemplos, visita:

Notas Importantes

  • Todos los endpoints requieren autenticación excepto los marcados como "público"
  • Los endpoints de administración requieren que el usuario tenga el rol admin en su array de roles
  • Los endpoints de experto requieren que active_role sea experto
  • Los endpoints de empresa requieren que active_role sea empresa con perfil verificado
  • Los usuarios pueden tener múltiples roles y cambiar entre ellos usando /api/auth/switch-role
  • La paginación está disponible en la mayoría de endpoints de listado
  • Los filtros y ordenación están disponibles según el endpoint