Owen / Portfolio

Télémétrie en temps réel

01%

Calibration des systèmes

Aller au contenu
Retour aux projetsRivality

Projet web

Mission / 01

Rivality

Événement web / Données live

Un affrontement EUW contre NA sur vingt jours, avec quarante-huit streamers et 20 400 € de dotation. Chaque match redessine la course en temps réel.

Rôle
Développeur full-stack
Année
2025
Équipe
Développement solo
RIVALITY // 1920 × 1080
Rivality — vue ordinateur
Rivality — vue tablette
Rivality — vue mobile
20
jours
48
streamers
2
régions
20 400 €
dotation

Technologies

  • Next.js 15
  • TypeScript
  • Supabase
  • Prisma
  • Tailwind CSS
  • Riot API
  • Twitch API

01.01

Un tournoi qui évolue en temps réel

Rivality était un vrai produit temps réel : 48 joueurs, 20 jours, des milliers de matchs et une communauté qui attend un classement qui bouge minute par minute. J’ai conçu le site et tout le pipeline de données pour garder l’expérience immédiate et lisible.

La plateforme transforme les signaux bruts de Riot et Twitch en un récit lisible : classements, variations de LP, performances par rôle, historique des matchs et totaux par équipe. Les mises à jour sont constantes, sans ralentir la consultation.

01.02 / Visual

Classements live et course par équipe

Les classements sont calculés depuis la base et se mettent à jour dès qu’un match est traité. Les joueurs sont triés par LP avec des règles de tie-break stables, et les totaux d’équipe sont agrégés pour visualiser la course EUW contre NA.

Comme l’interface lit un état mis en cache dans la base plutôt que d’appeler les API externes, les pages peuvent se rafraîchir très souvent tout en restant fluides pendant les pics de trafic.

Classement live des joueurs sur Rivality

01.03 / Process

Pipeline backend et couche de données

La plateforme transforme des données compétitives brutes en un hub de tournoi fiable et prêt pour le broadcast. La contrainte principale était claire : garder le site rapide et précis alors que les résultats et les streams évoluent en continu sur deux régions.

Toute l’ingestion externe est côté serveur via des routes cron protégées. Des tâches planifiées appellent les API Riot et Twitch, normalisent les réponses et stockent tout dans Supabase Postgres via Prisma. Le site ne lit que la base, ce qui protège les quotas et permet de servir le dernier état connu si une API tombe temporairement.

Le traitement est idempotent : relancer un job n’abîme pas les données et le système récupère proprement après un échec partiel.

  1. 01Découverte des nouveaux matchs
  2. 02Calcul asynchrone des LP et statistiques
  3. 03Snapshots périodiques pour les historiques
  4. 04Suivi du live et des viewers Twitch

01.04 / Visual

Des données brutes aux profils joueurs

Les mêmes données alimentent les statistiques par équipe et les profils individuels. Cette architecture évite les requêtes externes répétées et garantit une lecture cohérente dans toutes les vues.

Statistiques comparées des équipes Rivality
Comparaison des performances EUW et NA01 / 02

01.05

Intégrations Riot et Twitch

API Riot Games Utilisée pour l’historique de matchs, les rangs et les statistiques détaillées. Les données sont collectées par les crons, stockées dans la base, puis réutilisées partout — profils, classements et records — sans recontacter Riot depuis le front-end.

API Twitch Utilisée pour récupérer le statut live et le nombre de viewers. La plateforme met en avant les participants qui streament et permet de relier les moments compétitifs aux pics d’audience.

01.06 / Process

Rate limits et maîtrise des coûts

La stratégie consiste à séparer les appels API coûteux des lectures fréquentes et peu coûteuses. La base de données devient la source de vérité unique du site.

Résultat : un site réactif, sans dépendre de la latence des API ni dépasser les quotas.

  1. 01Appels centralisés dans les crons et workers serveur
  2. 02Retries avec backoff exponentiel
  3. 03Retraitement sûr des matchs incomplets
  4. 04Snapshots pour éviter les récupérations répétées

01.07

Défis techniques et solutions

Échelle et performance Faire tourner un tournoi multirégion pour 48 joueurs impose d’optimiser les requêtes en base, de traiter le travail d’arrière-plan par lots et de découpler l’interface des latences externes.

Cohérence Un match peut être découvert plusieurs fois, traité deux fois ou échouer en plein milieu. Le pipeline est conçu pour être idempotent : relancer un job ne corrompt jamais les données.

Fraîcheur Les classements se mettent à jour rapidement sans marteler l’API Riot : la base est actualisée et le site sert les résultats mis en cache.

Fiabilité et qualité des données Le pipeline inclut la détection des doublons, des upserts sûrs et des contrôles de cohérence. Les snapshots constituent aussi un historique vérifiable pour reconstruire les graphiques, comparer les états et repérer les anomalies.

01.08 / Visual

Le tournoi, écran par écran

Une dernière série de captures présente la page principale, le classement, les graphiques de statistiques et le panneau affiché à la fin de l’événement.

Page principale de Rivality
Page principale01 / 04