RepAttention
Historial de Cambios
Versión actual
v0.50.2
Historial de Cambios
Versión actual: 0.50.2
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🚀
FEATURE: Evaluacion automatica de alertas via MentionObserver (dispatch ProcessAlertJob al PROCESSED)
🚀
FEATURE: Cooldown y deduplicacion de menciones en ProcessAlertJob (evita re-evaluacion)
🚀
FEATURE: Calculo de severidad y reason por tipo de alerta (CRISIS_KEYWORD, SENTIMENT_DROP, etc.)
🚀
FEATURE: Notificaciones por email con AlertNotificationMail (template Blade, severidad visual)
🚀
FEATURE: Respeto de preferencias de notificacion del usuario (alert_email, alert_realtime_enabled)
🚀
FEATURE: API de Alert Triggers: 3 endpoints (index, show, update) con paginacion y filtro por status
🚀
FEATURE: Campo created_by en rri_alerts (tracking del creador de la alerta)
🐛
FIX: VOLUME_SPIKE ya no dispara con 0 menciones (retorna [$mentions->isNotEmpty(), ...])
🐛
FIX: Webhook secret ahora se envia como HMAC-SHA256 (X-Signature-256) en vez de plaintext
🔧
CONFIG: Migracion add_created_by_to_rri_alerts_table
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🐛
FIX: Prevenir doble ejecucion de pipeline al actualizar estudio (keywords duplicadas + scraping redundante)
🐛
FIX: Frontend preserva keyword IDs en update payload (antes siempre enviaba id:null → keywords recreadas)
🐛
FIX: Guard unificado isMutating impide click simultaneo en Save y Continue
🔧
CONFIG: Redis mutex lock en StudyController::update() (Cache::lock, patron AnalysisDispatchService)
🔧
CONFIG: Manejo de HTTP 409 Conflict en frontend con mensaje i18n
v0.50.2
ACTUAL
23/02/2026
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🐛
FIX: Campo rri_impact siempre presente en respuestas de alertas (antes se omitia cuando triggers no estaba cargado)
🐛
FIX: rri_impact devuelve 0 en vez de null cuando no hay triggers o menciones con RRI
🐛
FIX: Sincronizar storage/version desde imagen Docker al volume en cada deploy (changelog mostraba version antigua)
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🚀
FEATURE: Sistema de suscripcion a webhooks (13 eventos, CRUD endpoints, HMAC-SHA256 signing)
🚀
FEATURE: 8 endpoints API para gestion de webhook endpoints y entregas
🚀
FEATURE: Despacho automatico de webhooks desde ProcessEventService (12 eventos de pipeline)
🚀
FEATURE: Integracion webhook alert.triggered en ProcessAlertJob + dispatch SendAlertNotificationJob
🚀
FEATURE: Auto-desactivacion de endpoints tras 10 fallos consecutivos
🚀
FEATURE: Reintentos con backoff exponencial (30s, 120s, 480s)
🚀
FEATURE: Cola dedicada 'webhooks' en Horizon con supervisor independiente
🔧
CONFIG: Seccion webhooks en config/services.php (timeout, max_attempts, retention)
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🚀
feat(admin): paginas de visualizacion de estudios y menciones en panel admin (solo lectura)
🚀
feat(admin): componente JSON viewer reutilizable con busqueda, colapsable y syntax highlighting
🚀
feat(admin): enlace Estudios en sidebar del panel admin (seccion Datos)
🔧
chore(ui): extender modal con tamaños 3xl-6xl
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🗑️
CLEANUP: Eliminar tablas analysis_batches y analysis_batch_mention (sin uso en producción)
🗑️
CLEANUP: Eliminar endpoints batch-analysis y analysis/batch (nunca usados por funditec)
🗑️
CLEANUP: Eliminar modelo AnalysisBatch, requests y response classes asociados
📝
DOCS: Actualizar DATABASE_SCHEMA.md y ERD_AUTO.md sin tablas batch
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🚀
FEATURE: Modelo MentionAnalysisTask — tracking individual por mención en análisis NLP
🚀
FEATURE: Dispatch crea MentionAnalysisTask por cada mención (reemplaza JSON denormalizado)
🚀
FEATURE: Webhooks para eventos per-mention: MENTION_QUEUED, MENTION_STARTED, MENTION_FAILED
🚀
FEATURE: Auto-completar AnalysisJob cuando todas las MentionAnalysisTasks llegan a estado terminal
🚀
FEATURE: Retry quirúrgico de menciones fallidas con control de max_retries
🚀
FEATURE: Métricas de MentionAnalysisTask por estado en getMetrics()
⚡
PERF: getClaimedMentionIds() consulta tabla relacional en vez de JSON array
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🚀
FEATURE: Deduplicacion de menciones por URL — rechaza menciones con URL ya existente en el estudio (409)
🚀
FEATURE: Nuevo endpoint GET /studies/{study}/mentions/urls — lista plana de URLs existentes para pre-filtro en scraper
🐛
FIX: Migracion de limpieza soft-delete de menciones duplicadas por URL (conserva la mas antigua)
⚡
PERF: Indice compuesto (study_id, url) para optimizar deduplicacion
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🐛
FIX: `think_driver` siempre NULL al recibir analisis NLP — la ruta simplificada cortocircuitaba la extraccion desde `think_result.scores[]`
🐛
FIX: Mapeo ES→EN de drivers THINK y clasificaciones DO — el NLP envia nombres en espanol que no coincidian con los ENUM de la DB
🐛
FIX: `do_behavior` en batch LLM usaba `clasification` en espanol sin mapear al ENUM ingles
🐛
FIX: Regla de validacion `think_driver` aceptaba `PERFORMANCE` en vez de `FINANCIAL_PERFORMANCE`
🚀
FEATURE: Nueva columna `nlp_raw_response` (LONGTEXT/JSON) en tabla mentions para almacenar el payload completo de la peticion NLP
🚀
FEATURE: Campo `entity` del NLP ahora se almacena en `mentions_meta`
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🚀
FEATURE: Campo `rri_impact` computado en respuestas de alertas (promedio rri_final de menciones en triggers recientes)
🚀
FEATURE: Normalizar `feel_emotions` en respuestas de menciones: siempre devuelve las 4 claves (trust, admiration, respect, positive_feeling) con valor 0 por defecto
🐛
FIX: Endpoint GET highlights devuelve 200 con data:null en vez de 404 cuando no hay highlights generados
🔧
CONFIG: JWT_TTL aumentado a 1440 minutos (24 horas) para evitar logouts frecuentes
🔧
CONFIG: Regenerar token de comunicacion con scraper service (expira 2027-02-16)
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🚀
FEATURE: Circuit breaker para despacho NLP — pausa envío de batches tras 3 fallos consecutivos (cooldown 15 min)
🚀
FEATURE: Límite de batches concurrentes por estudio (max_concurrent_batches configurable)
🚀
FEATURE: Filtro pre-NLP de menciones sin URL ni contenido (marca como ERROR antes de despachar)
🚀
FEATURE: Endpoint GET /studies/{id}/pipeline/metrics — métricas agregadas del pipeline (menciones, jobs, rendimiento, circuit breaker)
🚀
FEATURE: Campo duration_seconds en ProcessEvent para tracking de duración por evento
🚀
FEATURE: Timeout forzado para scraping jobs >60 min sin completar (EXTRACTION_TIMEOUT_FORCED)
🚀
FEATURE: Dispatch automático de análisis al sincronizar scraping jobs completados
🐛
FIX: Retry de análisis ahora solo re-envía menciones en status PENDING (no PROCESSED ni ERROR)
⚡
PERF: Batch size y max concurrent batches configurables via env (NLP_BATCH_SIZE, NLP_MAX_CONCURRENT_BATCHES)
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🚀
FEATURE: StudyObserver con graceful pause: al pausar/completar/archivar un estudio se cancelan jobs PENDING/DISPATCHED, los en ejecución terminan naturalmente
🚀
FEATURE: Reactivación automática: al reactivar estudio PAUSED→ACTIVE se re-despachan menciones huérfanas en batches de 50
🚀
FEATURE: Guards en DispatchScrapingJob, DispatchBatchAnalysisJob, DispatchAnalysisJob y ScrapingJobObserver para no iniciar trabajo nuevo si el estudio no está ACTIVE
🚀
FEATURE: Estado CANCELLED para ScrapingJob (terminal, simétrico con AnalysisJob)
🚀
FEATURE: ProcessEvents STUDY_DEACTIVATED y STUDY_REACTIVATED con fase LIFECYCLE para trazabilidad
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🐛
FIX: Prevenir bucle infinito de reintentos en CheckOrphanedJobsCommand: guard que bloquea re-dispatch si hay ≥6 fallos en las últimas 2h
🐛
FIX: AuthController::refresh() usaba columnas inexistentes (token, last_activity) en vez de token_jti
🐛
FIX: Webhook analysis-complete ahora es idempotente: devuelve 200 en vez de 404 cuando no hay job activo (callbacks duplicados)
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🐛
FIX: Eliminar race condition TOCTOU en dispatch de análisis NLP: nuevo AnalysisDispatchService centralizado con Redis lock per-study
🐛
FIX: AnalysisJob se crea en DB antes de encolar (no dentro del Job asíncrono), eliminando ventana de duplicación
🔧
REFACTOR: 6 puntos de entrada (webhook, observer, scheduler, retry, reactivación, stale cleanup) ahora pasan por AnalysisDispatchService
🔧
REFACTOR: DispatchBatchAnalysisJob recibe AnalysisJob pre-creado en vez de Study+mentionIds
📝
DEPRECATION: DispatchAnalysisJob marcado como @deprecated (reemplazado por AnalysisDispatchService + DispatchBatchAnalysisJob)
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🚀
FEATURE: Endpoints API de control del pipeline: POST /pipeline/retry, /pipeline/cancel, /pipeline/force-complete
🚀
FEATURE: PipelineControlService con logica de retry (respeta max_retries), cancel (marca CANCELLED) y force-complete (cierra pipeline)
🚀
FEATURE: Estado STALLED en pipeline_phase cuando hay menciones PENDING sin jobs activos
🚀
FEATURE: Estado CANCELLED para AnalysisJob (terminal, distinto de FAILED: usuario decidio parar)
🚀
FEATURE: Columnas retry_count y max_retries en analysis_jobs para tracking de reintentos
🔧
CONFIG: CheckOrphanedJobsCommand migrado a DispatchBatchAnalysisJob con guards anti-loop y anti-cancel
🔧
CONFIG: CleanStaleAnalysisJobsCommand con auto-retry, ProcessEvents y tracking de retry exhausted
🔧
CONFIG: Todos los eventos de recuperacion generan ProcessEvents (visibles en timeline del frontend)
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🚀
FEATURE: Modelo ProcessEvent y servicio para historico de eventos del pipeline (append-only)
🚀
FEATURE: Webhook scraping-progress para recibir callbacks push del scraper (EXTRACTION_STARTED, TASK_COMPLETED, EXTRACTION_COMPLETED, EXTRACTION_FAILED)
🚀
FEATURE: Webhook analysis-progress para recibir callbacks push de Funditec (BATCH_STARTED, MENTION_COMPLETED, BATCH_COMPLETED, BATCH_FAILED)
🚀
FEATURE: Job DispatchBatchAnalysisJob para analisis NLP incremental por batch de scraper
🚀
FEATURE: FunditecService::triggerBatchAnalysis() para enviar batches de menciones especificas
🚀
FEATURE: Comando CheckOrphanedJobsCommand como safety net para jobs huerfanos y menciones sin procesar
🚀
FEATURE: Filtro ?ids=1,2,3 en endpoint de listado de menciones
🚀
FEATURE: Pipeline phase (IDLE/EXTRACTING/ANALYZING/COMPLETED) en process-status
🚀
FEATURE: Timeline de eventos en process-status con ultimos 50 ProcessEvents
🔧
CONFIG: ScrapingJobObserver con guard incremental (requiere menciones PENDING)
🔧
CONFIG: ScraperService envia callback_url en payload al scraper
🔧
CONFIG: AnalysisJob soporta mention_ids, scraping_job_id y batch_number
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🚀
FEATURE: Dockerfile producción multi-stage con build de assets Vite integrado
🚀
FEATURE: Bind de logs Laravel al host en producción para monitorización externa
🚀
FEATURE: Instalación optimizada de Horizon con --update-no-dev en producción
🐛
FIX: Corregido orden de instalación de Horizon y etapa de build de assets en Dockerfile
🐛
FIX: Corregido backup/restore de composer.json que rompía autoloader de Horizon
🐛
FIX: Ajustados permisos y comandos de copia de archivos en etapa de producción
🐛
FIX: URLs de fuentes Coftein cambiadas de localhost absoluto a rutas relativas
🔧
CONFIG: Documentación API (Scramble) accesible solo para usuarios autenticados
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🚀
FEATURE: Endpoint unificado GET /studies/{id}/process-status con estado de extraccion, analisis y menciones
🚀
FEATURE: Endpoint GET /studies/{id}/analysis-jobs para listar jobs de analisis NLP
🚀
FEATURE: Persistencia de progress_snapshot en ScrapingJob al completar extraccion
🚀
FEATURE: Campo completed_at en ScrapingJob para tracking temporal
🚀
FEATURE: Servicio StudyProcessStatusService con mapeo de estados pipeline (NOT_STARTED/IN_PROGRESS/COMPLETED/FAILED)
🚀
FEATURE: Frontend - Servicio ProcessStatusFacade con polling de estado del pipeline
🚀
FEATURE: Frontend - Estado NOT_STARTED en panel de extraccion cuando no hay jobs previos
🚀
FEATURE: Frontend - Estado completado-vacio con sugerencia de re-ejecutar cuando 0 menciones
🚀
FEATURE: Frontend - Integracion de datos reales de AnalysisJob en seccion de tracking NLP
✅
TESTS: 30 tests nuevos (ProcessStatus 15, AnalysisJob 9, ScrapingProgressSnapshot 6)
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🚀
FEATURE: Auto-trigger análisis NLP (Funditec) al completar scraping
🚀
FEATURE: ScrapingJobObserver detecta completitud y despacha DispatchAnalysisJob
🚀
FEATURE: FunditecService para comunicación HTTP con servicio NLP externo
🚀
FEATURE: Modelo AnalysisJob con tracking de estados (PENDING → DISPATCHED → COMPLETED/FAILED)
🚀
FEATURE: Webhook POST /webhooks/analysis-complete para callbacks de Funditec
🚀
FEATURE: Campo sectors (JSON) en Study para objetivos ALIGN en modo STRATEGIC
🔧
CONFIG: Variables de entorno FUNDITEC_* para configuración del servicio NLP
✅
TESTS: 26 tests nuevos (Observer 6, Job 8, Webhook 12)
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🚀
FEATURE: Endpoint GET /studies/{study}/scraping-jobs/{job}/progress para progreso en tiempo real
🚀
FEATURE: Proxy al servicio externo de scraping con sincronización automática de estado
🚀
FEATURE: Degradación graceful cuando el servicio externo no está disponible
🔧
REFACTOR: Constantes de estado en modelo ScrapingJob (STATUS_PENDING, STATUS_DISPATCHED, etc.)
✅
TESTS: 9 tests para el endpoint de progreso (permisos, estados terminales, degradación, sincronización)
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🐛
FIX: RRI ahora se calcula correctamente cuando feel_emotions es null/vacío
🐛
FIX: Severity usa valor externo del proveedor cuando no hay emociones disponibles
🐛
FIX: align_score se nullifica automáticamente en modo ANALYTICAL
🐛
FIX: Log warning cuando una mention PROCESSED no tiene RRI calculable
🚀
FEATURE: Dispatch automático de CalculateKeywordStatsJob al guardar mention con RRI
🚀
FEATURE: Comando artisan rri:recalculate para recalcular menciones rotas
🚀
FEATURE: Action RecalculateMentionRRIAction reutilizable para recálculo batch
🚀
FEATURE: Programación diaria de recálculo de stats de keywords (safety net)
🔧
MIGRATION: Migración automática para corregir menciones PROCESSED con rri_final null
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🚀
FEATURE: Rediseño completo de plantillas de email con nuevo diseño verde corporativo
🚀
FEATURE: Layout table-based para máxima compatibilidad con clientes de email
🚀
FEATURE: Soporte de banner opcional e imagen de logo en footer
🚀
FEATURE: Botones bulletproof con fallback VML para Outlook
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🚀
FEATURE: Sistema de highlights para estudios (5 endpoints CRUD con versionado)
🚀
FEATURE: Protección dashboard Horizon con autenticación y rol ADMIN
🐛
FIX: Scope del interceptor CSRF de Scalar limitado a same-origin
🐛
FIX: Referencias de host en docker-compose actualizadas para consistencia
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🚀
FEATURE: Integración servicio de scrapping bajo demanda (repattention-service)
🚀
FEATURE: Auto-dispatch scraping al crear estudio con keywords
🚀
FEATURE: Auto-dispatch scraping al crear keyword en estudio activo
🚀
FEATURE: Auto-dispatch scraping al actualizar estudio con keywords nuevos
🚀
FEATURE: Endpoints manuales POST /studies/{id}/scrape y POST /studies/{id}/keywords/{id}/scrape
🚀
FEATURE: Endpoint GET /studies/{id}/scraping-jobs con paginación
📦
Tabla scraping_jobs para tracking de trabajos enviados al scraper
🔧
ScrapperService HTTP client con JWT auth, timeout y retry configurable
🔧
DispatchScrapingJob queue job con afterCommit y backoff
✅
26 tests (19 feature + 7 unit) con 77 assertions
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🚀
FEATURE: Dockerización full-stack con Nginx + PHP-FPM + Horizon + Scheduler + Redis
🐳
Dockerfile PHP 8.4-FPM con extensiones necesarias (pdo_mysql, pcntl, gd, opcache, etc.)
🔧
Nginx como reverse proxy (único puerto externo configurable)
📦
Laravel Horizon integrado para gestión visual de colas (/horizon)
⏰
Contenedor Scheduler para tareas programadas
🔒
Redis interno (sin puerto expuesto), BD externa (host.docker.internal)
📝
Documentación completa en docs/DOCKER.md
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🚀
FEATURE: CRUD completo de administración de usuarios (solo ADMIN)
📥
GET /api/v1/admin/users - Listar usuarios con filtros, búsqueda y paginación
📝
POST/PUT/DELETE /api/v1/admin/users/{id} - Crear, editar y eliminar usuarios
📧
POST /api/v1/admin/users/{id}/invite - Enviar/reenviar invitación por email
🔑
POST /api/v1/auth/set-password - Configurar contraseña con token de invitación
🛡️
Protección contra auto-eliminación de admin
📋
Security logging en todas las operaciones CRUD (ENS compliance)
✅
44 tests con cobertura completa de CRUD, invitaciones y autorización
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🚀
FEATURE: Sistema de notas para estudios (CRUD completo)
📥
GET/POST /api/v1/studies/{id}/notes - Listar y crear notas
📝
PUT/DELETE /api/v1/studies/{id}/notes/{noteId} - Editar y eliminar notas
🔐
Permisos granulares: editar/eliminar solo autor o ADMIN global
🗃️
Nueva tabla study_notes con soft deletes e índice compuesto
✅
21 tests con cobertura completa de CRUD y autorización
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🔧
CONFIG: Docker usa variables .env existentes (DB_*, REDIS_*) sin archivo separado
⚡
PERF: Redis configurado como cache y queue por defecto
📦
DEP: Añadido predis/predis como cliente Redis (sin extensión PHP)
📝
DOCS: Actualizada guía de instalación con sección Docker completa
📝
DOCS: Planes Docker archivados como completados
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🚀
FEATURE: Endpoint batch para recibir respuestas completas del LLM
📥
POST /api/v1/mentions/analysis/batch - Procesa múltiples análisis en una sola petición
🧠
Acepta rri_final, severity, impact directamente del LLM (sin recalcular en backend)
⏱️
Almacena metadata de tiempos: start_time, end_time, total_elapsed_time_seconds, average_time_seconds
🗃️
Nueva tabla analysis_batches: tracking de lotes procesados por el LLM
🗃️
Nueva tabla analysis_batch_mention: relación pivot batch-menciones con status individual
📊
Soporte para errores parciales: procesa menciones válidas, reporta errores individuales
🔐
FEATURE: Endpoint protegido para archivos de storage
📁
GET /api/v1/storage/{path} - Sirve archivos con autenticación JWT/API token
🔒
Archivos en storage/app/public ahora requieren autenticación
✅
8 nuevos tests para batch analysis LLM (50 assertions)
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🚀
MAJOR: Sistema completo de notificaciones de usuario implementado
🔔
Notificaciones de Alertas: GET/PUT /api/v1/user/notifications/alert (realtime, in-app, email, Slack, Teams)
📢
Notificaciones del Sistema: GET/PUT /api/v1/user/notifications/system (team changes, billing, workspace, product updates)
💬
Notificaciones de Menciones: GET/PUT /api/v1/user/notifications/mentions (new mentions, only negative)
📧
Correos Resumen (Digest): GET/PUT /api/v1/user/notifications/digest (daily/weekly/monthly)
🌙
Horas Silenciosas: GET/PUT /api/v1/user/notifications/quiet-hours (timezone support)
👤
User Profile: PUT /api/v1/user/profile (name, phone), POST /api/v1/user/profile/avatar
🔐
Passwordless Auth: POST /api/v1/auth/request-code, POST /api/v1/auth/verify-code
⏰
SendDigestEmailJob: Job programado para envío de emails resumen (respeta timezone y quiet hours)
📬
DigestEmail Mailable: Template HTML responsive para correos resumen
🔑
AuthCode: Sistema de códigos de 6 dígitos con rate limiting y expiración
🗃️
Migración: create_user_notification_settings_table (configuraciones por usuario)
🗃️
Migración: add_profile_fields_to_users (phone_number, avatar_url)
🗃️
Migración: create_auth_codes_table (passwordless authentication)
🗃️
Migración: increase_security_logs_action_column (varchar 10 → 50)
🔧
FIX: Validación de status en alertas RRI (ACTIVE, INACTIVE, PAUSED)
✅
74 nuevos tests para el sistema de notificaciones
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🚀
MAJOR: API de Studies extendida para sincronización completa con frontend
📊
Nuevos campos en studies: entity_type, term_matching, folder_id
🆕
Nuevo modelo StudyObjective: objetivos simples (trust, awareness, transparency, innovation, leadership, ethics, responsibility, proximity)
🆕
Nuevo modelo CalendarMilestone: hitos del calendario con fecha + descripción
🔧
StoreStudyRequest/UpdateStudyRequest: validación de keywords, objectives y calendar_milestones anidados
✨
StudyController: sync inteligente de keywords (crear/actualizar/eliminar) con variants y exclusions
✨
StudyController: sync de objectives (estrategia reemplazo) y calendar_milestones (estrategia sync por id)
📦
StudyResource actualizado: incluye entity_type, term_matching, folder_id, objectives como array de strings
📦
KeywordResource: ahora incluye avg_rri, last_mention_date, statistics, variants y exclusions como arrays
🆕
CalendarMilestoneResource: nuevo resource para milestones
🗃️
Migración: add_fields_to_studies_table (entity_type, term_matching, folder_id)
🗃️
Migración: create_study_objectives_table
🗃️
Migración: create_calendar_milestones_table
🗃️
Migración: convert_status_enum_to_varchar_in_mentions (status ENUM → VARCHAR)
🔧
FIX: Migraciones pendientes marcadas como ejecutadas (mentions_meta y convert_enums ya existían en BD)
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🔧
REFACTOR: Sistema de versionado modular en storage/version/
📁
Estructura: manifest.json + changelog/*.x.json por serie
📦
Changelog compactado: 0.14.x.json contiene versiones 0.1.0 a 0.14.0
🧪
FIX: Test it_sets_error_status_when_calculation_fails actualizado para emociones parciales
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🎯
FIX: Cálculo RRI ahora acepta feel_emotions parciales (1-4 emociones en lugar de exactamente 4)
✨
Emociones faltantes tratadas como neutral (0), no como errores de validación
📊
Añadido logging INFO para emociones parciales para monitorear patrones del proveedor NLP
🧪
Nuevos tests: it_accepts_partial_feel_emotions, it_rejects_empty_feel_emotions
🎨
UI: Secciones del changelog ahora expandidas por defecto para mejor UX
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🎯
FIX: Adaptación al formato EXACTO del proveedor externo
✨
think_result ahora acepta scores array [{driver, score, reasoning}] + average_score
✨
feel_result ahora acepta scores array [{emotion, score, reasoning}] + average_score
✨
do_result ahora acepta clasification (con typo del proveedor) → behavior
✨
align_results (plural) en lugar de align_result
💾
Guardado de input, think_result, feel_result, do_result completos en mentions_meta
🔧
Helper methods adaptan scores arrays a campos de base de datos
📊
getThinkData(): Extrae driver con mayor score de scores array
📊
getFeelData(): Convierte scores array a emotions object normalizado
📊
getDoData(): Mapea clasification → do_behavior
🔧
audience_channel_score default 50.0 si no existe
🔧
severity guardada desde proveedor
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🚀
MAJOR: Manejo flexible de JSON para servicios NLP externos
✨
StoreMentionAnalysisRequest rediseñado con helper methods (getThinkData, getFeelData, getDoData, getAlignData)
📊
Acepta estructuras JSON variables: objetos think_result, feel_result, do_result
💾
Preservación completa de JSON en tabla mentions_meta para auditoría/reentrenamiento de IA
🔧
UpdateMentionStatusRequest mejorado con campos metadata opcionales (error_code, objeto metadata)
🎯
MentionAnalysisController::store() reescrito para normalizar formatos flexibles de proveedores IA
🔐
Integración SecurityLog para tracking de análisis con atribución de proveedor
📝
Cumplimiento estándar API: Usando clases Response personalizadas (no response()->json() directo)
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🐛
FIX: Corregida serialización de valores meta en ListMentionResponse
✨
Cambiado de ResourceCollection a interfaz Responsable
📊
Campos meta ahora retornan valores simples en lugar de arrays
🔧
Corregido problema de doble serialización con metadata de paginación
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🔄
API: Estructura de respuesta unificada para endpoint de menciones pendientes
✨
/mentions/pending ahora retorna mismos datos que /studies/{id}/mentions
📦
Usa MentionResource y ListMentionResponse para consistencia
🎯
Incluye relaciones keyword y study con datos minimizados
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
📚
API DOCS: Reordenados tags de endpoints alfabéticamente en documentación Scramble
🔤
Tags ahora aparecen en orden A-Z: Alerts, Authentication, Keywords, Mentions, Studies, Users
✨
Mejorada navegación y usabilidad de documentación API
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🔒
API: Optimizada exposición de datos de relaciones en MentionResource
✨
Creados MentionKeywordResource y MentionStudyResource para datos mínimos
📉
Eliminados deleted_at, timestamps y otros metadata de relaciones anidadas
🎯
Keyword: Solo muestra id, study_id, term, is_primary, total_mentions, avg_rri
🎯
Study: Solo muestra id, name, analyzed_brand, study_mode, status
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🔒
API: Optimizada exposición de datos de usuario en StudyResource
✨
Creado StudyUserResource para datos mínimos de usuario en listados de estudios
📉
Reducido tamaño de payload API eliminando campos de usuario innecesarios
🔐
Eliminados campos sensibles: email_verified_at, global_role, status, timestamps, pivot
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🔄
Sistema flexible de metadata para menciones (soporte análisis dinámicos de IA)
📊
Nueva tabla mentions_meta para campos no mapeados de proveedores externos
🔧
Conversión ENUM → VARCHAR en mentions (source_type, think_driver, do_behavior)
🤖
Auto-cálculo de external_context_score en MentionObserver (Decision 2C)
⚠️
Fallback a NEUTRAL con logging para do_behavior desconocido (Decision 1A)
🔍
Columna provider indexada en mentions_meta para queries eficientes (Decision 3B)
✨
MentionAnalysisController ahora guarda metadata de proveedores (model_used, reasoning, timing)
📝
StoreMentionAnalysisRequest acepta campos opcionales metadata (think_result, feel_result, do_result, source_analysis, context_analysis, performance)
🔗
MentionResource expone metadata agrupada por tipo (analysis_metadata, think_reasoning, feel_reasoning, etc.)
💾
Migración segura preservando datos existentes (temp column pattern)
🔌
Compatible con múltiples proveedores IA: ChatGPT4, Claude, modelos custom
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
✅
Fase 1 Completa: 100% Cumplimiento Estándar API Controller (Study, Keyword, RriAlert, ReputationSnapshot)
🔧
StudyController: Refactorizado con patrón FormRequest + Resource + Response
🔧
KeywordController: Refactorizado con autorización + validación completa en FormRequest
🔧
RriAlertController: Refactorizado con validación exhaustiva de configuración de alertas
🔧
ReputationSnapshotController: Refactorizado con soporte paginación + filtrado
📝
Creados 11 archivos FormRequest con autorización + reglas de validación apropiadas
📝
Creados 4 API Resources con documentación @property exhaustiva
📝
Creadas 12 clases Response para respuestas HTTP consistentes (Index/Show/Store/Update/Destroy)
🔐
Todos los controllers ahora siguen patrón de autorización FormRequest (movido desde controller)
✨
Todos los endpoints retornan clases Response personalizadas (sin response()->json() en controllers)
📊
Helpers de paginación en FormRequest (métodos getPagination, getFilters, getSorting)
🎯
Checklist de archivos relacionados: Controller → Request → Resource → Response → Migration → Scramble
📚
Ejemplo real: Fix de source_type (3 Requests + Resource + annotations + docs)
⚠️
Regla de oro: 1 cambio requiere validar 5+ archivos relacionados
🔗
Validación cruzada: Request rules ↔ Resource @property ↔ columnas DB ↔ valores ENUM
📋
Sincronización docs: Si cambia patrón → actualizar CHECKLIST + EXAMPLE + STANDARD
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🔧
FIX: Corrección de validación source_type en menciones
✅
CreateMentionRequest: Valores ENUM correctos (NEWS_MEDIA, SOCIAL_MEDIA, BLOG, FORUM, DARKWEB, VIDEO, PODCAST, OTHER)
✅
ListMentionRequest: Filtros actualizados con valores correctos del ENUM
✅
UpdateMentionRequest: Ya tenía valores correctos, sin cambios
📝
PHPDoc actualizado: MentionResource, CreateMentionRequest, ListMentionRequest
📖
Scramble annotations: MentionController index() y store() con valores correctos
📚
Documentación: EXPLICACION_MENCIONES.md, EXPLICACION_RRI.md, SCRAMBLE_ANNOTATIONS.md actualizados
📁
Roadmap: STEP-4 y STEP-5 con ejemplos corregidos
🎯
Eliminados valores incorrectos: WEB, NEWS, REVIEW (no existen en DB)
✅
Agregado valor OTHER faltante en todas las validaciones
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
📚
DOCS: Estándar completo de implementación de controladores API
📄
API_CONTROLLER_STANDARD.md: Documento maestro con 8 secciones modulares
🏗️
FILE_STRUCTURE.md: Convenciones de nomenclatura (Controller/Request/Resource/Response)
🎯
CONTROLLER_PATTERNS.md: 5 métodos CRUD con patrones completos
🔐
REQUEST_PATTERNS.md: authorize() + rules() + helpers con ejemplos
📝
RESOURCE_PATTERNS.md: @property tags + transformaciones + relationships
📊
RESPONSE_PATTERNS.md: Códigos de estado + estructura meta + paginación
📖
SCRAMBLE_ANNOTATIONS.md: Guía completa @tags/@queryParam/@bodyParam/@response
✅
IMPLEMENTATION_CHECKLIST.md: 70 items en 11 fases para validación
💡
STUDY_CRUD_EXAMPLE.md: Ejemplo completo Study CRUD siguiendo estándar
🔗
Integración INDICE.md: 4 referencias cruzadas al estándar API
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
📚
DOCS: Documentación completa para Scramble en todos los controladores API
✅
AuthController: @tags Authentication, login/logout/me/refresh con ejemplos JWT
✅
StudyController: @tags Studies, CRUD completo con validaciones y roles
✅
KeywordController: @tags Keywords, gestión con variants y exclusions
✅
MentionController: @tags Mentions, 6 endpoints documentados (index, show, store, update, destroy, statistics)
✅
RriAlertController: @tags Alerts, 5 tipos de alertas con configs específicas
✅
ApiTokenController: @tags API Tokens, gestión de tokens para integraciones
✅
MentionAnalysisController: @tags Mention Analysis (External Services), endpoints para servicios NLP/MML externos
✅
ReputationSnapshotController: @tags Reputation Snapshots, agregaciones DAILY/WEEKLY/MONTHLY
🎯
@bodyParam completos: Todos los campos con tipos, ejemplos y valores permitidos
🎯
@queryParam completos: Filtros, ordenamiento, paginación con ejemplos
📝
@response con ejemplos reales: 200, 201, 204, 403, 404, 422, 500
🏷️
Tags organizados por funcionalidad: Authentication, Studies, Keywords, Mentions, Alerts, API Tokens, Mention Analysis, Reputation Snapshots
📖
PHPDoc descriptivo: Explicaciones claras de funcionalidad, flujo y requisitos
🔐
Documentación de autorización: Roles requeridos (ADMIN, EDITOR, ANALYST, VIEWER)
🔄
Documentación de flujos externos: Patrones de integración de servicios NLP
📊
Ejemplos de respuestas: Datos realistas con estructura completa
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🏗️
REFACTOR: Separación arquitectónica Resources vs Responses
📁
Estructura: app/Http/Resources/ (transformaciones) + app/Http/Responses/ (wrappers HTTP)
📦
MentionResource movido a app/Http/Resources/ (raíz, sin subdirectorios)
📤
Responses en app/Http/Responses/Mention/ (ListMentionResponse, ShowMentionResponse, etc.)
🔄
Namespaces: App\Http\Resources vs App\Http\Responses\Mention
✅
Claridad semántica: Resources = Transformación de datos, Responses = Capa HTTP
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🔧
REFACTOR: Reestructuración de Resources - eliminados subdirectorios Api/V1
📁
Estructura simplificada: app/Http/Resources/Mention/ y app/Http/Resources/
🔄
Namespaces actualizados: App\Http\Resources\Mention y App\Http\Resources
✅
Imports actualizados en MentionController y ReputationSnapshotController
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
📝
FEATURE: Nuevo estándar de implementación para controladores API
🔧
MentionController refactorizado: Custom Requests + Custom Resources por endpoint
🔐
Autorización: Movida de controlador a Request->authorize() (patrón FormRequest)
🎯
Parámetros estandarizados: Todos los endpoints usan 'int $id' en lugar de $studyId/$mentionId
📚
Documentación Scramble: PHPDoc completo con @queryParam, @bodyParam, @response
🏷️
Tags organizados: Mentions, Studies, Keywords, Alerts, Users, Authentication
📦
Request Classes: ListMentionRequest, ShowMentionRequest, CreateMentionRequest, UpdateMentionRequest, DeleteMentionRequest, MentionStatisticsRequest
📤
Response Classes: ListMentionResponse, ShowMentionResponse, CreateMentionResponse, UpdateMentionResponse, DeleteMentionResponse, MentionStatisticsResponse
🔍
MentionResource: Base resource con tipos de retorno específicos (array{...})
🎨
ScrambleServiceProvider: Custom tags con descripciones para organización de endpoints
✅
Query params documentados: Filtros (fecha, RRI, driver, behavior, source), ordenamiento, paginación
✅
Body params documentados: Todos los campos con tipos, validaciones y ejemplos
🔄
Helper methods: getFilters(), getSorting(), getPagination() en ListMentionRequest
🚫
Eliminados: StoreMentionRequest (reemplazado por CreateMentionRequest)
📋
Valores enum documentados: THINK drivers, DO behaviors, source types, status values
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🛡️
FEATURE: Sistema completo de logs de seguridad ENS
🔎
Vista index: Filtros avanzados (usuario, acción, método, status, fechas, búsqueda)
🔍
Vista detail: Detalle completo de cada log con metadatos
📊
Exportar CSV: UTF-8 BOM con 12 columnas (ID, fecha, usuario, acción, método, ruta, status, IP, navegador, dispositivo, user agent)
🔉
Middleware automático: Registra TODAS las peticiones HTTP y API
🚫
Exclusiones: Assets (build/*, fonts/*), livewire, horizon, telescope
🔒
Campos capturados: method, path, status_code, user_id, ip_address, user_agent, details (JSON)
🌐
Detección IP: Soporte para X-Forwarded-For, X-Real-IP (proxies/balanceadores)
🧹
Sanitización: Redacta password, token, secret, api_key en logs
🎯
Badges semánticos: Actions (13 tipos) y códigos HTTP status con colores
📱
Detección dispositivo: Móvil, Tablet, Desktop + navegador (cURL, Postman, Chrome, Firefox, Safari, Edge)
👁️
Control de acceso: ADMIN ve todos, usuarios ven solo propios
🗑️
Prune: Eliminar logs antiguos (mínimo 30 días ENS)
🔒
Inmutabilidad: Sin UPDATED_AT, logs son permanentes
📈
Índices optimizados: (user_id, action, created_at), path
🔗
Navegación: Enlace en sidebar con icono shield, highlight activo
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🔉
BREAKING: Cambio de hash SHA-256 a encriptación AES-256 reversible
🔐
FEATURE: Copiar token siempre disponible (desencripta desde BD)
🔒
Formato visual mejorado: [7 letras]******[5 últimas letras]
✅
Notificación toast: Confirma copia al portapapeles con icono check
🔓
Método getPlainTextToken(): Desencripta token almacenado
🗄️
Migración actualizada: Columna 'token' de string(128) a text
🔍
findByToken(): Busca desencriptando todos los tokens activos
⚠️
NOTA: Requiere php artisan migrate:fresh (regenera tokens)
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🔐
FEATURE: Panel de gestión de API Tokens con CRUD completo
🔎
Listado de tokens: Nombre, estado (Activo/Inactivo/Nuevo/Expirado), último uso
➕
Crear token: Formulario con nombre descriptivo y prefijo 'rpa_'
🔒
Seguridad: Token solo se muestra una vez (SHA-256 hash almacenado)
📜
Historial detallado: Últimas 50 peticiones API por token
🌐
Tracking avanzado: IP, user-agent, endpoint, fecha/hora de cada petición
📱
Detección de dispositivo: Móvil/Tablet/Desktop + cliente (Chrome, cURL, Postman)
🎯
UI/UX: Badges de estado con colores semánticos, cards estadísticas
🗑️
Eliminar token: Confirmación de seguridad antes de borrar
🔒
Botón copiar: Copia token al portapapeles con feedback visual
🔉
Permisos: Solo ADMIN y ANALYST pueden gestionar tokens
🔔
Integración: SecurityLog registra uso de API (action: API_REQUEST)
✅
Navegación: Enlace en sidebar con highlight activo
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🔧
HOTFIX: Excluir /public/build/* del control de versiones
🐛
FIX: Conflicto entre npm run dev y npm run build en manifest.json
🔥
Gitignore actualizado para evitar commits de assets compilados
⚙️
Assets ahora se generan localmente y en CI/CD (no en repo)
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
📜
FEATURE: Changelog con navegación tipo árbol lateral desplegable
✅
Scroll-spy: Resalta automáticamente la versión visible en el árbol
🔀
Dual layout: Panel admin (autenticados) vs página pública (invitados)
📱
Responsive: Sidebar 300px desktop, oculto en móvil (<1024px)
🌲
Árbol colapsable: Versiones agrupadas por serie (0.15.x, 0.14.x)
⬆️
Botón 'Volver arriba': Aparece tras scroll de segunda sección
⚡
Botón 'Volver al inicio': Sticky bottom en sidebar (solo invitados)
🔗
Copiar enlace: Botón en cada versión para compartir enlace directo
💾
Persistencia: Estado del árbol guardado en localStorage
🎨
Tokens semánticos: bg-bg-surface, text-fg-base, border-border-base
🎯
Alpine.js store 'changelogTree': Gestión de estado del árbol
🧩
Componente reutilizable: <x-ui.changelog-tree> con props
🔀
Partial compartido: changelog-content.blade.php para ambos layouts
👁️
Intersection Observer API: Detección automática de sección visible
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🔧
HOTFIX: Corrección de error en método seed() de DatabaseSeeder
🐛
FIX: Actualizar llamadas a seeders en DatabaseSeeder
🔄
Renombrar seeders con sufijo Seeder estándar de Laravel
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🔉
FEATURE: Sistema de autenticación dual (Web + API)
🎯
UI: Login con validación, dashboard estadístico, navbar + sidebar
🔒
JWT: Tokens para API REST con middleware personalizado
🔐
Sesiones: Laravel Breeze para rutas web autenticadas
✅
Guards: 'web' (sesiones) y 'api' (JWT) en config/auth.php
📱
Responsive: Sidebar colapsable (Alpine.js), tema dark
🛡️
ENS: Logs de auditoría en security_logs (login, acceso, cambios)
🔎
Dashboard: Cards con estadísticas dinámicas (usuarios, estudios, menciones)
👁️
Componentes: Badge, button, modal, alert, dropdown, theme-toggle
🔍
Detección IP real: Soporte X-Forwarded-For/X-Real-IP
🌐
API Docs: Scramble /docs/api con auto-discovery de endpoints
🔄
Comandos CLI: token:generate para testing rápido de API
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🎯
FEATURE: Sistema de diseño completo con TailwindCSS 4 + SCSS
🌈
10 paletas de color + tokens semánticos (bg-base, fg-muted, border-base)
📈
Arquitectura @layer: variables, theme, typography, utilities
👁️
Componentes UI: navbar, sidebar, layouts (app.blade.php, admin.blade.php)
🌙
Dark mode: Sistema localStorage + Alpine.js con toggle
🔤
Tipografía: Familia Coftein (400-700) con rutas absolutas/dev y relativas/prod
⚙️
Layouts: Sistema Stack (@push meta/styles/scripts) para modularidad
⚡
Vite 7: HMR en puerto 5174, build optimizado con manifest.json
📱
Responsive: Breakpoints sm/md/lg/xl, sidebar colapsable
🔀
Alpine stores: sidebar (open/collapsed) con persistencia localStorage
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🔒
FEATURE: Sistema de API Tokens con autenticación Bearer
⚙️
Tabla api_tokens: user_id, name, token (SHA-256), abilities, expires_at
🔉
Modelo ApiToken: generateFor(), findByToken(), markAsUsed()
🛡️
Middleware ApiAuth: Valida Bearer tokens y gestiona expiración
🔎
Factory + Seeder: Datos de prueba para desarrollo
🔍
Relationships: ApiToken->user(), User->apiTokens()
•
✓ Validación: Comprobación de expiración con Carbon (método isValid)
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
⚠️
FEATURE: Sistema de alertas RRI con 5 tipos de detección
🚨
Alertas: CRISIS, SENTIMENT_DROP, NEGATIVE_SPIKE, THRESHOLD_BREACH, KEYWORD_ANOMALY
⚙️
Tablas: rri_alerts (reglas), alert_triggers (disparos), alert_trigger_mention (pivot)
📧
Canales: EMAIL, SLACK, WEBHOOK (config JSON por canal)
⚡
ProcessAlertJob: Evaluación automática con queries optimizadas
🔎
Factories + Seeders: 3 alertas predefinidas con triggers
🔍
Relationships: RriAlert->triggers(), AlertTrigger->mentions() many-to-many
✅
Estados: ACTIVE, TRIGGERED, RESOLVED con metadata de evaluación
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🔎
FEATURE: Sistema de snapshots reputacionales agregados
⚙️
Tabla reputation_snapshots: Agregación por estudio y periodo (DAILY/WEEKLY/MONTHLY)
📊
Métricas: avg_rri, min_rri, max_rri, total_mentions, sentiment_distribution
⚠️
Job GenerateReputationSnapshotJob: Cálculo asíncrono con agregaciones SQL
🔍
Índices optimizados: (study_id, period_type, period_start)
📅
Períodos: Snapshot diario (00:00), semanal (lunes), mensual (día 1)
🎯
Factory: Datos sintéticos para testing con sentimientos balanceados
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🕵️
FEATURE: Monitoreo de exposiciones en dark web
⚙️
Tabla data_exposures: source_url, exposed_data (JSON), severity (LOW/MEDIUM/HIGH/CRITICAL)
🔗
Relationships: DataExposure->study(), Study->dataExposures()
🔎
Factory + Seeder: 15 exposiciones sintéticas con datos realistas
🔍
Índices: (study_id, discovered_at), (severity)
⚠️
Validación: Enum severity con 4 niveles, JSON para exposed_data
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
📅
FEATURE: Gestión de eventos de marca con contexto externo
⚙️
Tabla brand_events: title, description, event_date, event_type (INTERNAL/EXTERNAL/INDUSTRY/CRISIS)
🔗
Relationships: BrandEvent->study(), Study->brandEvents()
🔎
Factory + Seeder: 30 eventos realistas con tipos variados
✅
Uso: Contexto para análisis RRI y correlación temporal
📊
Índices: (study_id, event_date) para queries temporales
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
✅
FEATURE: Sistema de objetivos reputacionales para modo STRATEGIC
⚙️
Tabla reputation_objectives: description, target_score (0-100), priority (LOW/MEDIUM/HIGH/CRITICAL)
🔗
Relationships: ReputationObjective->study(), Study->reputationObjectives()
🔎
Factory + Seeder: 12 objetivos distribuidos en 3 estudios STRATEGIC
⚠️
Validación: Solo estudios en modo STRATEGIC pueden tener objetivos
🎯
Prioridades: 4 niveles con distribución 50% MEDIUM, 25% HIGH, 15% LOW, 10% CRITICAL
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🔍
FEATURE: Sistema completo de keywords (primarias + variantes + exclusiones)
⚙️
Tablas: keywords, keyword_variants, keyword_exclusions con relaciones study_id
🔎
Seeder: 45 keywords (15 por estudio) con 3 variantes y 2 exclusiones cada una
🔗
Relationships: Study->keywords(), Keyword->variants/exclusions/mentions()
📊
Estadísticas: total_mentions calculado dinámicamente desde tabla mentions
✅
Uso: Sistema listo para scraping y análisis de menciones
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🔎
FEATURE: Modelo de menciones con RRI V2 completo
⚙️
Tabla mentions: 18 columnas incluyendo scores, sentimientos, y metadata
🔗
Relationships: Mention->study(), Mention->keyword(), study/keyword inversos
📊
Cálculo RRI: think_score (40%), feel_score (28%), do_score (20%), align_score (12%)
⚠️
MentionObserver: Auto-cálculo de RRI en eventos save/update
🎯
Enums: DriverEnum (7 drivers), BehaviorEnum (5 behaviors)
🔍
Índices optimizados: content_hash unique, (study_id, collected_at), (study_id, rri_final)
🌐
Campos: source_type (NEWS_MEDIA/SOCIAL_MEDIA/BLOG/FORUM/DARKWEB/VIDEO/PODCAST/OTHER), content, URL, fecha colección
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
👥
FEATURE: Roles de usuario a nivel de estudio con tabla pivot user_study
🔉
Roles: OWNER (control total), COLLABORATOR (edición), VIEWER (solo lectura)
🔗
Many-to-many: User <-> Study con columna 'role' en pivot
🔎
Factory + Seeder: Asignación automática de usuarios a estudios
⚡
Métodos: User->studies(), Study->users() con withPivot('role')
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
📜
FEATURE: Modelo Study con modos ANALYTICAL y STRATEGIC
⚙️
Migración: Tabla studies con 8 campos (name, description, mode, active, config)
🔗
Relationships: Study->user() (belongsTo), User->studies() (hasMany)
🔎
Factory + Seeder: 3 estudios (2 ANALYTICAL, 1 STRATEGIC) con configuración JSON
⚡
Config: sources (WEB, SOCIAL_MEDIA, DARKWEB), languages, search params
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🔉
FEATURE: Sistema de logs de auditoría compatible con ENS
⚙️
Tabla security_logs: action, user_id, ip_address, user_agent, details (JSON)
🔎
Acciones: LOGIN, LOGOUT, ACCESS, CREATE, UPDATE, DELETE, API_REQUEST
🔍
Índices: (user_id, created_at), (action, created_at) para queries rápidas
⚡
Modelo SecurityLog con cast JSON para 'details'
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
👥
FEATURE: Modelo User extendido con roles (ADMIN, ANALYST, VIEWER, API)
⚙️
Migración: Campo 'role' tipo enum en tabla users
🔎
Factory + Seeder: 10 usuarios (1 admin, 3 analistas, 3 viewers, 3 usuarios API)
🔉
Hashing contraseñas: Bcrypt por defecto en Laravel 11
⚡
Configuración: Guardia 'web' para autenticación de sesión
copied = false, 2000)"
class="p-2 text-fg-muted dark:text-fg-muted hover:text-primary-600 dark:hover:text-primary-400 hover:bg-bg-muted dark:hover:bg-bg-muted rounded-lg transition-colors relative"
title="Copiar enlace"
>
🎉
Inicialización del proyecto RepAttention Backend v3
⚙️
Laravel 12 con PHP 8.2, SQLite desarrollo, MySQL producción
⚡
Configuración base: Vite, TailwindCSS 4, SCSS, Alpine.js
🔥
Dependencias: JWT (tymon/jwt-auth), Laravel Pail, Scramble API Docs
🗄️
Migraciones base: users, cache, jobs, sessions
📚
Documentación: README.md
🔧
Scripts Composer: setup, dev, test para flujo de desarrollo