docs: Add comprehensive documentation for all new features

- FEATURES_OVERVIEW.md: Complete summary of all system features
- ANALYTICS.md: Analytics and reporting system documentation
- ODOO_INTEGRATION.md: Odoo ERP integration guide
- AB_TESTING.md: A/B testing system documentation
- CONTENT_RECYCLING.md: Content recycling system docs
- THREAD_SERIES.md: Thread series and scheduled posts
- IMAGE_TEMPLATES.md: Visual template system documentation

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-01-28 03:17:23 +00:00
parent ecc2ca73ea
commit e2882ce72b
7 changed files with 2099 additions and 0 deletions

267
docs/CONTENT_RECYCLING.md Normal file
View File

@@ -0,0 +1,267 @@
# Reciclaje de Contenido
Sistema para republica contenido exitoso y maximizar su alcance.
## Descripción
El reciclaje de contenido permite:
- Identificar posts con alto engagement
- Republicarlos con modificaciones opcionales
- Trackear rendimiento de versiones recicladas
- Automatizar el proceso de reciclaje
## Modelo de Datos
### RecycledPost
```python
RecycledPost:
id: int
original_post_id: int (FK -> posts)
new_post_id: int (FK -> posts)
recycle_number: int # 1, 2, 3... (veces reciclado)
modifications: JSON
# {"content_changed": true, "hashtags_updated": true, "image_changed": false}
modification_notes: str
original_engagement_rate: float
new_engagement_rate: float
status: str # pending, published, cancelled
reason: str # high_performer, evergreen, seasonal, manual
recycled_at: datetime
scheduled_for: datetime
```
### Campos en Post
```python
# Campos añadidos al modelo Post
is_recyclable: bool # Si puede ser reciclado (default True)
recycled_from_id: int (FK -> posts) # Post original si es reciclado
recycle_count: int # Veces que este post ha sido reciclado
```
## Configuración
```python
# En recycling_service.py
MIN_DAYS_SINCE_PUBLISH = 30 # No reciclar posts recientes
MIN_ENGAGEMENT_RATE = 2.0 # Mínimo 2% engagement
MAX_RECYCLE_COUNT = 3 # Máximo 3 veces por post
```
## API Endpoints
### GET /api/recycling/candidates
Obtiene posts candidatos para reciclar.
**Parámetros:**
- `platform` (str): Filtrar por plataforma
- `content_type` (str): Filtrar por tipo de contenido
- `min_engagement_rate` (float, default=2.0): Engagement mínimo
- `min_days` (int, default=30): Días desde publicación
- `limit` (int, default=20): Máximo candidatos
**Respuesta:**
```json
{
"candidates": [
{
"id": 123,
"content": "Tip: Usa IA para automatizar...",
"full_content": "...",
"content_type": "tip_tech",
"platforms": ["x"],
"published_at": "2024-12-01T10:00:00",
"days_since_publish": 58,
"engagement_rate": 4.5,
"recycle_count": 0,
"score": 3.8,
"metrics": {"likes": 150, "comments": 30}
}
],
"count": 10,
"filters": {
"min_engagement_rate": 2.0,
"min_days": 30
}
}
```
### POST /api/recycling/{post_id}
Recicla un post específico.
**Body (opcional):**
```json
{
"content": "Versión actualizada del contenido...",
"hashtags": ["#nuevo", "#hashtag"],
"image_url": "https://...",
"scheduled_for": "2025-02-01T10:00:00",
"platforms": ["x", "threads"],
"reason": "high_performer"
}
```
**Respuesta:**
```json
{
"message": "Post recycled successfully",
"success": true,
"new_post_id": 456,
"recycle_record_id": 1,
"scheduled_for": "2025-02-01T10:00:00",
"platforms": ["x", "threads"]
}
```
### POST /api/recycling/auto
Reciclaje automático de mejores posts.
**Parámetros:**
- `platform` (str, opcional): Plataforma específica
- `count` (int, default=1, max=5): Cantidad a reciclar
- `min_engagement_rate` (float, default=2.0)
**Respuesta:**
```json
{
"success": true,
"recycled": 2,
"posts": [
{
"original_id": 123,
"new_post_id": 456,
"engagement_rate": 4.5
}
]
}
```
### GET /api/recycling/history
Obtiene historial de reciclaje.
**Parámetros:**
- `original_post_id` (int, opcional): Filtrar por post original
- `limit` (int, default=50)
### POST /api/recycling/{post_id}/disable
Marca un post como no reciclable.
## Sistema de Puntuación
Los candidatos se puntúan con la fórmula:
```python
score = engagement_rate * recency_factor * recycled_penalty
donde:
recency_factor = min(days_since_publish / 90, 1.0)
recycled_penalty = 1 - (recycle_count * 0.2)
```
### Ejemplo
| Post | Engagement | Días | Reciclajes | Score |
|------|------------|------|------------|-------|
| A | 4.0% | 60 | 0 | 4.0 × 0.67 × 1.0 = 2.68 |
| B | 5.0% | 90 | 1 | 5.0 × 1.0 × 0.8 = 4.00 |
| C | 3.0% | 45 | 0 | 3.0 × 0.5 × 1.0 = 1.50 |
Post B tiene el score más alto.
## Tareas Programadas
### auto_recycle_content
- **Frecuencia:** Diario a las 2:00 AM
- **Función:**
- Busca 1 post por plataforma con engagement > 3%
- Programa reciclaje automático
- **Plataformas:** x, threads
## Flujo de Reciclaje
```
1. Identificar Candidatos
- Posts con > 30 días de antigüedad
- Engagement rate > 2%
- recycle_count < 3
- is_recyclable = true
2. Seleccionar por Score
- Ordenar por score descendente
3. Crear Post Reciclado
- Clonar contenido (o modificar)
- Establecer recycled_from_id
- Programar publicación
4. Registrar en RecycledPost
- Guardar relación
- Incrementar recycle_count del original
5. Publicar y Trackear
- Comparar new_engagement_rate vs original
```
## Razones de Reciclaje
| Razón | Descripción |
|-------|-------------|
| `high_performer` | Post con engagement alto |
| `evergreen` | Contenido atemporal relevante |
| `seasonal` | Contenido de temporada que regresa |
| `manual` | Reciclado manualmente |
## Ejemplo de Uso
```python
from app.services.recycling_service import recycling_service
# Buscar candidatos
candidates = await recycling_service.find_recyclable_posts(
platform="x",
min_engagement_rate=3.0,
limit=10
)
for candidate in candidates:
print(f"Post {candidate['id']}: {candidate['engagement_rate']}% - Score {candidate['score']}")
# Reciclar manualmente
result = await recycling_service.recycle_post(
post_id=123,
modifications={"content": "Versión actualizada..."},
reason="evergreen"
)
# Reciclaje automático
result = await recycling_service.auto_recycle(
platform="x",
count=2
)
```
## Mejores Prácticas
1. **Esperar suficiente tiempo:** Mínimo 30 días entre reciclajes
2. **Modificar ligeramente:** Actualiza hashtags o intro
3. **No abusar:** Máximo 3 reciclajes por post
4. **Monitorear:** Compara rendimiento nuevo vs original
5. **Contenido evergreen:** Prioriza contenido atemporal
## Tipos de Contenido Ideales para Reciclar
| Tipo | Ideal | Razón |
|------|-------|-------|
| Tips técnicos | ✅ | Siempre relevantes |
| Tutoriales | ✅ | Valor educativo permanente |
| Productos | ⚠️ | Si stock disponible |
| Promociones | ❌ | Fechas específicas |
| Efemérides | ❌ | Fechas específicas |
| Noticias | ❌ | Se vuelven obsoletas |