diff --git a/.claude/settings.local.json b/.claude/settings.local.json
index f19c67b..34fca85 100644
--- a/.claude/settings.local.json
+++ b/.claude/settings.local.json
@@ -27,7 +27,18 @@
"Bash(tee:*)",
"Bash(systemctl start:*)",
"Bash(systemctl enable:*)",
- "Bash(systemctl is-enabled:*)"
+ "Bash(systemctl is-enabled:*)",
+ "Bash(for f in dashboard/templates/*.html)",
+ "Bash(do)",
+ "Bash(if grep -q \"extends \"\"base.html\"\"\" \"$f\")",
+ "Bash(then)",
+ "Bash(echo:*)",
+ "Bash(else)",
+ "Bash(fi)",
+ "Bash(done)",
+ "Bash(xargs basename:*)",
+ "Bash(docker-compose down:*)",
+ "Bash(for:*)"
]
}
}
diff --git a/app/prompts/examples/by_category/productividad.yaml b/app/prompts/examples/by_category/productividad.yaml
index cdd8373..88a08c6 100644
--- a/app/prompts/examples/by_category/productividad.yaml
+++ b/app/prompts/examples/by_category/productividad.yaml
@@ -106,7 +106,7 @@ topics_to_cover:
- Automatización de tareas repetitivas
avoid:
- - "Levántate a las 5am" sin contexto
+ - '"Levántate a las 5am" sin contexto'
- Hustle culture tóxica
- Productividad como fin en sí misma
- Consejos que solo funcionan para privilegiados
diff --git a/app/prompts/platforms/x.yaml b/app/prompts/platforms/x.yaml
index 7378e91..bd62e86 100644
--- a/app/prompts/platforms/x.yaml
+++ b/app/prompts/platforms/x.yaml
@@ -68,7 +68,7 @@ avoid:
- Más de 2 hashtags
- Emojis excesivos
- Links en el medio del texto
- - "Hilo:" sin contenido de hilo real
+ - '"Hilo:" sin contenido de hilo real'
adaptation_rules: |
Cuando adaptes contenido para X:
diff --git a/app/prompts/templates/product_post.yaml b/app/prompts/templates/product_post.yaml
index cddce8e..f57250c 100644
--- a/app/prompts/templates/product_post.yaml
+++ b/app/prompts/templates/product_post.yaml
@@ -78,5 +78,5 @@ tone_guidelines:
- "¿Te interesa? Escríbenos para más detalles"
dont:
- "¡¡¡OFERTA INCREÍBLE!!!"
- - "ÚLTIMAS UNIDADES" (a menos que sea verdad)
+ - '"ÚLTIMAS UNIDADES" (a menos que sea verdad)'
- "Compra ahora antes de que se acabe"
diff --git a/app/services/ai/__init__.py b/app/services/ai/__init__.py
index 7e89e72..00391b3 100644
--- a/app/services/ai/__init__.py
+++ b/app/services/ai/__init__.py
@@ -9,16 +9,23 @@ Este módulo contiene los componentes del motor de generación de contenido:
- ContentValidator: Validación y scoring con IA
"""
-from app.services.ai.prompt_library import PromptLibrary
-from app.services.ai.context_engine import ContextEngine
-from app.services.ai.generator import ContentGeneratorV2
-from app.services.ai.platform_adapter import PlatformAdapter
-from app.services.ai.validator import ContentValidator
+from app.services.ai.prompt_library import PromptLibrary, prompt_library
+from app.services.ai.context_engine import ContextEngine, context_engine
+from app.services.ai.generator import ContentGeneratorV2, content_generator_v2
+from app.services.ai.platform_adapter import PlatformAdapter, platform_adapter
+from app.services.ai.validator import ContentValidator, content_validator
__all__ = [
+ # Classes
"PromptLibrary",
"ContextEngine",
"ContentGeneratorV2",
"PlatformAdapter",
"ContentValidator",
+ # Singleton instances
+ "prompt_library",
+ "context_engine",
+ "content_generator_v2",
+ "platform_adapter",
+ "content_validator",
]
diff --git a/app/services/ai/validator.py b/app/services/ai/validator.py
index 9e73f3a..f469f6b 100644
--- a/app/services/ai/validator.py
+++ b/app/services/ai/validator.py
@@ -261,11 +261,8 @@ class ContentValidator:
if not scoring_prompt:
scoring_prompt = self._default_scoring_prompt()
- # Renderizar prompt
- prompt = scoring_prompt.format(
- content=content,
- platform=platform
- )
+ # Renderizar prompt usando replace para evitar problemas con JSON
+ prompt = scoring_prompt.replace("{content}", content).replace("{platform}", platform)
# Llamar a DeepSeek
response = self.client.chat.completions.create(
@@ -340,7 +337,7 @@ CRITERIOS (suma = 100):
- CTA (0-10): ¿CTA claro si aplica?
RESPONDE EN JSON:
-{{"total": N, "breakdown": {{"hook_strength": N, "clarity": N, "actionability": N, "originality": N, "brand_voice": N, "cta_effectiveness": N}}, "feedback": "sugerencia"}}"""
+{"total": N, "breakdown": {"hook_strength": N, "clarity": N, "actionability": N, "originality": N, "brand_voice": N, "cta_effectiveness": N}, "feedback": "sugerencia"}"""
def _extract_score_from_text(self, text: str) -> Dict:
"""Extraer score de texto si falla JSON parsing."""
diff --git a/dashboard/templates/analytics.html b/dashboard/templates/analytics.html
index 42b6c24..881d63e 100644
--- a/dashboard/templates/analytics.html
+++ b/dashboard/templates/analytics.html
@@ -1,446 +1,256 @@
-
-
-
-
-
- Analytics - Social Media Automation
-
-
-
-
-
+{% extends "base.html" %}
+
+{% block title %}Analytics{% endblock %}
+
+{% block extra_head %}
+
+{% endblock %}
+
+{% block content %}
+
-
-
-
- Consultoría AS - Analytics
-
-
+
+
+
Analytics
+
Métricas y rendimiento de tus publicaciones
-
-
-
-
-
-
Dashboard de Analytics
-
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
Tendencia de Engagement
-
-
-
-
-