chartbastan/_bmad-output/implementation-artifacts/2-5-implémenter-le-calcul-d-energie-collective.md
2026-02-01 09:31:38 +01:00

6.9 KiB
Raw Blame History

Story 2.5: Implémenter le calcul d'énergie collective

Status: review

Acceptance Criteria

Given les données de sentiment sont disponibles (Twitter, Reddit, RSS) When le calcul d'énergie est exécuté Then il applique la formule : Score = (Positif - Négatif) × Volume × Viralité And il applique la pondération : Twitter 60%, Reddit 25%, RSS 15% And il applique la pondération temporelle (tweets récents plus importants) And le score final est entre 0 et 100

Given une source est indisponible (ex: Twitter down) When le calcul d'énergie est exécuté Then il utilise uniquement les sources disponibles avec pondération ajustée And le niveau de confiance est réduit (ex: 58% au lieu de 67%)

Tasks / Subtasks

  • Créer le module de calcul d'énergie (AC: #1)

    • Créer backend/app/ml/energy_calculator.py
    • Implémenter la formule de calcul d'énergie
    • Configurer les pondérations par source
    • Configurer la pondération temporelle
    • Normaliser le score final entre 0 et 100
  • Implémenter le calcul pondéré multi-sources (AC: #1)

    • Récupérer les scores de sentiment de Twitter (60%)
    • Récupérer les scores de sentiment de Reddit (25%)
    • Récupérer les scores de sentiment de RSS (15%)
    • Calculer le score pondéré final
    • Stocker le score d'énergie par équipe/match
  • Implémenter la pondération temporelle (AC: #1)

    • Configurer la fonction de décroissance temporelle
    • Tweets récents (1h) = poids 1.0
    • Tweets anciens (24h) = poids 0.5
    • Appliquer la pondération temporelle au calcul
    • Ajuster le score final
  • Créer les schémas de base de données pour scores d'énergie (AC: #1)

    • Créer la table energy_scores dans SQLite
    • Définir les colonnes: id, match_id, team_id, score, confidence, sources_used
    • Ajouter les colonnes pour les pondérations et métriques
    • Créer les indexes appropriés
    • Générer et appliquer les migrations
  • Implémenter le mode dégradé (AC: #2)

    • Détecter les sources indisponibles
    • Ajuster les pondérations proportionnellement
    • Réduire le niveau de confiance
    • Logger les sources utilisées/absentes
    • Tester le mode dégradé
  • Tester le calcul d'énergie (AC: #1, #2)

    • Tester le calcul avec toutes les sources
    • Tester le mode dégradé (source indisponible)
    • Vérifier la pondération temporelle
    • Valider que le score est entre 0 et 100
    • Tester la réduction de confiance

Dev Notes

Architecture Patterns et Contraintes

Stack Technique Imposé:

  • Formule: Score = (Positif - Négatif) × Volume × Viralité
  • Pondération: Twitter 60%, Reddit 25%, RSS 15%
  • Score final: Normalisé entre 0 et 100
  • Pondération temporelle: Tweets récents plus importants

Technical Requirements

Formule de Calcul:

def calculate_energy_score(match_id: int, team_id: int):
    # Récupérer les scores de sentiment par source
    twitter_score = get_twitter_sentiment(match_id, team_id)
    reddit_score = get_reddit_sentiment(match_id, team_id)
    rss_score = get_rss_sentiment(match_id, team_id)
    
    # Pondération par source
    weights = {
        'twitter': 0.60,
        'reddit': 0.25,
        'rss': 0.15
    }
    
    # Mode dégradé: ajuster les pondérations
    available_sources = get_available_sources()
    total_weight = sum(weights[s] for s in available_sources)
    adjusted_weights = {s: weights[s] / total_weight for s in available_sources}
    
    # Calcul du score pondéré
    weighted_score = (
        (twitter_score or 0) * adjusted_weights['twitter'] +
        (reddit_score or 0) * adjusted_weights['reddit'] +
        (rss_score or 0) * adjusted_weights['rss']
    )
    
    # Pondération temporelle
    time_weighted_score = apply_temporal_weighting(weighted_score, team_id)
    
    # Normalisation entre 0 et 100
    final_score = max(0, min(100, time_weighted_score * 100))
    
    # Calcul du niveau de confiance
    confidence = calculate_confidence(available_sources, total_weight)
    
    return {
        'score': final_score,
        'confidence': confidence,
        'sources_used': available_sources
    }

def apply_temporal_weighting(score: float, team_id: int) -> float:
    # Récupérer les tweets avec leurs timestamps
    tweets = get_tweets_with_timestamps(team_id)
    
    # Calculer le score temporellement pondéré
    now = datetime.now()
    weighted_sum = 0
    total_weight = 0
    
    for tweet in tweets:
        hours_ago = (now - tweet.created_at).total_seconds() / 3600
        time_weight = max(0.5, 1.0 - (hours_ago / 48))  # 1.0 à 0.5 sur 48h
        weighted_sum += tweet.sentiment_score * time_weight
        total_weight += time_weight
    
    return weighted_sum / total_weight if total_weight > 0 else score

File Structure

backend/
├── app/
│   ├── ml/
│   │   └── energy_calculator.py
│   ├── models/
│   │   └── energy_score.py
│   └── schemas/
│       └── energy_score.py

References

  • [Source: _bmad-output/planning-artifacts/epics.md#Story-2.5]

Dev Agent Record

Agent Model Used

GLM-4.7

Completion Notes List

  • Module de calcul d'énergie créé (backend/app/ml/energy_calculator.py)
  • Formule de calcul implémentée : Score = (Positif - Négatif) × Volume × Viralité
  • Pondération multi-sources configurée : Twitter 60%, Reddit 25%, RSS 15%
  • Pondération temporelle implémentée : tweets récents (1h) = poids 1.0, tweets anciens (24h+) = poids 0.5
  • Normalisation des scores entre 0 et 100
  • Mode dégradé implémenté : ajustement automatique des pondérations quand sources indisponibles
  • Modèle SQLAlchemy créé (backend/app/models/energy_score.py)
  • Schémas Pydantic créés (backend/app/schemas/energy_score.py)
  • Service d'énergie créé (backend/app/services/energy_service.py)
  • Migration Alembic créée (20260117_0004_create_energy_scores_table.py)
  • Tests unitaires complets créés pour le calculateur d'énergie
  • Tests manuels créés pour validation rapide
  • Fixtures pytest configurées dans conftest.py
  • Tous les critères d'acceptation satisfaits :
    • AC #1 : Formule de calcul correctement appliquée avec pondérations multi-sources et temporelles
    • AC #2 : Mode dégradé fonctionnel avec ajustement de confiance

File List

  • backend/app/ml/energy_calculator.py
  • backend/app/models/energy_score.py
  • backend/app/schemas/energy_score.py
  • backend/app/services/energy_service.py
  • backend/alembic/versions/20260117_0004_create_energy_scores_table.py
  • backend/tests/test_energy_calculator.py
  • backend/tests/test_energy_service.py
  • backend/tests/conftest.py
  • backend/tests/test_energy_manual.py
  • backend/app/models/__init__.py (modifié)
  • backend/app/schemas/__init__.py (modifié)