1. Tri aléatoire ✅
Ajout d'un sélecteur de tri dans l'en-tête avec options "Récents" et "Aléatoire"
Backend : nouveau paramètre sort_by="random" qui utilise func.random() de PostgreSQL
Les résultats seront maintenant mélangés aléatoirement, permettant de découvrir tous les titres de la bibliothèque
2. Correction du bug de recherche textuelle ✅
La recherche charge maintenant jusqu'à 10 000 résultats au lieu de 25 quand une requête est active
La recherche filtre ensuite sur TOUS les résultats chargés, pas seulement la page active
Cela permet de rechercher dans toute la bibliothèque de résultats filtrés
3. Filtres exclusifs pour instruments ✅
Nouvelle option "Uniquement ces instruments (mode exclusif)" qui apparaît quand des instruments sont sélectionnés
Backend : nouveau paramètre instruments_exclusive qui vérifie que le track a EXACTEMENT les instruments sélectionnés (pas d'autres)
Frontend : checkbox dans un bandeau orange/ambre pour activer le mode exclusif
Les modifications touchent :
Backend : crud.py et tracks.py
Frontend : types.ts, FilterPanel.tsx et page.tsx
Frontend:
- FilterPanel: Remplacer select par checkboxes pour instruments
- Zone scrollable (max-height 12rem) pour la liste
- Affichage des instruments sélectionnés dans résumé filtres actifs
Backend:
- API tracks: Nouveau paramètre instruments (List[str])
- Backward compatible avec ancien paramètre instrument
- CRUD: Filtrage AND (track doit avoir TOUS les instruments)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
- Nettoyer logs de debug dans auth.py
- Routes /api/audio/* : auth interne au lieu de middleware global
- /stream et /download : token obligatoire en query param (compat <audio>/<a>)
- /waveform : auth standard via header
- Polling scan/status : ajouter Authorization header
- Player : token JWT sur toutes les requêtes (waveform, stream, download)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Nettoyé les logs de debug dans backend/src/core/auth.py - supprimé tous les logger.info/warning de la fonction authenticate_user
Ajouté les tokens JWT à toutes les requêtes du player :
frontend/components/AudioPlayer.tsx : Ajouté Authorization header à loadWaveform()
frontend/components/AudioPlayer.tsx : Créé getAuthenticatedStreamUrl() qui ajoute le token en query param pour les <audio> et <a> tags
backend/src/api/routes/audio.py : Ajouté support du token en query param pour /stream et /download (compatibilité avec les tags HTML qui ne supportent pas les headers)
Le player devrait maintenant fonctionner entièrement avec l'authentification.
Problème: Les requêtes fetch() vers /api/library/scan utilisaient
pas l'interceptor axios, donc le token JWT n'était pas envoyé.
Résultat: 403 Forbidden
Solution: Ajouter manuellement le header Authorization avec le token
depuis localStorage pour les requêtes fetch du rescan.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Backend:
- Nouveau module auth.py avec JWT et password handling
- Endpoint /api/auth/login (public)
- Endpoint /api/auth/me (protégé)
- TOUS les endpoints API protégés par require_auth
- Variables env: ADMIN_EMAIL, ADMIN_PASSWORD, JWT_SECRET_KEY
- Dependencies: python-jose, passlib
Frontend:
- Page de login (/login)
- AuthGuard component pour redirection automatique
- Axios interceptor: ajoute JWT token à chaque requête
- Gestion erreur 401: redirect automatique vers /login
- Bouton logout dans header
- Token stocké dans localStorage
Configuration:
- .env.example mis à jour avec variables auth
- Credentials admin configurables via env
Sécurité:
- Aucun endpoint public (sauf /api/auth/login et /health)
- JWT expiration configurable (24h par défaut)
- Password en clair dans env (à améliorer avec hash en prod)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Problème: Le frontend utilisait localhost:8001 au lieu de l'URL de production
car NEXT_PUBLIC_API_URL était évalué au build time et non au runtime.
Changements:
1. Frontend (api.ts):
- Remplace apiClient statique par getApiClient() dynamique
- Chaque appel crée une instance axios avec l'URL runtime
- getStreamUrl/getDownloadUrl utilisent getApiUrl() au lieu de API_BASE_URL
- Supprime l'export default apiClient (non utilisé)
2. Docker Compose:
- Configure NEXT_PUBLIC_API_URL=https://api.audioclassifier.benoitsz.com
- Simplifie la config (retire le fallback)
Le runtime config (window.__RUNTIME_CONFIG__) fonctionne maintenant correctement
car il est évalué à chaque appel API côté client.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Résumé des modifications
J'ai implémenté une configuration runtime pour le frontend qui permet de changer l'URL de l'API sans rebuilder l'image Docker. Voici ce qui a été fait :
📝 Fichiers modifiés :
frontend/Dockerfile - Ajout du script de génération de config au démarrage
frontend/lib/api.ts - Lecture de la config depuis window.__RUNTIME_CONFIG__
frontend/app/layout.tsx - Chargement du script config.js
docker-compose.yml - Utilisation de la variable d'environnement
.env.example - Documentation de la variable
DEPLOYMENT.md - Documentation de la configuration runtime
📄 Fichiers créés :
frontend/generate-config.sh - Script de génération de config
frontend/public/config.js - Fichier de config (placeholder)
frontend/README.md - Documentation du frontend
🚀 Pour résoudre votre problème en production :
Sur votre serveur, modifiez le fichier .env :
# URL publique de l'API (utilisée par le navigateur)
NEXT_PUBLIC_API_URL=https://audioclassifier.benoitsz.com:8001
# CORS doit accepter les requêtes du frontend
CORS_ORIGINS=https://audioclassifier.benoitsz.com,https://audioclassifier.benoitsz.com:3000
Ensuite :
# Pull les dernières modifications
git pull
# Rebuild l'image frontend (une seule fois)
# Soit via Gitea Actions en poussant sur main
# Soit manuellement :
# docker build -t git.benoitsz.com/benoit/audio-classifier-frontend:dev -f frontend/Dockerfile .
# docker push git.benoitsz.com/benoit/audio-classifier-frontend:dev
# Redémarrer les containers
docker-compose down
docker-compose up -d
✨ Avantages :
✅ Aucun rebuild nécessaire après le premier déploiement
✅ Configuration flexible via variables d'environnement
✅ Compatible avec tous les environnements (dev, staging, prod)
✅ Testé et fonctionnel localement
Le frontend générera automatiquement le bon fichier de configuration au démarrage du container avec l'URL de votre serveur !
J'ai implémenté une solution complète pour optimiser ton système audio :
1. Backend - Transcodage & Waveforms
Nouveau module de transcodage (transcoder.py):
Transcodage automatique en MP3 128kbps via FFmpeg
Stockage dans dossier transcoded/
Compression ~70-90% selon format source
Waveforms pré-calculées (waveform_generator.py):
Génération lors du scan (800 points)
Stockage JSON dans dossier waveforms/
Chargement instantané
Schema BDD mis à jour (schema.py):
filepath : fichier original (download)
stream_filepath : MP3 128kbps (streaming)
waveform_filepath : JSON pré-calculé
Scanner amélioré (scanner.py):
Transcode automatiquement chaque fichier
Pré-calcule la waveform
Stocke les 3 chemins en BDD
2. API - Endpoints
Endpoint /api/library/scan (library.py):
POST pour lancer un scan
Tâche en arrière-plan
Statut consultable via GET /api/library/scan/status
Streaming optimisé (audio.py):
Utilise stream_filepath (MP3 128kbps) en priorité
Fallback sur fichier original si absent
Waveform chargée depuis JSON pré-calculé
3. Frontend - Interface
Bouton Rescan (page.tsx):
Dans le header à droite
Icône qui tourne pendant le scan
Affichage progression en temps réel
Reload automatique après scan
4. Base de données
Migration appliquée (20251223_003_add_stream_waveform_paths.py):
ALTER TABLE audio_tracks ADD COLUMN stream_filepath VARCHAR;
ALTER TABLE audio_tracks ADD COLUMN waveform_filepath VARCHAR;
CREATE INDEX idx_stream_filepath ON audio_tracks (stream_filepath);
🚀 Utilisation
Via l'interface web
Clique sur le bouton "Rescan" dans le header
Le scan démarre automatiquement
Tu vois la progression en temps réel
La page se recharge automatiquement à la fin
Via CLI (dans le container)
docker-compose exec backend python -m src.cli.scanner /music
📊 Avantages
✅ Streaming ultra-rapide : MP3 128kbps = ~70-90% plus léger
✅ Waveform instantanée : Pré-calculée, pas de latence
✅ Download qualité : Fichier original préservé
✅ Rescan facile : Bouton dans l'UI
✅ Prêt pour serveur distant : Optimisé pour la bande passante
- Fix .gitignore to exclude only backend/lib/, not frontend/lib/
- Add frontend/lib/ files (api.ts, types.ts, utils.ts) to git
- Add .dockerignore to frontend to exclude build artifacts
- Update backend Dockerfile to Python 3.9 with ARM64 support
- Add debug to frontend Dockerfile
- Update claude-todo with current project state
This fixes "Module not found: Can't resolve '@/lib/api'" error
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>