0% ont trouvé ce document utile (0 vote)
0 vues11 pages

Context

Transféré par

cyprien.16boue
Copyright
© All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd
0% ont trouvé ce document utile (0 vote)
0 vues11 pages

Context

Transféré par

cyprien.16boue
Copyright
© All Rights Reserved
Nous prenons très au sérieux les droits relatifs au contenu. Si vous pensez qu’il s’agit de votre contenu, signalez une atteinte au droit d’auteur ici.
Formats disponibles
Téléchargez aux formats PDF, TXT ou lisez en ligne sur Scribd

SURPASSE TOI

Source de vérité du projet

[Link] — Juin 2026

[Link] — Source de vérité du projet « Surpasse Toi »


> Ce fichier est la source de vérité permanente pour toutes les sessions Claude Code.

> Il remplace l'ancien APP_DESCRIPTION.md.

>

> - BLOC 1 — Conventions & contraintes : statique. Règles non-négociables. À lire avant toute modification.

> - BLOC 2 — État actuel du projet : dynamique. Décrit l'app telle qu'implémentée. À mettre à jour après chaque
modification significative (nouvelle page, nouveau modèle Prisma, nouvel outil Jarvis, changement de comportement).

>

> Dernière synchronisation BLOC 2 ↔ code : 2026-06-13.

■ BLOC 1 — CONVENTIONS & CONTRAINTES (statique)


Stack technique exacte

Conventions NON-NÉGOCIABLES

1. Design HALO — tokens CSS uniquement. Toutes les couleurs, rayons, durées, polices passent par les 148 tokens
définis dans src/styles/[Link] (ex. var(--violet), var(--fg1), var(--surface), var(--success), var(--r-lg),
var(--dur-enter)). ZÉRO couleur hardcodée (#7c3aed, rgb(...) interdits). ■■ Dette existante : ~195 hex à migrer (cf.
[Link] axe 6) — ne pas en ajouter de nouvelles.

2. TypeScript strict. strict: true actif. Aucun any (le code actuel en compte 0 — maintenir ce standard). Typer les
bodies d'API et les retours Prisma.

3. Aucune régression. Toute modification doit préserver le comportement existant décrit au BLOC 2. Vérifier les
pages/routes touchées avant de livrer.

4. Migrations Prisma : prisma db push avec DIRECT_URL (port 5432) — JAMAIS prisma migrate dev. Le runtime
applicatif utilise DATABASE_URL (pooler), mais les changements de schéma se poussent via la connexion directe port 5432.

5. Toute route API protégée par requireAuth() (src/lib/[Link]) en première instruction. habits/week,
habits/trends et tts ont été sécurisées le 2026-06-12 (cf. [Link] axe 5).

Patterns établis à RÉUTILISER (ne pas réinventer)


Outils UI actifs dans Claude Code

Pour toute tâche UI, mentionner et utiliser :

→ Les inclure explicitement dans chaque prompt UI.

Règles Jarvis (assistant IA)

■ BLOC 2 — ÉTAT ACTUEL DU PROJET (dynamique — à mettre à jour)


Cette section reprend l'intégralité de l'ancien APP_DESCRIPTION.md : pages, sections visibles, calculs, actions, données
Prisma lues/écrites et comportements particuliers. La maintenir synchronisée avec le code après chaque évolution.

> ### État multi-utilisateur — migration terminée (voir MULTIUSER_PLAN.md)

> La migration multi-user (étapes 1 à 10) est complète depuis le 2026-06-13 :

> - Authentification : Supabase Auth (email/password, sessions par cookies SSR via @supabase/ssr). NextAuth retiré.
Le userId exposé est le vrai UUID Supabase ([Link]).

> - Schéma Prisma : userId String @[Link] NOT NULL sur les 22 tables de données (Goal, Habit, HabitLog, Kpi,
KpiLog, Workout, Meal, Craving, CravingPreset, MealPreset, MealTemplate, WeightLog, BiometricLog, Review, Task,
UserSetting, CalendarEvent, GoogleAccount, Settings, CoachMessage, CoachAction, CoachMemory), avec contraintes
@@unique composites (userId, date / userId, key / userId, email).

> - Backfill : toutes les données existantes rattachées à l'UUID Supabase de l'utilisateur courant (0 ligne userId IS NULL).

> - Routes API + pages serveur : scoping where: { userId } appliqué via requireUser().

> - RLS Supabase : politiques owner_* (SQL dans scripts/[Link]) en filet de sécurité (Prisma reste en
service-role, isolation primaire = scoping applicatif).

> - Durcissement : whitelist sur PATCH /api/goals/[id], erreurs Prisma masquées côté client ("Erreur interne" + log
serveur).

Description de l'application — Surpasse Toi


Ce document décrit l'application telle qu'elle est implémentée aujourd'hui dans le code source : pages, sections visibles,
calculs automatiques, actions utilisateur, données lues/écrites en base (Prisma) et comportements particuliers
(localStorage, seuils visuels, logique conditionnelle).

Toutes les pages sont protégées par le proxy Supabase (src/[Link]) et les routes API par requireAuth() (session
Supabase, cf. section Login) ; elles redirigent vers /login si l'utilisateur n'est pas connecté.

1. Dashboard (`/`)

Fichier : src/app/[Link]

Titre
Sections visibles
a) MotionFeed (bandeau de messages rotatifs)

b) Objectifs du jour / Objectifs de la semaine (2 cartes côte à côte)

c) Habitudes du jour

d) Carte KPI

e) Carte "Win Streak" (série de réussite)

Actions utilisateur
Calculs automatiques
STREAK_THRESHOLD = 7

goodDates = jours où count([Link]=true) >= 7

streakCurrent = jours consécutifs depuis hier dans goodDates

streakBest = plus longue séquence consécutive (tout historique)

streakTotal = |goodDates|

KPI : weeklyTotal = somme des KpiLog de la semaine ISO en cours

pct = round(weeklyTotal / target * 100)

Données lues (Prisma)


Données écrites (Prisma)
Comportements particuliers

2. Sport (`/sport`)
Fichiers : src/app/sport/[Link] + [Link]

Titre
Sections visibles
a) En-tête avec bouton "magnétique" d'ajout

b) Grille hebdomadaire (7 colonnes, lundi → dimanche)

c) Panneau d'édition flottant

d) Formulaire d'ajout en ligne

Configuration des types de séance et calcul des calories


WORKOUT_CONFIG = [

{ name: "Running", inputType: "calories", rate: null, input: "Calories brûlées (Strava)" },

{ name: "Badminton", inputType: "duration", rate: 8, input: "Durée (min)" },

{ name: "Tractions EMOM", inputType: "duration", rate: 7, input: "Durée (min)" },

{ name: "Front Lever", inputType: "duration", rate: 6, input: "Durée (min)" },

{ name: "HSPU", inputType: "duration", rate: 8, input: "Durée (min)" },


{ name: "Abdos", inputType: "duration", rate: 5, input: "Durée (min)" },

{ name: "Pompes", inputType: "reps", rate: 0.36, input: "Répétitions" },

{ name: "Personnalisé", inputType: "calories", rate: null, input: "Calories brûlées" },

Formule de calcul :

function computeCalories(config, inputValue) {

const num = parseFloat(inputValue);

if (!inputValue || isNaN(num) || num <= 0) return null;

if ([Link] === "calories") return [Link](num); // saisie directe

if ([Link] === null) return null;

return [Link](num * [Link]); // durée × taux ou reps × taux


}

Actions utilisateur
Calculs automatiques
todayKcal = somme des [Link] du jour

dayKcal (par jour de la semaine) = somme des [Link] du jour

formatDuration(min) → "Xh", "Xh0Y" ou "X min"

Données lues (Prisma)


Données écrites (Prisma)
Comportements particuliers

3. Objectifs (`/objectifs`)

Fichiers : src/app/objectifs/[Link] + [Link]

Titre
Sections visibles (5 cartes)
a) Objectifs annuels 2026

b) Objectifs trimestriels

c) Mensuel

d) Semaine

e) Jour

Actions utilisateur
Calculs automatiques
todayStr = date du jour (YYYY-MM-DD)

thisWeek = id semaine ISO courante

thisMonth = id mois courant (YYYY-MM)

currentQ = [Link]((mois+1)/3)

annualGoals = goals où horizon="annual" et period="2026"

annualDone = [Link](done).length

pct (annuel/trimestriel) = doneCount/total * 100

Badges de catégorie (CAT_COLORS) :

Sport : fond rgba(249,115,22,.10), texte #c2410c

Perso : fond rgba(34,197,94,.10), texte #166534

Étude : fond rgba(59,130,246,.10), texte #1d4ed8

défaut : violet-100 / violet-700

Données lues (Prisma)


Données écrites (Prisma)
Comportements particuliers

4. Nutrition & Poids (`/nutrition`)


Fichiers : src/app/nutrition/[Link], [Link], [Link], [Link], [Link],
[Link]

Titre
Données chargées au chargement de la page
Constantes par défaut (si réglage absent) :

Sections visibles
a) Trois cartes de bilan calorique

1. "Mangé" : SUM([Link] du jour) + SUM([Link] du jour). Cible calorique éditable (icône crayon,
par défaut 2395 ou calorie_target) → PATCH /api/user-settings (clé calorie_target).

2. "Dépensé" : tdeeBase + SUM([Link] où done=true, du jour). TDEE de base éditable (par


défaut 2695 ou tdee_base) → PATCH /api/user-settings (clé tdee_base). Affiche séparément le TDEE de base et les
calories sport.

3. "Balance" : intake - (tdeeBase + caloriesSport).

b) Barres de progression macros (Protéines, Glucides, Lipides)


c) Repas du jour

Bibliothèque (deux onglets) :

Onglet "Aliments rapides" :

Panneau de gestion des aliments :

Onglet "Mes repas" :

Formulaire de création de repas-type :

d) Craquages du jour

description: [Link],

calories: [Link] * quantité,

proteins: round([Link] * quantité, 1),

carbs: round([Link] * quantité, 1),

fat: round([Link] * quantité, 1),

time, presetId, date: aujourd'hui

e) Poids

Calculs automatiques (résumé)


totalProteins = SUM(meals[].proteins) + SUM(cravings[].proteins)

totalCarbs = SUM(meals[].carbs) + SUM(cravings[].carbs)

totalFat = SUM(meals[].fat) + SUM(cravings[].fat)

cravingKcal = SUM(cravings[].calories)

totalBurned = tdeeBase + sportCalories

balance = intake - totalBurned

Macro pct = total / objectif * 100

Moyenne mobile poids (7j) = moyenne des valeurs non nulles sur 7 jours, si >= 3 valeurs
Données lues (Prisma)
Meal, Craving, CravingPreset, MealPreset, MealTemplate, MealTemplateItem, WeightLog, Workout (calories du jour),
UserSetting.

Données écrites (Prisma)


Comportements particuliers
Navigation temporelle (Jour / Semaine / Mois)
Vue Semaine
Vue Mois
Nouvelles routes API

5. Bien-être (`/biometrics`)

Fichiers : src/app/biometrics/[Link] + [Link]

Titre
Données chargées
Sections visibles
a) En-tête avec navigation par jour

b) Formulaire de saisie quotidienne (carte repliable)

{ date, bedtime: ISO|null, wakeTime: ISO|null, sleepQuality: number|null, energyLevel: number|null, notes: string|null }

Upsert (@@unique([date])). Confirmation visuelle "✓ Sauvegardé" (2s).

c) Cartes statistiques (grille 3 colonnes : Semaine, Mois, Trimestre)

d) Graphiques (2 colonnes, 30 derniers jours)

e) Tableau d'historique (30 derniers jours, y compris jours sans donnée)

Données lues (Prisma)


Données écrites (Prisma)
Comportements particuliers

6. Brain Dump (`/brain-dump`)

Fichiers : src/app/brain-dump/[Link] + [Link]

Titre
Données chargées
Sections visibles
a) Champ de saisie principal

b) Panneau d'options (apparaît au focus)

c) Filtres

d) Liste des tâches

Actions utilisateur
Calculs / logique
Données lues (Prisma)
Données écrites (Prisma)
Comportements particuliers
7. Calendrier (`/calendrier` et `/calendrier/accounts`)

Fichiers : src/app/calendrier/[Link] + [Link], src/app/calendrier/accounts/[Link]

Sections visibles
a) En-tête

b) Barre latérale (repliable)

c) Vue semaine (grille 7 colonnes)

d) Popover de détail d'événement

e) Modale de création d'événement

Hiérarchie de résolution des couleurs (ordre de priorité)


1. Couleur personnalisée de l'événement (localStorage clé event-colors)

2. Couleur Google de l'événement (mappée via colorIdToHex() à la synchronisation)

3. Couleur personnalisée du calendrier (localStorage clé calendar-colors)


4. Couleur déterministe issue de la palette (CALENDAR_COLOR_VARS =
["--violet-500","--success","--warning","--danger","--violet-700","--violet-400"], cyclique)

Actions utilisateur
Page `/calendrier/accounts`
Données lues (Prisma)
Données écrites (Prisma)
Comportements particuliers

8. Habitudes (`/habitudes`)

Fichiers : src/app/habitudes/[Link], [Link], src/components/[Link]

Titre
Sections visibles
a) Grille hebdomadaire (HabitsWeekGrid)

b) Graphique de tendance

c) Tableau d'analyse par habitude (basé sur 90 jours)

Calculs automatiques
avg7 = round(count_7j / 7 * 100)

avg30 = round(count_30j / 30 * 100)

avgQ = round(count_90j / 90 * 100)

score60 = round(count_60j / 60 * 100), scoreDays = count_60j

statut :

"Validée" si score60 >= 80 ET scoreDays >= 42

"Maîtrisée" si score60 >= 80

"Ancrée" si score60 >= 60

"En cours" si score60 >= 30

"À construire" si score60 < 30


tendance (curr7 vs prev7) :

"up" si curr7/7 > prev7/7 + 0.05

"down" si curr7/7 < prev7/7 - 0.05

"stable" sinon

Couleurs des badges de statut :

Couleurs des badges de pourcentage : ≥80% vert #22c55e, ≥60% violet #7c3aed, ≥30% orange #f59e0b, <30% rouge
#ef4444.

Flèche de tendance : prev7=0 → "→ n/a" (gris) ; hausse >5% → "↑ +X.X%" (vert) ; baisse >5% → "↓ −X.X%" (rouge) ; sinon
"→ X.X%" (gris).

Actions utilisateur
Données lues (Prisma)
Données écrites (Prisma)
Comportements particuliers

9. KPIs (`/kpis`)

Fichiers : src/app/kpis/[Link] + [Link]

Sections visibles
a) Une carte par KPI

b) Tableau d'analyse par KPI

Calculs automatiques
weeklyTotal (côté serveur) = somme des KpiLog de la semaine ISO en cours

pct = round(weeklyTotal / target * 100) si target > 0, sinon 0

statut(pct) :

pct >= 100 → "Dépassé ■" (fond #fefce8, texte #a16207)

pct >= 75 → "Sur la cible" (fond var(--violet-soft), texte var(--violet))

pct >= 25 → "En cours" (fond #fff7ed, texte #c2410c)

pct < 25 → "En retard" (fond var(--error-soft), texte var(--error))

prevWeekSum = somme des KpiLog de la semaine précédente (lundi-7 → lundi)


lastNWeeksAvg(N) = somme(N dernières semaines avec total>0) / nb de semaines avec total>0

evoNum = round((thisPct - prevPct) / prevPct * 100) si prevPct > 0, sinon null

evoUp = true si evoNum >= 0 ou null

Actions utilisateur
Données lues (Prisma)
Données écrites (Prisma)
Comportements particuliers

10. Insights (`/insights`)

Fichiers : src/app/insights/[Link] + [Link]

Sections visibles
a) Sélecteur de période

b) Bandeau d'avertissement (conditionnel)

c) Corrélations de Pearson — Top 6

d) Nuages de points — Top 6 corrélations

e) Corrélations décalées (J → J+1) — Top 6

f) Tendances hebdomadaires (6 mini-graphiques)

g) Graphique de régularité (hebdomadaire, courbes)

h) Analyse IA

Calculs / formules détaillées


Endpoint : GET /api/insights/correlations?period={30|60|90|365}

Variables calculées par jour, à partir de :

sleepDuration (min) = (wakeTime + 1440 - bedtimeNormalized) % 1440

sleepQuality, energyLevel : valeurs 1-5 du BiometricLog

habitScore (%) = (nb habitudes faites / total habitudes) * 100

workoutDone = 0 ou 1

calorieIntake = somme des [Link] du jour

bedtimeMinutes = minutes depuis minuit, normalisé (utilisé pour les corrélations décalées)

Pearson :

r = Σ((x-x■)(y-■)) / √(Σ(x-x■)² × Σ(y-■)²)

n minimum = 3 ; r = null si dénominateur = 0

r arrondi à 3 décimales

Données lues (Prisma)


Comportements particuliers

11. Récap (`/recap`)

Fichiers : src/app/recap/[Link] + [Link]

Navigation
1. Aujourd'hui : YYYY-MM-DD

2. Semaine : YYYY-WXX, libellé "Semaine XX · YYYY"

3. Mois : YYYY-MM, libellé "Mois Année"

4. Quarter : YYYY-QX, libellé "TX YYYY"

Vue "Aujourd'hui"
a) Objectifs du jour

b) Habitudes du jour

c) Sport du jour (grille 2 colonnes)

d) Nutrition du jour (grille 2 colonnes)

e) KPIs loggés aujourd'hui

f) Tableaux récap du jour


Vues Semaine / Mois / Quarter
a) Grille de stats (4 cartes)

b) Tableaux de période (grille 2×2)

c) Reviews (revues structurées)

1. Qu'est-ce qui a le mieux fonctionné cette semaine ?

2. Quelles difficultés ou erreurs ai-je rencontrées, et comment les corriger ?

3. Qu'ai-je appris cette semaine, et comment puis-je l'appliquer ?

4. Quelles actions ai-je déjà entreprises (ou prévu) pour progresser vers mes objectifs ?

5. Quelles sont mes 3 priorités principales la semaine prochaine ?

Calculs automatiques
% complétion habitudes = (habitudesCochées / habitudesTotal) * 100

habitudesTotal = totalHabitudes * joursÉcoulés


joursÉcoulés = (période en cours) du début à aujourd'hui ; (période passée) durée totale de la période

bilan calorique = totalMangé - (caloriesBrûlées + dépenseDeBase)

TDEE de base = lu depuis Settings, ou 2200 kcal par défaut

Données lues (Prisma)


Données écrites (Prisma)
Comportements particuliers

12. Paramètres (`/settings`)

Fichiers : src/app/settings/[Link] + [Link]

En-tête
Sections (6 cartes)
a) Mon profil

b) Personnalité & comportement de J.A.R.V.I.S.

c) Raccourcis J.A.R.V.I.S.

1. "Résume ma semaine" → "Résume ma progression cette semaine : habitudes, objectifs, KPIs."

2. "Objectifs du jour" → "Donne-moi mes 3 priorités absolues pour aujourd'hui."

3. "Cocher une habitude" → "Quelles habitudes n'ai-je pas encore cochées aujourd'hui ?"

4. "Ajouter une tâche" → "Ajoute une tâche : "

5. "Nouvel objectif" → "Aide-moi à formuler un nouvel objectif SMART."

6. (emplacement vide pour ajout libre)

d) Mes habitudes

e) Mes KPIs

f) Catégories Brain Dump

Données lues (Prisma)


Données écrites (Prisma / fichiers)
13. J.A.R.V.I.S. (assistant IA)

UI : panneau JarvisPanel (accessible depuis le layout/dashboard), aperçu visuel sur /jarvis-preview et sur la page de
connexion (JarvisHeaderPreviewV1).

Backend : src/app/api/coach/[Link] (chat + exécution d'outils en streaming),


src/app/api/coach/memory/[Link], src/app/api/tts/[Link], src/lib/[Link].

Contexte fourni au modèle à chaque message


Outils disponibles (exécutables par l'assistant)
Mémoire et journal du coach
Voix / TTS
Prompt système

14. Connexion (`/(auth)/login`)

Fichier : src/app/(auth)/login/[Link]

Mécanisme d'authentification
Sections visibles
Comportement après connexion
Design
Données lues / écrites (Prisma)

Récapitulatif des modèles Prisma et de leurs usages

Schéma Prisma résumé (modèles & relations clés)

Source : prisma/[Link] — PostgreSQL, IDs cuid(). Dates métier en @[Link] (sans heure).

> Multi-user — étape 1/10 (2026-06-12) : userId String? @[Link] (nullable) ajouté sur les 22 tables listées au §1 de
MULTIUSER_PLAN.md (toutes sauf MealTemplateItem), avec les @@index([userId]) / @@index([userId, date]) /
@@index([userId, start]) (CalendarEvent) correspondants. Aucune contrainte @unique existante modifiée, pas de
@@unique composite encore (prévu étape 7). Index de performance ajoutés en même temps ([Link] axe 2) :
@@index([habitId]) sur HabitLog, @@index([kpiId]) sur KpiLog (les @@index([date]) sont couverts par les
composites [userId, date]). onDelete ajoutés : [Link] et [Link] → Cascade, [Link] →
SetNull, [Link] → Restrict.

Objectifs & suivi

Santé & nutrition

Calendrier

Jarvis & réglages

Relations clés (cardinalités)

Goal ■■■ (self) parent/children

Habit 1■■n HabitLog Kpi 1■■n KpiLog

CravingPreset 1■■n Craving

MealTemplate 1■■n MealTemplateItem n■■1 MealPreset

Vous aimerez peut-être aussi