`.
+### workout.service.js
----
+Création, lecture, suppression de séances, gestion des brouillons, finalisation avec calcul des totaux et application de l'anti-triche temporel serveur.
-#### `POST /api/exercises`
+### exercise.service.js
-Enregistrer les performances d'un exercice pour une séance donnée.
+Enregistrement des performances, historique de progression par exercice, classement entre amis sur un exercice donné.
-**Body**
-```json
-{
- "workout": "65a3b...",
- "exerciceNom": "Développé couché",
- "series": [
- { "poids": 80, "repetitions": 8 },
- { "poids": 82.5, "repetitions": 6 },
- { "poids": 80, "repetitions": 7 }
- ],
- "note": "Léger PR sur la série 2"
-}
-```
-
-**Réponse 201**
-```json
-{
- "record": {
- "_id": "65b1c...",
- "exerciceNom": "Développé couché",
- "series": [ ... ],
- "recommandedNextWeight": 85,
- "createdAt": "2024-09-15T14:22:00.000Z"
- }
-}
-```
+### email.service.js
----
+Templates HTML de la marque (fond sombre, logo Athly) pour les codes de vérification et de réinitialisation, envoyés via Nodemailer.
-#### `GET /api/exercises/history/:name`
+### push.service.js
-Récupérer l'historique de progression d'un exercice (pour les graphes).
+Envoi de notifications push via expo-server-sdk, utilisé pour Secouer, les invitations de groupe et de lobby, les réactions du flux d'activité.
-**Exemple :** `GET /api/exercises/history/Développé%20couché`
+### chest.service.js
-**Réponse 200**
-```json
-{
- "history": [
- {
- "_id": "65b1c...",
- "workout": "65a3b...",
- "series": [
- { "poids": 80, "repetitions": 8 }
- ],
- "createdAt": "2024-09-15T14:22:00.000Z"
- },
- {
- "_id": "65b0a...",
- "workout": "65a2d...",
- "series": [
- { "poids": 77.5, "repetitions": 8 }
- ],
- "createdAt": "2024-09-12T09:15:00.000Z"
- }
- ]
-}
-```
+Table de drop pondérée et tirage aléatoire d'un objet à l'ouverture d'un coffre.
----
+### inventory.service.js
-#### `GET /api/exercises/workout/:workoutId`
+Logique de consommation atomique des objets d'inventaire, pour éviter toute condition de course sur la derniÚre unité disponible.
-Récupérer tous les records d'exercices associés à une séance spécifique.
+### activity.service.js
-**Réponse 200**
-```json
-{
- "records": [
- {
- "_id": "65b1c...",
- "exerciceNom": "Développé couché",
- "series": [ ... ]
- },
- {
- "_id": "65b1d...",
- "exerciceNom": "Dips",
- "series": [ ... ]
- }
- ]
-}
-```
+Construction et filtrage du flux d'activité social visible par un utilisateur.
---
-#### `GET /health`
+## Catalogues de données
-Point de terminaison de santé (public, sans auth).
+### `data/titleCatalog.js`
-**Réponse 200**
-```json
-{
- "status": "OK",
- "uptime": 3600.42
-}
-```
+17 titres RPG déblocables, avec leurs conditions (niveau, records personnels, séances en groupe, participation communautaire).
----
+### `data/localTrophyCatalog.js`
-## đ ModĂšles de donnĂ©es
+Miroir des métadonnées d'affichage des 40 trophées locaux définis cÎté front, plus le trophée capstone Souverain Absolu qui se débloque automatiquement une fois tous les autres trophées obtenus. Les conditions de déblocage sont évaluées cÎté client (elles dépendent des logs de séances stockés en AsyncStorage) : ce fichier ne porte que les métadonnées et sert d'allowlist pour la synchronisation.
-### User
+### `data/shakeMessages.js`
-```javascript
-{
- // Identité
- pseudo: String (required, trim),
- email: String (required, unique, lowercase),
- password: String (required, bcrypt hash),
-
- // Vérification email
- isVerified: Boolean (default: false),
- verificationCode: String,
- verifyAttempts: Number (default: 0, max: 5),
-
- // Reset password
- resetPasswordCode: String,
- codeExpires: Date, // TTL : 10 min (vérif) / 15 min (reset)
-
- // Profil physique
- age: Number,
- sexe: Enum ["H", "F", "Autre"],
- poids: Number, // kg
- poidsCible: Number, // kg
- taille: Number, // cm
- niveauSportif: Enum ["Débutant", "Intermédiaire", "Avancé"],
- objectif: Enum ["prise de masse", "perte de poids", "entretien", "force"],
- rythme: Number, // 1-7 séances/semaine
- equipements: [String],
-
- // Gamification
- xp: Number (default: 0),
- level: Number (default: 1),
-
- // Timestamps Mongoose
- createdAt, updatedAt
-}
-```
+Messages aléatoires envoyés par notification push lors d'un Secouer entre membres de groupe.
-### Workout
+### Catalogue de trophées serveur
-```javascript
-{
- user: ObjectId â User (required),
- date: Date (default: Date.now),
- name: String (default: "Séance"),
-
- exercises: [
- {
- exerciseId: ObjectId â Exercise (optional),
- name: String (required),
- targetMuscle: String,
- equipment: [String],
- sets: [
- {
- weight: Number,
- reps: Number,
- completed: Boolean (default: false),
- timestamp: Date
- }
- ],
- notes: String,
- videoUrl: String
- }
- ],
-
- // Métriques (calculées à la finalisation)
- durationSeconds: Number,
- totalVolume: Number, // kg · reps cumulé
- setsCompleted: Number,
- xpEarned: Number,
- notes: String,
-
- // Statut
- status: Enum ["draft", "in_progress", "finished", "completed"],
- completedAt: Date,
-
- // Timestamps Mongoose
- createdAt, updatedAt
-}
-
-// Méthodes d'instance
-workout.computeTotals() // â {totalVolume, setsCompleted}
-workout.finalize(options) // â {totalVolume, setsCompleted, xp}
-```
-
-### ExerciseRecord
-
-```javascript
-{
- user: ObjectId â User (required),
- workout: ObjectId â Workout (required),
-
- exerciceNom: String (required),
- series: [
- {
- poids: Number, // kg (0 si bodyweight)
- repetitions: Number
- }
- ],
- note: String,
- recommandedNextWeight: Number, // suggestion poids prochaine séance
-
- // Timestamps Mongoose
- createdAt, updatedAt
-}
-```
+Défini directement dans `reward.controller.js` (`ACHIEVEMENT_CATALOG`), 20 entrées réparties en trois catégories : profil (anniversaire, parrainage), social (amitié, groupe), collection (raretés d'objets et paliers de coffres ouverts).
---
-## đ§ Services & logique mĂ©tier
-
-### auth.service.js
-
-| Fonction | Description |
-|----------|-------------|
-| `register(pseudo, email, password)` | Hash password, crée User, génÚre OTP 6 chiffres, envoie email |
-| `login(email, password)` | Vérifie identifiants, génÚre JWT, retourne user |
-| `verifyEmail(email, code)` | Vérifie OTP, active compte, retourne JWT |
-| `resendVerification(email)` | GénÚre nouveau code, envoie email |
-| `forgotPassword(email)` | GénÚre code reset, envoie email |
-| `resetPassword(email, code, newPassword)` | Vérifie code, hash nouveau password, invalide code |
-
-**Constantes :**
-```javascript
-MAX_OTP_ATTEMPTS = 5 // Tentatives max avant blocage
-CODE_TTL_VERIFY = 10 * 60 // 10 minutes (en secondes)
-CODE_TTL_RESET = 15 * 60 // 15 minutes
-```
-
-### user.service.js
+## Formules de gamification
-| Fonction | Description |
-|----------|-------------|
-| `getUserProfile(userId)` | Retourne user sans password |
-| `updateUser(userId, data)` | Mise Ă jour profil (whitelist de champs) |
-| `deleteAccount(userId)` | Suppression cascade : ExerciseRecord â Workout â User |
-| `addExperience(userId, xp)` | `user.xp += xp`, recalcule level = `floor(sqrt(xp / 250))` |
+### Courbe XP et niveau
-### workout.service.js
+Source de vérité unique : `utils/levelHelpers.js`, identique à la formule utilisée cÎté front.
-| Fonction | Description |
-|----------|-------------|
-| `createWorkout(userId, data)` | Crée et sauvegarde une séance |
-| `getMyWorkouts(userId)` | Toutes les séances, triées par date desc |
-| `getWorkoutById(userId, id)` | Détail + vérification ownership |
-| `deleteWorkout(userId, id)` | Suppression (ownership check) |
-| `createDraft(userId, data)` | Brouillon (status: "draft") |
-| `updateDraft(userId, id, patch)` | Mise Ă jour partielle du brouillon |
-| `finalizeWorkout(userId, id, opts)` | Calcule totaux, applique l'anti-cheat, crédite XP et recalcule le niveau |
-| `completeWorkout(userId, id)` | `xp = 100 + 10ĂexercisesWithSets`, crĂ©dite XP et recalcule le niveau |
-
-**Anti-cheat temporel (miroir du front-end) :**
```javascript
-if (shortSession === true || duration < 300) xp = 0 // < 5 min â 0 XP
-else if (duration < 900) xp = round(xp/10) // 5â15 min â XP Ă· 10
-// â„ 15 min â XP plein
-```
+xpForLevel(n) = Math.round(4665 * (1.03 ** min(n, 200) - 1))
+levelFromXP(xp) // recherche binaire inverse, plafonnée au niveau 200
-**Formule de niveau (harmonisée avec le front-end) :**
-```javascript
-// utils/levelHelpers.js â source de vĂ©ritĂ© unique
-xpForLevel(n) = Math.round(4665 * (1.03^n - 1))
-levelFromXP(xp) // recherche binaire inverse
-// Exemples : ~1 600 XP â L10 · ~85 000 XP â L100 · ~1 150 000 XP â L200
+// RepĂšres : niveau 1 environ 140 XP, niveau 10 environ 1600 XP,
+// niveau 100 environ 85 000 XP, niveau 200 environ 1 720 000 XP
```
-### email.service.js
-
-Templates HTML professionnels (fond dark `#0D1018`, logo Athly) pour :
-- **Vérification d'email** : code OTP 6 chiffres en grande police
-- **Reset password** : mĂȘme format, texte diffĂ©rent
+### Rangs
-Utilise Nodemailer avec SSL/TLS sur le port 465.
+Dix paliers, du niveau 1 au niveau 200 et au-delĂ : Novice, InitiĂ© (11), AthlĂšte (31), CompĂ©titeur (51), Warrior (71), Ălite (91), MaĂźtre (111), Grand MaĂźtre (141), LĂ©gende (171), ATHLY GOD (200).
-### wger.service.js
+### Bonus de groupe (lobby multijoueur)
-Proxy vers `https://wger.de/api/v2` :
-
-```javascript
-getExercisesByMuscleAndEquipment(muscleId, equipmentId, includeDetails)
-// â [{id, name, videoUrl}]
-```
+| Membres | Bonus d'XP |
+|---------|------------|
+| 2 | 15 pour cent |
+| 3 | 25 pour cent |
+| 4 | 35 pour cent |
+| 5 | 50 pour cent |
---
-## đ§Ș Tests
+## Tests
```bash
-# Lancer tous les tests
-npm test
-
-# Tests en mode watch
-npm test -- --watch
-
-# Couverture de code
-npm test -- --coverage
+npm test # suite complĂšte
+npm test -- --watch # mode watch
+npm test -- --coverage # couverture de code
```
-### Tests unitaires et d'intégrité (sans base de données)
+26 fichiers de tests, exĂ©cutĂ©s contre une instance MongoDB en mĂ©moire (mongodb-memory-server), dĂ©marrĂ©e et arrĂȘtĂ©e automatiquement par `tests/globalSetup.js` et `tests/globalTeardown.js`. Aucune connexion rĂ©seau requise, y compris en intĂ©gration continue.
-Ces trois suites tournent sans connexion MongoDB â elles sont la cible principale de la CI.
-
-#### `tests/levelHelpers.test.js` â 24 tests
-
-Vérifie la formule XP/niveau définie dans `utils/levelHelpers.js` :
-
-| Groupe | Ce qui est testé |
-|--------|-----------------|
-| `xpForLevel` | Niveau 0, 1, 10, 100, 200 ; cap >200 ; valeurs négatives ; progression strictement croissante |
-| `levelFromXP` | 0 XP â L0 ; valeurs nulles/NaN/nĂ©gatives ; bijectivitĂ© `levelFromXP(xpForLevel(n)) === n` pour n â {1,5,10,25,50,75,100,150,200} ; 85 000 XP â L100 |
-
-#### `tests/workoutAnticheat.test.js` â 13 tests
-
-Vérifie la logique d'anti-cheat serveur dans `workout.service.js::finalizeWorkout` via `jest.mock()` (aucun appel MongoDB) :
-
-| Scénario | XP attendu |
-|----------|-----------|
-| `durationSeconds = 0` | 0 |
-| `durationSeconds = 150` (< 5 min) | 0 |
-| `durationSeconds = 299` | 0 |
-| `shortSession: true` + 1 800 s | 0 |
-| `durationSeconds = 300` (seuil exact) | XP Ă· 10 |
-| `durationSeconds = 600` | XP Ă· 10 |
-| `durationSeconds = 899` | XP Ă· 10 |
-| `durationSeconds = 900` (seuil exact) | XP plein |
-| `durationSeconds = 3 600` | XP plein |
-| User null (absent en BDD) | pas de crash |
-| Workout introuvable | lance une erreur |
-
-#### `tests/modelsIntegrity.test.js` â 36 tests
-
-VĂ©rifie l'Ă©tat des schĂ©mas Mongoose sans requĂȘte rĂ©seau :
-
-| Groupe | Ce qui est testé |
-|--------|-----------------|
-| Imports réels | User, Workout, ExerciseRecord s'importent sans erreur |
-| ModĂšles fantĂŽmes | UserQuest, RefreshToken, WorkoutLog, RitualLog, UserProgress, Notification â `MODULE_NOT_FOUND` |
-| Schéma User | Champs email/password/xp/level/isVerified ; contrainte unique email ; xp défaut 0 ; level défaut 1 |
-| Schéma Workout | Champs user/exercises/xpEarned/durationSeconds/status/notes ; méthodes `finalize()` et `computeTotals()` ; enum status contient draft/in_progress/finished |
-| Schéma ExerciseRecord | Champs user/workout/exerciceNom/series ; refs User et Workout |
-
-### Tests d'intégration HTTP (avec base de données)
-
-| Fichier | Routes couvertes |
-|---------|-----------------|
-| `health.test.js` | `GET /health` |
-| `auth.test.js` | Register, login, verify-email, forgot/reset password |
-| `user.test.js` | `GET/PUT /me`, delete account |
-| `workout.test.js` | CRUD séances, draft, finalize, complete |
-| `exercise.test.js` | Create record, get history, get by workout |
-
-Ces tests utilisent **Supertest** et nécessitent un cluster MongoDB accessible (variable `MONGO_URI`).
+| Fichier | PérimÚtre |
+|---------|-----------|
+| `levelHelpers.test.js` | Formule XP et niveau : bornes, plafond, bijectivité |
+| `workoutAnticheat.test.js` | Anti-triche serveur sur la finalisation de séance |
+| `modelsIntegrity.test.js` | Intégrité des 8 schémas Mongoose |
+| `health.test.js` | Point de santé |
+| `auth.test.js` | Inscription, connexion, vérification, mot de passe oublié |
+| `googleAuth.test.js` | Connexion et création de compte via Google OAuth |
+| `discriminator.test.js` | Unicité du combo pseudo et discriminant |
+| `user.test.js` | Profil, cadre, vitrines, push token, onboarding, synchronisation XP, suppression de compte |
+| `workout.test.js` | CRUD séances, brouillon, finalisation, complétion |
+| `exercise.test.js` | Enregistrement de performances, historique, classement |
+| `friendship.test.js` | Demandes d'amis, acceptation, refus, retrait, recherche |
+| `socialEngine.test.js` | Classement, profil public, niveaux d'amitié |
+| `groupStreak.test.js` | Groupes, invitations, streak collective, Secouer |
+| `inventory.test.js` | Ouverture de coffres, consommation atomique, réclamation de cosmétiques |
+| `reward.test.js` | Trophées serveur, synchronisation, anniversaire |
+| `trophyUnification.test.js` | Cohérence du catalogue combiné local plus serveur |
+| `bloodSangRewards.test.js` | Attribution du cosmétique Unique de groupe |
+| `referral.test.js` | Parrainage, récompenses, garde-fous anti-triche |
+| `titles.test.js` | Déblocage et équipement des titres |
+| `activityFeed.test.js` | Flux d'activité et réactions |
+| `weight.test.js` | Historique de pesées |
+| `workoutLobby.test.js` | Cycle de vie complet du lobby multijoueur |
+| `debug.test.js` | Endpoints God Mode, blocage en production |
+| `profanityFilter.test.js` | Filtre de pseudos |
+| `deepIntegration.test.js` | Scénarios croisés de bout en bout |
---
-## âïž IntĂ©gration continue (CI)
-
-Les tests unitaires et d'intégrité (`levelHelpers`, `workoutAnticheat`, `modelsIntegrity`) sont conçus pour s'exécuter **sans base de données** dans n'importe quel environnement CI/CD.
-
-Exemple de workflow GitHub Actions :
+## Intégration continue
-```yaml
-name: Tests
+Le workflow GitHub Actions (`.github/workflows/ci.yml`) exécute deux jobs indépendants, chacun déclenché uniquement si son dossier a changé :
-on: [push, pull_request]
+- **Backend** : installation, lint ESLint, vérification syntaxique de `server.js`, audit de sécurité npm sur les dépendances de production (bloquant à partir du niveau élevé), puis suite de tests complÚte. Aucune base de données externe n'est requise, la suite Jest démarre sa propre instance en mémoire.
+- **Frontend** : installation avec `--legacy-peer-deps`, audit de sécurité npm, puis build de la PWA via `expo export --platform web`, qui détecte immédiatement tout composant natif non compatible avec le web.
-jobs:
- unit-tests:
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v4
- - uses: actions/setup-node@v4
- with:
- node-version: '22'
- cache: 'npm'
- - run: npm ci
- - run: npx jest tests/levelHelpers.test.js tests/workoutAnticheat.test.js tests/modelsIntegrity.test.js --runInBand --forceExit
-```
-
-> Les tests d'intégration HTTP (`auth`, `user`, `workout`, `exercise`) nécessitent un secret `MONGO_URI` configuré dans les variables d'environnement du runner CI.
+Un push qui ne touche que `front/` ne déclenche pas le job backend, et inversement.
---
-## đ SĂ©curitĂ©
+## Sécurité
| Mesure | Implémentation |
-|--------|---------------|
-| Passwords hashés | bcrypt avec salt rounds = 10 |
-| JWT court-vécu | Expiration 1 jour (configurable) |
-| Vérification email | OTP 6 chiffres, expiration 10 min |
+|--------|-----------------|
+| Mots de passe hashés | bcrypt |
+| JWT à courte durée de vie | Expiration configurable, 1 jour par défaut |
+| Vérification email | OTP à 6 chiffres, expiration 10 minutes |
| Brute-force OTP | Blocage aprĂšs 5 tentatives |
-| Headers sécurisés | Helmet (X-Frame-Options, CSP, HSTS, etc.) |
-| CORS | Configuré pour les origines autorisées |
-| Validation entrĂ©es | Joi sur tous les body de requĂȘte |
-| Ownership check | Chaque workout/record vérifié contre `req.user.id` |
-| Logs HTTP | Morgan en mode `dev` |
+| Headers sécurisés | Helmet (CSP, HSTS, noSniff, frameguard) |
+| CORS | Allowlist via `CORS_ORIGINS`, permissif uniquement en développement |
+| Rate limiting global | 300 requĂȘtes par 15 minutes et par IP sur `/api` |
+| Rate limiting authentification | 20 requĂȘtes par 15 minutes, clĂ© IP plus email ciblĂ© |
+| Injection NoSQL | Assainissement récursif des clés suspectes avant toute route |
+| Validation des entrĂ©es | SchĂ©mas Joi sur toutes les routes Ă corps de requĂȘte |
+| Limite de payload | 1 Mo maximum par requĂȘte |
+| Vérification de propriété | Chaque séance ou record est vérifié contre `req.user.id` |
+| Cache | `Cache-Control: no-store` sur toutes les réponses `/api` |
+| Logs HTTP | Morgan, désactivé pendant les tests |
| Variables sensibles | Jamais en dur, toujours via `.env` |
+Détail complet de l'architecture de sécurité et de résilience : `docs/ARCHITECTURE-SECURITE.md` à la racine du dépÎt.
+
---
-**Athly API** · Node.js + Express + MongoDB · Authentification JWT + OTP
+Athly API : Node.js, Express, MongoDB. Authentification par mot de passe, OTP et Google OAuth.
diff --git a/front/README.md b/front/README.md
index 0e59363..b5aee07 100644
--- a/front/README.md
+++ b/front/README.md
@@ -1,636 +1,539 @@
-# đïž ATHLY â Application Mobile de Fitness GamifiĂ©e
+# ATHLY : Application Mobile de Fitness Gamifiée
-**Tracker d'entraßnement React Native · Stockage local AsyncStorage · Gamification complÚte**
+**React Native, Expo, PWA. Stockage local AsyncStorage, gamification complĂšte, social et multijoueur**

-
-
+
+

-
+
-> Athly transforme chaque sĂ©ance d'entraĂźnement en une expĂ©rience de jeu. XP, streaks, quĂȘtes quotidiennes, trophĂ©es, rituels de rĂ©cupĂ©ration â progresser n'a jamais Ă©tĂ© aussi addictif.
+Athly transforme chaque sĂ©ance d'entraĂźnement en expĂ©rience de jeu : XP, niveaux, streaks, quĂȘtes quotidiennes, trophĂ©es, titres RPG, coffres Ă ouvrir, groupes d'amis avec streak collective, lobby multijoueur, et un tutoriel interactif qui accompagne la dĂ©couverte de toutes ces fonctionnalitĂ©s.
---
-## đ Table des matiĂšres
-
-1. [Vue d'ensemble](#-vue-densemble)
-2. [Fonctionnalités](#-fonctionnalités)
-3. [Stack technique](#-stack-technique)
-4. [Architecture](#-architecture)
-5. [Installation & lancement](#-installation--lancement)
-6. [Variables d'environnement](#-variables-denvironnement)
-7. [Structure du projet](#-structure-du-projet)
-8. [SystĂšme de gamification](#-systĂšme-de-gamification)
-9. [Contextes React](#-contextes-react)
-10. [Services](#-services)
-11. [Navigation](#-navigation)
-12. [Composants clés](#-composants-clés)
-13. [Backend associé](#-backend-associé)
+## Table des matiĂšres
+
+1. [Vue d'ensemble](#vue-densemble)
+2. [Fonctionnalités](#fonctionnalités)
+3. [Stack technique](#stack-technique)
+4. [Architecture](#architecture)
+5. [Installation et lancement](#installation-et-lancement)
+6. [Variables d'environnement](#variables-denvironnement)
+7. [Structure du projet](#structure-du-projet)
+8. [Navigation](#navigation)
+9. [Contextes React](#contextes-react)
+10. [Services](#services)
+11. [Catalogues de données](#catalogues-de-données)
+12. [SystĂšme de gamification](#systĂšme-de-gamification)
+13. [Tutoriel interactif](#tutoriel-interactif)
+14. [ParamÚtres développeur](#paramÚtres-développeur)
+15. [Tests](#tests)
+16. [Backend associé](#backend-associé)
---
-## đŻ Vue d'ensemble
+## Vue d'ensemble
-Athly est une application mobile de fitness construite avec React Native (Expo). L'application **nĂ©cessite une connexion Internet et un compte** pour fonctionner : l'authentification passe par le backend (JWT). Une fois connectĂ©, toutes les donnĂ©es de progression (logs de sĂ©ances, XP, quĂȘtes, rituels) sont stockĂ©es localement dans AsyncStorage sur l'appareil pour des performances optimales, et synchronisĂ©es avec le backend en best-effort.
+Athly est une application mobile construite avec React Native et Expo, Ă©galement buildĂ©e en PWA pour le web. Elle nĂ©cessite une connexion Internet et un compte pour fonctionner : l'authentification (mot de passe, Google OAuth, vĂ©rification email) passe obligatoirement par le backend. Une fois connectĂ©, les donnĂ©es de progression immĂ©diate (logs de sĂ©ances, XP cumulatif, streak, quĂȘtes, rituels) sont calculĂ©es et stockĂ©es localement dans AsyncStorage pour des performances instantanĂ©es, tandis que le backend fait autoritĂ© pour le profil, le social, l'inventaire et le multijoueur.
### Philosophie
| Principe | Description |
-|----------|-------------|
-| **Backend requis** | L'authentification (connexion, inscription, reset password) nécessite une connexion au backend. Sans réseau, l'app n'est pas utilisable. |
-| **DonnĂ©es locales** | Une fois connectĂ©, les logs de sĂ©ances, XP, quĂȘtes et rituels sont stockĂ©s dans AsyncStorage â les calculs se font entiĂšrement cĂŽtĂ© client. |
-| **Sync best-effort** | La finalisation d'une séance tente une sync backend, mais l'échec ne bloque pas l'utilisateur. Les données locales font foi. |
-| **Gamification profonde** | Chaque sĂ©ance rapporte des XP, alimente une streak, valide des quĂȘtes et peut dĂ©bloquer des trophĂ©es. |
-| **Anti-triche intĂ©grĂ©** | Une sĂ©ance < 5 min ne rapporte aucun XP, ne valide pas les quĂȘtes et n'incrĂ©mente pas la streak. |
-| **Récupération active** | Les jours sans séance, 5 rituels de récupération permettent de maintenir la streak (+20 à +100 XP). |
+|----------|--------------|
+| Backend requis | L'authentification nécessite une connexion réseau. Sans elle, l'application n'est pas utilisable. |
+| DonnĂ©es de sĂ©ance locales | Logs, XP, streak, quĂȘtes et rituels vivent dans AsyncStorage, les calculs se font entiĂšrement cĂŽtĂ© client. |
+| Synchronisation best effort | L'XP totale est poussée vers le backend (`POST /users/me/sync-xp`) à chaque événement clé, avec ratchet anti-régression cÎté serveur. Un échec réseau ne bloque jamais l'utilisateur, un retry automatique a lieu au prochain événement. |
+| Social et multijoueur sur backend | Amis, groupes de streak, lobby, inventaire, titres et trophées serveur sont gérés en direct par l'API : ils nécessitent le réseau. |
+| Gamification profonde | Chaque sĂ©ance rapporte de l'XP, alimente une streak, valide des quĂȘtes, peut dĂ©bloquer des trophĂ©es et des titres. |
+| Anti-triche intĂ©grĂ© | Une sĂ©ance de moins de 5 minutes ne rapporte aucun XP, ne valide aucune quĂȘte et n'incrĂ©mente pas la streak. Entre 5 et 15 minutes, l'XP est divisĂ© par 10. Le serveur applique la mĂȘme rĂšgle Ă la finalisation. |
+| Récupération active | Les jours sans séance, 5 rituels permettent de maintenir la streak. |
---
-## ⚠Fonctionnalités
-
-### đïž Gestion des sĂ©ances
-- **Timer en temps réel** pendant l'entraßnement avec chronomÚtre visible
-- **Sets & reps** : saisie poids/reps pour chaque exercice, validation par set
-- **Supersets** : regroupement de plusieurs exercices en circuit
-- **Notes** par séance et par exercice
-- **Workout Builder** : créer des séances à partir d'un catalogue de 100+ exercices
-- **Exercices personnalisés** : créer et gérer ses propres mouvements (persistés localement)
-- **Séances favorites** : sauvegarder et réutiliser ses programmes
-- **WorkoutRecapModal** : rĂ©capitulatif complet post-sĂ©ance (volume, XP gagnĂ©, nouveaux PRs, quĂȘtes validĂ©es)
-
-### đĄïž SystĂšme Anti-triche (5 minutes)
-- Une séance finalisée en **< 5 minutes** déclenche une modale d'avertissement
-- L'utilisateur peut choisir de **continuer** ou de **forcer la validation**
-- En cas de forçage : `xpEarned = 0`, flag `shortSession: true`, **aucune quĂȘte validĂ©e**, **aucun incrĂ©ment de streak**
-- **God Mode** : toggle en paramÚtres développeur pour bypasser le check
-
-### đź Gamification
-
-#### XP & Niveaux
-- Chaque séance rapporte de l'XP calculé sur le volume, le nombre de sets et le multiplicateur de streak
-- Courbe de progression **exponentielle** (base 4665, taux 1.03)
-- Cap quotidien : **2 séances XP/jour** maximum (anti-farming)
-- Les rituels de récupération ne comptent pas dans le cap quotidien
-
-#### Streak
-- La streak s'incrémente si au moins **1 log valide** (pas `shortSession`) est posé dans la journée
-- Les rituels de récupération comptent pour la streak
-- **8 paliers de multiplicateur** : jusqu'Ă Ă7.0 Ă 730 jours consĂ©cutifs
-
-#### QuĂȘtes quotidiennes
-- **3 quĂȘtes** tirĂ©es parmi 20 templates, dĂ©terministes par la date (reproductibles)
-- Exemples : "Faire 25 séries", "Terminer en < 45 min", "Travailler les jambes", "Battre un PR"
-- ComplĂ©ter les 3 quĂȘtes dĂ©bloque un **bonus de 1000 XP supplĂ©mentaires**
-- Les sĂ©ances `shortSession` ne valident **aucune** quĂȘte
-
-#### Trophées
-- **50+ trophées** catégorisés (Régularité, Volume, Force, Diversité, Spéciaux)
-- Ăvaluation automatique post-sĂ©ance et au chargement du profil
-- **Trophy Room** : galerie avec états verrouillé/débloqué, animations
-
-### đ§ Rituels de RĂ©cupĂ©ration Active
-5 rituels disponibles les jours sans séance (ou en complément) :
+## Fonctionnalités
-| Rituel | Mécanique | XP |
-|--------|-----------|-----|
-| **Mobilité & Souplesse** | Timer 5 min | +20 XP |
-| **Marche Quotidienne** | Timer 15 min | +100 XP |
-| **Respiration & Mental** | Cercle animé inspire/expire · 5 min | +20 XP |
-| **Automassage** | 5 zones Ă 1 min (Mollets â Ăpaules) | +20 XP |
-| **Focus & Culture** | Article à lire · timer 5 min bloquant | +20 XP |
-
-- 1 rituel maximum par jour calendaire
-- Compte pour la streak (mĂȘme valeur qu'une vraie sĂ©ance)
-- XP non soumis au cap quotidien de 2 séances
-
-### đ Statistiques
-- Volume total, sets complétés, distribution musculaire (camembert)
-- Graphe de progression par exercice (LineChart)
-- Historique complet des séances avec filtres et tri
-- Nouveaux PRs (Personal Records) détectés automatiquement aprÚs chaque séance
-
-### đ Tutoriel interactif
-- SystĂšme **step-by-step** avec overlay semi-transparent
-- Met en surbrillance les éléments de l'UI ciblés
-- Auto-scroll vers les éléments mis en avant
-- Chapitres : **Dashboard** (6 étapes) + **Workout** (6 étapes)
-- Inclut une étape dédiée au systÚme anti-triche et aux rituels
-
-### đ€ Profil & Personnalisation
-- Données physiques (poids, taille, ùge, objectif, rythme)
-- Ăquipements disponibles pour la recommandation d'exercices
-- **ThĂšmes de profil** : plusieurs palettes visuelles
-- Suppression de compte RGPD (cascade sur toutes les données)
+### Gestion des séances
+
+Timer en temps rĂ©el, saisie poids et rĂ©pĂ©titions par sĂ©rie, supersets, notes par sĂ©ance et par exercice, Workout Builder pour gĂ©nĂ©rer une sĂ©ance sur mesure Ă partir d'un catalogue de plus de 350 exercices, crĂ©ation manuelle exercice par exercice, exercices personnalisĂ©s persistĂ©s localement, sĂ©ances sauvegardĂ©es comme modĂšles rĂ©utilisables (modifiables aprĂšs coup, avec les mĂȘmes critĂšres de gĂ©nĂ©ration prĂ©-remplis), rĂ©capitulatif complet post-sĂ©ance (volume, XP gagnĂ©, nouveaux records, quĂȘtes validĂ©es).
+
+### Anti-triche
+
+Une sĂ©ance finalisĂ©e en moins de 5 minutes dĂ©clenche une modale d'avertissement. L'utilisateur peut modifier la sĂ©ance ou forcer la validation : dans ce cas, l'XP gagnĂ© est nul, la sĂ©ance est marquĂ©e `shortSession`, aucune quĂȘte n'est validĂ©e et la streak n'est pas incrĂ©mentĂ©e. Le backend applique la mĂȘme logique Ă la finalisation, indĂ©pendamment du client.
+
+### Gamification
+
+XP et niveaux sur une courbe exponentielle, streak avec 8 paliers de multiplicateur jusqu'Ă 7 fois l'XP de base, 3 quĂȘtes quotidiennes tirĂ©es parmi 20 modĂšles de façon dĂ©terministe par la date (tout le monde a les mĂȘmes quĂȘtes le mĂȘme jour), rangs de Novice Ă ATHLY GOD, catalogue de plus de 60 trophĂ©es rĂ©parti en 9 catĂ©gories, 17 titres RPG dĂ©blocables et Ă©quipables sous le pseudo.
+
+### Coffres et inventaire
+
+Un coffre toutes les 2 heures de séance cumulées, débloqué au rang Initié (niveau 11). Ouverture avec animation, table de drop par rareté (commune, rare, épique, légendaire, unique), objets consommables (boissons d'XP, gels de streak, boosts de multiplicateur, coupons de niveau), cosmétiques Unique Rouge Sang réclamables sous conditions rares.
+
+### Social
+
+Ajout d'ami par tag unique façon Discord, aperçu de profil avant envoi de la demande, classement XP entre amis, classement par exercice, profil public consultable, niveaux d'amitié progressifs, flux d'activité avec réactions (bravo, respect, hue, jaloux) sur les records et coffres légendaires des amis.
+
+### Groupes de streak
+
+Groupe de 5 membres maximum, invitations, streak collective (validĂ©e si tous les membres valident leur journĂ©e), mĂ©tĂ©o des sĂ©ances en direct (statut prĂȘt, actif, validĂ© de chaque membre), bouton Secouer pour relancer un retardataire par notification, Hall of Shame si la streak casse, rĂ©compense cosmĂ©tique Unique Ă 30 jours de streak collective Ă taille maximale.
+
+### Lobby multijoueur
+
+Invitation d'amis pour démarrer une séance ensemble, chacun sur son propre appareil, bonus d'XP de groupe croissant selon le nombre de participants (15 à 50 pour cent).
+
+### Statistiques
+
+Volume total, sets complétés, répartition musculaire en camembert, graphe de progression par exercice, suivi de poids avec objectif et rappel hebdomadaire, historique complet des séances avec filtres, détection automatique des nouveaux records personnels.
+
+### Profil et personnalisation
+
+Données physiques, équipements disponibles, cadre de profil personnalisable (forme et couleur), thÚmes visuels débloqués par la progression, vitrine de trophées et de records mis en avant, roadmap des rangs, célébration d'anniversaire, systÚme de parrainage avec récompenses pour les deux parties, suppression de compte RGPD en cascade.
+
+### Tutoriel interactif
+
+SystÚme de spotlight en huit chapitres qui met en surbrillance les éléments réels de l'interface, avec démonstrations en direct, auto-scroll vers les éléments ciblés, et persistance de la complétion à la fois localement et cÎté serveur pour une cohérence entre appareils.
---
-## đ Stack technique
+## Stack technique
| Couche | Technologie | Version |
|--------|-------------|---------|
| Framework | React Native | 0.81.5 |
-| Environnement | Expo | ~54.0.27 |
-| Navigation | React Navigation | 7.x |
+| Runtime React | React | 19.1.0 |
+| Environnement | Expo | 54.x |
+| Navigation | React Navigation (native, bottom-tabs, stack, native-stack) | 7.x |
| Stockage local | AsyncStorage | 2.2.0 |
-| Token sécurisé | Expo SecureStore | ~15.0.8 |
-| HTTP client | Axios | ^1.16.0 |
-| Animations | Lottie React Native | ~7.3.1 |
-| Graphiques | React Native Chart Kit | ^6.12.2 |
-| SVG | React Native SVG | 15.12.1 |
-| IcĂŽnes | @expo/vector-icons (Ionicons) | ^15.0.3 |
-| Haptics | Expo Haptics | ~15.0.8 |
-| Gradients | Expo Linear Gradient | ~15.0.8 |
-| Gestures | React Native Gesture Handler | ~2.28.0 |
+| Token sécurisé | Expo SecureStore | 15.x |
+| HTTP client | Axios | 1.18 |
+| Animations | Lottie React Native | 7.3.1 |
+| Graphiques | React Native Chart Kit | 6.12 |
+| SVG | React Native SVG | 15.12 |
+| IcĂŽnes | Expo Vector Icons (Ionicons) | 15.x |
+| Haptique | Expo Haptics | 15.x |
+| Dégradés | Expo Linear Gradient | 15.x |
+| Gestes | React Native Gesture Handler | 2.28 |
+| Notifications | Expo Notifications | 0.32 |
+| Authentification Google | Expo Auth Session | 7.x |
+| Support web | React Native Web | 0.19 |
+| Variables d'environnement | react-native-dotenv | 3.x |
+| Tests | Jest, Babel Jest | 29.x |
---
-## đ Architecture
+## Architecture
+
+### Répartition backend et stockage local
+
+```
+Nécessite le backend, réseau requis
+ - Connexion, inscription, réinitialisation de mot de passe, connexion Google
+ - Profil utilisateur, cadre équipé, vitrines
+ - Amis, groupes de streak, lobby multijoueur, inventaire, coffres
+ - Titres RPG, trophées serveur, parrainage, anniversaire
+ - Synchronisation de l'XP totale (best effort, ne bloque jamais)
+
+Stocké localement (AsyncStorage)
+ - Logs de séances, XP cumulatif, streak
+ - QuĂȘtes quotidiennes et Ă©tat du bonus
+ - Rituels de récupération
+ - Exercices personnalisés, séances sauvegardées
+ - Progression et complétion du tutoriel interactif
+ - ParamÚtres développeur (God Mode, bypass anti-triche)
+```
-### Répartition backend / stockage local
+### Arbre de providers
```
-âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
-â NĂCESSITE LE BACKEND (rĂ©seau requis) â
-â âą Connexion / Inscription / Reset password â
-â âą RĂ©cupĂ©ration du profil utilisateur â
-â âą Catalogue d'exercices WGER â
-â âą Sync sĂ©ances (best-effort, ne bloque pas si KO) â
-âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
-
-âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
-â STOCKĂ LOCALEMENT (AsyncStorage) â
-â âą Logs de sĂ©ances, XP cumulatif, streak â
-â âą QuĂȘtes quotidiennes et Ă©tat bonus â
-â âą Rituels de rĂ©cupĂ©ration â
-â âą Exercices personnalisĂ©s, sĂ©ances favorites â
-â âą ParamĂštres dĂ©veloppeur (God Mode, bypassâŠ) â
-âââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââââ
-
-âââââââââââââââââââââââââââââââââââââââââââââââââââââââ
-â COMPOSANT UI â
-ââââââââââââââââââââââŹâââââââââââââââââââââââââââââââââ
- â
-ââââââââââââââââââââââŒâââââââââââââââââââââââââââââââââ
-â CONTEXT (Ă©tat global React) â
-â WorkoutLogsContext · QuestContext · TutorialContext â
-âââââââââââââŹââââââââââââââââââââââââââŹââââââââââââââââ
- â read/write â best-effort
-âââââââââââââŒâââââââââââ âââââââââââŒâââââââââââââââ
-â AsyncStorage â â API Backend â
-â (source de vĂ©ritĂ© â â (auth + sync) â
-â pour les logs) â â â
-ââââââââââââââââââââââââ âââââââââââââââââââââââââ-â
+NavigationContainer
+ TutorialProvider
+ UserProvider
+ WorkoutLogsProvider
+ SavedWorkoutsProvider
+ CustomExercisesProvider
+ QuestProvider
+ AuthStack (non connecté)
+ ou BottomTabs (connecté), avec en overlay :
+ BirthdayCelebration, LevelUpCelebration,
+ ActivityFeedModal, WeightReminderCheck, LobbyInviteCheck
```
-### Finalisation d'une séance (WorkoutInProgressContext)
+### Finalisation d'une séance
```
handleTerminate()
- â
- âââ elapsed < 5 min && !bypassAnticheat ?
- â âââ ShortSessionWarningModal
- â âââ "Modifier" â retour sĂ©ance
- â âââ "Forcer" â finalizeWithLog({ shortSession: true })
- â
- âââ finalizeWithLog({ durationSeconds, notes, ... })
- â
- âââ buildLogFromWorkout() // calcul XP, volume, muscleDistribution
- âââ shortSession ? xpEarned = 0 : normal
- âââ workoutLogs.create(log) // AsyncStorage (toujours)
- âââ !shortSession â questContext.checkAndUpdateQuests()
- âââ bundle.actions.finalize() // sync backend (best-effort)
+ elapsed < 5 minutes et bypass non activé
+ -> ShortSessionWarningModal
+ Modifier : retour à la séance
+ Forcer : finalise avec shortSession = true
+
+ finalizeWithLog(...)
+ buildLogFromWorkout() calcule XP, volume, répartition musculaire
+ shortSession ? xpEarned = 0 : calcul normal avec multiplicateur de streak
+ workoutLogs.create(log) écriture AsyncStorage, toujours exécutée
+ !shortSession -> questContext.checkAndUpdateQuests()
+ actions.finalize() synchronisation backend, best effort
+ xpSync.service -> POST /users/me/sync-xp avec le nouveau total
```
---
-## đ Installation & lancement
+## Installation et lancement
### Prérequis
-- Node.js â„ 18
-- npm ou yarn
+- Node.js 18 ou supérieur
- Expo CLI (`npm install -g expo-cli`)
-- Expo Go sur votre téléphone (iOS ou Android) **ou** un émulateur
+- Expo Go sur un téléphone, ou un simulateur iOS ou Android, ou un navigateur pour la version web
### Ătapes
```bash
-# 1. Cloner le dépÎt
git clone https://github.com/ClemLy/Athly.git
cd Athly/front
-# 2. Installer les dépendances
npm install
-# 3. Configurer les variables d'environnement
cp .env.example .env
-# Ăditer .env avec l'URL de votre backend (voir section suivante)
-
-# 4. Lancer le serveur de développement
-npm start
+# Ăditer .env avec l'URL de votre backend, voir la section suivante
-# Alternatives ciblées
-npm run android # Lancer sur émulateur Android
-npm run ios # Lancer sur simulateur iOS (macOS requis)
-npm run web # Lancer dans le navigateur
+npm start # Metro bundler, QR code Expo Go
+npm run android # émulateur Android
+npm run ios # simulateur iOS, macOS requis
+npm run web # navigateur
+npm run build:web # build PWA de production (expo export puis copie du service worker)
```
-Expo affichera un QR code à scanner avec Expo Go sur votre téléphone.
-
---
-## đ Variables d'environnement
-
-Créer un fichier `.env` à la racine de `athly-app/` :
+## Variables d'environnement
```env
-# URL de l'API backend (remplacer par votre IP locale en développement)
+# URL de l'API backend. En développement local, utiliser l'IP de la machine
+# sur le réseau local, jamais "localhost" : un téléphone physique ne peut pas
+# le résoudre.
API_URL=http://VOTRE_IP_LOCALE:4000/api
-# Clé de stockage du token JWT dans SecureStore
+# Clé de stockage du token JWT dans Expo SecureStore
TOKEN_KEY=athly_token
-# Environnement (development | production)
+# development ou production
APP_ENV=development
+
+# Client IDs Google OAuth (un par plateforme, type d'application différent
+# pour chacun). Tant qu'ils ne sont pas renseignés, le bouton Google reste
+# désactivé cÎté client.
+GOOGLE_EXPO_CLIENT_ID=
+GOOGLE_IOS_CLIENT_ID=
+GOOGLE_ANDROID_CLIENT_ID=
+GOOGLE_WEB_CLIENT_ID=
```
-> **Important :** En dĂ©veloppement local, utilisez votre adresse IP sur le rĂ©seau local (pas `localhost` â React Native ne peut pas rĂ©soudre `localhost` sur tĂ©lĂ©phone physique).
+Trouver son IP locale : `ipconfig` sous Windows, `ifconfig` ou `ip addr` sous macOS et Linux.
---
-## đ Structure du projet
+## Structure du projet
```
-athly-app/
-âââ index.js # Point d'entrĂ©e Expo
-âââ App.js # Root : providers + navigation
-âââ app.json # Configuration Expo
-âââ .env # Variables d'environnement
-â
-âââ assets/
-â âââ icon.png, adaptive-icon.png, splash-icon.png
-â âââ logo-orange.png, logo-violet.png
-â âââ animations/
-â âââ confetti.json # Animation Lottie (quĂȘte bonus)
-â
-âââ src/
- âââ api/
- â âââ api.js # Instance Axios (JWT auto-inject, 401 handler)
- â
- âââ context/ # Ătat global React (9 contextes)
- â âââ AuthContext.js
- â âââ UserContext.js
- â âââ WorkoutInProgressContext.js
- â âââ WorkoutLogsContext.js
- â âââ CustomExercisesContext.js
- â âââ SavedWorkoutsContext.js
- â âââ QuestContext.js
- â âââ TutorialContext.js
- â âââ ToastContext.js
- â
- âââ screens/ # 23 Ă©crans
- â âââ Auth/ # AuthScreen, Login, Register, Verify, ForgotPassword
- â âââ Home/ # HomeScreen
- â âââ Workouts/ # WorkoutScreen, Builder, List, Detail, ExerciseStatsâŠ
- â âââ Profile/ # Profile, Edit, Settings, RankRoadmap, TrophyRoom
- â âââ Stats/ # StatsScreen
- â
- âââ components/ # 47 composants rĂ©utilisables
- â âââ home/ # DailyQuestsCard, RecoveryRitualsCard, QuickStatsRowâŠ
- â âââ workouts/ # SetTable, AddExerciseSheet, ShortSessionWarningModalâŠ
- â âââ cards/ # ExerciseCard, WorkoutItem, StatBoxâŠ
- â âââ profile/ # TrophyGrid, EmberParticles
- â âââ tutorial/ # TutorialOverlay
- â âââ ui/ # AppToast
- â
- âââ services/ # Logique mĂ©tier
- â âââ stats.service.js # XP, streak, logs AsyncStorage (source de vĂ©ritĂ©)
- â âââ quest.service.js # 20 templates · 3 quĂȘtes/jour dĂ©terministes
- â âââ auth.service.js # API auth
- â âââ workout.service.js # API workouts
- â âââ customExercises.service.js
- â âââ savedWorkouts.service.js
- â
- âââ hooks/ # Custom hooks
- â âââ useWorkoutState.js # Reducer pattern pour l'Ă©tat sĂ©ance
- â âââ useEffortTimer.js # ChronomĂštre sĂ©ance
- â âââ useDevSettings.js # ParamĂštres dĂ©veloppeur (God Mode, bypassâŠ)
- â âââ useExerciseSorting.js
- â
- âââ data/ # DonnĂ©es statiques
- â âââ exerciseCatalog.js # 100+ exercices avec muscles cibles
- â âââ trophyCatalog.js # 50+ dĂ©finitions de trophĂ©es
- â âââ tutorialChapters.js # Ătapes du tutoriel
- â âââ workoutTemplates.js # Programmes prĂ©dĂ©finis
- â âââ ritualTypes.js # 5 rituels de rĂ©cupĂ©ration
- â âââ profileThemes.js # ThĂšmes visuels du profil
- â
- âââ navigation/
- â âââ index.js # AppNavigator (Auth vs App)
- â âââ AuthStack.js
- â âââ BottomTabs.js # 5 onglets
- â âââ WorkoutStack.js
- â âââ ProfileStack.js
- â
- âââ constants/
- â âââ theme.js # Design tokens (Colors, MUSCLE_GROUP_COLORS)
- â âââ exerciseFilters.js # Mapping muscles/Ă©quipements
- â
- âââ styles/
- âââ global.js # Styles utilitaires partagĂ©s
+front/
+ index.js Point d'entrée Expo
+ App.js Composant racine, wrapping des providers
+ app.json Configuration Expo, y compris la PWA
+ eas.json Profils de build EAS
+ web/index.html Shell HTML pour le build web
+
+ assets/
+
+ src/
+ api/
+ api.js Instance Axios : injection du JWT, gestion du 401
+
+ context/ 9 contextes React
+ AuthContext.js
+ UserContext.js
+ WorkoutInProgressContext.js
+ WorkoutLogsContext.js
+ CustomExercisesContext.js
+ SavedWorkoutsContext.js
+ QuestContext.js
+ TutorialContext.js
+ ToastContext.js
+
+ screens/ 21 écrans
+ Auth/ Login, Register, EmailVerification, ForgotPassword
+ Home/ HomeScreen
+ Workouts/ WorkoutList, Workout, Builder, ManualCreator,
+ ExerciseDetail, ExerciseStats, EditExercise,
+ CustomExercises
+ Social/ SocialScreen, FriendProfileScreen
+ Stats/ StatsScreen
+ Profile/ Profile, EditProfile, Settings, RankRoadmap,
+ TrophyRoom, Inventory
+
+ components/ Organisés par domaine
+ home/ Cartes du tableau de bord, rituels de récupération
+ workouts/ Feuille d'ajout d'exercice, lobby multijoueur,
+ modale de sauvegarde, avertissement anti-triche
+ cards/ Cartes d'exercices réutilisables
+ profile/ Cadre d'avatar, vitrine de trophées, célébrations
+ social/ Modales d'amis, de groupe, flux d'activité
+ inventory/ Modale d'ouverture de coffre
+ stats/ Graphiques, calendrier, historique
+ tutorial/ Overlay du tutoriel interactif
+ common/ Modales partagées, barrel d'export
+ inputs/, ui/, web/ Composants transverses
+
+ services/ Barrel d'export unique, 17 fichiers
+ stats.service.js XP, streak, logs AsyncStorage, source de vérité locale
+ quest.service.js ModĂšles de quĂȘtes, sĂ©lection dĂ©terministe du jour
+ auth.service.js, workouts.service.js, savedWorkouts.service.js,
+ customExercises.service.js, social.service.js, inventory.service.js,
+ reward.service.js, title.service.js, weight.service.js,
+ xpSync.service.js, onboarding.service.js, profile.service.js,
+ lobby.service.js, debug.service.js, haptics.service.js,
+ notificationService.js
+
+ hooks/ Barrel d'export unique
+ useWorkoutState.js Pattern reducer pour l'état de séance en cours
+ useEffortTimer.js ChronomÚtre de séance
+ useDevSettings.js ParamĂštres God Mode
+ useExerciseSorting.js
+ useAvatarFrame.js
+ useFeaturedTrophies.js
+ useGoogleAuth.js
+
+ data/ Catalogues statiques
+ exerciseCatalog.js Plus de 350 exercices avec muscles ciblés
+ trophyCatalog.js Catalogue local de trophées et filtres
+ backendTrophyCategories.js Correspondance des catégories serveur
+ tutorialChapters.js 8 chapitres du tutoriel interactif
+ workoutTemplates.js Programmes prédéfinis
+ ritualTypes.js 5 rituels de récupération
+ profileThemes.js ThĂšmes visuels du profil
+ majorExercises.js Exercices de référence pour les classements
+
+ navigation/
+ index.js AppNavigator : bascule Auth ou App, providers globaux
+ AuthStack.js
+ BottomTabs.js 5 onglets
+ WorkoutStack.js
+ ProfileStack.js
+ SocialStack.js
+
+ constants/
+ theme.js Jetons de design (Colors, MUSCLE_GROUP_COLORS)
+ exerciseFilters.js Correspondance muscles et équipements
```
---
-## đź SystĂšme de gamification
+## Navigation
-### Calcul de l'XP par séance
+```
+AppNavigator (racine)
+ Non connecté : AuthStack
+ Auth (LoginScreen)
+ Register
+ EmailVerification
+ ForgotPassword
+
+ Connecté : BottomTabs, 5 onglets
+ Accueil HomeScreen
+ Séances WorkoutStack
+ WorkoutList, WorkoutBuilder, ManualWorkoutCreator, CustomExercises,
+ EditExercise, Workout (séance en cours), ExerciseDetail, ExerciseStats
+ Stats StatsScreen
+ SocialTab SocialStack
+ SocialHub, FriendProfile
+ ProfileTab ProfileStack
+ ProfileMain, EditProfile, RankRoadmap, TrophyRoom, Settings, Inventory
+```
-```javascript
-// 1. XP de base (calculé par buildLogFromWorkout)
-baseXP = volume * 0.12 + setsCompleted * 8 + totalExercises * 15
+---
-// 2. Multiplicateur de streak
-xpEarned = round(baseXP * streakMultiplier)
+## Contextes React
-// 3. Bonus séance longue (> 15 min)
-// Normal : aucun modificateur négatif
-// Séance courte (< 15 min mais > 5 min) : XP ÷ 10
-// Séance trop courte (< 5 min, forcée) : XP = 0
-```
+### WorkoutLogsContext
-### Niveaux
+Source de vérité principale pour l'historique de séances, persistée dans AsyncStorage. Expose la liste complÚte des logs, les logs de séances seules, les logs comptant pour la streak, l'XP cumulatif, ainsi que les opérations de création, suppression et ajout de rituel.
-```javascript
-// XP nécessaire pour le niveau N
-xpForLevel(n) = 4665 * (1.03^n - 1) / (1.03 - 1)
-
-// Exemples
-Niveau 1 â 140 XP total
-Niveau 10 â 1 604 XP total
-Niveau 30 â 6 657 XP total
-Niveau 100 â 85 000 XP total
-```
+### QuestContext
-### Multiplicateurs de streak
+Les 3 quĂȘtes du jour, le nombre complĂ©tĂ©, l'Ă©tat du bonus, et la fonction qui Ă©value une sĂ©ance terminĂ©e contre les quĂȘtes actives.
-| Streak | Multiplicateur | Label |
-|--------|---------------|-------|
-| 0 jour | Ă1.0 | â |
-| 3 jours | Ă1.1 | On Fire đ„ |
-| 7 jours | Ă1.2 | Week Warrior âïž |
-| 30 jours | Ă1.5 | Godly Streak đ |
-| 90 jours | Ă2.0 | 3 Mois de Feu đ |
-| 180 jours | Ă3.0 | Semi-Annuel đ |
-| 365 jours | Ă4.5 | Streak Annuel đ |
-| 730 jours | Ă7.0 | Streak LĂ©gendaire ⥠|
+### TutorialContext
-### QuĂȘtes quotidiennes
+Machine à états du tutoriel interactif : chapitre actif, étape courante, cibles enregistrées par les écrans, fonctions de scroll et de re-mesure, complétion locale et réconciliation avec le flag serveur.
+
+### WorkoutInProgressContext
-3 quĂȘtes sont sĂ©lectionnĂ©es chaque jour parmi 20 templates (sĂ©lection dĂ©terministe par hash de la date â tout le monde a les mĂȘmes quĂȘtes le mĂȘme jour) :
+Ătat de la sĂ©ance en cours (reducer), actions d'ajout et de modification de sets et d'exercices, et la fonction `finalize` qui orchestre le log local, la validation des quĂȘtes et la synchronisation backend.
-```javascript
-// Exemples de templates
-{ id: 'volume_10k', check: log => log.totalVolume >= 10000 }
-{ id: 'sets_25', check: log => log.setsCompleted >= 25 }
-{ id: 'duration_45', check: log => log.durationSeconds <= 2700 }
-{ id: 'legs_day', check: log => log.muscleDistribution.jambes >= 40 }
-{ id: 'new_pr', check: (_, prs) => prs.length > 0 }
-```
+### UserContext
+
+Profil utilisateur courant, récupéré depuis le backend, avec fonction de rafraßchissement.
+
+### AuthContext
+
+Token JWT, état de chargement initial, connexion et déconnexion.
-- ComplĂ©ter **1 quĂȘte** : +500 XP
-- ComplĂ©ter **les 3 quĂȘtes** : +1000 XP bonus (animation confetti)
+### SavedWorkoutsContext, CustomExercisesContext
+
+CRUD des séances sauvegardées et des exercices personnalisés, persistés dans AsyncStorage.
+
+### ToastContext
+
+File de notifications toast affichées en overlay.
---
-## đ§© Contextes React
+## Services
-### WorkoutLogsContext
+Tous les services sont exposés via un barrel unique (`src/services/index.js`), ce qui permet des imports courts comme `import { getFriendsList, haptics } from '../services'`.
-Source de vérité principale pour l'historique des séances. Persiste dans AsyncStorage.
+### stats.service.js
-```javascript
-const {
- items, // Tous les logs (sĂ©ances + rituels + quĂȘtes)
- sessionLogs, // Logs séances uniquement (pas rituels, pas quest_reward)
- activityLogs, // Pour calcul streak (pas shortSession, pas quest_reward)
- loading, error,
- refresh,
- create(log), // Ajouter log
- remove(id), // Supprimer log
- addRitual(ritualId, label, duration, xpEarned), // Rituel de récupération
- totalXP, // XP cumulatif
- clearAll, // Debug uniquement
-} = useWorkoutLogs();
-```
+Le service le plus important : gestion complÚte des logs AsyncStorage, calcul de l'XP par séance, du streak, du multiplicateur, du niveau, des rangs, de la répartition musculaire, détection des nouveaux records.
-### QuestContext
+### quest.service.js
-```javascript
-const {
- quests, // [{id, label, icon, completed, xp}] Ă 3
- bonusClaimed, // Bonus 3/3 quĂȘtes dĂ©jĂ rĂ©clamĂ©
- completedCount, // 0-3
- checkAndUpdateQuests(log, newPRs), // â {completedQuests, bonusUnlocked, questXP}
- refresh,
-} = useQuests();
-```
+Chargement des quĂȘtes du jour, sĂ©lection dĂ©terministe par hash de date parmi 20 modĂšles, vĂ©rification et marquage de complĂ©tion.
-### TutorialContext
+### workouts.service.js
-```javascript
-const {
- isActive, activeChapterId, stepIndex,
- hasCompleted, pendingChapterId,
- targets,
- registerTarget(key, rect),
- registerScrollRef(chapterId, ref),
- registerRemeasure(chapterId, fn),
- scrollToStep(chapterId, y),
- startChapter(chapterId),
- nextStep, prevStep, finishChapter,
- bootstrapped,
-} = useTutorial();
-```
+Cycle de vie cÎté backend des séances : création de brouillon, mise à jour, finalisation, complétion.
-### WorkoutInProgressContext
+### api.js
-```javascript
-const {
- state, // {id, name, exercises, notes, status, durationSeconds}
- dispatch,
- actions: {
- finalize, // = finalizeWithLog() â log local + sync backend
- addSet, updateSet, removeSet,
- addExercise, removeExercise,
- updateNotes,
- },
- loadWorkout(workout),
- addExerciseToWorkout(exercise),
-} = useWorkoutInProgress();
-```
+Instance Axios : URL de base depuis `.env`, timeout, injection automatique du Bearer token, et sur une réponse 401, déconnexion automatique avec message de session expirée.
---
-## âïž Services
+## Catalogues de données
-### stats.service.js (AsyncStorage)
+### exerciseCatalog.js
-Le service le plus important â toute la logique locale de logs et de calculs XP.
+Plus de 350 exercices, chacun avec son groupe musculaire, son muscle cible principal, ses muscles secondaires, son équipement requis, son niveau de difficulté, et un indicateur de mouvement composé ou d'isolation.
-```javascript
-// CRUD logs AsyncStorage
-listLogs() â WorkoutLog[]
-addLog(log) â WorkoutLog (avec cap 2 XP/jour)
-removeLog(id) â void
-addRitualLog(ritualId, label, duration, xpEarned) â WorkoutLog | null (max 1/jour)
-
-// Calculs purs
-buildLogFromWorkout(stateSnapshot, prevLogs) â WorkoutLog complet
-findNewPRsInLog(log, allLogs) â PR[]
-computeStreak(logs) â number
-getStreakMultiplier(streak) â {multiplier, label, color, tier}
-xpForLevel(n) â number
-totalCumulativeXP(logs) â number
-```
+### trophyCatalog.js
-### quest.service.js
+40 trophées locaux répartis en 8 catégories (Héritage, Force, Exploration, Secret, Corps, Régularité, Social, Spécial), plus le trophée capstone Souverain Absolu. Combiné avec les 20 trophées serveur (catégorie Collection notamment), le total dépasse 60 trophées répartis en 9 catégories affichées dans la Salle des Trophées.
-```javascript
-loadTodayQuests() â {date, quests, bonusClaimed}
-checkAndMarkQuests(log, prs) â {completedIds, bonusUnlocked}
-saveTodayQuests(state)
-getTemplateById(id) â Template
-```
+### tutorialChapters.js
-### api.js (instance Axios)
+8 chapitres correspondant aux grands écrans de l'application : Dashboard, Entraßnement, Profil et Vitrine, Salle des Trophées, Inventaire, Social, Statistiques, Réglages.
-- **URL de base** : `API_URL` depuis `.env`
-- **Timeout** : 10 secondes
-- **Intercepteur requĂȘte** : injecte automatiquement `Authorization: Bearer {token}`
-- **Intercepteur rĂ©ponse** : sur 401 â appelle `signOut()` + message "Session expirĂ©e"
+### ritualTypes.js
----
+5 rituels de récupération active.
-## đș Navigation
+| Rituel | Mécanique | XP |
+|--------|-----------|-----|
+| Mobilité et souplesse | Minuteur de 5 minutes | 20 |
+| Marche quotidienne | Minuteur de 15 minutes | 100 |
+| Respiration et mental | Cercle animé inspire et expire, 5 minutes | 20 |
+| Automassage | 5 zones d'une minute chacune | 20 |
+| Focus et culture | Article Ă lire, minuteur bloquant de 5 minutes | 20 |
-```
-AppNavigator (root)
-âââ {!userToken} AuthStack
-â âââ AuthScreen (landing)
-â âââ LoginScreen
-â âââ RegisterScreen
-â âââ EmailVerificationScreen
-â âââ ForgotPasswordScreen
-â
-âââ {userToken} BottomTabs (5 onglets)
- âââ đ HomeScreen
- âââ đȘ WorkoutStack
- â âââ WorkoutListScreen
- â âââ WorkoutScreen (sĂ©ance en cours)
- â âââ WorkoutBuilderScreen
- â âââ WorkoutDetailScreen
- â âââ ManualWorkoutCreatorScreen
- â âââ ExerciseDetailScreen
- â âââ ExerciseStatsScreen
- â âââ EditExerciseScreen
- â âââ CustomExercisesScreen
- âââ đ StatsScreen
- âââ đ€ ProfileStack
- âââ ProfileScreen
- âââ EditProfileScreen
- âââ SettingsScreen
- âââ RankRoadmapScreen
- âââ TrophyRoomScreen
-```
+Un rituel maximum par jour calendaire. Compte pour la streak au mĂȘme titre qu'une sĂ©ance, et son XP n'est pas soumis au plafond quotidien.
---
-## đš Composants clĂ©s
-
-### `RecoveryRitualsCard`
-Carte affichée sur HomeScreen les jours sans séance. Propose 5 rituels de récupération, chacun avec son propre composant interactif :
-- `CountdownTimer` â timer circulaire standard (mobilitĂ©, marche)
-- `BreathingTimer` â cercle animĂ© inspire (4s) / expire (6s)
-- `FoamRollingTimer` â 5 zones Ă 60s avec dots de progression
-- `FocusReader` â article alĂ©atoire parmi 3, timer 5 min bloquant
+## SystĂšme de gamification
-### `ShortSessionWarningModal`
-Modale animée (spring) déclenchée si la séance dure < 5 min :
-- "Modifier la sĂ©ance" â reprend l'entraĂźnement
-- "Valider quand mĂȘme (0 XP)" â sauvegarde avec `shortSession: true`
-
-### `WorkoutRecapModal`
-Récapitulatif post-séance :
-- Volume total, sets complétés, durée, XP gagné
-- Nouveaux PRs battus
-- QuĂȘtes validĂ©es dans la sĂ©ance
-- Animation confetti si bonus 3/3 quĂȘtes
+### Calcul de l'XP par séance
-### `TutorialOverlay`
-Overlay semi-transparent avec :
-- Découpe transparente autour de l'élément cible (`registerTarget`)
-- Bulle de texte positionnée dynamiquement (top/bottom/center)
-- Boutons Précédent / Suivant / Terminer
+```javascript
+// Par exercice, calculé en local (stats.service.js)
+xp += setsCompleted * 10 + (volume * multiplicateur) / 20
+// multiplicateur = 1.2 si l'exercice est un mouvement composé, sinon 1
-### `DailyQuestsCard`
-Affiche les 3 quĂȘtes du jour avec progression, labels, icĂŽnes et le statut du bonus.
+// Multiplicateur de streak appliqué au total
+xpEarned = round(xp * streakMultiplier)
-### Design System (`src/constants/theme.js`)
+// Anti-triche temporel
+// moins de 5 minutes, forcé : xpEarned = 0
+// entre 5 et 15 minutes : xpEarned = xpEarned / 10
+// 15 minutes ou plus : XP plein
+```
-Toutes les couleurs passent par des tokens centralisés :
+### Niveaux
```javascript
-Colors.primary // #FE7439 (orange â accent principal)
-Colors.secondaryAccent // #6E6AF0 (violet)
-Colors.valid // #22C55E (vert validation)
-Colors.warningAmber // #F59E0B (avertissement)
-Colors.textPrimary // blanc pleine opacité
-Colors.textSecondary // blanc ~70%
-Colors.textMuted // blanc ~45%
-Colors.card // fond carte
-Colors.background // fond général (dark)
+xpForLevel(n) = round(4665 * (1.03 ** min(n, 200) - 1))
+// niveau 1 environ 140 XP, niveau 10 environ 1600 XP,
+// niveau 100 environ 85 000 XP, niveau 200 environ 1 720 000 XP
```
+### Multiplicateurs de streak
+
+| Streak | Multiplicateur | Label |
+|--------|-----------------|-------|
+| 0 jour | x1.0 | |
+| 3 jours | x1.1 | On Fire |
+| 7 jours | x1.2 | Week Warrior |
+| 30 jours | x1.5 | Godly Streak |
+| 90 jours | x2.0 | 3 Mois de Feu |
+| 180 jours | x3.0 | Semi-Annuel |
+| 365 jours | x4.5 | Streak Annuel |
+| 730 jours | x7.0 | Streak Légendaire |
+
+### QuĂȘtes quotidiennes
+
+3 quĂȘtes sĂ©lectionnĂ©es chaque jour parmi 20 modĂšles, par un hash dĂ©terministe de la date : tout le monde reçoit les mĂȘmes quĂȘtes le mĂȘme jour. ComplĂ©ter une quĂȘte rapporte de l'XP, complĂ©ter les 3 dĂ©clenche un bonus supplĂ©mentaire avec animation.
+
+### Rangs
+
+Novice, InitiĂ© Ă partir du niveau 11, AthlĂšte Ă 31, CompĂ©titeur Ă 51, Warrior Ă 71, Ălite Ă 91, MaĂźtre Ă 111, Grand MaĂźtre Ă 141, LĂ©gende Ă 171, ATHLY GOD Ă 200.
+
---
-## đ Backend associĂ©
+## Tutoriel interactif
+
+SystÚme de spotlight en 8 chapitres, un par grande zone de l'application. Chaque étape peut cibler un élément réel de l'écran (mesuré dynamiquement via `useTutorialTarget`) ou afficher une carte centrée, avec positionnement automatique du texte au-dessus ou en dessous de la cible selon l'espace disponible. Auto-scroll vers les éléments hors champ, indicateur de progression Chapitre X sur N, retour haptique sur les actions de navigation. La complétion est persistée à la fois dans AsyncStorage pour une reprise immédiate, et cÎté serveur (`hasCompletedOnboarding`) pour rester cohérente entre appareils. Rejouable à tout moment depuis les Réglages, chapitre par chapitre.
+
+---
-Ce dépÎt frontend communique avec l'API **Athly Backend** (dépÎt séparé).
+## ParamÚtres développeur (God Mode)
-Le backend gĂšre :
-- Authentification (JWT + OTP email)
-- Synchronisation des séances (best-effort depuis le front)
-- Catalogue d'exercices (intégration WGER)
-- Profil utilisateur
+Accessibles depuis Réglages, section God Mode.
-> Voir le README du dépÎt backend pour l'installation et la documentation complÚte de l'API.
+| Réglage | Effet |
+|---------|-------|
+| God Mode | Bascule générale utilisée par plusieurs outils de test |
+| Bypass anti-triche 5 minutes | Ignore le seuil de durée minimale d'une séance |
+| Forcer l'affichage des rituels | Affiche la carte de rituels mĂȘme aprĂšs une sĂ©ance dĂ©jĂ faite |
+| Overrides de trophées | Force le déblocage ou le verrouillage d'un trophée pour le tester |
-**L'application nĂ©cessite le backend pour l'authentification.** Une fois connectĂ©, les donnĂ©es de progression (logs, XP, quĂȘtes, rituels, trophĂ©es) sont stockĂ©es localement dans AsyncStorage â les calculs sont faits cĂŽtĂ© client.
+Persistés dans AsyncStorage, rechargés à chaque focus de l'écran concerné.
---
-## đ§ ParamĂštres dĂ©veloppeur (God Mode)
+## Tests
+
+```bash
+npm test
+```
+
+3 suites Jest sur les modules JS purs (données et services sans dépendance React Native), exécutées via Babel en environnement Node : intégrité structurelle du catalogue de chapitres du tutoriel, non-régression des rituels de récupération, comportement du service de synchronisation d'XP.
+
+---
-Accessibles depuis ParamĂštres â section God Mode (uniquement en mode dev) :
+## Backend associé
-| Toggle | Effet |
-|--------|-------|
-| God Mode | Bypass général pour tests |
-| Bypass anti-triche 5 min | Ignore le check de durée minimum |
-| Forcer l'affichage des rituels | Affiche la carte rituels mĂȘme aprĂšs une sĂ©ance |
+Ce dĂ©pĂŽt frontend communique avec l'API Athly Backend, dans le dossier `back/` du mĂȘme dĂ©pĂŽt. Le backend gĂšre l'authentification, le profil, le social (amis, groupes, lobby), l'inventaire et les coffres, les titres et trophĂ©es serveur, le parrainage, ainsi que la synchronisation de l'XP. Voir `back/README.md` pour l'installation et la documentation complĂšte de l'API.
-Ces paramÚtres sont persistés dans AsyncStorage et se rechargent à chaque focus de l'écran concerné.
+L'application nĂ©cessite le backend pour l'authentification et pour toutes les fonctionnalitĂ©s sociales et multijoueur. Les donnĂ©es de sĂ©ance immĂ©diates (logs, XP local, quĂȘtes, rituels) restent utilisables mĂȘme en cas de coupure rĂ©seau temporaire, la synchronisation reprenant automatiquement au retour du rĂ©seau.
---
-**Athly Front** · React Native + Expo · Offline-first
+Athly Front : React Native, Expo, PWA. Local first pour l'entraĂźnement, backend pour le social.