# MyInfoMate Sport — Spécification V1 ## Concept Verticale "clubs sportifs" de MyInfoMate, pilote avec le **Hockey Club de Namur**. Même infrastructure que MyInfoMate (manager-service, manager-app, PostgreSQL, Firebase) — un club = une `Instance`. Marché cible : clubs sportifs structurés (D1/D2) qui veulent une app branded pour leurs membres. Concurrent principal à analyser : **Spond** (gratuit, très utilisé), **iclub** (gestion administrative, marché belge). Différenciation : expérience membre, white-label, module mobilisation (arbitrage + renfort), kiosk tablette. --- ## Rôles ### Responsable du club (= `InstanceAdmin` dans manager-app) - Crée et gère les équipes - Crée les membres et vérifie leur statut (cotisation en ordre) - Assigne les membres aux équipes - Désigne les capitaines - Gère le contenu global de l'app (sections, programme, résultats, events) - Envoie des notifications à tout le club ou par équipe ciblée ### Capitaine (= `ContentEditor` dans manager-app) - Gère les membres de son équipe - Encode les matchs et résultats de son équipe - Poste les demandes d'arbitrage et de renfort (**lui seul peut créer ces demandes**) - Envoie des notifications à son équipe uniquement ### Membre (= nouveau rôle, app mobile uniquement) - Voit le contenu global + contenu de ses équipes - Reçoit les notifications ciblées - Peut se proposer comme arbitre ou comme renfort - Ne peut pas créer de demandes --- ## Gestion des membres ### Flow d'inscription 1. Responsable club crée le membre dans manager-app (nom, email, cotisation OK) 2. Le membre reçoit un email d'invitation avec un lien pour créer son mot de passe 3. Il se connecte dans l'app mobile avec email/password 4. Responsable ou capitaine l'assigne à une ou plusieurs équipes 5. Si cotisation non payée → compte désactivé (`IsActive = false`), accès bloqué ### Entité `Member` (nouvelle, séparée de `User`) `User` existant = gestionnaires de la solution (manager-app). `Member` = membres du club (app mobile). Auth séparée, JWT séparé. ``` Member - Id - InstanceId (le club) - TeamIds (ses équipes) - FirstName, LastName - Email - PasswordHash - IsCaptain (bool) - IsActive (cotisation OK) - DateCreation - InvitationToken (flow email invitation) ``` Nouvel endpoint : `POST /api/member/login` → JWT avec claims membres. --- ## Module Mobilisation ### Demandes d'arbitrage (par équipe) - Le capitaine poste une demande pour un match (date, heure, rémunération proposée) - Les membres volontaires (liste arbitres) reçoivent une notification - Un membre accepte → demande confirmée, fermée pour les autres - Seul le capitaine peut créer/clôturer une demande ### Demandes de renfort (inter-équipes) - Le capitaine poste "besoin de X joueurs" pour un match - Les membres d'autres équipes compatibles reçoivent une notification - Ils se proposent → le capitaine valide - Même logique que l'arbitrage ### Modèle technique suggéré Un modèle générique `ClubRequest` avec un type (Arbitrage / Renfort) plutôt que deux modèles séparés. ``` ClubRequest - Id - InstanceId - TeamId - MatchId - Type (Arbitrage | Renfort) - Description - Compensation (arbitrage : montant, renfort : nb joueurs) - Status (Open | Closed) - CreatedByMemberId (capitaine uniquement) - DateCreation ``` --- ## Sections de l'app mobile ### Réutilisées depuis MyInfoMate | Section | Usage sport | |---------|-------------| | `SectionAgenda` | Programme des rencontres + événements club | | `SectionArticle` | Règles du hockey, infos pratiques, présentation | | `SectionSlider` | Galerie photos des matchs | | `SectionVideo` | Highlights, interviews, vidéos entraînement | | `SectionMap` | Localisation terrains, plans déplacements extérieurs | | `SectionWeb` | Live score fédération, site RBFH | | `SectionPDF` | Règlement intérieur, convocations, documents | | `SectionWeather` | Météo pour savoir si terrain praticable | ### Nouvelles sections à créer | Section | Usage | |---------|-------| | `SectionTeam` | Roster équipe (photos, numéros, stats) | | `SectionMatch` | Résultats + classement en temps réel | | `SectionRequest` | Demandes arbitrage/renfort ouvertes (capitaine uniquement pour créer) | --- ## App mobile membres ### Navigation **Header** - Logo + nom du club à gauche (brandé via Flutter flavor) - Avatar du membre en haut à droite → tap → page profil **Bottom navigation bar (5 onglets)** | Icône | Onglet | Contenu | |-------|--------|---------| | Maison | Home | Météo, news, prochains matchs, demandes ouvertes | | Calendrier | Programme | Calendrier filtrable par équipe | | Maillot | Mon équipe | Roster, résultats, classement | | Mégaphone | Mobilisation | Demandes arbitrage/renfort ouvertes | | Plus | Club | Sections configurées depuis manager-app (articles, vidéos, PDF, map...) | --- ### Page Profil (accessible via avatar) - Photo, nom, numéro de maillot - Ses équipes - Stats perso (V2) - Trophées gagnés (V2) - Paramètres / déconnexion --- ### Home - Météo du jour (terrain du club) - Dernières news du club - Prochains matchs de MES équipes - Demandes de mobilisation ouvertes pour moi ### Programme - Calendrier de tous les matchs du club - Filtrable par équipe - Tap sur un match → détail (heure, terrain, adversaire, résultat) ### Mon équipe - Roster de l'équipe (liste des joueurs, numéros, postes) - Résultats et classement de l'équipe ### Mobilisation - Demandes d'arbitrage ouvertes - Demandes de renfort ouvertes - Je me propose → validation par le capitaine ### Club (dynamique) - Sections configurées depuis manager-app par le responsable - Même logique de rendu que mymuseum-visitapp - Articles, vidéos, galerie, PDF, map, events... --- ## Pricing (cible) - **40-90€/mois** par club - Basé sur : nombre d'équipes, nombre de membres actifs, notifications/mois - Pas de quota stockage/IA (inutile dans ce contexte) - Pilote Hockey Namur : **gratuit 3-6 mois** pour valider les features --- ## Architecture technique - **manager-service** : nouvelles entités (Team, Match, Member, ClubRequest) + nouveaux controllers. Rien d'existant modifié. - **manager-app** : nouvelles sections dans le menu. UI globale inchangée. - **Nouvelle app Flutter** : app mobile membres, consomme le client API généré depuis manager-app. **White-label via Flutter flavors dès le départ** — une seule codebase, un flavor par club (couleurs, logo, nom d'app, bundle ID). - **Base PostgreSQL** : même instance, isolation par `InstanceId`. Nouvelles tables via migrations EF Core. - **mymuseum-visitapp** : non touchée. --- ## V2 (hors scope V1) ### Messagerie d'équipe (remplacement WhatsApp) - Texte uniquement dans un premier temps (pas de photos/vidéos) - Historique limité à 90 jours — suppression automatique au-delà - Stocké en PostgreSQL (pas Firebase Storage) — coût marginal nul - Notifications push via FCM (gratuit sans limite) - Photos/vidéos envisageables en V3 avec quota strict par club dans le plan tarifaire ### Intégration fédérale RBFH (hockey.be) API publique disponible sur `hockey.be/wp-json/sportlink-api/cached` — pas d'auth requise. Endpoints identifiés : - `endpoint=program&clubid=CC6VD3E` → programme des matchs (date, heure, équipes, division) - `endpoint=standing&clubid=CC6VD3E&subpool=A` → classement (subpool à investiguer pour les autres divisions) Implémentation : job Hangfire quotidien (pattern identique à `AgendaSyncService`) qui synchronise programme + classements automatiquement sans encodage manuel. À investiguer : paramètre `subpool` pour récupérer toutes les divisions (pas uniquement la D1). ### Stats et gamification - Stats par joueur : buts, assists, cartons, matchs joués - Stats par équipe : classement, buts pour/contre - Trophées automatiques calculés par job Hangfire hebdomadaire : - "Meilleur buteur U16 de la saison" - "100 matchs joués au club" - "Arbitre de la saison" (nombre d'arbitrages acceptés) - "Joueur le plus fiable" (jamais forfait) - "Renfort d'or" (x fois venu en renfort) ### Autres - Réservation de terrains - État des terrains en temps réel (MQTT + capteurs)