Files
AudiOhm/backend/LIBRARY_DEPLOYMENT.md
root 801e6a050b prod: UI Optimisée mise en production
- Documentation archivée et réorganisée
- Backend: Ajout tests, migrations, library service, rate limiting
- Frontend: Suppression Flutter, focus sur interface web HTML/JS
- Tailwind CSS ajouté pour le style
- Améliorations UX et corrections bugs

Generated with [Claude Code](https://claude.com/claude-code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
2026-01-20 09:56:39 +00:00

7.9 KiB

Guide de Déploiement - Module Bibliothèque

Checklist de Déploiement

1. Migration de la Base de Données

Le module bibliothèque nécessite deux nouvelles tables. Exécutez les commandes suivantes:

cd /opt/audiOhm/backend

# Option 1: Utiliser Alembic (recommandé en production)
alembic revision --autogenerate -m "Add library tables (listening_history, liked_tracks)"
alembic upgrade head

# Option 2: Recréer la base (environnement de développement uniquement)
# Attention: Cela efface toutes les données existantes!
python -c "from app.core.database import init_db; import asyncio; asyncio.run(init_db())"

2. Vérification de l'Installation

# Exécuter les tests
python3 test_library_features.py

# Vérifier que tous les tests passent (6/6)

3. Redémarrage du Serveur

# Arrêter le serveur existant
pkill -f "uvicorn app.main:app"

# Démarrer le nouveau serveur
cd /opt/audiOhm/backend
python -m app.main
# OU
uvicorn app.main:app --host 0.0.0.0 --port 8000 --reload

4. Vérification des Endpoints

# Vérifier que le serveur répond
curl http://localhost:8000/health

# Vérifier la documentation OpenAPI
curl http://localhost:8000/api/openapi.json | grep -A 5 "/api/v1/library"

# Tester un endpoint (nécessite un token JWT valide)
curl -X GET http://localhost:8000/api/v1/library/stats \
  -H "Authorization: Bearer YOUR_TOKEN"

Structure des Tables

Table listening_history

CREATE TABLE listening_history (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    track_id UUID NOT NULL REFERENCES tracks(id) ON DELETE CASCADE,
    played_for INTEGER NOT NULL DEFAULT 0,
    completed BOOLEAN NOT NULL DEFAULT FALSE,
    source VARCHAR(50),
    played_at TIMESTAMP NOT NULL DEFAULT NOW(),
    created_at TIMESTAMP NOT NULL DEFAULT NOW()
);

-- Index pour les requêtes fréquentes
CREATE INDEX ix_listening_history_user_played
    ON listening_history(user_id, played_at DESC);

CREATE INDEX ix_listening_history_user_track
    ON listening_history(user_id, track_id);

CREATE INDEX ix_listening_history_user_id
    ON listening_history(user_id);

CREATE INDEX ix_listening_history_track_id
    ON listening_history(track_id);

CREATE INDEX ix_listening_history_played_at
    ON listening_history(played_at DESC);

Table liked_tracks

CREATE TABLE liked_tracks (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
    track_id UUID NOT NULL REFERENCES tracks(id) ON DELETE CASCADE,
    notes VARCHAR(1000),
    created_at TIMESTAMP NOT NULL DEFAULT NOW(),
    updated_at TIMESTAMP NOT NULL DEFAULT NOW(),
    CONSTRAINT unique_user_track UNIQUE (user_id, track_id)
);

-- Index pour les requêtes fréquentes
CREATE INDEX ix_liked_tracks_user_track
    ON liked_tracks(user_id, track_id);

CREATE INDEX ix_liked_tracks_user_id
    ON liked_tracks(user_id);

CREATE INDEX ix_liked_tracks_track_id
    ON liked_tracks(track_id);

CREATE INDEX ix_liked_tracks_created_at
    ON liked_tracks(created_at DESC);

Configuration Requise

Variables d'Environnement

Aucune variable d'environnement supplémentaire n'est requise. Le module utilise les variables existantes:

  • DATABASE_URL: Connection string PostgreSQL
  • REDIS_URL (optionnel): Pour le cache futur

Dépendances Python

Toutes les dépendances sont déjà installées. Le module utilise:

  • fastapi: Framework API
  • sqlalchemy: ORM de base de données
  • pydantic: Validation des données
  • asyncpg: Driver PostgreSQL asynchrone

Performance et Optimisation

1. Index de Base de Données

Les index sont déjà définis dans les modèles et seront créés automatiquement par Alembic.

2. Cache (Optionnel)

Pour améliorer les performances, vous pouvez ajouter du cache Redis:

# Dans library_service.py
from app.core.cache import cache_manager

@cache_manager.cache(ttl=300)  # Cache 5 minutes
async def get_library_stats(self, user_id: UUID) -> dict:
    # ... code existant ...

3. Partitionnement (Futur)

Pour les bases de données avec beaucoup d'historique, envisagez le partitionnement:

-- Partitionnement mensuel de listening_history
CREATE TABLE listening_history_2026_01 PARTITION OF listening_history
    FOR VALUES FROM ('2026-01-01') TO ('2026-02-01');

Surveillance et Logs

Métriques à Surveiller

  1. Nombre d'entrées d'historique par utilisateur

    SELECT user_id, COUNT(*) as total
    FROM listening_history
    GROUP BY user_id
    ORDER BY total DESC
    LIMIT 10;
    
  2. Morceaux les plus likés

    SELECT track_id, COUNT(*) as like_count
    FROM liked_tracks
    GROUP BY track_id
    ORDER BY like_count DESC
    LIMIT 10;
    
  3. Croissance de l'historique

    SELECT DATE(played_at) as date, COUNT(*) as count
    FROM listening_history
    GROUP BY DATE(played_at)
    ORDER BY date DESC
    LIMIT 30;
    

Alertes Recommandées

  • Taille de la table listening_history > 1M entrées
  • Temps de réponse moyen des endpoints > 500ms
  • Erreurs 500 sur les endpoints de bibliothèque

Sécurité

Permissions

Tous les endpoints:

  • Nécessitent une authentification JWT valide
  • Vérifient que l'utilisateur accède uniquement à ses propres données
  • Utilisent des requêtes paramétrées pour prévenir les injections SQL

Rate Limiting (Recommandé)

# Dans main.py
from slowapi import Limiter
from slowapi.util import get_remote_address

limiter = Limiter(key_func=get_remote_address)
app.state.limiter = limiter

@router.get("/library/history")
@limiter.limit("60/minute")
async def get_listening_history(...):
    ...

Rollback Plan

En cas de problème, voici comment revenir en arrière:

1. Désactiver les Routes

# Dans main.py, commenter la ligne:
# app.include_router(library.router, prefix=settings.API_V1_PREFIX, tags=["library"])

2. Supprimer les Tables (si nécessaire)

# Se connecter à PostgreSQL
psql $DATABASE_URL

# Supprimer les tables
DROP TABLE IF EXISTS listening_history CASCADE;
DROP TABLE IF EXISTS liked_tracks CASCADE;

3. Redémarrer le Serveur

pkill -f "uvicorn app.main:app"
python -m app.main

Tests Post-Déploiement

1. Tests Manuels

# Récupérer un token JWT
TOKEN=$(curl -X POST http://localhost:8000/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{"email":"test@example.com","password":"password"}' \
  | jq -r '.access_token')

# Tester les endpoints
curl -X GET http://localhost:8000/api/v1/library/stats \
  -H "Authorization: Bearer $TOKEN"

curl -X GET http://localhost:8000/api/v1/library/liked \
  -H "Authorization: Bearer $TOKEN"

2. Tests Automatisés

cd /opt/audiOhm/backend
python3 test_library_features.py

Maintenance

Tâches Planifiées

  1. Nettoyage de l'historique ancien (optionnel)

    # Tâche mensuelle pour archiver/épurér les données > 1 an
    async def cleanup_old_history():
        cutoff = datetime.utcnow() - timedelta(days=365)
        await library_service.clear_listening_history(
            user_id=None,  # Tous les utilisateurs
            before_date=cutoff
        )
    
  2. Recalcul des statistiques (si cache utilisé)

    # Tâche hebdomadaire
    async def refresh_stats_cache():
        # Invalider le cache des stats
        await cache_manager.clear_pattern("library_stats:*")
    

Support

En cas de problème:

  1. Vérifier les logs: journalctl -u audiOhm-backend -f
  2. Vérifier la connexion BD: psql $DATABASE_URL
  3. Exécuter les tests: python3 test_library_features.py
  4. Consulter la documentation: LIBRARY_IMPLEMENTATION.md

Prochaine Étape

Une fois le déploiement réussi:

  1. Informer l'équipe frontend des nouveaux endpoints
  2. Partager le guide API: LIBRARY_API_GUIDE.md
  3. Surveiller les métriques pendant 24-48h
  4. Collecter les feedbacks utilisateurs