{"openapi":"3.0.3","info":{"title":"LectorAI API","description":"\nAPI REST para el servicio de traducción de libros LectorAI.\n\n## Arquitectura de Traducciones\n\nLectorAI soporta dos modos de procesamiento de traducciones:\n\n### Modo AWS SQS + Lambda (Producción)\n- Las traducciones se procesan mediante AWS Lambda\n- Los jobs se encolan en SQS FIFO queues (ordenados por libro)\n- **Las traducciones NO se interrumpen durante deploys**\n- Escalado automático según demanda\n- Dead Letter Queue (DLQ) para reintentos fallidos\n- Máximo 3 reintentos antes de ir a DLQ\n\n### Modo BullMQ (Desarrollo/Fallback)\n- Los jobs se procesan mediante workers Node.js\n- Requiere Redis como broker de mensajes\n- Activado cuando `USE_AWS_QUEUE=false`\n\n## Sistema de Traducción (3 Pases)\n\nCada capítulo se traduce en 3 pases para máxima calidad:\n\n1. **Pase 1 - Traducción inicial**: Traducción directa del texto original\n2. **Pase 2 - Revisión de consistencia**: Verifica términos, nombres y estilo\n3. **Pase 3 - Pulido final**: Refina fluidez y naturalidad del texto\n\nEl glosario personalizado se aplica en todos los pases para mantener consistencia de términos.\n\n## Autenticación\n\nLa API soporta dos métodos de autenticación:\n\n### 1. API Key (Recomendado para integraciones)\n```\nAuthorization: Bearer lector_xxxxxxxxxxxxxxxx\n```\n\n### 2. Session Cookie (Para uso en navegador)\nUtiliza la sesión de NextAuth automáticamente.\n\n## Límites de Rate\n\n- **Free**: 100 requests/hora\n- **Pro**: 1,000 requests/hora\n- **Business**: 10,000 requests/hora\n\n## Webhooks\n\nConfigura webhooks para recibir notificaciones cuando:\n- `book.completed` - Un libro termina de traducirse\n- `translation.error` - Ocurre un error en la traducción\n    ","version":"1.0.0","contact":{"name":"LectorAI Support","email":"soporte@lectorai.com"}},"servers":[{"url":"https://lectorai.com","description":"Production"},{"url":"http://localhost:3000","description":"Development"}],"tags":[{"name":"Books","description":"Gestión de libros"},{"name":"Translation","description":"Control de traducción"},{"name":"Download","description":"Descarga de archivos"},{"name":"Community","description":"Posts y comentarios de la comunidad"},{"name":"API Keys","description":"Gestión de API keys"},{"name":"Webhooks","description":"Gestión de webhooks"},{"name":"Usage","description":"Uso y límites"},{"name":"Admin","description":"Endpoints de administración (requiere SUPER_ADMIN)"},{"name":"SEO","description":"Sitemap, RSS feeds, y robots.txt para optimización de motores de búsqueda"},{"name":"Health","description":"Estado del sistema"},{"name":"Notifications","description":"Notificaciones del usuario"},{"name":"Glossary","description":"Glosarios personalizados para traducción"},{"name":"Settings","description":"Configuración y preferencias del usuario"},{"name":"User","description":"Gestión de cuenta y datos del usuario (GDPR)"}],"paths":{"/api/books":{"get":{"tags":["Books"],"summary":"Listar libros","description":"Obtiene todos los libros del usuario autenticado","operationId":"listBooks","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"parameters":[{"name":"status","in":"query","description":"Filtrar por estado","schema":{"type":"string","enum":["UPLOADED","EXTRACTING","EXTRACTED","TRANSLATING","PAUSED","TRANSLATED","GENERATING","COMPLETED","ERROR"]}},{"name":"limit","in":"query","description":"Número máximo de resultados","schema":{"type":"integer","default":50}}],"responses":{"200":{"description":"Lista de libros","content":{"application/json":{"schema":{"type":"object","properties":{"books":{"type":"array","items":{"$ref":"#/components/schemas/Book"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/books/{id}":{"get":{"tags":["Books"],"summary":"Obtener libro","description":"Obtiene los detalles de un libro específico incluyendo capítulos","operationId":"getBook","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"ID del libro","schema":{"type":"string"}}],"responses":{"200":{"description":"Detalles del libro","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BookDetail"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}},"patch":{"tags":["Books"],"summary":"Actualizar libro","description":"Actualiza el título o autor de un libro","operationId":"updateBook","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"ID del libro","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"title":{"type":"string"},"author":{"type":"string"}}}}}},"responses":{"200":{"description":"Libro actualizado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Book"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}},"delete":{"tags":["Books"],"summary":"Eliminar libro","description":"Elimina un libro y todos sus archivos asociados","operationId":"deleteBook","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"ID del libro","schema":{"type":"string"}}],"responses":{"200":{"description":"Libro eliminado","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/books/{id}/share":{"post":{"tags":["Books"],"summary":"Compartir libro","description":"Genera un enlace público para compartir un libro traducido. El libro quedará accesible sin autenticación.","operationId":"shareBook","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"ID del libro","schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"expiresIn":{"type":"integer","description":"Días hasta expirar (null = nunca expira)","example":30}}}}}},"responses":{"200":{"description":"Enlace de compartir generado","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"shareUrl":{"type":"string","format":"uri"},"shareToken":{"type":"string"},"expiresAt":{"type":"string","format":"date-time","nullable":true}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}},"delete":{"tags":["Books"],"summary":"Dejar de compartir libro","description":"Revoca el enlace público de un libro compartido","operationId":"unshareBook","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"ID del libro","schema":{"type":"string"}}],"responses":{"200":{"description":"Libro ya no es público","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/upload":{"post":{"tags":["Books"],"summary":"Subir libro","description":"Sube un archivo de libro (EPUB, PDF, TXT, DOCX, HTML) para traducir","operationId":"uploadBook","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"type":"object","required":["file"],"properties":{"file":{"type":"string","format":"binary","description":"Archivo del libro (max 50MB)"},"title":{"type":"string","description":"Título personalizado (opcional)"}}}}}},"responses":{"200":{"description":"Libro subido exitosamente","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"book":{"$ref":"#/components/schemas/Book"}}}}}},"400":{"description":"Archivo inválido o límite excedido","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/translate":{"post":{"tags":["Translation"],"summary":"Iniciar traducción","description":"Inicia el proceso de traducción de un libro. Cada capítulo pasa por 3 pases de traducción para máxima calidad. Los capítulos se encolan para procesamiento asíncrono mediante AWS SQS + Lambda (producción) o BullMQ (desarrollo). El estado se puede monitorear con GET /api/translate/status.","operationId":"startTranslation","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["bookId"],"properties":{"bookId":{"type":"string","description":"ID del libro a traducir"},"model":{"type":"string","enum":["gpt-4o-mini","gpt-4o","claude-3-haiku","claude-sonnet-4-20250514","gemini-2.0-flash","gemini-1.5-pro"],"default":"gpt-4o-mini","description":"Modelo de IA a usar (OpenAI, Anthropic o Google)"}}}}}},"responses":{"200":{"description":"Traducción iniciada","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"message":{"type":"string"},"jobsCreated":{"type":"integer"}}}}}},"400":{"description":"Libro no está listo para traducir","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/translate/pause":{"post":{"tags":["Translation"],"summary":"Pausar traducción","description":"Pausa la traducción de un libro en progreso","operationId":"pauseTranslation","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["bookId"],"properties":{"bookId":{"type":"string"}}}}}},"responses":{"200":{"description":"Traducción pausada","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/translate/status":{"get":{"tags":["Translation"],"summary":"Estado de traducción","description":"Obtiene el estado actual de la traducción de un libro, incluyendo progreso, capítulos completados y errores","operationId":"getTranslationStatus","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"parameters":[{"name":"bookId","in":"query","required":true,"description":"ID del libro","schema":{"type":"string"}}],"responses":{"200":{"description":"Estado de la traducción","content":{"application/json":{"schema":{"type":"object","properties":{"status":{"type":"string","enum":["UPLOADED","EXTRACTING","EXTRACTED","TRANSLATING","PAUSED","TRANSLATED","GENERATING","COMPLETED","ERROR"]},"progress":{"type":"integer","minimum":0,"maximum":100},"chaptersTotal":{"type":"integer"},"chaptersCompleted":{"type":"integer"},"currentChapter":{"type":"string","nullable":true},"estimatedTimeRemaining":{"type":"integer","nullable":true,"description":"Tiempo estimado en segundos"},"errors":{"type":"array","items":{"type":"object","properties":{"chapterId":{"type":"string"},"error":{"type":"string"}}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/translate/resume":{"post":{"tags":["Translation"],"summary":"Reanudar traducción","description":"Reanuda una traducción pausada, con error o atascada. Preserva el progreso existente y solo re-encola los capítulos pendientes. Funciona tanto con AWS SQS como con BullMQ según la configuración del servidor.","operationId":"resumeTranslation","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["bookId"],"properties":{"bookId":{"type":"string"}}}}}},"responses":{"200":{"description":"Traducción reanudada","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"message":{"type":"string","example":"Reanudando traducción de 5 capítulo(s)"},"resumed":{"type":"integer","description":"Capítulos re-encolados"},"total":{"type":"integer","description":"Total de capítulos del libro"}}}}}},"400":{"description":"El libro no está en un estado que permita reanudar (debe ser ERROR, PAUSED o TRANSLATING)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/translate/stop":{"post":{"tags":["Translation"],"summary":"Detener traducción","description":"Detiene completamente la traducción y limpia la cola","operationId":"stopTranslation","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["bookId"],"properties":{"bookId":{"type":"string"}}}}}},"responses":{"200":{"description":"Traducción detenida","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/generate":{"post":{"tags":["Download"],"summary":"Generar archivo","description":"Genera el archivo EPUB o PDF del libro traducido","operationId":"generateFile","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["bookId","format"],"properties":{"bookId":{"type":"string"},"format":{"type":"string","enum":["epub","pdf"]}}}}}},"responses":{"200":{"description":"Generación iniciada","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/download/{id}":{"get":{"tags":["Download"],"summary":"Descargar libro","description":"Descarga el archivo traducido en formato EPUB o PDF","operationId":"downloadBook","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"ID del libro","schema":{"type":"string"}},{"name":"format","in":"query","required":true,"description":"Formato de descarga","schema":{"type":"string","enum":["epub","pdf"]}}],"responses":{"200":{"description":"URL de descarga","content":{"application/json":{"schema":{"type":"object","properties":{"url":{"type":"string","format":"uri","description":"URL firmada de S3 (válida por 1 hora)"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/community/posts":{"get":{"tags":["Community"],"summary":"Listar posts","description":"Obtiene los posts de la comunidad. No requiere autenticación para posts públicos.","operationId":"listPosts","parameters":[{"name":"page","in":"query","description":"Número de página","schema":{"type":"integer","default":1}},{"name":"limit","in":"query","description":"Posts por página","schema":{"type":"integer","default":10}},{"name":"category","in":"query","description":"Filtrar por slug de categoría","schema":{"type":"string"}},{"name":"tag","in":"query","description":"Filtrar por slug de tag","schema":{"type":"string"}},{"name":"featured","in":"query","description":"Solo posts destacados","schema":{"type":"boolean"}}],"responses":{"200":{"description":"Lista de posts","content":{"application/json":{"schema":{"type":"object","properties":{"posts":{"type":"array","items":{"$ref":"#/components/schemas/BlogPost"}},"pagination":{"type":"object","properties":{"page":{"type":"integer"},"limit":{"type":"integer"},"total":{"type":"integer"},"totalPages":{"type":"integer"}}}}}}}}}},"post":{"tags":["Community"],"summary":"Crear post","description":"Crea un nuevo post en la comunidad. Soporta autenticación por session o API key.","operationId":"createPost","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["title","content"],"properties":{"title":{"type":"string","description":"Título del post","example":"Mi primer post desde CLI"},"content":{"type":"string","description":"Contenido en Markdown","example":"# Hola mundo\\n\\nEste es mi primer post."},"excerpt":{"type":"string","description":"Resumen corto (opcional)"},"coverImage":{"type":"string","format":"uri","description":"URL de imagen de portada (opcional)"},"categoryId":{"type":"string","description":"ID de la categoría"},"categorySlug":{"type":"string","description":"Slug de la categoría (alternativa a categoryId)","example":"tutoriales"},"tagIds":{"type":"array","items":{"type":"string"},"description":"IDs de los tags"},"tagSlugs":{"type":"array","items":{"type":"string"},"description":"Slugs de los tags (alternativa a tagIds)","example":["cli","api"]},"status":{"type":"string","enum":["DRAFT","PUBLISHED"],"default":"DRAFT","description":"Estado del post"}}}}}},"responses":{"201":{"description":"Post creado","content":{"application/json":{"schema":{"type":"object","properties":{"post":{"$ref":"#/components/schemas/BlogPost"}}}}}},"400":{"description":"Datos inválidos","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/community/posts/{id}":{"get":{"tags":["Community"],"summary":"Obtener post","description":"Obtiene un post por ID o slug","operationId":"getPost","parameters":[{"name":"id","in":"path","required":true,"description":"ID o slug del post","schema":{"type":"string"}}],"responses":{"200":{"description":"Detalles del post","content":{"application/json":{"schema":{"type":"object","properties":{"post":{"$ref":"#/components/schemas/BlogPost"}}}}}},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/community/comments":{"get":{"tags":["Community"],"summary":"Listar comentarios","description":"Obtiene los comentarios de un post","operationId":"listComments","parameters":[{"name":"postId","in":"query","description":"ID del post","schema":{"type":"string"}},{"name":"postSlug","in":"query","description":"Slug del post (alternativa a postId)","schema":{"type":"string"}}],"responses":{"200":{"description":"Lista de comentarios","content":{"application/json":{"schema":{"type":"object","properties":{"comments":{"type":"array","items":{"$ref":"#/components/schemas/BlogComment"}}}}}}},"400":{"description":"postId o postSlug es requerido","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Community"],"summary":"Crear comentario","description":"Crea un comentario en un post. Soporta autenticación por session o API key.","operationId":"createComment","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["content"],"properties":{"postId":{"type":"string","description":"ID del post"},"postSlug":{"type":"string","description":"Slug del post (alternativa a postId)","example":"mi-primer-post"},"content":{"type":"string","description":"Contenido del comentario (máx 5000 caracteres)","example":"Excelente artículo!"},"parentId":{"type":"string","description":"ID del comentario padre (para respuestas)"},"mood":{"type":"string","enum":["EXCITED","LOVED","HAPPY","SAD","THUMBSY"],"description":"Estado de ánimo (opcional)"}}}}}},"responses":{"201":{"description":"Comentario creado","content":{"application/json":{"schema":{"type":"object","properties":{"comment":{"$ref":"#/components/schemas/BlogComment"}}}}}},"400":{"description":"Datos inválidos","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/community/categories":{"get":{"tags":["Community"],"summary":"Listar categorías","description":"Obtiene todas las categorías de la comunidad","operationId":"listCategories","responses":{"200":{"description":"Lista de categorías","content":{"application/json":{"schema":{"type":"object","properties":{"categories":{"type":"array","items":{"$ref":"#/components/schemas/BlogCategory"}}}}}}}}}},"/api/community/tags":{"get":{"tags":["Community"],"summary":"Listar tags","description":"Obtiene todos los tags de la comunidad","operationId":"listTags","responses":{"200":{"description":"Lista de tags","content":{"application/json":{"schema":{"type":"object","properties":{"tags":{"type":"array","items":{"$ref":"#/components/schemas/BlogTag"}}}}}}}}}},"/api/keys":{"get":{"tags":["API Keys"],"summary":"Listar API keys","description":"Obtiene todas las API keys del usuario (sin mostrar el key completo)","operationId":"listApiKeys","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"Lista de API keys","content":{"application/json":{"schema":{"type":"object","properties":{"keys":{"type":"array","items":{"$ref":"#/components/schemas/ApiKey"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"post":{"tags":["API Keys"],"summary":"Crear API key","description":"Crea una nueva API key. El key completo solo se muestra una vez.","operationId":"createApiKey","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name"],"properties":{"name":{"type":"string","description":"Nombre descriptivo para el key"},"scopes":{"type":"array","items":{"type":"string","enum":["read","write"]},"default":["read","write"]},"expiresAt":{"type":"string","format":"date-time","description":"Fecha de expiración (opcional)"}}}}}},"responses":{"200":{"description":"API key creada","content":{"application/json":{"schema":{"type":"object","properties":{"key":{"$ref":"#/components/schemas/ApiKey"},"secretKey":{"type":"string","description":"Key completo (solo se muestra una vez)","example":"lector_abc123def456..."}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/keys/{id}":{"delete":{"tags":["API Keys"],"summary":"Revocar API key","description":"Revoca (elimina) una API key existente","operationId":"revokeApiKey","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"ID del API key","schema":{"type":"string"}}],"responses":{"200":{"description":"API key revocada","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/webhooks":{"get":{"tags":["Webhooks"],"summary":"Listar webhooks","description":"Obtiene todos los webhooks configurados","operationId":"listWebhooks","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"Lista de webhooks","content":{"application/json":{"schema":{"type":"object","properties":{"webhooks":{"type":"array","items":{"$ref":"#/components/schemas/Webhook"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"post":{"tags":["Webhooks"],"summary":"Crear webhook","description":"Crea un nuevo webhook para recibir notificaciones","operationId":"createWebhook","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url","events"],"properties":{"url":{"type":"string","format":"uri","description":"URL donde enviar las notificaciones"},"events":{"type":"array","items":{"type":"string","enum":["book.completed","translation.error"]},"description":"Eventos a los que suscribirse"}}}}}},"responses":{"200":{"description":"Webhook creado","content":{"application/json":{"schema":{"type":"object","properties":{"webhook":{"$ref":"#/components/schemas/Webhook"},"secret":{"type":"string","description":"Secret para verificar firmas (solo se muestra una vez)"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/webhooks/{id}":{"delete":{"tags":["Webhooks"],"summary":"Eliminar webhook","description":"Elimina un webhook existente","operationId":"deleteWebhook","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"ID del webhook","schema":{"type":"string"}}],"responses":{"200":{"description":"Webhook eliminado","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}},"post":{"tags":["Webhooks"],"summary":"Test webhook","description":"Envía un evento de prueba al webhook","operationId":"testWebhook","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"ID del webhook","schema":{"type":"string"}}],"responses":{"200":{"description":"Test enviado","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"statusCode":{"type":"integer"},"response":{"type":"string"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/usage":{"get":{"tags":["Usage"],"summary":"Obtener uso","description":"Obtiene el uso actual y límites del plan","operationId":"getUsage","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"Información de uso","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Usage"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/notifications":{"get":{"tags":["Notifications"],"summary":"Listar notificaciones","description":"Obtiene las notificaciones del usuario con paginación","operationId":"listNotifications","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"parameters":[{"name":"page","in":"query","description":"Número de página","schema":{"type":"integer","default":1}},{"name":"limit","in":"query","description":"Notificaciones por página","schema":{"type":"integer","default":20}},{"name":"unread","in":"query","description":"Solo no leídas","schema":{"type":"boolean"}}],"responses":{"200":{"description":"Lista de notificaciones","content":{"application/json":{"schema":{"type":"object","properties":{"notifications":{"type":"array","items":{"$ref":"#/components/schemas/Notification"}},"pagination":{"type":"object","properties":{"page":{"type":"integer"},"limit":{"type":"integer"},"total":{"type":"integer"},"totalPages":{"type":"integer"}}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/notifications/unread-count":{"get":{"tags":["Notifications"],"summary":"Contar no leídas","description":"Obtiene el número de notificaciones no leídas","operationId":"getUnreadCount","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"Conteo de no leídas","content":{"application/json":{"schema":{"type":"object","properties":{"count":{"type":"integer"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/notifications/read":{"post":{"tags":["Notifications"],"summary":"Marcar como leída","description":"Marca una o varias notificaciones como leídas","operationId":"markAsRead","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"notificationIds":{"type":"array","items":{"type":"string"},"description":"IDs de notificaciones a marcar"}}}}}},"responses":{"200":{"description":"Notificaciones marcadas","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"markedCount":{"type":"integer"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/notifications/read-all":{"post":{"tags":["Notifications"],"summary":"Marcar todas como leídas","description":"Marca todas las notificaciones del usuario como leídas","operationId":"markAllAsRead","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"Todas marcadas como leídas","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"markedCount":{"type":"integer"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/glossary":{"get":{"tags":["Glossary"],"summary":"Listar glosarios","description":"Obtiene los glosarios personalizados del usuario","operationId":"listGlossaries","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"Lista de glosarios","content":{"application/json":{"schema":{"type":"object","properties":{"glossaries":{"type":"array","items":{"$ref":"#/components/schemas/Glossary"}}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"post":{"tags":["Glossary"],"summary":"Crear glosario","description":"Crea un nuevo glosario con términos personalizados para mejorar la consistencia de las traducciones","operationId":"createGlossary","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["name","entries"],"properties":{"name":{"type":"string","description":"Nombre del glosario","example":"Términos de fantasía"},"description":{"type":"string","description":"Descripción opcional"},"entries":{"type":"array","items":{"type":"object","required":["source","target"],"properties":{"source":{"type":"string","description":"Término original","example":"The Dark Lord"},"target":{"type":"string","description":"Traducción preferida","example":"El Señor Oscuro"},"context":{"type":"string","description":"Contexto de uso"}}}}}}}}},"responses":{"201":{"description":"Glosario creado","content":{"application/json":{"schema":{"type":"object","properties":{"glossary":{"$ref":"#/components/schemas/Glossary"}}}}}},"400":{"description":"Datos inválidos","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/glossary/{id}":{"get":{"tags":["Glossary"],"summary":"Obtener glosario","description":"Obtiene un glosario específico con todos sus términos","operationId":"getGlossary","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"ID del glosario","schema":{"type":"string"}}],"responses":{"200":{"description":"Detalles del glosario","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Glossary"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}},"patch":{"tags":["Glossary"],"summary":"Actualizar glosario","description":"Actualiza nombre, descripción o términos de un glosario","operationId":"updateGlossary","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"ID del glosario","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"entries":{"type":"array","items":{"type":"object","properties":{"source":{"type":"string"},"target":{"type":"string"},"context":{"type":"string"}}}}}}}}},"responses":{"200":{"description":"Glosario actualizado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Glossary"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}},"delete":{"tags":["Glossary"],"summary":"Eliminar glosario","description":"Elimina un glosario y todos sus términos","operationId":"deleteGlossary","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"ID del glosario","schema":{"type":"string"}}],"responses":{"200":{"description":"Glosario eliminado","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"404":{"$ref":"#/components/responses/NotFound"}}}},"/api/user":{"get":{"tags":["User"],"summary":"Obtener perfil","description":"Obtiene el perfil del usuario autenticado","operationId":"getUserProfile","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"Perfil del usuario","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserProfile"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"patch":{"tags":["User"],"summary":"Actualizar perfil","description":"Actualiza nombre y configuración del usuario","operationId":"updateUserProfile","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"preferredLanguage":{"type":"string"}}}}}},"responses":{"200":{"description":"Perfil actualizado","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserProfile"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/user/export":{"get":{"tags":["User"],"summary":"Exportar datos (GDPR)","description":"Exporta todos los datos del usuario en formato JSON, incluyendo libros, traducciones, configuración y actividad. Cumple con el derecho de portabilidad del GDPR.","operationId":"exportUserData","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"Datos exportados","content":{"application/json":{"schema":{"type":"object","properties":{"user":{"$ref":"#/components/schemas/UserProfile"},"books":{"type":"array","items":{"$ref":"#/components/schemas/Book"}},"apiKeys":{"type":"array","items":{"$ref":"#/components/schemas/ApiKey"}},"webhooks":{"type":"array","items":{"$ref":"#/components/schemas/Webhook"}},"glossaries":{"type":"array","items":{"$ref":"#/components/schemas/Glossary"}},"exportedAt":{"type":"string","format":"date-time"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/user/delete":{"delete":{"tags":["User"],"summary":"Eliminar cuenta (GDPR)","description":"Elimina permanentemente la cuenta del usuario y todos sus datos asociados. Esta acción es irreversible. Cumple con el derecho al olvido del GDPR.","operationId":"deleteUserAccount","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["confirmation"],"properties":{"confirmation":{"type":"string","description":"Debe ser exactamente 'DELETE MY ACCOUNT'","example":"DELETE MY ACCOUNT"},"reason":{"type":"string","description":"Razón opcional para la eliminación"}}}}}},"responses":{"200":{"description":"Cuenta eliminada","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"message":{"type":"string"},"deletedAt":{"type":"string","format":"date-time"}}}}}},"400":{"description":"Confirmación incorrecta","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/settings/preferences":{"get":{"tags":["Settings"],"summary":"Obtener preferencias","description":"Obtiene las preferencias de traducción del usuario","operationId":"getPreferences","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"Preferencias del usuario","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserPreferences"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"patch":{"tags":["Settings"],"summary":"Actualizar preferencias","description":"Actualiza las preferencias de traducción","operationId":"updatePreferences","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserPreferences"}}}},"responses":{"200":{"description":"Preferencias actualizadas","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserPreferences"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/settings/notifications":{"get":{"tags":["Settings"],"summary":"Obtener config de notificaciones","description":"Obtiene la configuración de notificaciones del usuario","operationId":"getNotificationSettings","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"Configuración de notificaciones","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationSettings"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"patch":{"tags":["Settings"],"summary":"Actualizar config de notificaciones","description":"Actualiza qué notificaciones recibir por email y en la app","operationId":"updateNotificationSettings","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationSettings"}}}},"responses":{"200":{"description":"Configuración actualizada","content":{"application/json":{"schema":{"$ref":"#/components/schemas/NotificationSettings"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/settings/developer":{"get":{"tags":["Settings"],"summary":"Obtener config de developer","description":"Obtiene las claves personalizadas de OpenAI/Anthropic/Google del usuario","operationId":"getDeveloperSettings","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"Configuración de developer","content":{"application/json":{"schema":{"type":"object","properties":{"hasOpenAIKey":{"type":"boolean"},"hasAnthropicKey":{"type":"boolean"},"hasGoogleKey":{"type":"boolean"},"openAIKeyPreview":{"type":"string","nullable":true,"example":"sk-...abc"},"anthropicKeyPreview":{"type":"string","nullable":true,"example":"sk-ant-...xyz"},"googleKeyPreview":{"type":"string","nullable":true,"example":"AIza...def"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}},"patch":{"tags":["Settings"],"summary":"Actualizar claves de API","description":"Configura claves personalizadas de OpenAI, Anthropic o Google para usar tu propio crédito","operationId":"updateDeveloperSettings","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"openAIKey":{"type":"string","nullable":true},"anthropicKey":{"type":"string","nullable":true},"googleKey":{"type":"string","nullable":true}}}}}},"responses":{"200":{"description":"Claves actualizadas","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}},"400":{"description":"Clave inválida","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"}}}},"/api/admin/emails/config":{"get":{"tags":["Admin"],"summary":"Obtener configuración de email","description":"Obtiene la configuración actual de Gmail SMTP. Requiere rol SUPER_ADMIN.","operationId":"getEmailConfig","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"responses":{"200":{"description":"Configuración de email","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmailConfig"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"description":"Requiere rol SUPER_ADMIN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"put":{"tags":["Admin"],"summary":"Actualizar configuración de email","description":"Actualiza el prefijo del remitente y nombre. Requiere rol SUPER_ADMIN.","operationId":"updateEmailConfig","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"senderPrefix":{"type":"string","enum":["noreply","support","notifications","team","billing"],"description":"Prefijo del email remitente","example":"noreply"},"senderName":{"type":"string","description":"Nombre del remitente","example":"LectorAI"},"replyToPrefix":{"type":"string","nullable":true,"enum":["noreply","support","notifications","team","billing"],"description":"Prefijo del email reply-to (opcional)"}}}}}},"responses":{"200":{"description":"Configuración actualizada","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"senderEmail":{"type":"string","example":"curetcore@gmail.com"}}}}}},"400":{"description":"Prefijo inválido","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"description":"Requiere rol SUPER_ADMIN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/admin/emails/test":{"post":{"tags":["Admin"],"summary":"Probar conexión o enviar email de prueba","description":"Sin body: prueba la conexión SMTP. Con email: envía un email de prueba. Requiere rol SUPER_ADMIN.","operationId":"testEmailConnection","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"email":{"type":"string","format":"email","description":"Email destino para prueba (opcional)","example":"test@example.com"}}}}}},"responses":{"200":{"description":"Resultado de la prueba","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"description":"Requiere rol SUPER_ADMIN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/api/admin/emails/verify":{"post":{"tags":["Admin"],"summary":"Verificar email (modo sandbox)","description":"Envía un email de verificación a una dirección para agregarla a la lista de destinatarios permitidos en modo sandbox. Requiere rol SUPER_ADMIN.","operationId":"verifyEmail","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["email"],"properties":{"email":{"type":"string","format":"email","description":"Email a verificar","example":"user@example.com"}}}}}},"responses":{"200":{"description":"Email de verificación enviado","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"message":{"type":"string","example":"Se envió un email de verificación a user@example.com"}}}}}},"400":{"description":"Email inválido","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"description":"Requiere rol SUPER_ADMIN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"delete":{"tags":["Admin"],"summary":"Eliminar email verificado","description":"Función deprecada. Gmail SMTP no requiere verificación de emails.","operationId":"deleteVerifiedEmail","security":[{"bearerAuth":[]},{"cookieAuth":[]}],"parameters":[{"name":"email","in":"query","required":true,"description":"Email a eliminar","schema":{"type":"string","format":"email"}}],"responses":{"200":{"description":"Email eliminado","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"message":{"type":"string"}}}}}},"400":{"description":"Email requerido","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"$ref":"#/components/responses/Unauthorized"},"403":{"description":"Requiere rol SUPER_ADMIN","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/sitemap.xml":{"get":{"tags":["SEO"],"summary":"XML Sitemap","description":"\nRetorna el sitemap XML dinámico del sitio.\n\nIncluye:\n- Páginas estáticas principales (landing, pricing, docs, legal)\n- Posts de la comunidad (publicados)\n- Categorías y tags de la comunidad\n- Libros públicos compartidos\n\nEl sitemap se genera dinámicamente y se actualiza automáticamente cuando hay nuevo contenido.\n        ","operationId":"getSitemap","responses":{"200":{"description":"Sitemap XML","content":{"application/xml":{"schema":{"type":"string","example":"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<urlset xmlns=\"http://www.sitemaps.org/schemas/sitemap/0.9\">\n  <url>\n    <loc>https://lectorai.com</loc>\n    <lastmod>2024-01-01T00:00:00.000Z</lastmod>\n    <changefreq>weekly</changefreq>\n    <priority>1</priority>\n  </url>\n</urlset>"}}}}}}},"/robots.txt":{"get":{"tags":["SEO"],"summary":"Robots.txt","description":"\nRetorna el archivo robots.txt que indica a los motores de búsqueda qué páginas pueden rastrear.\n\nConfigura:\n- Páginas públicas permitidas\n- Rutas de admin y API bloqueadas\n- Referencia al sitemap\n        ","operationId":"getRobotsTxt","responses":{"200":{"description":"Robots.txt","content":{"text/plain":{"schema":{"type":"string","example":"User-Agent: *\nAllow: /\nDisallow: /dashboard/\nDisallow: /admin/\nDisallow: /api/\nSitemap: https://lectorai.com/sitemap.xml"}}}}}}},"/comunidad/feed.xml":{"get":{"tags":["SEO"],"summary":"RSS Feed de la comunidad","description":"\nRetorna el feed RSS de los posts de la comunidad.\n\nEl feed incluye:\n- Últimos 50 posts publicados\n- Título, descripción, autor y fecha\n- Enlace al post completo\n\nCompatible con lectores RSS como Feedly, Inoreader, etc.\n        ","operationId":"getCommunityFeed","responses":{"200":{"description":"Feed RSS","content":{"application/rss+xml":{"schema":{"type":"string","example":"<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<rss version=\"2.0\">\n  <channel>\n    <title>LectorAI Comunidad</title>\n    <link>https://lectorai.com/comunidad</link>\n    <description>Artículos sobre traducción de libros con IA</description>\n    <item>\n      <title>Cómo traducir un libro con GPT-4</title>\n      <link>https://lectorai.com/comunidad/como-traducir-libro-gpt4</link>\n      <pubDate>Mon, 01 Jan 2024 00:00:00 GMT</pubDate>\n    </item>\n  </channel>\n</rss>"}}}}}}},"/api/health":{"get":{"tags":["Health"],"summary":"Health check","description":"Verifica el estado de salud del sistema (no requiere autenticación)","operationId":"healthCheck","responses":{"200":{"description":"Sistema saludable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Health"}}}},"503":{"description":"Sistema no disponible","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Health"}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"API Key","description":"API key con prefijo lector_"},"cookieAuth":{"type":"apiKey","in":"cookie","name":"next-auth.session-token","description":"Cookie de sesión NextAuth"}},"schemas":{"Book":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"author":{"type":"string","nullable":true},"originalLang":{"type":"string","example":"en"},"targetLang":{"type":"string","example":"es"},"status":{"type":"string","enum":["UPLOADED","EXTRACTING","EXTRACTED","TRANSLATING","PAUSED","TRANSLATED","GENERATING","COMPLETED","ERROR"]},"progress":{"type":"integer","minimum":0,"maximum":100},"wordCount":{"type":"integer","nullable":true},"chapterCount":{"type":"integer","nullable":true},"translationModel":{"type":"string","nullable":true},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"},"completedAt":{"type":"string","format":"date-time","nullable":true}}},"BookDetail":{"allOf":[{"$ref":"#/components/schemas/Book"},{"type":"object","properties":{"chapters":{"type":"array","items":{"$ref":"#/components/schemas/Chapter"}}}}]},"Chapter":{"type":"object","properties":{"id":{"type":"string"},"number":{"type":"integer"},"title":{"type":"string","nullable":true},"wordCount":{"type":"integer","nullable":true},"status":{"type":"string","enum":["PENDING","TRANSLATING","COMPLETED","ERROR"]}}},"ApiKey":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"prefix":{"type":"string","example":"lector_ab"},"scopes":{"type":"array","items":{"type":"string"}},"lastUsedAt":{"type":"string","format":"date-time","nullable":true},"expiresAt":{"type":"string","format":"date-time","nullable":true},"createdAt":{"type":"string","format":"date-time"}}},"Webhook":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"type":"string"}},"isActive":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"}}},"Usage":{"type":"object","properties":{"plan":{"type":"string","enum":["FREE","PRO","BUSINESS"]},"planName":{"type":"string"},"books":{"type":"object","properties":{"used":{"type":"integer"},"limit":{"type":"integer","nullable":true},"remaining":{"type":"integer","nullable":true},"percentage":{"type":"number"}}},"words":{"type":"object","properties":{"used":{"type":"integer"},"limit":{"type":"integer","nullable":true},"remaining":{"type":"integer","nullable":true},"percentage":{"type":"number"}}},"allowedModels":{"type":"array","items":{"type":"string"}},"priority":{"type":"boolean"},"resetDate":{"type":"string","format":"date-time"}}},"Health":{"type":"object","properties":{"status":{"type":"string","enum":["healthy","degraded","unhealthy"]},"timestamp":{"type":"string","format":"date-time"},"version":{"type":"string"},"uptime":{"type":"integer","description":"Uptime en segundos"},"queueMode":{"type":"string","enum":["aws-sqs","bullmq"],"description":"Modo de cola activo (AWS SQS + Lambda o BullMQ)"},"checks":{"type":"object","properties":{"database":{"$ref":"#/components/schemas/HealthCheck"},"redis":{"$ref":"#/components/schemas/HealthCheck"},"sqs":{"$ref":"#/components/schemas/HealthCheck"}}},"queues":{"type":"object","nullable":true,"description":"Estadísticas de colas (solo en modo BullMQ)","properties":{"translate":{"type":"object","properties":{"active":{"type":"integer"},"waiting":{"type":"integer"},"completed":{"type":"integer"},"failed":{"type":"integer"}}}}}}},"HealthCheck":{"type":"object","properties":{"status":{"type":"string","enum":["up","down"]},"latency":{"type":"integer","description":"Latencia en ms"},"error":{"type":"string","nullable":true}}},"BlogPost":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"title":{"type":"string"},"content":{"type":"string"},"excerpt":{"type":"string","nullable":true},"coverImage":{"type":"string","nullable":true},"status":{"type":"string","enum":["DRAFT","PUBLISHED","ARCHIVED"]},"featured":{"type":"boolean"},"viewCount":{"type":"integer"},"publishedAt":{"type":"string","format":"date-time","nullable":true},"createdAt":{"type":"string","format":"date-time"},"author":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"image":{"type":"string","nullable":true}}},"category":{"$ref":"#/components/schemas/BlogCategory"},"tags":{"type":"array","items":{"$ref":"#/components/schemas/BlogTag"}},"_count":{"type":"object","properties":{"comments":{"type":"integer"},"reactions":{"type":"integer"}}}}},"BlogComment":{"type":"object","properties":{"id":{"type":"string"},"content":{"type":"string"},"mood":{"type":"string","nullable":true,"enum":["EXCITED","LOVED","HAPPY","SAD","THUMBSY"]},"status":{"type":"string","enum":["PENDING","APPROVED","SPAM","DELETED"]},"createdAt":{"type":"string","format":"date-time"},"author":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"image":{"type":"string","nullable":true}}},"replies":{"type":"array","items":{"$ref":"#/components/schemas/BlogComment"}}}},"BlogCategory":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"color":{"type":"string","example":"#3B82F6"}}},"BlogTag":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"name":{"type":"string"}}},"Error":{"type":"object","properties":{"error":{"type":"string"},"message":{"type":"string"}}},"EmailConfig":{"type":"object","properties":{"configured":{"type":"boolean","description":"Gmail SMTP está configurado"},"connected":{"type":"boolean","description":"Gmail SMTP está conectado"},"error":{"type":"string","nullable":true,"description":"Error de conexión si existe"},"provider":{"type":"string","example":"Gmail SMTP"},"smtpHost":{"type":"string","example":"smtp.gmail.com"},"smtpPort":{"type":"integer","example":587},"senderEmail":{"type":"string","example":"curetcore@gmail.com"},"senderName":{"type":"string","example":"LectorAI"},"lastTestAt":{"type":"string","format":"date-time","nullable":true},"lastTestStatus":{"type":"string","nullable":true}}},"Notification":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string","enum":["BOOK_COMPLETED","TRANSLATION_ERROR","SYSTEM_ANNOUNCEMENT","COMMENT_REPLY","POST_REACTION","WEEKLY_DIGEST"]},"title":{"type":"string"},"message":{"type":"string"},"link":{"type":"string","nullable":true},"read":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"}}},"Glossary":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string","nullable":true},"entryCount":{"type":"integer"},"entries":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"source":{"type":"string"},"target":{"type":"string"},"context":{"type":"string","nullable":true}}}},"createdAt":{"type":"string","format":"date-time"},"updatedAt":{"type":"string","format":"date-time"}}},"UserProfile":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string","nullable":true},"email":{"type":"string","format":"email"},"image":{"type":"string","nullable":true},"role":{"type":"string","enum":["USER","ADMIN","SUPER_ADMIN"]},"plan":{"type":"string","enum":["FREE","PRO","BUSINESS"]},"emailVerified":{"type":"boolean"},"twoFactorEnabled":{"type":"boolean"},"createdAt":{"type":"string","format":"date-time"}}},"UserPreferences":{"type":"object","properties":{"defaultModel":{"type":"string","enum":["gpt-4o-mini","gpt-4o","claude-3-haiku","claude-sonnet-4-20250514","gemini-2.0-flash","gemini-1.5-pro"]},"defaultTargetLanguage":{"type":"string","example":"es"},"preserveFormatting":{"type":"boolean"},"autoStartTranslation":{"type":"boolean"},"defaultGlossaryId":{"type":"string","nullable":true}}},"NotificationSettings":{"type":"object","properties":{"emailBookCompleted":{"type":"boolean","description":"Email cuando un libro termina"},"emailTranslationError":{"type":"boolean","description":"Email cuando hay error"},"emailWeeklyDigest":{"type":"boolean","description":"Resumen semanal"},"emailNewsletter":{"type":"boolean","description":"Noticias y actualizaciones"},"pushEnabled":{"type":"boolean","description":"Notificaciones push en navegador"},"inAppEnabled":{"type":"boolean","description":"Notificaciones en la app"}}}},"responses":{"Unauthorized":{"description":"No autorizado - API key inválida o sesión expirada","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","example":"No autorizado"}}}}}},"NotFound":{"description":"Recurso no encontrado","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","example":"No encontrado"}}}}}}}}}