801e6a050b
- 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>
318 lines
7.9 KiB
Markdown
318 lines
7.9 KiB
Markdown
# 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
|