DOCS/sport/myinfomate-sport-spec.md
Thomas Fransolet a5a8ecdb20 Documentation interne MyInfoMate / Unov
Import initial de la documentation : statut, roadmap, plans V1/V2,
specs verticales (creche, sport), audits securite, plan de test,
analyse concurrentielle et maquettes de design.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 11:17:01 +02:00

232 lines
8.1 KiB
Markdown

# 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)