# Algorithme de Découverte Veza > **Version** : v0.12.9 > **Dernière mise à jour** : 2026-03-12 > **Référence** : ORIGIN_BUSINESS_LOGIC.md §11, ORIGIN_FEATURES_REGISTRY.md F351-F375, ORIGIN_UI_UX_SYSTEM.md §13-14 --- ## Principes fondamentaux L'algorithme de découverte de Veza est conçu selon des principes éthiques stricts : 1. **Chronologique, pas algorithmique** — Le feed et la découverte sont ordonnés par date de création (du plus récent au plus ancien). Aucun critère d'engagement (play count, likes, partages) n'influence l'ordre d'affichage. 2. **Pas de ML/IA** — Aucun algorithme de machine learning (collaborative filtering, content-based filtering, analyse prédictive) n'est utilisé. La découverte repose exclusivement sur des mécanismes déclaratifs et humains. 3. **Visibilité égale** — Un artiste émergent avec 0 écoutes a exactement la même chance d'apparaître qu'un artiste établi avec des millions d'écoutes, à condition qu'il soit dans le même genre/tag et que son contenu soit plus récent. 4. **Métriques privées** — Les compteurs d'écoutes, likes et followers ne sont JAMAIS visibles publiquement. Ils sont réservés exclusivement au créateur dans son tableau de bord analytics. --- ## Mécanismes de découverte ### 1. Feed personnel (chronologique) **Implémentation** : `internal/core/feed/service.go` Le feed d'un utilisateur affiche les tracks des artistes qu'il suit, triées par `created_at DESC`. ``` Requête : SELECT tracks.* FROM tracks INNER JOIN follows ON follows.followed_id = tracks.creator_id WHERE follows.follower_id = :user_id ORDER BY tracks.created_at DESC, tracks.id DESC ``` Aucun facteur de popularité n'intervient. L'ordre est strictement chronologique. ### 2. Découverte par genre (F353) **Implémentation** : `internal/core/discover/service.go` — `GetTracksByGenre()` Browse par genre avec pagination curseur. Tri : `created_at DESC, id DESC`. ``` Requête : SELECT tracks.* FROM tracks INNER JOIN track_genres ON track_genres.track_id = tracks.id WHERE track_genres.genre_slug = :slug AND tracks.status = 'completed' AND tracks.is_public = true ORDER BY tracks.created_at DESC, tracks.id DESC ``` ### 3. Découverte par tag (F353) **Implémentation** : `internal/core/discover/service.go` — `GetTracksByTag()` Même principe que par genre, avec les tags déclarés par l'artiste. ### 4. Nouveautés des genres suivis (F355) **Implémentation** : `internal/core/discover/service.go` — `GetTracksFromFollowedGenres()` Affiche les tracks récentes dans les genres que l'utilisateur suit. Tri chronologique. ### 5. Playlists éditoriales (F141) **Implémentation** : `internal/core/discover/service.go` — `GetEditorialPlaylists()` Playlists créées manuellement par l'équipe de curation. Aucune génération automatique. ### 6. Recherche textuelle (F375) **Implémentation** : - PostgreSQL : `internal/services/search_service.go` (ILIKE pattern matching) - Elasticsearch : `internal/elasticsearch/search_service.go` (BM25 + fuzziness) La recherche utilise la pertinence textuelle (BM25 sur Elasticsearch, ILIKE sur PostgreSQL). Le commentaire dans le code est explicite : ```go // F364: fuzziness for typo tolerance; no boost by popularity (ethical) ``` Les champs boostés sont `title^2` et `artist^2` — c'est un boost de pertinence textuelle, PAS de popularité. --- ## Ce qui est explicitement INTERDIT | Mécanisme | Raison de l'interdiction | Référence | |-----------|-------------------------|-----------| | Collaborative filtering | Optimise la rétention, pas la découverte authentique | ORIGIN_BUSINESS_LOGIC.md §11 | | Content-based filtering ML | Crée des bulles de filtrage | ORIGIN_BUSINESS_LOGIC.md §11 | | Analyse prédictive du comportement | Manipulation de l'engagement | ORIGIN_BUSINESS_LOGIC.md §11 | | Trending basé sur play counts | Favorise les artistes établis | ORIGIN_UI_UX_SYSTEM.md §13 | | "X personnes écoutent maintenant" | Dark pattern FOMO | ORIGIN_UI_UX_SYSTEM.md §13 | | Compteurs publics de followers | Biais de preuve sociale | ORIGIN_UI_UX_SYSTEM.md §13 | | Leaderboards/classements | Gamification interdite | CLAUDE.md règle #3 | | Badges de performance | XP/streaks interdits | CLAUDE.md règle #3 | --- ## Garanties éthiques testées Les tests suivants vérifient en continu le respect de ces principes : | Test | Fichier | Ce qu'il vérifie | |------|---------|-----------------| | `TestDiscovery_NoPlayCountBias_GenreBrowse` | `discover/ethical_bias_test.go` | Genre browse : ordre chronologique, pas par play count | | `TestDiscovery_NoPlayCountBias_TagBrowse` | `discover/ethical_bias_test.go` | Tag browse : même vérification | | `TestDiscovery_EmergingArtistVisibility` | `discover/ethical_bias_test.go` | Artiste 0 plays non défavorisé | | `TestDiscovery_MetricsNotExposedInJSON` | `discover/ethical_bias_test.go` | play_count/like_count absents du JSON | | `TestSearch_ArtistZeroPlays_Discoverable` | `services/ethical_search_test.go` | Artiste 0 plays trouvable par nom | | `TestSearch_ZeroPlaysTrack_NotFilteredOut` | `services/ethical_search_test.go` | Track 0 plays non filtré | | `TestSearch_DefaultSortIsChronological` | `services/ethical_search_test.go` | Tri par défaut = chronologique | | `TestSearch_NoPopularityBias_InDefaultRanking` | `services/ethical_search_test.go` | Pas de biais popularité dans le ranking par défaut | --- ## Audit et transparence Cet algorithme est : - **Documenté** : ce fichier constitue la documentation publique - **Auditable** : le code source est lisible et les requêtes SQL sont explicites - **Testé** : les tests éthiques ci-dessus sont exécutés en CI - **Déterministe** : pas de composante aléatoire ou opaque Toute modification de l'algorithme de découverte doit passer les tests éthiques existants et être documentée ici.