# 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: ```bash 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 ```bash # Exécuter les tests python3 test_library_features.py # Vérifier que tous les tests passent (6/6) ``` ### 3. Redémarrage du Serveur ```bash # 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 ```bash # 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` ```sql 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` ```sql 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: ```python # 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: ```sql -- 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** ```sql 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** ```sql 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** ```sql 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é) ```python # 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 ```python # 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) ```bash # 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 ```bash pkill -f "uvicorn app.main:app" python -m app.main ``` ## Tests Post-Déploiement ### 1. Tests Manuels ```bash # 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 ```bash cd /opt/audiOhm/backend python3 test_library_features.py ``` ## Maintenance ### Tâches Planifiées 1. **Nettoyage de l'historique ancien** (optionnel) ```python # 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é) ```python # 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