L'essentiel
- Le projet est un MVP mature et bien documenté, avec une architecture en couches propre : écrans, composants, logique métier isolée dans
lib/, backend Firebase, et un pipeline de vision consommé comme une source de données externe. - L'app ne fait aucune vision par ordinateur. Le couplage se fait par deux manifestes JSON stockés dans Firestore. Le stage 1 arrive par un script d'import manuel, le stage 2 tourne dans une Cloud Function Python qui embarque le code de l'équipe CV tel quel. Ce couplage est manuel et doit devenir automatique.
- La sécurité repose entièrement sur les règles Firestore, et deux Cloud Functions les contournent. Le classement Elo est calculé et écrit côté client, donc falsifiable. Ce sont les deux points à traiter avant tout élargissement.
- Il n'existe aucun environnement de staging. Les variantes dev et prod de l'app partagent le même projet Firebase, la même base et les mêmes fonctions.
- Le code mobile est de bonne qualité mais concentre trop de responsabilités dans deux fichiers, et conserve un chemin stage 2 mort dont la documentation parle encore comme du chemin actif.
- Une web app Next.js branchée sur le même Firebase est réaliste et recommandée, à condition de poser d'abord les rôles, les règles par rôle et le staging. La spec « Compo & Résa » et le web partagent le même modèle de données à concevoir une fois.
- Le site web antérieur, toujours en ligne sur squadfield.fr, est un autre produit sur un autre projet Firebase, avec une API sans authentification. Il ne peut pas servir de socle au web. Il faut le sécuriser ou l'éteindre, et rapatrier les pages légales que l'app mobile lui emprunte.
01Contexte du projet
Squadfield est une application mobile iOS et Android pour les joueurs de football à cinq dans des centres partenaires. Une caméra filme le match, un pipeline de vision par ordinateur l'analyse, et chaque joueur reçoit sur son téléphone une carte de match, ses statistiques individuelles, une comparaison avec les autres joueurs, des médailles, un archétype de jeu et un classement Elo par centre.
Le parcours joueur est le suivant : le capitaine qui a réservé reçoit un lien, chaque joueur ouvre l'app, colle le lien, se reconnaît sur une capture du match, le capitaine forme les équipes et saisit le score, puis la feuille de match est disponible pour tous.
Le produit est au stade MVP. Ses objectifs déclarés sont de valider l'expérience par des tests utilisateurs, de décrocher un premier contrat avec un centre partenaire et de servir de socle aux fonctionnalités suivantes. Une spec fonctionnelle datée du 9 septembre 2026 ajoute trois briques : ajout de joueurs et réseau d'amis, composition d'équipes, réservation de terrain avec paiement.
Chiffres du dépôt
| Élément | Volume | Remarque |
|---|---|---|
| Routes Expo Router | 43 | 3 onglets, 4 piles de navigation |
| Composants React | 54 | Regroupés par domaine |
Modules métier lib/ | 17 | 3 606 lignes, dont 1 929 dans match.ts |
| Fichiers de test Jest | 70 | Seuil de couverture 80 % imposé sur lib/ |
| Cloud Functions Node | 7 | 820 lignes, région europe-west1 |
| Codebase Python | 2 | 587 lignes de glue, code CV vendorisé à part |
| Console admin Next.js | 1 | 1 562 lignes, usage local uniquement |
| Locales | 2 | Français par défaut, anglais |
02Audit d'architecture
Stack et briques
| Couche | Technologie |
|---|---|
| App mobile | Expo SDK 54, React Native 0.81, React 19, Expo Router 6, NativeWind 4, Zustand + MMKV, Reanimated, Lottie |
| Backend | Firebase : Auth, Firestore, Storage, Hosting, Cloud Functions Node 20 et Python 3.12, région europe-west1 |
| Authentification | Lien magique par email via Resend, Google Sign-In, Apple Sign-In |
| Vision par ordinateur | Scoresphere, API agentcast.studio pour le stage 1, code stage 2 vendorisé dans le projet |
| Services tiers | Resend pour les emails, Replicate pour les rendus de cartes IA, PostHog pour l'analytique |
| Outillage | pnpm, Jest, ESLint, Prettier, GitHub Actions et Fastlane, builds natifs locaux, EAS réservé aux identifiants push |
| Console admin | Next.js 16, shadcn/ui, proxy serveur vers l'API Scoresphere |
Le découpage du code mobile est net et respecté : les écrans dans app/, les composants dans components/, la logique métier sans framework dans lib/ avec des imports Firebase paresseux, et un contrat de types unique dans types/match.ts partagé par tous les écrans.
Brique analyse vidéo
Le couplage entre l'app et la vision est un couplage par données : deux manifestes JSON, typés dans types/match.ts, et aucun appel direct de l'app vers le moteur. Trois dépendances externes subsistent : la clé API agentcast côté script et console, les URLs S3 présignées des CSV de tracking lues par la Python, et le ref upstream figé dans vendor/UPSTREAM_REF.
- Stage 1, hors du projet. Le manifeste contient trois candidats de tracking, chacun avec une image de board, les rectangles pixel par joueur, les métriques et l'équipe détectée, plus la géométrie du terrain, le fps et les URLs des CSV.
- Import manuel. Le script re-héberge les boards dans Storage, annote leur taille en pixels et écrit le payload brut dans
matches/{code}. Sans ce script, rien n'arrive dans l'app. - Lecture stage 1. La forme brute est reconnue par ses clés, sans numéro de version. Les métriques stage 1 ne servent que de placeholder.
- Stage 2 à la demande. Un seul stage 2 par match, protégé par un lock Firestore. La fonction Python télécharge les CSV, les met en cache dans Storage, filtre les joueurs non sélectionnés, valide la sélection, exécute le pipeline vendorisé, puis écrit un manifeste réduit à neuf clés sur le document match.
- Calcul métier client. Distance projetée, profil, scores de carte, radar, archétype, médailles et momentum sont calculés dans
lib/. La feuille figée capture ce calcul à un instant donné, sans recalcul si les formules évoluent.
Modèle de données Firestore
| Collection | Écrit par | Contenu et accès |
|---|---|---|
matches/{code} | Script d'import, fonction Python | Payload CV brut, manifeste stage 2, score, choix du board. Lecture par tout compte connecté, jamais de listage ni de création client. |
matches/{code}/claims/{uid} | App | Joueur revendiqué par un compte, immuable une fois posé. |
matches/{code}/locks/{id} | App | Verrou de travail, premier écrivain gagnant, reprise après 10 minutes. |
users/{uid} | App, fonction cartes | Profil privé, statut de génération des cartes. Propriétaire seulement, jamais de suppression client. |
users/{uid}/match_sheets/{code} | App | Feuille de match rendue. Sa création déclenche l'email post-match. |
profiles/{uid} | App, fonction cartes | Carte publique : nom, images, Elo, matchs, badges. Lisible par tout compte, écrite librement par son propriétaire. |
centers/{id} | Back-office web, script CLI | Centres partenaires. Écriture réservée à une liste d'emails codée dans les règles. |
ranking_snapshots/{date} | Fonction planifiée | Rangs quotidiens pour les flèches de tendance, jamais écrits par un client. |
Environnements
Le dépôt sépare des variantes d'installation, pas des environnements de données. Un commutateur au prebuild produit deux apps qui peuvent cohabiter sur un téléphone, « Squadfield » et « Squadfield Dev », différentes seulement par le nom, le bundle id et le scheme d'URL. Tout le reste est partagé : un seul projet Firebase, une seule base, un seul déploiement de fonctions, un seul jeu de variables d'environnement, un seul projet PostHog.
Le seul comportement qui varie à l'exécution dépend du mode du bundle Metro, pas de la variante : le repli sur un match simulé et l'étiquette d'environnement analytique. Les deux axes sont indépendants.
| Bundle de développement | Bundle release | |
|---|---|---|
| Variante dev | Matchs simulés actifs, base de production | Comportement prod, base de production |
| Variante prod | Matchs simulés actifs, base de production | Ce que reçoivent les stores |
Conséquences : toute action faite depuis la variante dev écrit dans la base de production, un onboarding de test déclenche une génération de cartes payante, et une modification de règles ou de fonction ne peut être validée qu'en la déployant en production. La CI ne construit que la variante prod, vers TestFlight et Play internal, à chaque push sur la branche principale.
Sécurité
Les fondations sont saines : aucun secret dans le code, clés API en Secret Manager, règles commentées et validées en forme, CI épinglée par SHA, nonce Apple et audience Google corrects. Le problème est que les règles Firestore sont le seul périmètre de sécurité, et que le SDK admin des fonctions passe au-dessus.
- HauteStage 2 réécrivable par n'importe quel compte. La callable Python ne vérifie que l'authentification : ni participation au match, ni respect du lock, ni refus si le stage 2 existe. La callable Node résiduelle a le même défaut et déclenche en plus un appel payant à Scoresphere.
- HauteClassement falsifiable. Un propriétaire écrit n'importe quel champ de son profil public, dont l'Elo lu par le snapshot quotidien.
- Moyenne +Allow-list admin sans vérification d'email. Quatre adresses codées dans les règles, sans contrôle
email_verified. À remplacer par des custom claims. - MoyenneAbus de coût, pas d'App Check. Envoi de lien magique sans authentification ni limite, six prédictions Replicate à chaque changement de photo, fonction Python de 540 secondes plafonnée à 20 instances de 2 Gio, soit 40 Gio mobilisables par un appelant.
- MoyenneCache des CSV empoisonnable. Le
job_idfourni par le client sert de clé de cache sans être comparé au document. - MoyenneGriefing dans le flux match. Choix du board modifiable par tout compte, claims dupliqués possibles, score réécrivable sans limite par tout claimant.
- Basse +Confidentialité. Photos originales publiques par uid, document match brut avec URLs S3 lisible par tout compte ayant le code, emails en clair dans les logs.
- BasseProxy de la console admin sans authentification. Sans conséquence en local, relais ouvert vers l'API payante si déployé.
Vérifications dans la console Firebase
Lecture seule via les CLI Firebase et gcloud, compte au rôle Viewer, projet squadfield-465f1.
| Point | Constat |
|---|---|
| Fonctions déployées | Neuf, toutes en europe-west1. La callable Node runTeamAnalysis est toujours active, avec le secret Scoresphere lié. La Python tourne avec 20 instances maximum, 2 Gio, 540 s, une requête par instance. |
| Dérive de déploiement | Les fonctions de cartes tournent sur Node 22 avec 5 instances maximum, alors que le dépôt déclare Node 20 et 20 instances pour le déclencheur. Le backend en production ne correspond pas exactement au dépôt : les fonctions se déploient à la main, sans CI. |
| Invocation des callables | Ouvertes à allUsers au niveau Cloud Run, ce qui est le fonctionnement normal des callables Firebase : l'authentification se fait dans le code, d'où l'importance des contrôles relevés plus haut. |
| Clés API | Trois clés auto-créées, restreintes aux APIs Firebase habituelles, sans restriction de client. Attendu pour une app mobile sur SDK JavaScript. |
| Domaines Auth autorisés | localhost, les deux domaines Firebase du projet et squadfield.app. Une politique de mot de passe est active, six caractères minimum, ce qui suggère un fournisseur mot de passe existant sans permettre de le confirmer. |
| Rôles IAM | Deux propriétaires humains, auguste@coop2t.com et mikebuilder22@gmail.com. Sur les quatre emails de l'allow-list admin des règles, un seul est propriétaire du projet. |
| Secrets | Trois secrets, conformes au guide de déploiement. |
| Storage | Bucket sans accès public au niveau IAM, accès régi par les règles. |
| Planification | Deux tâches actives, snapshot des classements et purge des comptes, conformes au code. |
| BigQuery | Aucun jeu de données : pas d'export Firestore en place. |
| Facturation | Plan Blaze actif. Les budgets ne sont pas lisibles avec le rôle Viewer. |
| Autres projets | squadfield-app est un projet vide, un site Hosting sans app ni base : candidat naturel pour le staging. squadfield-f1f49, qui héberge l'ancien site, n'est pas visible par ce compte. |
| Hors de portée du rôle Viewer | Fournisseurs d'authentification activés, état d'App Check, règles réellement déployées, alertes de budget. Un rôle serviceusage.serviceUsageConsumer ajouté par un propriétaire suffirait, sans donner de droit d'écriture. |
Dépendances
| Codebase | Critiques | Hautes | Remarque |
|---|---|---|---|
| App mobile | 2 | 52 | Quasi exclusivement la chaîne d'outils Expo, pas le bundle livré |
| Console admin | 2 | 26 | Next.js 16.2.7 porte deux RCE non authentifiées |
| Functions Node | 0 | 1 | Via firebase-admin, un bump suffit |
| Python | – | – | Non audité, outil absent de la machine |
03Résumé fonctionnel par brique
App mobile
Trois onglets : matchs, niveau, classements. Authentification par lien magique, Google ou Apple. Onboarding en quatre étapes avec photo de profil. Flux match : lien, identification sur le board, formation des équipes, score, analyse, feuille de match. Réglages, désactivation de compte avec délai de 30 jours, galerie de trophées.
- Adapte les manifestes CV et calcule cartes, radar, archétypes, médailles et Elo.
- Cache local MMKV par match, synchronisé avec Firestore.
- Deux variantes d'installation, builds natifs locaux, livraison stores par CI.
Firebase Auth
Sessions persistées sur l'appareil. Le fournisseur d'auth crée le profil Firestore à la première connexion, mire les changements d'email, gère la réactivation d'un compte désactivé et purge l'état local lors d'un changement de compte.
Firestore
Base de vérité pour matchs, profils, feuilles, centres et snapshots. Règles validées en forme pour les trois écritures client autorisées sur un match. Aucune création ni suppression de match par un client.
Storage
Photos de profil et cartes générées, publiques en lecture. Boards de tracking re-hébergés par le script d'import. Cache des CSV de tracking écrit par la fonction Python, inaccessible aux clients.
Hosting
Domaine des liens universels et App Links, pages web de repli pour les liens de match et de connexion, fichiers AASA et assetlinks, back-office statique des centres partenaires, images de référence pour les cartes IA.
Cloud Functions Node
sendMagicLinkEmail: lien de connexion via Resend.onMatchSheetCreated: email post-match avec QR et code de partage.generateCardsOnPhotoChangeetgenerateCardImages: trois rendus de carte via Replicate, avec suppression du fond.snapshotRankings: rangs quotidiens.purgeDeactivatedAccounts: suppression des comptes après 30 jours.runTeamAnalysis: ancien proxy Scoresphere, toujours déployé, plus appelé.
Cloud Functions Python
Exécute le stage 2 avec le code de l'équipe CV copié tel quel dans vendor/, stack numérique épinglée aux versions de leur hôte. La glue met en scène les CSV dans /tmp, valide la sélection, nettoie les NaN et réduit le manifeste. Un endpoint de self-test vérifie les imports et la géométrie après déploiement.
Scoresphere
Moteur de vision de l'équipe CV. Reçoit la vidéo, produit le manifeste stage 1 et les CSV de tracking. Son API stage 2 n'est plus utilisée, le code étant vendorisé.
Script d'import
Lancé à la main depuis un poste avec des identifiants Firebase. Récupère un job terminé, re-héberge les images, écrit le document match et imprime le lien à partager au capitaine. Le maillon humain du pipeline.
Console admin
Outil interne local pour piloter la chaîne Scoresphere de bout en bout et inspecter le JSON brut. La clé API reste côté serveur derrière un proxy. Pas d'authentification, pas de déploiement.
Services tiers
Emails transactionnels depuis le domaine vérifié. Rendus de cartes par un modèle génératif puis suppression de fond. Analytique produit avec nettoyage des données personnelles avant envoi, session replay désactivé par défaut.
04Forces et faiblesses du code mobile
Points forts
- Documentation nettement au-dessus de la moyenne : README développeur, docs de fonctionnalités, guide de déploiement, note de vendoring, audit de scalabilité.
- Couches respectées, logique métier sans framework, contrat de types unique.
- 70 fichiers de test, seuil de couverture de 80 % sur
lib/, aucunanynits-ignore, un seulconsole.*et un seul TODO dans le code applicatif. - Aucun secret côté client, règles commentées, matchs non créables par un client, verrous stage 2.
- CI épinglée par SHA, variantes dev et prod coexistantes, builds reproductibles.
- Décision de vendoriser le stage 2 argumentée chiffres à l'appui, pins numériques justifiés, tests sur de vrais octets CSV.
- Test automatique interdisant les couleurs brutes hors du thème.
Points faibles
lib/match.tsfait 1 929 lignes, plus de la moitié de la logique métier : adaptateurs, persistance, liens, stage 2, mock, formatage.providers/auth_provider.tsxfait 584 lignes et importe Firebase directement, à l'inverse delib/.- Chemin stage 2 Node mort mais déployé, testé, et documenté comme actif dans quatre fichiers. Deux
trimManifestà maintenir. - Elo calculé côté client avec des lectures N+1, écrit dans un profil librement modifiable.
- Aucun test de règles Firestore malgré des règles complexes.
- Configuration Jest dépendante des modules de
functions/, non installés par le guide de démarrage ni par la CI. nativewinden version flottante. Commentaires de types en décalage avec le README sur deux points.- Dépendances vulnérables dans la console admin et la chaîne d'outils.
05Chantiers à prévoir
Les priorités reflètent le risque porté, pas la valeur produit. Les nouveaux modules suivent la règle TDD du projet. Aucune estimation d'effort n'est donnée à ce stade.
Chantiers techniques
| Chantier | Priorité | Contenu |
|---|---|---|
| A. Sécurisation du backend | P0 | Supprimer la callable Node. Ajouter dans la Python le contrôle de claim, le refus si le stage 2 existe, la comparaison du job_id et un plafond d'instances abaissé. Custom claims à la place de l'allow-list. App Check. Limite sur le lien magique. Tests de règles avec l'émulateur. Bumps de firebase-admin et Next. |
| B. Architecture de staging | P0 | Second projet Firebase avec alias, fichiers d'environnement par variante chargés nativement par Expo, secrets CI par environnement, clients OAuth et site Hosting pour le bundle dev, déploiement des fonctions et des règles sur les deux projets. |
| C. Elo et intégrité du classement | P0 | Calcul de l'Elo par Cloud Function à la création de feuille ou au score final, deltas stockés par match, profil restreint aux champs d'identité pour le propriétaire. Prérequis de la composition d'équipes, qui affiche l'Elo en permanence. |
| D. Refactoring ciblé | P1 | Scinder match.ts en quatre ou cinq modules. Alléger le fournisseur d'auth. Mettre la documentation en accord avec le chemin Python. Épingler nativewind. Extraire un package de domaine partagé, prérequis du web. |
| E. Intégration automatique de l'analyse vidéo | P1 | Faire entrer l'analyse dans le workflow de l'application sans intervention humaine : remplacer le script d'import manuel par une fonction planifiée ou un webhook qui interroge Scoresphere, écrit Firestore et notifie le capitaine. Déclarer un numéro de version dans les manifestes. Ne plus stocker le payload brut entier, déplacer le momentum en sous-collection. Prévoir le recalcul des feuilles quand les formules changent. Préparer la liaison réservation, match importé, composition. |
| F. Frontend web | P2 | Une seule app Next.js multi-rôles sur le même Firebase, groupes de routes par rôle gardés par les claims. Logique privilégiée maintenue dans les callables. Hébergement Firebase App Hosting ou Vercel. Première tranche : administration du projet, sans nouveau modèle de données. Puis espaces salles et capitaines, qui convergent avec la spec fonctionnelle. |
| G. Statistiques et observabilité | P2 | Export Firestore vers BigQuery par l'extension officielle, ou agrégats calculés par fonction planifiée. Aucune agrégation depuis le navigateur. |
| L. Ancien site web | P0 | Décider entre extinction et maintien minimal. Dans les deux cas : couper ou protéger les endpoints non authentifiés de l'API Python, fermer les écritures Storage anonymes, vérifier les abonnements Stripe actifs et les comptes du projet squadfield-f1f49. Servir CGU, CGV et politique de confidentialité depuis le Hosting du projet mobile et mettre à jour les liens de l'app. |
Chantiers fonctionnels
Issus de la spec « Compo & Résa ». L'ordre demandé par la spec est le bon. La réservation est découpée en lots pour ne pas bloquer sur les dépendances externes.
| Lot | Dépendances | Points d'attention |
|---|---|---|
| H. Ajout de joueurs et amis | Aucune | Amitié symétrique instantanée : passer par une callable transactionnelle. Recherche par préfixe sur un champ de nom normalisé, avec backfill. Lien d'invitation sous /invite/{code} pour ne pas entrer en conflit avec l'analyse des liens de match. |
| I. Composition d'équipes | Chantier C | Cinq onglets dans la barre flottante à vérifier sur petits écrans. Capture de vue et partage natif pour le visuel WhatsApp. Livrer d'abord sans le toggle réservation, comme la spec le demande. |
| J. Réservation : centres et carte | Données centres à saisir | Étendre la collection des centres et le back-office avec photo et coordonnées. Carte optionnelle avec MapLibre pour rester open source. |
| K. Réservation : créneaux et paiement | Connecteurs partenaires, Stripe, Apple Pay, cadre juridique | Le logiciel de réservation de chaque centre est inconnu. Le modèle de flux d'argent, commission comprise, doit être tranché avant le design technique. Réservations et statut payé écrits uniquement par les fonctions. |
Opportunité non mentionnée par la spec. Aujourd'hui le match arrive par SMS du centre et par le script d'import. Une réservation connue à l'avance donne à Squadfield qui joue, où et quand : elle permettrait de lier automatiquement le match importé, la composition et les claims, et de supprimer une bonne part de l'identification manuelle.
Séquencement proposé
-
Phase 0
Réduire le risque. Rien de fonctionnel ne devrait sortir avant.
- A. Sécurisation du backend
- B. Architecture de staging
- L. Ancien site web : sécuriser ou éteindre, rapatrier les pages légales
- Ouverture des discussions partenaires et du dossier Stripe, chemins critiques du lot K
-
Phase 1
Consolider et livrer la première fonctionnalité.
- C. Elo côté serveur
- D. Refactoring et package de domaine
- E. Intégration automatique de l'analyse vidéo dans le workflow : import sans opérateur, versionnage des manifestes
- H. Ajout de joueurs et amis
-
Phase 2
Élargir le périmètre.
- I. Composition d'équipes
- J. Centres et carte
- F. Frontend web, tranche administration
-
Phase 3
Réservation et espaces professionnels. Dépend des réponses partenaires obtenues en phase 0.
- K. Créneaux, pré-réservation, paiement
- F. Espaces salles et capitaines sur le web
- G. BigQuery et tableaux de bord
06Projet web antérieur
Le dépôt squadfield-app-master contient un site web commencé avant l'application mobile. Il a été audité pour répondre à une question précise : peut-il servir de socle à la future web app branchée sur le backend du mobile ? La réponse est non, pour des raisons de produit, de données et de sécurité, détaillées ci-dessous.
Ce que c'est
Un générateur de cartes de joueur par IA. L'utilisateur déclare ses statistiques dans un formulaire, envoie une photo, et un modèle génératif produit une carte stylisée. S'y ajoutent des abonnements et des commandes d'impression via Stripe, une gestion de clubs et une analyse vidéo par extraction d'images envoyées à un modèle de langage. C'est un produit différent de l'app mobile, dont les statistiques sont mesurées par vision sur un match réel.
| Élément | Site web antérieur | App mobile |
|---|---|---|
| Projet Firebase | squadfield-f1f49, confirmé dans le bundle du site en ligne | squadfield-465f1 |
| Front | Next.js Pages Router, React 18, 92 % de fichiers JSX non typés | Expo, React 19, TypeScript strict |
| Backend | FastAPI Python sur fonctions serverless Vercel, SDK admin Firebase, OpenAI, Stripe | Cloud Functions Node et Python dans le projet Firebase |
| Modèle de données | users avec crédits et abonnement, cards, clubs, print_orders, features | users, profiles, matches, centers, ranking_snapshots |
| Authentification | Email et mot de passe, Google | Lien magique, Google, Apple |
| Tests | Aucun | 70 fichiers, couverture imposée |
| Identité visuelle | Orbitron, orange #FF9B00, couleurs en dur | Kit Figma, Archivo, tokens de thème |
| Environnements | Deux projets Vercel, prod et dev, avec variables séparées | Un seul projet Firebase |
État en ligne et accès
Le projet Firebase squadfield-f1f49 n'apparaît pas dans les projets visibles par le compte Squadfield audité. Son propriétaire est vraisemblablement l'équipe qui a développé l'ancien site. Toute décision d'extinction ou de migration passe par un accès à ce projet, ou par son propriétaire.
Le site répond sur squadfield.fr, sur les deux déploiements Vercel, et son API Python répond sur /api/py/health. L'app mobile pointe vers squadfield.fr/cgv et squadfield.fr/privacy pour ses conditions et sa politique de confidentialité : les pages légales du produit actuel sont servies par l'ancien site.
Sécurité
- HauteAPI sans authentification. La vérification du jeton Firebase existe mais n'est appliquée qu'aux routes d'administration. Lecture et écriture du profil de n'importe quel utilisateur, crédits compris, création et modification de clubs, ajout de cartes à un compte tiers, annulation de l'abonnement d'un tiers : tout est ouvert.
- HauteÉlévation de privilège. Le statut administrateur est un champ du document utilisateur, que les règles Firestore laissent le propriétaire écrire lui-même.
- MoyenneCoûts exposés. Génération d'image et analyse vidéo appelables sans compte, donc dépense OpenAI à volonté. Deux préfixes Storage acceptent des envois anonymes jusqu'à 50 Mo, en lecture publique.
- MoyenneCORS avec identifiants ouvert à tout sous-domaine Vercel. Configuration Firebase complète imprimée dans la console du navigateur.
- CorrectWebhook Stripe signé. Aucun secret dans le code, fichiers d'environnement absents du dépôt.
Pourquoi ne pas s'en servir comme socle
- Un autre projet Firebase, donc pas de backend commun. Le brancher sur le projet mobile n'est pas un changement de configuration : la collection
usersporte des champs incompatibles, et les règles de l'ancien site refusent tout ce que le mobile utilise. - Un second backend privilégié en Python hors Firebase, sans authentification, à l'opposé de la recommandation de garder la logique dans les Cloud Functions.
- Une base JSX sans types ni tests, avec composants dupliqués et endpoints appelés par le front qui n'existent plus côté API.
Ce qui reste utile
- Le flux Stripe complet, session de paiement, webhook signé, mise à jour des droits, comme référence pour le paiement de la réservation.
- Le contenu des pages CGU, CGV, mentions légales et confidentialité, à rapatrier sur le Hosting du projet mobile.
- Le concept clubs, joueurs, cartes, précurseur de l'espace capitaines.
- Le pattern de deux projets Vercel avec variables séparées, comme exemple de séparation d'environnements.
Décision à prendre rapidement. Tant que le site est en ligne, ses endpoints ouverts sont un risque de coût et de données, y compris pour les comptes encore présents dans squadfield-f1f49 et d'éventuels abonnements Stripe actifs. Voir le chantier L.
07Annexe
Questions à trancher avec le produit
- La suppression d'un ami est-elle symétrique ?
- Le lien d'invitation crée-t-il l'amitié avec le parrain à l'inscription ?
- Les listes d'amis d'un ami sont-elles visibles par tous ?
- Que devient une réservation une fois le match joué ?
- Annulation et remboursement d'une réservation.
- Squadfield encaisse-t-il pour le centre, ou le centre encaisse-t-il directement ?
- Quels logiciels de réservation utilisent les centres partenaires ?
- Faut-il un consentement pour être visible dans la recherche de joueurs ?
Méthode et limites
- Analyse statique du dépôt tel que livré, sans historique git ni dépendances installées. La suite de tests et le typecheck n'ont pas été exécutés.
- Audit des dépendances sur les fichiers de verrouillage seulement. Les dépendances Python n'ont pas été auditées.
- La console Firebase a été consultée en lecture seule via les CLI Firebase et gcloud, avec un compte au rôle Viewer. Ce rôle ne permet pas d'interroger les APIs de configuration de l'Auth, d'App Check, des règles déployées et des budgets. Le point sur l'allow-list admin reste donc ouvert.
Références dans le dépôt
README.md: guide développeur, modèle de données, fonctions.docs/scalability.md: audit de passage à l'échelle, dettes déjà identifiées.docs/environments.mdetdocs/cicd.md: variantes et livraison.functions-python/UPSTREAM.md: pourquoi et comment le stage 2 est vendorisé.functions/DEPLOY.md: déploiement et secrets des fonctions Node.Spec 2 MVP _ Compo and Resa .docx: spec fonctionnelle des trois nouvelles briques.squadfield-app-master/ARCHITECTURE.md: guide de passation de l'ancien site web.