Vue d'ensemble du SHL GM Dashboard : carte d'équipe des Edmonton Blizzard avec une barre d'utilisation du plafond salarial, à côté d'un widget de classement, du calendrier et des actions rapides

SHL GM Dashboard

Projet personnel · En développement actif

juillet à septembre 2026Projet solo
Diagramme d'architecture : l'API du portail et Google Sheets alimentent quatre routes de synchronisation vers Postgres, que l'application Next.js App Router consulte, en plus de lectures en direct de l'index de simulation de la ligue, pour servir la connexion des DG
Deux chemins vers l'application : quatre routes de synchronisation déclenchées manuellement chargent l'API du portail et Google Sheets dans Postgres, tandis que le classement et les meneurs en direct interrogent directement l'index de simulation.

Le projet

La Simulation Hockey League est une ligue fantaisiste gérée par sa communauté, où les DG dirigent les équipes : signer des contrats, rester sous le plafond, échanger des choix. Ce qu'ils doivent savoir est réparti entre une API de portail de forum, l'index de simulation de la ligue et des feuilles Google partagées, donc répondre à « puis-je me permettre ce joueur? » veut dire ouvrir quatre onglets et faire le calcul à la main. Le tableau de bord y répond derrière une seule connexion : effectifs, contrats avec une projection de plafond salarial sur quatre saisons, classement en direct, choix de repêchage, échanges et messagerie entre DG. C'est une application Next.js App Router sur PostgreSQL via Prisma.

Ma contribution

Projet solo, donc tout : le schéma Postgres, la connexion avec sa file d'approbation administrateur et les rôles par équipe, quatre routes de synchronisation depuis l'API du portail et des exports de feuilles de calcul, les pages d'équipe, la projection de plafond salarial, les propositions d'échange avec contre-offres, la file de révision des contrats et le journal d'audit en dessous.

Le plus difficile

Le plus difficile, c'est que l'application ne possède pas encore ses données. Les contrats sont encore rédigés dans une feuille de calcul puis synchronisés, mais l'objectif est qu'un DG signe un joueur directement dans l'application, donc un contrat approuvé doit survivre à la prochaine synchronisation plutôt que d'être écrasé par une ligne de feuille plus ancienne. Chaque approbation est conservée sous forme d'empreinte, et chaque synchronisation classe la ligne de la feuille par rapport à elle : convergée, divergée ou illisible, parce qu'une ligne que l'analyseur ne peut pas lire est un problème différent d'une ligne en désaccord.

Chaque règle des chemins d'écriture existe parce qu'en briser une a causé un vrai bug. Le rôle et l'équipe sont relus dans la transaction plutôt que pris de la session, puisqu'un administrateur a pu les modifier. Les préconditions vivent dans la clause WHERE de la mise à jour, et zéro ligne modifiée compte comme un conflit, parce qu'une vérification dans une instruction séparée est une vérification que deux appelants peuvent tous les deux franchir. Les transactions sont sérialisables, et un conflit renvoie un 409 plutôt que de réessayer : une nouvelle tentative avec une autorisation périmée transformerait une action refusée en action acceptée.

Ce que je changerais

La synchronisation est encore manuelle : un administrateur appuie sur un bouton et rien n'est planifié. Les statistiques sont jumelées aux joueurs par un nom normalisé, donc un doublon ou un renommage en jeu créerait une correspondance erronée en silence; un identifiant stable demanderait que la ligue en expose un. La prochaine étape est la signature des contrats dans l'application, ce qui est toute la raison pour laquelle les contrats résident dans Postgres.

Feuille de plafond salarial pour toute la ligue : 24 équipes avec joueurs signés, plafond utilisé, marge disponible et trois saisons de projections
La feuille de plafond salarial de toute la ligue, triée par marge restante. Le plafond utilisé vient de la feuille de budget; les colonnes S90 à S92 sont projetées à partir des saisons de contrat, donc un tiret signifie que rien n'est signé aussi loin.
Page des contrats listant chaque joueur de l'effectif avec position, type de contrat, durée et salaire, chaque ligne avec un bouton Proposer
Chaque joueur de l'effectif avec sa durée et son salaire. Proposer envoie un contrat à la file de révision de l'administrateur, le chemin destiné à remplacer la modification manuelle de la feuille.
← Tous les projets