diff --git a/.claude/skills/design_system/SKILL.md b/.claude/skills/design_system/SKILL.md new file mode 100644 index 0000000..1ef0513 --- /dev/null +++ b/.claude/skills/design_system/SKILL.md @@ -0,0 +1,576 @@ +--- +name: tabata-kine-design-system +description: > + Design system complet pour l'application Tabata Kiné. Utilise ce skill pour + toute tâche liée au design, aux composants UI, aux écrans, aux couleurs, à la + typographie ou aux décisions d'interface de l'app Tabata Kiné. Déclenche ce + skill dès que l'utilisateur mentionne : un écran de l'app (onboarding, séance, + dashboard, paywall, programmes), un composant (bouton, carte, timer, badge, + input), une couleur, une typographie, une animation, un espacement, ou demande + à coder un élément UI. Ce skill contient les règles non négociables du design + "Dark Medical" — le style qui différencie l'app de tous les concurrents fitness. +--- + +# Design System — Tabata Kiné + +## Principe directeur : Dark Medical + +L'app Tabata Kiné n'est **pas** une app fitness classique. C'est une app médicale +qui utilise le format tabata. Le style "Dark Medical" traduit visuellement ce +positionnement : fond sombre professionnel, vert santé comme seule couleur d'action, +expertise kiné visible à chaque écran. + +**Règles absolues :** +- Pas de mode clair. Dark only, sans exception. +- Le vert (#00C896) ne sert qu'aux actions et à la validation. +- L'orange (#FF8A5C) ne sert qu'aux conseils kiné et alertes positives. +- Le rouge (#FF4444) est réservé au timer en phase d'urgence (<10s). +- Touch target minimum : 44×44px pour tous les éléments interactifs. + +--- + +## 1. Tokens de couleur + +### Fonds — Navy + +| Token | Valeur | Usage | +|-------|--------|-------| +| `navy-900` | `#0D1B2A` | Fond principal de l'app | +| `navy-800` | `#112240` | Surface 1 — cartes par défaut | +| `navy-700` | `#1A3050` | Surface 2 — cartes surélevées | +| `navy-600` | `#243C5E` | Bordures actives | + +### Vert Kiné — action & santé + +| Token | Valeur | Usage | +|-------|--------|-------| +| `green-500` | `#00C896` | CTA principal, timer effort, progress | +| `green-600` | `#00A67C` | État hover / pressed | +| `green-700` | `#00875F` | État active deep | +| `green-dim` | `rgba(0,200,150,0.12)` | Fond badge, chip, card accent | +| `green-border` | `rgba(0,200,150,0.35)` | Bordure card accent | + +### Texte & bordures + +| Token | Valeur | Usage | +|-------|--------|-------| +| `white-100` | `#E6F1FF` | Texte primaire | +| `slate-300` | `#A8B2D8` | Texte secondaire | +| `slate-400` | `#8892B0` | Texte tertiaire, placeholders | +| `border-dim` | `rgba(168,178,216,0.15)` | Bordure par défaut | +| `border-hover` | `rgba(168,178,216,0.25)` | Bordure hover | + +### Orange — conseils kiné uniquement + +| Token | Valeur | Usage | +|-------|--------|-------| +| `orange-500` | `#FF8A5C` | Tip card border, badge Kiné+ | +| `orange-600` | `#E06A3C` | Hover orange | +| `orange-dim` | `rgba(255,138,92,0.12)` | Fond tip card | + +### Sémantique + +| Token | Valeur | Usage | +|-------|--------|-------| +| `red-500` | `#FF4444` | Timer urgence <10s UNIQUEMENT | + +--- + +## 2. Typographie + +### Familles + +| Rôle | Famille | Notes | +|------|---------|-------| +| Titres émotionnels | Serif italique (ex: DM Serif Display, Georgia) | Célébration, fin de séance, accroches | +| Interface & corps | Sans-serif géométrique (ex: Outfit, DM Sans) | Navigation, descriptions, labels | +| Données & timer | Monospace (ex: DM Mono, JetBrains Mono) | Timer, stats, codes, metadata | + +### Échelle + +| Style | Famille | Taille | Poids | Usage | +|-------|---------|--------|-------|-------| +| `display` | Serif italic | 28–32px | 400 | Fin de séance, titres forts | +| `heading-1` | Serif | 22–24px | 500 | Titres de section | +| `heading-2` | Sans | 18px | 500 | Titre exercice, carte programme | +| `body` | Sans | 15–16px | 400 | Corps, conseil kiné | +| `label` | Mono | 11–13px | 500 | Tags, metadata, uppercase tracking | +| `timer` | Mono | **80–100px** | 500 | Timer séance — lisible à 2 mètres | +| `caption` | Sans | 12px | 400 | Sous-labels, hints | + +**Règle typographie :** La taille du timer est la décision de design la plus +importante de l'écran séance. Tout se dimensionne autour de lui. + +--- + +## 3. Espacement + +Base : **4px** + +| Token | Valeur | Usage | +|-------|--------|-------| +| `space-1` | 4px | Gap minimal entre éléments liés | +| `space-2` | 8px | Gap interne composant | +| `space-3` | 12px | Gap entre composants proches | +| `space-4` | 16px | Padding carte, gap standard | +| `space-6` | 24px | Espacement sections | +| `space-8` | 32px | Padding écran horizontal | +| `space-12` | 48px | Espacement majeur | +| `space-16` | 64px | Espacement entre blocs screens | + +--- + +## 4. Border Radius + +| Token | Valeur | Usage | +|-------|--------|-------| +| `radius-sm` | 4px | Badge, chip, tag | +| `radius-md` | 8px | Bouton, input, tip card | +| `radius-lg` | 12px | Carte programme standard | +| `radius-xl` | 16px | Carte large, modal | +| `radius-pill` | 9999px | Pill, toggle, progress bar | +| `radius-circle` | 50% | Icon button, avatar, streak dot | + +--- + +## 5. Système d'élévation (surfaces) + +``` +Fond (navy-900) + └── Surface 1 (navy-800) — cartes par défaut + └── Surface 2 (navy-700) — cartes surélevées / hover + └── Surface active (navy-800 + border green-500 1.5px) +``` + +Différencier les surfaces **uniquement par la couleur de fond**, jamais par des +ombres portées (box-shadow : non). La bordure active verte est le seul signal +d'état sélectionné. + +--- + +## 6. Composants + +### Boutons + +``` +PrimaryButton + background: green-500 + color: navy-900 + padding: 14px 24px + height: 52–56px + border-radius: radius-md + font: sans 15px 500 + width: 100% (full-width dans les screens) + hover: background green-600 + active: background green-700 + scale(0.98) + +SecondaryButton + background: transparent + color: green-500 + border: 1.5px solid green-500 + padding: 13px 24px + hover: background green-dim + +GhostButton + background: transparent + color: slate-300 + no border + usage: actions secondaires (Passer, Annuler) + +DangerButton + background: rgba(255,68,68,0.12) + color: #FF6B6B + border: 1px solid rgba(255,68,68,0.3) + usage: Quitter la séance UNIQUEMENT + +IconButton + width: 44px + height: 44px + border-radius: 50% + background: rgba(168,178,216,0.10) + color: slate-300 + JAMAIS en dessous de 44×44px (accessibilité) +``` + +### Inputs + +``` +TextField + background: navy-800 + border: 1px solid border-dim + border-radius: radius-md + padding: 12px 16px + color: white-100 + font: sans 15px 400 + focus: border green-500 + error: border red-500 + height: 48px +``` + +### Badges & Pills + +``` +Badge (tier) + font: mono 11px 500 + padding: 3px 10px + border-radius: radius-sm + UPPERCASE + letter-spacing: 0.08em + + .free: background green-dim, color green-500 + .premium: background orange-dim, color orange-500 + .kine: background rgba(168,178,216,0.12), color slate-300 + +Pill (metadata) + font: sans 12px 400 + padding: 4px 12px + border-radius: radius-pill + border: 1px solid (couleur correspondante à 0.3 opacity) +``` + +### Cartes + +``` +CardDefault + background: navy-800 + border: 1px solid border-dim + border-radius: radius-lg + padding: 16px + +CardAccent (CTA, prochaine séance) + background: rgba(0,200,150,0.05) + border: 1.5px solid green-border + border-radius: radius-lg + +CardTip (conseil kiné) + background: orange-dim + border-left: 3px solid orange-500 + border-radius: 0 radius-lg radius-lg 0 + NE PAS arrondir le côté gauche (border-left unique) + Structure: icône 💡 + texte + signature "— Prénom, kiné" + +CardProgram + border-radius: radius-xl + overflow: hidden + Thumbnail: 120px height, gradient navy-700→navy-600 + Body: padding 14px + Toujours afficher: progression bar + "X/12 séances" +``` + +### Timer + +``` +Timer (composant le plus critique de l'app) + font: mono 80–100px 500 + text-align: center + + État effort normal (>10s): + color: green-500 + + État urgence (<10s): + color: red-500 + animation: pulse subtil (scale 1→1.02→1, 1s infinite) + + Label sous le chiffre: + font: mono 14px 400 + color: slate-400 + letter-spacing: 0.1em + text: "SECONDES" + + Contexte repos: + color: slate-300 (pas de vert, signal visuel de repos) +``` + +### Progress Bar + +``` +ProgressBar + track: background rgba(168,178,216,0.12), height 4px, border-radius pill + fill: background green-500, border-radius pill + + Variante séance (épaisseur réduite): + height: 3px + + Variante programme: + height: 4px + Afficher le % à droite en mono 11px green-500 + + Animation: transition width 300ms ease +``` + +### Feedback ressenti + +``` +FeedbackButton + width: flex (3 boutons égaux) + height: 72px + border-radius: radius-lg + background: navy-800 + border: 1px solid border-dim + flex-direction: column + gap: 4px + + Emoji: 28px + Label: sans 12px slate-400 + + État sélectionné: + border: 1.5px solid green-500 + background: green-dim +``` + +### Streak hebdomadaire + +``` +StreakDot + width: 32px + height: 32px + border-radius: 50% + + .done: background rgba(0,200,150,0.15) → afficher ✓ + .today: background green-500 → afficher ✓ + .empty: background rgba(168,178,216,0.06), border 1px border-dim + +Label jour: mono 10px slate-400, centré sous chaque dot +``` + +--- + +## 7. Écran séance — règles spéciales + +L'écran séance est le plus critique de l'app. Il doit être utilisable **les mains +sur les genoux, en sueur, à 2 mètres de l'écran**. Chaque décision de design doit +passer ce test. + +### Architecture visuelle + +``` +[Vidéo plein écran en boucle — fond de tout l'écran] + ↓ Gradient top navy→transparent (40% opacité, 100px height) + → Contrôles pause/audio en overlay + → Indicateur exercice X/8 centré + ↓ Zone centrale nette (pas de gradient — l'utilisateur voit le mouvement) + ↓ Gradient bottom transparent→navy (70% opacité, 220px height) + → Timer géant centré + → Progress bar + → Tip card conseil kiné +``` + +### Transitions séance + +``` +Effort → Repos: + Fond passe de vidéo plein écran → navy-800 uni + Transition: fade 300ms + Vibration haptique légère (si disponible) + Le repos a une identité visuelle différente (pas de vidéo, couleur unie) + +Repos → Effort: + Countdown audio "3... 2... 1..." + Vibration haptique + transition fade + +Exercice suivant pendant le repos: + Afficher un thumbnail 56×56px du prochain exercice + Nom en sans 14px 500 + Label "PROCHAIN EXERCICE" en mono 11px slate-400 +``` + +### Phase repos + +L'écran repos doit être **visuellement différent** de l'écran effort. + +- Fond : `navy-800` uni (plus de vidéo plein écran) +- Timer couleur : `slate-300` (pas de vert — c'est le repos) +- Mot "REPOS" en mono 13px slate-400, letter-spacing 0.15em +- Aperçu prochain exercice centré + +--- + +## 8. Navigation + +``` +Tab Bar (5 onglets, fixé en bas) + height: 56px + safe area inset + background: navy-800 + border-top: 1px solid border-dim + + Onglets: + - Accueil (home icon) + - Programmes (grid icon) + - Minuteur (timer icon) + - Progression (chart icon) + - Profil (person icon) + + Onglet actif: icône green-500 + label green-500 + Onglet inactif: icône slate-400 + label slate-400 + + Font label: sans 11px 400 + Icon size: 22×22px + Touch target: 44×44px minimum +``` + +--- + +## 9. Animations & micro-interactions + +``` +FadeIn: + opacity: 0 → 1 + duration: 300ms + easing: ease + +SlideUp (bottom sheet, modal): + translateY(100%) → 0 + duration: 400ms + easing: cubic-bezier(0.4, 0, 0.2, 1) + +Pulse (CTA bouton, timer urgence): + scale: 1 → 1.02 → 1 + duration: 2s + infinite, ease-in-out + +Bounce (célébration fin de séance): + scale: 0.5 → 1.05 → 0.98 → 1 + duration: 600ms + easing: spring + +StaggerList (items qui apparaissent en séquence): + Délai: 100ms entre chaque item + Chaque item: FadeIn + translateY(12px→0) + +ScalePress (tous les boutons): + active: scale(0.97) + duration: 100ms +``` + +**Règle d'or animations :** Une animation bien exécutée au chargement d'écran +vaut mieux que des micro-interactions dispersées partout. + +--- + +## 10. Paywall — règles de design conversion + +``` +Structure obligatoire du paywall: + 1. Célébration des accomplissements (TOUJOURS en premier) + → Font serif italic, emoji, stats concrètes + 2. Valeur du contenu débloqué (liste concrète) + 3. Pricing transparent (pas de dark patterns) + → "Essai gratuit 7 jours · puis 24,99€/an · soit 2,08€/mois" + 4. CTA principal (PrimaryButton full-width) + 5. Réassurance ("Annulation facile à tout moment") + 6. Alternative gratuite visible (GhostButton ou lien) + + Couleur encadré pricing: CardAccent (vert) + Bouton fermeture: TOUJOURS visible en haut à gauche + Pas de compte à rebours fictif, pas de stock limité : anti dark patterns +``` + +--- + +## 11. Accessibilité + +``` +Contraste texte: + Texte primaire (#E6F1FF) sur navy-900 → ratio 15:1 ✓ + Texte secondaire (#A8B2D8) sur navy-900 → ratio 7:1 ✓ + Vert (#00C896) sur navy-900 → ratio 8:1 ✓ + Tous conformes WCAG AA (4.5:1 minimum requis) + +Touch targets: + Minimum 44×44px pour TOUS les éléments interactifs + Espacement minimum 8px entre deux éléments interactifs adjacents + +Timer: + La couleur n'est pas le seul signal d'urgence + Ajouter aussi: pulse animation + vibration haptique + signal audio + +Audio: + Toujours proposer une alternative visuelle à chaque signal audio + Le toggle audio est accessible en 1 tap depuis l'écran séance +``` + +--- + +## 12. Tokens React Native / Expo + +```typescript +// design-tokens.ts +export const colors = { + // Navy + navy900: '#0D1B2A', + navy800: '#112240', + navy700: '#1A3050', + navy600: '#243C5E', + + // Green + green500: '#00C896', + green600: '#00A67C', + green700: '#00875F', + greenDim: 'rgba(0,200,150,0.12)', + greenBorder: 'rgba(0,200,150,0.35)', + + // Text + white100: '#E6F1FF', + slate300: '#A8B2D8', + slate400: '#8892B0', + + // Borders + borderDim: 'rgba(168,178,216,0.15)', + borderHover: 'rgba(168,178,216,0.25)', + + // Orange (tip/kine only) + orange500: '#FF8A5C', + orange600: '#E06A3C', + orangeDim: 'rgba(255,138,92,0.12)', + + // Semantic + red500: '#FF4444', // timer urgence ONLY +} as const + +export const spacing = { + 1: 4, + 2: 8, + 3: 12, + 4: 16, + 6: 24, + 8: 32, + 12: 48, + 16: 64, +} as const + +export const radius = { + sm: 4, + md: 8, + lg: 12, + xl: 16, + pill: 9999, +} as const + +export const fontSizes = { + caption: 12, + label: 13, + body: 15, + heading2: 18, + heading1: 22, + display: 28, + timer: 88, // taille par défaut du timer +} as const + +export const timerThreshold = 10 // secondes — passage vert → rouge +``` + +--- + +## Checklist avant livraison d'un écran + +- [ ] Fond `navy-900` utilisé comme base +- [ ] Aucun shadow/élévation — différenciation par couleur uniquement +- [ ] Tous les touch targets ≥ 44×44px +- [ ] Le vert n'est utilisé que pour des actions ou validations +- [ ] L'orange n'est utilisé que pour des conseils kiné ou alertes positives +- [ ] Le rouge n'apparaît que sur le timer en urgence +- [ ] Timer ≥ 80px de haut sur l'écran séance +- [ ] Vidéo plein écran sur l'écran séance (pas un bloc vidéo) +- [ ] Gradients top + bottom sur l'écran séance pour la lisibilité +- [ ] Phase repos visuellement différente de la phase effort +- [ ] Paywall : célébration en premier, alternative gratuite visible +- [ ] Typographie : serif pour les moments émotionnels, mono pour les données diff --git a/.claude/skills/gitnexus/gitnexus-cli/SKILL.md b/.claude/skills/gitnexus/gitnexus-cli/SKILL.md new file mode 100644 index 0000000..c9e0af3 --- /dev/null +++ b/.claude/skills/gitnexus/gitnexus-cli/SKILL.md @@ -0,0 +1,82 @@ +--- +name: gitnexus-cli +description: "Use when the user needs to run GitNexus CLI commands like analyze/index a repo, check status, clean the index, generate a wiki, or list indexed repos. Examples: \"Index this repo\", \"Reanalyze the codebase\", \"Generate a wiki\"" +--- + +# GitNexus CLI Commands + +All commands work via `npx` — no global install required. + +## Commands + +### analyze — Build or refresh the index + +```bash +npx gitnexus analyze +``` + +Run from the project root. This parses all source files, builds the knowledge graph, writes it to `.gitnexus/`, and generates CLAUDE.md / AGENTS.md context files. + +| Flag | Effect | +| -------------- | ---------------------------------------------------------------- | +| `--force` | Force full re-index even if up to date | +| `--embeddings` | Enable embedding generation for semantic search (off by default) | + +**When to run:** First time in a project, after major code changes, or when `gitnexus://repo/{name}/context` reports the index is stale. In Claude Code, a PostToolUse hook runs `analyze` automatically after `git commit` and `git merge`, preserving embeddings if previously generated. + +### status — Check index freshness + +```bash +npx gitnexus status +``` + +Shows whether the current repo has a GitNexus index, when it was last updated, and symbol/relationship counts. Use this to check if re-indexing is needed. + +### clean — Delete the index + +```bash +npx gitnexus clean +``` + +Deletes the `.gitnexus/` directory and unregisters the repo from the global registry. Use before re-indexing if the index is corrupt or after removing GitNexus from a project. + +| Flag | Effect | +| --------- | ------------------------------------------------- | +| `--force` | Skip confirmation prompt | +| `--all` | Clean all indexed repos, not just the current one | + +### wiki — Generate documentation from the graph + +```bash +npx gitnexus wiki +``` + +Generates repository documentation from the knowledge graph using an LLM. Requires an API key (saved to `~/.gitnexus/config.json` on first use). + +| Flag | Effect | +| ------------------- | ----------------------------------------- | +| `--force` | Force full regeneration | +| `--model ` | LLM model (default: minimax/minimax-m2.5) | +| `--base-url ` | LLM API base URL | +| `--api-key ` | LLM API key | +| `--concurrency ` | Parallel LLM calls (default: 3) | +| `--gist` | Publish wiki as a public GitHub Gist | + +### list — Show all indexed repos + +```bash +npx gitnexus list +``` + +Lists all repositories registered in `~/.gitnexus/registry.json`. The MCP `list_repos` tool provides the same information. + +## After Indexing + +1. **Read `gitnexus://repo/{name}/context`** to verify the index loaded +2. Use the other GitNexus skills (`exploring`, `debugging`, `impact-analysis`, `refactoring`) for your task + +## Troubleshooting + +- **"Not inside a git repository"**: Run from a directory inside a git repo +- **Index is stale after re-analyzing**: Restart Claude Code to reload the MCP server +- **Embeddings slow**: Omit `--embeddings` (it's off by default) or set `OPENAI_API_KEY` for faster API-based embedding diff --git a/.claude/skills/gitnexus/gitnexus-debugging/SKILL.md b/.claude/skills/gitnexus/gitnexus-debugging/SKILL.md new file mode 100644 index 0000000..9510b97 --- /dev/null +++ b/.claude/skills/gitnexus/gitnexus-debugging/SKILL.md @@ -0,0 +1,89 @@ +--- +name: gitnexus-debugging +description: "Use when the user is debugging a bug, tracing an error, or asking why something fails. Examples: \"Why is X failing?\", \"Where does this error come from?\", \"Trace this bug\"" +--- + +# Debugging with GitNexus + +## When to Use + +- "Why is this function failing?" +- "Trace where this error comes from" +- "Who calls this method?" +- "This endpoint returns 500" +- Investigating bugs, errors, or unexpected behavior + +## Workflow + +``` +1. gitnexus_query({query: ""}) → Find related execution flows +2. gitnexus_context({name: ""}) → See callers/callees/processes +3. READ gitnexus://repo/{name}/process/{name} → Trace execution flow +4. gitnexus_cypher({query: "MATCH path..."}) → Custom traces if needed +``` + +> If "Index is stale" → run `npx gitnexus analyze` in terminal. + +## Checklist + +``` +- [ ] Understand the symptom (error message, unexpected behavior) +- [ ] gitnexus_query for error text or related code +- [ ] Identify the suspect function from returned processes +- [ ] gitnexus_context to see callers and callees +- [ ] Trace execution flow via process resource if applicable +- [ ] gitnexus_cypher for custom call chain traces if needed +- [ ] Read source files to confirm root cause +``` + +## Debugging Patterns + +| Symptom | GitNexus Approach | +| -------------------- | ---------------------------------------------------------- | +| Error message | `gitnexus_query` for error text → `context` on throw sites | +| Wrong return value | `context` on the function → trace callees for data flow | +| Intermittent failure | `context` → look for external calls, async deps | +| Performance issue | `context` → find symbols with many callers (hot paths) | +| Recent regression | `detect_changes` to see what your changes affect | + +## Tools + +**gitnexus_query** — find code related to error: + +``` +gitnexus_query({query: "payment validation error"}) +→ Processes: CheckoutFlow, ErrorHandling +→ Symbols: validatePayment, handlePaymentError, PaymentException +``` + +**gitnexus_context** — full context for a suspect: + +``` +gitnexus_context({name: "validatePayment"}) +→ Incoming calls: processCheckout, webhookHandler +→ Outgoing calls: verifyCard, fetchRates (external API!) +→ Processes: CheckoutFlow (step 3/7) +``` + +**gitnexus_cypher** — custom call chain traces: + +```cypher +MATCH path = (a)-[:CodeRelation {type: 'CALLS'}*1..2]->(b:Function {name: "validatePayment"}) +RETURN [n IN nodes(path) | n.name] AS chain +``` + +## Example: "Payment endpoint returns 500 intermittently" + +``` +1. gitnexus_query({query: "payment error handling"}) + → Processes: CheckoutFlow, ErrorHandling + → Symbols: validatePayment, handlePaymentError + +2. gitnexus_context({name: "validatePayment"}) + → Outgoing calls: verifyCard, fetchRates (external API!) + +3. READ gitnexus://repo/my-app/process/CheckoutFlow + → Step 3: validatePayment → calls fetchRates (external) + +4. Root cause: fetchRates calls external API without proper timeout +``` diff --git a/.claude/skills/gitnexus/gitnexus-exploring/SKILL.md b/.claude/skills/gitnexus/gitnexus-exploring/SKILL.md new file mode 100644 index 0000000..927a4e4 --- /dev/null +++ b/.claude/skills/gitnexus/gitnexus-exploring/SKILL.md @@ -0,0 +1,78 @@ +--- +name: gitnexus-exploring +description: "Use when the user asks how code works, wants to understand architecture, trace execution flows, or explore unfamiliar parts of the codebase. Examples: \"How does X work?\", \"What calls this function?\", \"Show me the auth flow\"" +--- + +# Exploring Codebases with GitNexus + +## When to Use + +- "How does authentication work?" +- "What's the project structure?" +- "Show me the main components" +- "Where is the database logic?" +- Understanding code you haven't seen before + +## Workflow + +``` +1. READ gitnexus://repos → Discover indexed repos +2. READ gitnexus://repo/{name}/context → Codebase overview, check staleness +3. gitnexus_query({query: ""}) → Find related execution flows +4. gitnexus_context({name: ""}) → Deep dive on specific symbol +5. READ gitnexus://repo/{name}/process/{name} → Trace full execution flow +``` + +> If step 2 says "Index is stale" → run `npx gitnexus analyze` in terminal. + +## Checklist + +``` +- [ ] READ gitnexus://repo/{name}/context +- [ ] gitnexus_query for the concept you want to understand +- [ ] Review returned processes (execution flows) +- [ ] gitnexus_context on key symbols for callers/callees +- [ ] READ process resource for full execution traces +- [ ] Read source files for implementation details +``` + +## Resources + +| Resource | What you get | +| --------------------------------------- | ------------------------------------------------------- | +| `gitnexus://repo/{name}/context` | Stats, staleness warning (~150 tokens) | +| `gitnexus://repo/{name}/clusters` | All functional areas with cohesion scores (~300 tokens) | +| `gitnexus://repo/{name}/cluster/{name}` | Area members with file paths (~500 tokens) | +| `gitnexus://repo/{name}/process/{name}` | Step-by-step execution trace (~200 tokens) | + +## Tools + +**gitnexus_query** — find execution flows related to a concept: + +``` +gitnexus_query({query: "payment processing"}) +→ Processes: CheckoutFlow, RefundFlow, WebhookHandler +→ Symbols grouped by flow with file locations +``` + +**gitnexus_context** — 360-degree view of a symbol: + +``` +gitnexus_context({name: "validateUser"}) +→ Incoming calls: loginHandler, apiMiddleware +→ Outgoing calls: checkToken, getUserById +→ Processes: LoginFlow (step 2/5), TokenRefresh (step 1/3) +``` + +## Example: "How does payment processing work?" + +``` +1. READ gitnexus://repo/my-app/context → 918 symbols, 45 processes +2. gitnexus_query({query: "payment processing"}) + → CheckoutFlow: processPayment → validateCard → chargeStripe + → RefundFlow: initiateRefund → calculateRefund → processRefund +3. gitnexus_context({name: "processPayment"}) + → Incoming: checkoutHandler, webhookHandler + → Outgoing: validateCard, chargeStripe, saveTransaction +4. Read src/payments/processor.ts for implementation details +``` diff --git a/.claude/skills/gitnexus/gitnexus-guide/SKILL.md b/.claude/skills/gitnexus/gitnexus-guide/SKILL.md new file mode 100644 index 0000000..937ac73 --- /dev/null +++ b/.claude/skills/gitnexus/gitnexus-guide/SKILL.md @@ -0,0 +1,64 @@ +--- +name: gitnexus-guide +description: "Use when the user asks about GitNexus itself — available tools, how to query the knowledge graph, MCP resources, graph schema, or workflow reference. Examples: \"What GitNexus tools are available?\", \"How do I use GitNexus?\"" +--- + +# GitNexus Guide + +Quick reference for all GitNexus MCP tools, resources, and the knowledge graph schema. + +## Always Start Here + +For any task involving code understanding, debugging, impact analysis, or refactoring: + +1. **Read `gitnexus://repo/{name}/context`** — codebase overview + check index freshness +2. **Match your task to a skill below** and **read that skill file** +3. **Follow the skill's workflow and checklist** + +> If step 1 warns the index is stale, run `npx gitnexus analyze` in the terminal first. + +## Skills + +| Task | Skill to read | +| -------------------------------------------- | ------------------- | +| Understand architecture / "How does X work?" | `gitnexus-exploring` | +| Blast radius / "What breaks if I change X?" | `gitnexus-impact-analysis` | +| Trace bugs / "Why is X failing?" | `gitnexus-debugging` | +| Rename / extract / split / refactor | `gitnexus-refactoring` | +| Tools, resources, schema reference | `gitnexus-guide` (this file) | +| Index, status, clean, wiki CLI commands | `gitnexus-cli` | + +## Tools Reference + +| Tool | What it gives you | +| ---------------- | ------------------------------------------------------------------------ | +| `query` | Process-grouped code intelligence — execution flows related to a concept | +| `context` | 360-degree symbol view — categorized refs, processes it participates in | +| `impact` | Symbol blast radius — what breaks at depth 1/2/3 with confidence | +| `detect_changes` | Git-diff impact — what do your current changes affect | +| `rename` | Multi-file coordinated rename with confidence-tagged edits | +| `cypher` | Raw graph queries (read `gitnexus://repo/{name}/schema` first) | +| `list_repos` | Discover indexed repos | + +## Resources Reference + +Lightweight reads (~100-500 tokens) for navigation: + +| Resource | Content | +| ---------------------------------------------- | ----------------------------------------- | +| `gitnexus://repo/{name}/context` | Stats, staleness check | +| `gitnexus://repo/{name}/clusters` | All functional areas with cohesion scores | +| `gitnexus://repo/{name}/cluster/{clusterName}` | Area members | +| `gitnexus://repo/{name}/processes` | All execution flows | +| `gitnexus://repo/{name}/process/{processName}` | Step-by-step trace | +| `gitnexus://repo/{name}/schema` | Graph schema for Cypher | + +## Graph Schema + +**Nodes:** File, Function, Class, Interface, Method, Community, Process +**Edges (via CodeRelation.type):** CALLS, IMPORTS, EXTENDS, IMPLEMENTS, DEFINES, MEMBER_OF, STEP_IN_PROCESS + +```cypher +MATCH (caller)-[:CodeRelation {type: 'CALLS'}]->(f:Function {name: "myFunc"}) +RETURN caller.name, caller.filePath +``` diff --git a/.claude/skills/gitnexus/gitnexus-impact-analysis/SKILL.md b/.claude/skills/gitnexus/gitnexus-impact-analysis/SKILL.md new file mode 100644 index 0000000..e19af28 --- /dev/null +++ b/.claude/skills/gitnexus/gitnexus-impact-analysis/SKILL.md @@ -0,0 +1,97 @@ +--- +name: gitnexus-impact-analysis +description: "Use when the user wants to know what will break if they change something, or needs safety analysis before editing code. Examples: \"Is it safe to change X?\", \"What depends on this?\", \"What will break?\"" +--- + +# Impact Analysis with GitNexus + +## When to Use + +- "Is it safe to change this function?" +- "What will break if I modify X?" +- "Show me the blast radius" +- "Who uses this code?" +- Before making non-trivial code changes +- Before committing — to understand what your changes affect + +## Workflow + +``` +1. gitnexus_impact({target: "X", direction: "upstream"}) → What depends on this +2. READ gitnexus://repo/{name}/processes → Check affected execution flows +3. gitnexus_detect_changes() → Map current git changes to affected flows +4. Assess risk and report to user +``` + +> If "Index is stale" → run `npx gitnexus analyze` in terminal. + +## Checklist + +``` +- [ ] gitnexus_impact({target, direction: "upstream"}) to find dependents +- [ ] Review d=1 items first (these WILL BREAK) +- [ ] Check high-confidence (>0.8) dependencies +- [ ] READ processes to check affected execution flows +- [ ] gitnexus_detect_changes() for pre-commit check +- [ ] Assess risk level and report to user +``` + +## Understanding Output + +| Depth | Risk Level | Meaning | +| ----- | ---------------- | ------------------------ | +| d=1 | **WILL BREAK** | Direct callers/importers | +| d=2 | LIKELY AFFECTED | Indirect dependencies | +| d=3 | MAY NEED TESTING | Transitive effects | + +## Risk Assessment + +| Affected | Risk | +| ------------------------------ | -------- | +| <5 symbols, few processes | LOW | +| 5-15 symbols, 2-5 processes | MEDIUM | +| >15 symbols or many processes | HIGH | +| Critical path (auth, payments) | CRITICAL | + +## Tools + +**gitnexus_impact** — the primary tool for symbol blast radius: + +``` +gitnexus_impact({ + target: "validateUser", + direction: "upstream", + minConfidence: 0.8, + maxDepth: 3 +}) + +→ d=1 (WILL BREAK): + - loginHandler (src/auth/login.ts:42) [CALLS, 100%] + - apiMiddleware (src/api/middleware.ts:15) [CALLS, 100%] + +→ d=2 (LIKELY AFFECTED): + - authRouter (src/routes/auth.ts:22) [CALLS, 95%] +``` + +**gitnexus_detect_changes** — git-diff based impact analysis: + +``` +gitnexus_detect_changes({scope: "staged"}) + +→ Changed: 5 symbols in 3 files +→ Affected: LoginFlow, TokenRefresh, APIMiddlewarePipeline +→ Risk: MEDIUM +``` + +## Example: "What breaks if I change validateUser?" + +``` +1. gitnexus_impact({target: "validateUser", direction: "upstream"}) + → d=1: loginHandler, apiMiddleware (WILL BREAK) + → d=2: authRouter, sessionManager (LIKELY AFFECTED) + +2. READ gitnexus://repo/my-app/processes + → LoginFlow and TokenRefresh touch validateUser + +3. Risk: 2 direct callers, 2 processes = MEDIUM +``` diff --git a/.claude/skills/gitnexus/gitnexus-refactoring/SKILL.md b/.claude/skills/gitnexus/gitnexus-refactoring/SKILL.md new file mode 100644 index 0000000..f48cc01 --- /dev/null +++ b/.claude/skills/gitnexus/gitnexus-refactoring/SKILL.md @@ -0,0 +1,121 @@ +--- +name: gitnexus-refactoring +description: "Use when the user wants to rename, extract, split, move, or restructure code safely. Examples: \"Rename this function\", \"Extract this into a module\", \"Refactor this class\", \"Move this to a separate file\"" +--- + +# Refactoring with GitNexus + +## When to Use + +- "Rename this function safely" +- "Extract this into a module" +- "Split this service" +- "Move this to a new file" +- Any task involving renaming, extracting, splitting, or restructuring code + +## Workflow + +``` +1. gitnexus_impact({target: "X", direction: "upstream"}) → Map all dependents +2. gitnexus_query({query: "X"}) → Find execution flows involving X +3. gitnexus_context({name: "X"}) → See all incoming/outgoing refs +4. Plan update order: interfaces → implementations → callers → tests +``` + +> If "Index is stale" → run `npx gitnexus analyze` in terminal. + +## Checklists + +### Rename Symbol + +``` +- [ ] gitnexus_rename({symbol_name: "oldName", new_name: "newName", dry_run: true}) — preview all edits +- [ ] Review graph edits (high confidence) and ast_search edits (review carefully) +- [ ] If satisfied: gitnexus_rename({..., dry_run: false}) — apply edits +- [ ] gitnexus_detect_changes() — verify only expected files changed +- [ ] Run tests for affected processes +``` + +### Extract Module + +``` +- [ ] gitnexus_context({name: target}) — see all incoming/outgoing refs +- [ ] gitnexus_impact({target, direction: "upstream"}) — find all external callers +- [ ] Define new module interface +- [ ] Extract code, update imports +- [ ] gitnexus_detect_changes() — verify affected scope +- [ ] Run tests for affected processes +``` + +### Split Function/Service + +``` +- [ ] gitnexus_context({name: target}) — understand all callees +- [ ] Group callees by responsibility +- [ ] gitnexus_impact({target, direction: "upstream"}) — map callers to update +- [ ] Create new functions/services +- [ ] Update callers +- [ ] gitnexus_detect_changes() — verify affected scope +- [ ] Run tests for affected processes +``` + +## Tools + +**gitnexus_rename** — automated multi-file rename: + +``` +gitnexus_rename({symbol_name: "validateUser", new_name: "authenticateUser", dry_run: true}) +→ 12 edits across 8 files +→ 10 graph edits (high confidence), 2 ast_search edits (review) +→ Changes: [{file_path, edits: [{line, old_text, new_text, confidence}]}] +``` + +**gitnexus_impact** — map all dependents first: + +``` +gitnexus_impact({target: "validateUser", direction: "upstream"}) +→ d=1: loginHandler, apiMiddleware, testUtils +→ Affected Processes: LoginFlow, TokenRefresh +``` + +**gitnexus_detect_changes** — verify your changes after refactoring: + +``` +gitnexus_detect_changes({scope: "all"}) +→ Changed: 8 files, 12 symbols +→ Affected processes: LoginFlow, TokenRefresh +→ Risk: MEDIUM +``` + +**gitnexus_cypher** — custom reference queries: + +```cypher +MATCH (caller)-[:CodeRelation {type: 'CALLS'}]->(f:Function {name: "validateUser"}) +RETURN caller.name, caller.filePath ORDER BY caller.filePath +``` + +## Risk Rules + +| Risk Factor | Mitigation | +| ------------------- | ----------------------------------------- | +| Many callers (>5) | Use gitnexus_rename for automated updates | +| Cross-area refs | Use detect_changes after to verify scope | +| String/dynamic refs | gitnexus_query to find them | +| External/public API | Version and deprecate properly | + +## Example: Rename `validateUser` to `authenticateUser` + +``` +1. gitnexus_rename({symbol_name: "validateUser", new_name: "authenticateUser", dry_run: true}) + → 12 edits: 10 graph (safe), 2 ast_search (review) + → Files: validator.ts, login.ts, middleware.ts, config.json... + +2. Review ast_search edits (config.json: dynamic reference!) + +3. gitnexus_rename({symbol_name: "validateUser", new_name: "authenticateUser", dry_run: false}) + → Applied 12 edits across 8 files + +4. gitnexus_detect_changes({scope: "all"}) + → Affected: LoginFlow, TokenRefresh + → Risk: MEDIUM — run tests for these flows +``` diff --git a/.gitignore b/.gitignore index 36a409a..842ea2a 100644 --- a/.gitignore +++ b/.gitignore @@ -52,3 +52,4 @@ coverage/ # Node compile cache node-compile-cache/ +.gitnexus diff --git a/AGENTS.md b/AGENTS.md index e7c2b5c..c829c72 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -445,3 +445,105 @@ Search results can flood context. Use `context-mode_ctx_execute(language: "shell | `ctx stats` | Call the `stats` MCP tool and display the full output verbatim | | `ctx doctor` | Call the `doctor` MCP tool, run the returned shell command, display as checklist | | `ctx upgrade` | Call the `upgrade` MCP tool, run the returned shell command, display as checklist | + + +# GitNexus — Code Intelligence + +This project is indexed by GitNexus as **tabatago** (1839 symbols, 3401 relationships, 52 execution flows). Use the GitNexus MCP tools to understand code, assess impact, and navigate safely. + +> If any GitNexus tool warns the index is stale, run `npx gitnexus analyze` in terminal first. + +## Always Do + +- **MUST run impact analysis before editing any symbol.** Before modifying a function, class, or method, run `gitnexus_impact({target: "symbolName", direction: "upstream"})` and report the blast radius (direct callers, affected processes, risk level) to the user. +- **MUST run `gitnexus_detect_changes()` before committing** to verify your changes only affect expected symbols and execution flows. +- **MUST warn the user** if impact analysis returns HIGH or CRITICAL risk before proceeding with edits. +- When exploring unfamiliar code, use `gitnexus_query({query: "concept"})` to find execution flows instead of grepping. It returns process-grouped results ranked by relevance. +- When you need full context on a specific symbol — callers, callees, which execution flows it participates in — use `gitnexus_context({name: "symbolName"})`. + +## When Debugging + +1. `gitnexus_query({query: ""})` — find execution flows related to the issue +2. `gitnexus_context({name: ""})` — see all callers, callees, and process participation +3. `READ gitnexus://repo/tabatago/process/{processName}` — trace the full execution flow step by step +4. For regressions: `gitnexus_detect_changes({scope: "compare", base_ref: "main"})` — see what your branch changed + +## When Refactoring + +- **Renaming**: MUST use `gitnexus_rename({symbol_name: "old", new_name: "new", dry_run: true})` first. Review the preview — graph edits are safe, text_search edits need manual review. Then run with `dry_run: false`. +- **Extracting/Splitting**: MUST run `gitnexus_context({name: "target"})` to see all incoming/outgoing refs, then `gitnexus_impact({target: "target", direction: "upstream"})` to find all external callers before moving code. +- After any refactor: run `gitnexus_detect_changes({scope: "all"})` to verify only expected files changed. + +## Never Do + +- NEVER edit a function, class, or method without first running `gitnexus_impact` on it. +- NEVER ignore HIGH or CRITICAL risk warnings from impact analysis. +- NEVER rename symbols with find-and-replace — use `gitnexus_rename` which understands the call graph. +- NEVER commit changes without running `gitnexus_detect_changes()` to check affected scope. + +## Tools Quick Reference + +| Tool | When to use | Command | +|------|-------------|---------| +| `query` | Find code by concept | `gitnexus_query({query: "auth validation"})` | +| `context` | 360-degree view of one symbol | `gitnexus_context({name: "validateUser"})` | +| `impact` | Blast radius before editing | `gitnexus_impact({target: "X", direction: "upstream"})` | +| `detect_changes` | Pre-commit scope check | `gitnexus_detect_changes({scope: "staged"})` | +| `rename` | Safe multi-file rename | `gitnexus_rename({symbol_name: "old", new_name: "new", dry_run: true})` | +| `cypher` | Custom graph queries | `gitnexus_cypher({query: "MATCH ..."})` | + +## Impact Risk Levels + +| Depth | Meaning | Action | +|-------|---------|--------| +| d=1 | WILL BREAK — direct callers/importers | MUST update these | +| d=2 | LIKELY AFFECTED — indirect deps | Should test | +| d=3 | MAY NEED TESTING — transitive | Test if critical path | + +## Resources + +| Resource | Use for | +|----------|---------| +| `gitnexus://repo/tabatago/context` | Codebase overview, check index freshness | +| `gitnexus://repo/tabatago/clusters` | All functional areas | +| `gitnexus://repo/tabatago/processes` | All execution flows | +| `gitnexus://repo/tabatago/process/{name}` | Step-by-step execution trace | + +## Self-Check Before Finishing + +Before completing any code modification task, verify: +1. `gitnexus_impact` was run for all modified symbols +2. No HIGH/CRITICAL risk warnings were ignored +3. `gitnexus_detect_changes()` confirms changes match expected scope +4. All d=1 (WILL BREAK) dependents were updated + +## Keeping the Index Fresh + +After committing code changes, the GitNexus index becomes stale. Re-run analyze to update it: + +```bash +npx gitnexus analyze +``` + +If the index previously included embeddings, preserve them by adding `--embeddings`: + +```bash +npx gitnexus analyze --embeddings +``` + +To check whether embeddings exist, inspect `.gitnexus/meta.json` — the `stats.embeddings` field shows the count (0 means no embeddings). **Running analyze without `--embeddings` will delete any previously generated embeddings.** + +> Claude Code users: A PostToolUse hook handles this automatically after `git commit` and `git merge`. + +## CLI + +| Task | Read this skill file | +|------|---------------------| +| Understand architecture / "How does X work?" | `.claude/skills/gitnexus/gitnexus-exploring/SKILL.md` | +| Blast radius / "What breaks if I change X?" | `.claude/skills/gitnexus/gitnexus-impact-analysis/SKILL.md` | +| Trace bugs / "Why is X failing?" | `.claude/skills/gitnexus/gitnexus-debugging/SKILL.md` | +| Rename / extract / split / refactor | `.claude/skills/gitnexus/gitnexus-refactoring/SKILL.md` | +| Tools, resources, schema reference | `.claude/skills/gitnexus/gitnexus-guide/SKILL.md` | +| Index, status, clean, wiki CLI commands | `.claude/skills/gitnexus/gitnexus-cli/SKILL.md` | + + diff --git a/CLAUDE.md b/CLAUDE.md index dd2575a..ef0cd03 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -192,11 +192,13 @@ COMPLETE: '#30D158' // Green ## 🚀 Commands +Use `rtk` (token-optimized CLI proxy) for all non-interactive commands. + ```bash -npx expo start # Development +npx expo start # Development (interactive, no rtk) npx expo start --tunnel # If network issues npx expo start --clear # Clear cache -npx tsc --noEmit # Type check +rtk tsc --noEmit # Type check (grouped errors) eas build --profile dev # Dev build ``` @@ -211,3 +213,105 @@ Voir `.claude/skills/` pour les guides spécialisés. *Document updated: February 18, 2026* *Version: 2.0* *Project: TabataFit — Apple Fitness+ for Tabata* + + +# GitNexus — Code Intelligence + +This project is indexed by GitNexus as **tabatago** (1839 symbols, 3401 relationships, 52 execution flows). Use the GitNexus MCP tools to understand code, assess impact, and navigate safely. + +> If any GitNexus tool warns the index is stale, run `npx gitnexus analyze` in terminal first. + +## Always Do + +- **MUST run impact analysis before editing any symbol.** Before modifying a function, class, or method, run `gitnexus_impact({target: "symbolName", direction: "upstream"})` and report the blast radius (direct callers, affected processes, risk level) to the user. +- **MUST run `gitnexus_detect_changes()` before committing** to verify your changes only affect expected symbols and execution flows. +- **MUST warn the user** if impact analysis returns HIGH or CRITICAL risk before proceeding with edits. +- When exploring unfamiliar code, use `gitnexus_query({query: "concept"})` to find execution flows instead of grepping. It returns process-grouped results ranked by relevance. +- When you need full context on a specific symbol — callers, callees, which execution flows it participates in — use `gitnexus_context({name: "symbolName"})`. + +## When Debugging + +1. `gitnexus_query({query: ""})` — find execution flows related to the issue +2. `gitnexus_context({name: ""})` — see all callers, callees, and process participation +3. `READ gitnexus://repo/tabatago/process/{processName}` — trace the full execution flow step by step +4. For regressions: `gitnexus_detect_changes({scope: "compare", base_ref: "main"})` — see what your branch changed + +## When Refactoring + +- **Renaming**: MUST use `gitnexus_rename({symbol_name: "old", new_name: "new", dry_run: true})` first. Review the preview — graph edits are safe, text_search edits need manual review. Then run with `dry_run: false`. +- **Extracting/Splitting**: MUST run `gitnexus_context({name: "target"})` to see all incoming/outgoing refs, then `gitnexus_impact({target: "target", direction: "upstream"})` to find all external callers before moving code. +- After any refactor: run `gitnexus_detect_changes({scope: "all"})` to verify only expected files changed. + +## Never Do + +- NEVER edit a function, class, or method without first running `gitnexus_impact` on it. +- NEVER ignore HIGH or CRITICAL risk warnings from impact analysis. +- NEVER rename symbols with find-and-replace — use `gitnexus_rename` which understands the call graph. +- NEVER commit changes without running `gitnexus_detect_changes()` to check affected scope. + +## Tools Quick Reference + +| Tool | When to use | Command | +|------|-------------|---------| +| `query` | Find code by concept | `gitnexus_query({query: "auth validation"})` | +| `context` | 360-degree view of one symbol | `gitnexus_context({name: "validateUser"})` | +| `impact` | Blast radius before editing | `gitnexus_impact({target: "X", direction: "upstream"})` | +| `detect_changes` | Pre-commit scope check | `gitnexus_detect_changes({scope: "staged"})` | +| `rename` | Safe multi-file rename | `gitnexus_rename({symbol_name: "old", new_name: "new", dry_run: true})` | +| `cypher` | Custom graph queries | `gitnexus_cypher({query: "MATCH ..."})` | + +## Impact Risk Levels + +| Depth | Meaning | Action | +|-------|---------|--------| +| d=1 | WILL BREAK — direct callers/importers | MUST update these | +| d=2 | LIKELY AFFECTED — indirect deps | Should test | +| d=3 | MAY NEED TESTING — transitive | Test if critical path | + +## Resources + +| Resource | Use for | +|----------|---------| +| `gitnexus://repo/tabatago/context` | Codebase overview, check index freshness | +| `gitnexus://repo/tabatago/clusters` | All functional areas | +| `gitnexus://repo/tabatago/processes` | All execution flows | +| `gitnexus://repo/tabatago/process/{name}` | Step-by-step execution trace | + +## Self-Check Before Finishing + +Before completing any code modification task, verify: +1. `gitnexus_impact` was run for all modified symbols +2. No HIGH/CRITICAL risk warnings were ignored +3. `gitnexus_detect_changes()` confirms changes match expected scope +4. All d=1 (WILL BREAK) dependents were updated + +## Keeping the Index Fresh + +After committing code changes, the GitNexus index becomes stale. Re-run analyze to update it: + +```bash +npx gitnexus analyze +``` + +If the index previously included embeddings, preserve them by adding `--embeddings`: + +```bash +npx gitnexus analyze --embeddings +``` + +To check whether embeddings exist, inspect `.gitnexus/meta.json` — the `stats.embeddings` field shows the count (0 means no embeddings). **Running analyze without `--embeddings` will delete any previously generated embeddings.** + +> Claude Code users: A PostToolUse hook handles this automatically after `git commit` and `git merge`. + +## CLI + +| Task | Read this skill file | +|------|---------------------| +| Understand architecture / "How does X work?" | `.claude/skills/gitnexus/gitnexus-exploring/SKILL.md` | +| Blast radius / "What breaks if I change X?" | `.claude/skills/gitnexus/gitnexus-impact-analysis/SKILL.md` | +| Trace bugs / "Why is X failing?" | `.claude/skills/gitnexus/gitnexus-debugging/SKILL.md` | +| Rename / extract / split / refactor | `.claude/skills/gitnexus/gitnexus-refactoring/SKILL.md` | +| Tools, resources, schema reference | `.claude/skills/gitnexus/gitnexus-guide/SKILL.md` | +| Index, status, clean, wiki CLI commands | `.claude/skills/gitnexus/gitnexus-cli/SKILL.md` | + + diff --git a/TabataKine_Guide_Complet.md b/TabataKine_Guide_Complet.md new file mode 100644 index 0000000..750cb9f --- /dev/null +++ b/TabataKine_Guide_Complet.md @@ -0,0 +1,1179 @@ +# TABATA KINÉ — Guide Complet des Programmes + +> **Programmes conçus par une Kinésithérapeute Diplômée d'État** +> Sécurité · Progression médicale · Accessibilité +> 6 programmes · 26 semaines · 100+ exercices détaillés + +--- + +## Sommaire + +1. [Vue d'ensemble](#1-vue-densemble) +2. [Programme Débutant — 4 semaines](#2-programme-débutant--4-semaines) +3. [Programme Intermédiaire — 4 semaines](#3-programme-intermédiaire--4-semaines) +4. [Programme Avancé — 4 semaines](#4-programme-avancé--4-semaines) +5. [Programme Post-Partum — 6 semaines](#5-programme-post-partum--6-semaines) +6. [Programme Seniors — 4 semaines](#6-programme-seniors--4-semaines) +7. [Programme Bureau — 4 semaines](#7-programme-bureau--4-semaines) +8. [Récapitulatif global](#8-récapitulatif-global) + +--- + +## 1. Vue d'ensemble + +| Programme | Durée | Séances/sem | Blocs max | Impacts | Prérequis | Tier | +|---|---|---|---|---|---|---| +| 🟢 Débutant | 4 semaines | 3 | 3 blocs | ❌ Aucun | Aucun | Gratuit | +| 🔵 Intermédiaire | 4 semaines | 4 | 4 blocs | ⚡ Léger | Débutant | Premium | +| 🔴 Avancé | 4 semaines | 5 | 5 blocs | 🔥 Fort | Intermédiaire | Premium | +| 🩷 Post-partum | 6 semaines | 4 | 3 blocs | ❌ Aucun | Accord médical | Kiné+ | +| 🟤 Seniors | 4 semaines | 3 | 3 blocs | ❌ Aucun | Accord médecin | Kiné+ | +| 🟡 Bureau | 4 semaines | 3–5 | 5 blocs | ❌ Aucun | Aucun | Premium | + +### La signature kiné — ce qui rend ces programmes uniques + +- Chaque exercice inclut un conseil kinésithérapeutique sur la technique, les erreurs à éviter et les contre-indications +- Les progressions sont médicalement raisonnées : aucun impact avant maîtrise du mouvement, semaine de décharge systématique +- Les programmes de niche (post-partum, seniors, bureau) adressent des besoins non couverts par les apps concurrentes +- Les tests de fin de programme sont issus de protocoles cliniques validés + +--- + +## 2. Programme Débutant — 4 semaines + +**Objectif :** apprendre le protocole tabata, construire les bases techniques de chaque mouvement fondamental, et terminer 12 séances sans douleur articulaire. Le succès n'est pas mesuré en calories brûlées mais en confiance acquise. + +**Prérequis :** aucun — accessible à tous, pas de matériel requis. +**Organisation :** 3 séances/semaine — Lundi · Mercredi · Vendredi recommandé. + +### Principes fondateurs + +**Règle 1 — Zéro impact les 2 premières semaines.** Pas de sauts, pas de chocs. Les articulations doivent s'adapter progressivement. Cause numéro 1 des abandons par douleur. + +**Règle 2 — La technique avant l'intensité.** 20 secondes c'est court mais suffisant pour faire une mauvaise répétition. Mieux vaut 8 squats propres que 15 squats avec le dos arrondi. + +**Règle 3 — Semaine 4 = décharge.** Volume réduit de 40%. C'est là que le corps consolide les adaptations. La progression se fait pendant le repos, pas pendant l'effort. + +--- + +### SEMAINE 1 — Découverte du rythme + +**Format :** 1 bloc tabata par séance (4 min) + échauffement + retour au calme +**Durée totale :** ~20 minutes + +--- + +#### Séance 1A — Membres inférieurs + +**Échauffement — 4 min** +- 1 min — Marche sur place avec genoux hauts +- 1 min — Cercles de chevilles (30 sec chaque pied) +- 1 min — Flexions de genoux lentes (3 sec descente / 1 sec montée) +- 1 min — Fentes statiques alternées lentes + +**⏱ Bloc 1 — 4 min | 8 rounds | 20 sec effort / 10 sec repos** + +| Rounds impairs | Rounds pairs | +|---|---| +| **Squat classique** — pieds largeur d'épaules, descente jusqu'aux cuisses parallèles au sol, regard droit, talons à plat | **Pont fessier** — allongé sur le dos, pieds à plat, monter et descendre le bassin lentement, serrer les fessiers en haut | +| 📋 *Si les talons se soulèvent : écarter davantage les pieds ou placer un support sous les talons. Genoux dans l'axe des pieds, jamais vers l'intérieur.* | 📋 *Ne pas creuser le bas du dos en position haute. Le bassin monte grâce aux fessiers, pas grâce aux lombaires.* | + +**Retour au calme — 3 min** +- 45 sec — Étirement quadriceps debout (chaque jambe) +- 45 sec — Étirement ischio-jambiers assis (chaque jambe) +- 30 sec — Respiration diaphragmatique + +--- + +#### Séance 1B — Membres supérieurs & gainage + +**Échauffement — 4 min** +- 1 min — Rotations d'épaules avant et arrière +- 1 min — Ouvertures de poitrine (mains croisées dans le dos) +- 1 min — Cercles de poignets dans les deux sens +- 1 min — Cat-cow : mobilité lombaire à quatre pattes + +**⏱ Bloc 1 — 4 min | 8 rounds | 20 sec effort / 10 sec repos** + +| Rounds impairs | Rounds pairs | +|---|---| +| **Pompes genoux** — corps aligné des genoux aux épaules, descendre la poitrine à 2–3 cm du sol, coudes à 45° | **Planche basse sur avant-bras** — corps aligné, coudes sous les épaules, ne pas laisser tomber les hanches ni les remonter | +| 📋 *Si douleur aux poignets : faire sur les poings fermés ou les avant-bras. Vérifier l'alignement poignet / coude / épaule.* | 📋 *Respirer normalement. La planche doit être une contraction active — réduire la durée si tremblements excessifs.* | + +**Retour au calme — 3 min** +- 45 sec — Étirement pectoraux contre un mur (chaque côté) +- 30 sec — Étirement triceps derrière la tête (chaque bras) +- 30 sec — Étirement cervical latéral doux (chaque côté) + +--- + +#### Séance 1C — Corps entier + +**Échauffement — 4 min** +- 1 min — Jumping jacks lents sans sauter (décaler les pieds) +- 1 min — Rotations de hanches debout +- 1 min — Marche avec bras croisés devant +- 1 min — Squats ¼ de descente (activation légère) + +**⏱ Bloc 1 — 4 min | 8 rounds | 20 sec effort / 10 sec repos** + +| Rounds impairs | Rounds pairs | +|---|---| +| **Step touch latéral** — pas latéraux rapides droite/gauche avec bras actifs, rythme soutenu | **Superman** — allongé ventre au sol, lever simultanément bras et jambes 2 secondes, relâcher complètement | +| 📋 *Garder le regard droit. Les bras actifs contribuent à 20% de l'effort cardiovasculaire.* | 📋 *Ne pas forcer sur le cou — il reste dans l'axe. Exercice roi pour les lombaires et les paravertébraux.* | + +**Retour au calme — 3 min** +- 1 min — Posture de l'enfant (balasana) +- 45 sec — Étirement des hanches en pigeon (chaque côté) + +--- + +### SEMAINE 2 — Consolidation + +**Format :** 2 blocs tabata + 1 min récupération active entre les blocs +**Durée totale :** ~25 minutes + +#### Nouveaux exercices introduits en semaine 2 + +**Fente avant alternée** — un pas en avant, genou arrière descend vers le sol sans toucher. +📋 *Le genou avant ne dépasse pas les orteils. Si douleur rotulienne : réduire l'amplitude.* + +**Dead bug** — allongé sur le dos, bras vers le plafond, jambes à 90°. Descendre un bras et la jambe opposée sans que le bas du dos se décolle. Expirer en descendant. +📋 *Gainage profond transverse — excellent pour les lombaires. La version un seul membre reste disponible si besoin.* + +**Bird dog** — à quatre pattes, tendre simultanément le bras droit et la jambe gauche. Maintenir 2 secondes, bassin horizontal. Alterner. +📋 *Placer une bouteille sur le dos pour vérifier que le bassin reste horizontal.* + +--- + +#### Séance 2A — Membres inférieurs renforcés + +**⏱ Bloc 1** + +| Rounds impairs | Rounds pairs | +|---|---| +| **Squat classique (consolidation)** — augmenter la profondeur, viser cuisses parallèles au sol, tempo 2-1-2 | **Pont fessier (consolidation)** — ajouter 1 sec de maintien en haut, soulever les orteils pour intensifier | + +⏸ *1 min récupération active — marche lente, respiration nasale* + +**⏱ Bloc 2** + +| Rounds impairs | Rounds pairs | +|---|---| +| **Fente avant alternée** — vérifier que le genou avant ne dépasse pas les orteils, tronc droit, regard devant | **Dead bug** — dos bien à plat au sol, expirer en descendant le membre, réduire l'amplitude si le dos se décolle | + +**Retour au calme — 4 min** +- 1 min — Étirement du psoas en fente basse (chaque côté) +- 45 sec — Étirement des ischio-jambiers allongé (chaque jambe) +- 30 sec — Respiration guidée + +--- + +#### Séance 2B — Haut du corps renforcé + +**⏱ Bloc 1** + +| Rounds impairs | Rounds pairs | +|---|---| +| **Pompes genoux (consolidation)** — essayer 2–3 pompes complètes sur orteils si possible | **Planche avant-bras (consolidation)** — tenter la planche sur orteils 10 sec puis repasser sur genoux si besoin | + +⏸ *1 min récupération active* + +**⏱ Bloc 2** + +| Rounds impairs | Rounds pairs | +|---|---| +| **Bird dog** — maintenir le bassin parfaitement horizontal | **Superman dynamique** — version dynamique : lever et descendre en rythme avec la respiration | + +--- + +#### Séance 2C — Corps entier mixte + +**⏱ Bloc 1** + +| Rounds impairs | Rounds pairs | +|---|---| +| **Step touch + bras (consolidation)** — augmenter la vitesse, bras au-dessus des épaules | **Superman (consolidation)** — maintenir la position haute 3 secondes au lieu de 2 | + +⏸ *1 min récupération active* + +**⏱ Bloc 2** + +| Rounds impairs | Rounds pairs | +|---|---| +| **Fente avant alternée + rotation de buste** — en fente basse, rotation du tronc vers le genou avant | **Dead bug lent** — 5 secondes par membre, qualité absolue | + +--- + +### SEMAINE 3 — Montée en intensité + +**Format :** 3 blocs tabata + 1 min récupération entre chaque +**Durée totale :** ~30 minutes + +#### Nouveaux exercices introduits en semaine 3 + +**Squat jump low** — même mouvement que le squat mais à la montée on monte sur la pointe des pieds sans quitter le sol. Préparation au squat sauté. +📋 *Réception silencieuse sur avant-pied. Si bruit à l'atterrissage : réduire la hauteur.* + +**Step-up sur marche basse** — monter/descendre sur une marche basse, alterner les jambes. Équivalent cardio des fentes sautées sans l'impact. +📋 *Genou de la jambe de montée au-dessus du pied de la marche.* + +**Mountain climber lent** — en position de pompes, ramener un genou vers la poitrine en 1 sec aller / 1 sec retour. +📋 *Gainage parfait pendant tout le mouvement. Ne pas laisser les hanches monter.* + +--- + +#### Séances 3A/B/C — Structure type (3 blocs) + +**⏱ Bloc 1** — exercice maîtrisé des semaines précédentes + +| Rounds impairs | Rounds pairs | +|---|---| +| **Squat classique** — focus sur la respiration : inspirer en descendant, expirer en remontant | **Pont fessier unilatéral** — jambe non-travaillante tendue en l'air | +| | 📋 *Le bassin ne doit pas s'incliner du côté de la jambe levée — signe de faiblesse du moyen fessier.* | + +⏸ *1 min récupération active* + +**⏱ Bloc 2** — nouveau mouvement + +| Rounds impairs | Rounds pairs | +|---|---| +| **Squat jump low** — réception silencieuse sur avant-pied | **Fente avant alternée (maîtrisée)** — ¼ de descente supplémentaire | + +⏸ *1 min récupération active* + +**⏱ Bloc 3** — mixte + +| Rounds impairs | Rounds pairs | +|---|---| +| **Step-up sur marche basse** — alterner les jambes à mi-bloc | **Mountain climber lent** — gainage parfait, hanches basses | + +--- + +### SEMAINE 4 — Décharge & consolidation + +**Format :** retour à 2 blocs tabata. Volume réduit de 40%. +**Durée totale :** ~25 minutes + +> 💡 **Pourquoi la décharge ?** C'est pendant le repos que le corps consolide les adaptations musculaires et articulaires. Les sportifs qui sautent la décharge progressent moins vite à long terme. + +Pas de nouveaux exercices. Focus sur : +- Technique parfaite à chaque répétition +- Respiration consciente et coordonnée avec le mouvement +- Ressenti musculaire : identifier les muscles sollicités +- Bilan personnel : quels exercices sont devenus faciles ? Lesquels restent difficiles ? + +--- + +### Récapitulatif Programme Débutant + +| Semaine | Blocs/séance | Min effectives | Séances/sem | Impacts | Durée totale | +|---|---|---|---|---|---| +| Semaine 1 | 1 bloc | 4 min | 3 | ❌ Aucun | ~20 min | +| Semaine 2 | 2 blocs | 8 min | 3 | ❌ Aucun | ~25 min | +| Semaine 3 | 3 blocs | 12 min | 3 | ⚡ Très léger | ~30 min | +| Semaine 4 | 2 blocs | 8 min | 3 | ❌ Aucun | ~25 min | + +**Critères de passage au programme Intermédiaire :** +- Planche sur avant-bras tenue 30 secondes sans compensation +- 10 squats propres consécutifs sans douleur aux genoux +- 5 pompes complètes (sur orteils) avec corps parfaitement aligné +- Aucune douleur articulaire résiduelle après les séances + +--- + +## 3. Programme Intermédiaire — 4 semaines + +**Objectif :** introduire la plyométrie contrôlée, intensifier le travail unilatéral, passer à 4 blocs tabata. L'utilisateur construit puissance et conscience corporelle, apprend à distinguer brûlure musculaire (normale) et douleur articulaire (signal d'arrêt). + +**Organisation :** 4 séances/semaine — Lundi · Mardi · Jeudi · Samedi. 1 séance mobilité/récupération active. Ne jamais faire 2 séances intenses consécutives. + +**Règle de réception des impacts :** silencieuse, sur avant-pied, genou fléchi. Un bruit à l'atterrissage = muscles ne font pas leur travail d'amortisseur. + +--- + +### SEMAINE 1 — Transition avec impacts + +**Format :** 3 blocs tabata + 1 min récupération active entre chaque +**Durée totale :** ~35 minutes + +--- + +#### Séance 2A — Membres inférieurs plyométriques + +**Échauffement — 5 min** +- 1 min — Marche rapide avec bras actifs +- 1 min — Squats lents x10 (activation) +- 1 min — Fentes alternées lentes x8 +- 30 sec — Sauts très légers sur place (test des chevilles) +- 30 sec — Montées de genoux en trottinant +- 1 min — Hip circles : cercles de hanches debout + +**⏱ Bloc 1** + +| Rounds impairs | Rounds pairs | +|---|---| +| **Squat jump** — descente contrôlée, explosion vers le haut, réception silencieuse avant-pied, absorption immédiate en flexion | **Pont fessier unilatéral** — une jambe tendue levée, montée du bassin, maintien 2 sec en haut | +| 📋 *Si la réception fait du bruit : les muscles ne font pas leur travail. Réduire la hauteur. Genoux dans l'axe des pieds.* | 📋 *Le bassin ne s'incline pas du côté de la jambe levée. Si c'est le cas : faiblesse du moyen fessier.* | + +⏸ *1 min récupération active — marche lente, respiration nasale* + +**⏱ Bloc 2** + +| Rounds impairs | Rounds pairs | +|---|---| +| **Fente sautée alternée** — depuis la fente basse, saut pour changer de jambe, réception directement en fente | **Isométrie squat (chaise)** — dos au mur, cuisses parallèles au sol, tenir 20 secondes, respirer calmement | +| 📋 *Si douleur antérieure du genou : revenir à la fente marchée. Réception absorbée sur 2–3 secondes.* | 📋 *L'isométrie renforce l'endurance musculaire sans impact. Excellent pour skieurs et cyclistes.* | + +⏸ *1 min récupération active* + +**⏱ Bloc 3** + +| Rounds impairs | Rounds pairs | +|---|---| +| **Step-up explosif** — monter rapidement en poussant sur le pied avant, descendre contrôlé, alterner à mi-bloc | **Glute kickback à quatre pattes** — genou fléchi à 90°, pousser le talon vers le plafond, lent et contrôlé | +| 📋 *La descente est aussi importante que la montée. Ne pas sauter en bas.* | 📋 *Ne pas cambrer le bas du dos pour aller plus haut — c'est la hanche qui travaille, pas les lombaires.* | + +**Retour au calme — 5 min** +- 1 min — Étirement psoas en fente basse (chaque côté) +- 45 sec — Étirement mollets contre un mur (chaque jambe) +- 1 min — Automassage quadriceps +- 30 sec — Respiration guidée + +--- + +#### Séance 2B — Haut du corps & gainage dynamique + +**Échauffement — 5 min** +- 1 min — Rotations complètes d'épaules avec serviette +- 1 min — Face pulls avec résistance manuelle (rétraction scapulaire) +- 1 min — Pompes lentes x8 (échauffement scapulaires) +- 1 min — Planche dynamique haute ↔ basse lentement +- 1 min — Dead bug lent (consolidation) + +**⏱ Bloc 1** + +| Rounds impairs | Rounds pairs | +|---|---| +| **Pompes classiques complètes** — corps aligné, coudes à 45°, descendre jusqu'au contact de la poitrine | **Renegade row sans poids** — en position de pompes, lever alternativement un bras vers la hanche en contractant l'omoplate | +| 📋 *Douleur aux poignets = vérifier l'alignement poignet/coude/épaule. Si persistant : pompes sur les poings.* | 📋 *Gainage total pendant le mouvement. Le bassin ne se balance pas.* | + +⏸ *1 min récupération active* + +**⏱ Bloc 2** + +| Rounds impairs | Rounds pairs | +|---|---| +| **Pompes avec rotation en T** — en haut de la pompe, rotation latérale avec bras vers le plafond, alterner | **Planche avec tap épaule** — en planche haute, toucher alternativement l'épaule opposée, minimiser la rotation du bassin | +| 📋 *Exercice combiné : obliques + dentelés antérieurs + rotateurs d'épaule. Ouvrir complètement la hanche.* | 📋 *La résistance à la rotation du bassin est l'objectif. Pieds plus écartés pour stabiliser.* | + +⏸ *1 min récupération active* + +**⏱ Bloc 3** + +| Rounds impairs | Rounds pairs | +|---|---| +| **Dips sur chaise** — mains sur le bord, corps décollé, descendre les coudes à 90° | **Superman en Y·W·T** — allongé ventre, lever bras et jambes puis former successivement Y, W, T avec les bras | +| 📋 *Si inconfort à l'avant de l'épaule : réduire l'amplitude. Contre-indiqué si tendinopathie du biceps.* | 📋 *Travail intense des rhomboïdes et trapèzes inférieurs. Muscles posturaux clés contre la position assise.* | + +**Retour au calme — 5 min** +- 1 min — Étirement pectoraux en porte (chaque côté) +- 45 sec — Étirement grand dorsal avec inclinaison latérale (chaque côté) +- 1 min — Mobilisation cervicale douce + +--- + +#### Séance 2C — Corps entier cardio dominant + +**⏱ Bloc 1** + +| Rounds impairs | Rounds pairs | +|---|---| +| **Burpee modifié** — marcher les pieds en arrière jusqu'à planche, marcher retour, se relever (pas de saut) | **Mountain climber rapide** — alterner les jambes le plus vite possible en maintenant le gainage | +| 📋 *Le burpee modifié permet de maîtriser le schéma moteur sans impact lombaire brutal. Le burpee complet vient en semaine 3.* | 📋 *Les hanches ne remontent pas au-dessus des épaules. Regard vers le sol.* | + +⏸ *1 min récupération active* + +**⏱ Bloc 2** + +| Rounds impairs | Rounds pairs | +|---|---| +| **Skaters** — saut latéral d'un pied sur l'autre en simulant le patineur, bras opposé en avant | **Planche to downward dog** — depuis planche avant-bras, pousser en planche haute puis lever les hanches en V inversé | +| 📋 *Atterrissage sur un pied — demande une bonne proprioception de cheville. En cas d'entorse récente : éviter.* | 📋 *Tirer les talons vers le sol en V inversé pour étirer les mollets.* | + +⏸ *1 min récupération active* + +**⏱ Bloc 3** + +| Rounds impairs | Rounds pairs | +|---|---| +| **High knees** — course sur place avec genoux hauts, bras actifs, regard droit, maintenir le rythme | **Bear crawl sur place** — à quatre pattes, genoux à 3 cm du sol, reculer/avancer sur 2 pas rapidement | +| 📋 *Le but est le rythme, pas la hauteur maximale. Les bras pompants contribuent à 15% de la dépense calorique.* | 📋 *Très intense pour le gainage et les épaules malgré l'apparente simplicité. Genoux à 3 cm du sol.* | + +**Retour au calme — 5 min** +- 2 min — Foam roller ou automassage mollets et IT band +- 1 min — Pigeon yoga (chaque côté) +- 1 min — Respiration 4-7-8 (inspirer 4 sec, bloquer 7, expirer 8) × 4 cycles + +--- + +#### Séance 2D — Mobilité & récupération active + +> ℹ️ **Format spécial — Pas de blocs 20/10.** Cette séance ne suit pas le protocole tabata. 25–30 min de travail doux mais structuré. Elle est aussi importante que les trois autres — c'est pendant la récupération que le corps reconstruit les fibres musculaires. + +- 10 min — Mobilité articulaire complète : chevilles, hanches, colonne, épaules +- 10 min — Étirements ciblés sur les zones sollicitées en semaine +- 5 min — Respiration et relaxation guidée + +--- + +### SEMAINE 2 — Montée en densité + +**Format :** 4 blocs tabata + 1 min récup entre chaque +**Durée totale :** ~40 minutes + +#### Nouveaux exercices introduits en semaine 2 + +**Thruster** — squat puis poussée des bras vers le haut. Expirer lors de la poussée. Exercice total-body par excellence. +📋 *La montée en pression intra-abdominale est importante — expirer lors de la poussée vers le haut.* + +**Burpee complet** — depuis debout : squat, mains au sol, saut des pieds en arrière, pompe optionnelle, saut retour, saut vertical avec clap. Point critique : fléchir les genoux en posant les mains. +📋 *Ne jamais arrondir violemment le dos sous fatigue.* + +**Hollow body** — allongé, bras tendus derrière la tête, jambes tendues à 30° du sol, bas du dos collé au sol. Maintenir 20 secondes. +📋 *Gainage profond issu de la gymnastique artistique — le plus efficace pour les abdominaux profonds.* + +**V-sit hold** — assis, jambes levées à 45° et bras parallèles au sol. Tenir. +📋 *Si douleur lombaire : fléchir légèrement les genoux. Ne jamais forcer si le bas du dos compense.* + +--- + +### SEMAINE 3 — Intensité maximale + +**Format :** 4 blocs tabata denses +**Durée totale :** ~40 minutes + +#### Exercices signature de la semaine 3 + +**Burpee avec saut latéral** — ajouter un saut latéral à la fin du burpee classique. Augmente l'impact cardiovasculaire et la coordination. + +**Pistol squat assisté** — squat sur une jambe en tenant un support léger. +📋 *Révélateur des asymétries de force et de mobilité. Si un côté est significativement plus difficile : information précieuse sur les déséquilibres à corriger.* + +**Archer push-up** — pompes larges en ramenant tout le poids sur un seul bras, l'autre restant tendu à plat. Quasi-pompe à un bras. + +**Turkish get-up simplifié** — depuis allongé, se lever en séquence contrôlée : coude → main → genou → debout, puis redescendre. +📋 *Exercice de rééducation fonctionnelle utilisé en cabinet kiné. Exceptionnel pour la coordination et la proprioception.* + +--- + +### SEMAINE 4 — Décharge & bilan + +**Format :** retour à 3 blocs tabata, exercices maîtrisés, focus sur la technique parfaite. + +#### Tests de fin de programme Intermédiaire + +| Test | Protocole | Objectif | +|---|---|---| +| Planche avant-bras | Tenir en planche basse sans compensation | 60 secondes | +| Burpee endurance | Compter les burpees complets en 1 minute | 12 à 15 répétitions | +| Squat jump | 8 rounds de 20 sec de squat jump | Maintenir le rythme au round 7-8 | +| Asymétrie | Pistol squat assisté G/D | Différence < 20% entre les côtés | + +--- + +### Récapitulatif Programme Intermédiaire + +| Semaine | Blocs/séance | Min effectives | Séances/sem | Impacts | Durée totale | +|---|---|---|---|---|---| +| Semaine 1 | 3 blocs | 12 min | 4 | ⚡ Moyens | ~35 min | +| Semaine 2 | 4 blocs | 16 min | 4 | 🔥 Intenses | ~40 min | +| Semaine 3 | 4 blocs | 16 min | 4 | 🔥🔥 Max | ~40 min | +| Semaine 4 | 3 blocs | 12 min | 4 | ⚡ Moyens | ~35 min | + +--- + +## 4. Programme Avancé — 4 semaines + +**Objectif :** mouvements complexes sous fatigue, travail unilatéral systématique, préparation physique fonctionnelle de haut niveau. L'utilisateur développe une intelligence physique : savoir doser l'intensité sur 20 minutes de travail effectif. + +**Prérequis :** +- 15 burpees/min sans s'effondrer +- Planche avant-bras 60 secondes +- Squat jump ×8 rounds propres +- Pistol squat assisté G/D symétrique +- Aucune douleur articulaire chronique + +**Organisation :** 5 séances/semaine — 4 tabata + 1 MetCon. Repos : mercredi + dimanche. + +> ⚠️ La fatigue neurologique se manifeste par une perte de coordination, des réactions ralenties, une irritabilité. Si ces signes apparaissent : réduire d'une séance par semaine avant de forcer. + +--- + +### SEMAINE 1 — Bascule vers la complexité + +**Format :** 4 blocs tabata + 1 min 30 récupération active entre chaque +**Durée totale :** ~45 minutes + +--- + +#### Séance 3A — Membres inférieurs explosifs + +**Échauffement — 6 min** +- 1 min — Jogging sur place progressif +- 1 min — Leg swings dynamiques avant/arrière et latéraux +- 1 min — Fentes dynamiques avec rotation du tronc +- 1 min — Squat profond maintenu 3 sec en bas (ouverture des hanches) +- 1 min — Sauts bas et rapides à deux pieds (activation système nerveux) +- 30 sec — Clamshells rapides debout (activation fessiers) + +**⏱ Bloc 1** + +| Rounds impairs | Rounds pairs | +|---|---| +| **Squat jump avec rotation 180°** — squat, explosion, rotation 180° dans les airs, réception en squat absorbée | **Pistol squat complet** — squat sur une jambe sans support, jambe libre tendue devant, descente complète | +| 📋 *La réception en rotation sollicite fortement le LCA. Antécédent de genou = rester au squat jump classique. Réception sur 2–3 secondes, jamais jambe tendue.* | 📋 *Talon qui se soulève = manque de mobilité de cheville. Tronc qui bascule = faiblesse du moyen fessier. Corriger avant de forcer.* | + +⏸ *1 min 30 récupération active — marche avec respiration nasale* + +**⏱ Bloc 2** + +| Rounds impairs | Rounds pairs | +|---|---| +| **Nordic curl assisté** — à genoux, pieds bloqués, descendre le buste vers le sol lentement en résistant avec les ischio-jambiers, poser les mains avant d'atterrir | **Isométrie fente bulgare** — pied arrière posé sur une chaise, descendre en fente, maintenir 20 secondes | +| 📋 *Cliniquement prouvé pour réduire les blessures ischio-jambiers de 50%. Même 3–4 reps contrôlées par round sont excellentes.* | 📋 *Sollicitation intense du psoas-iliaque et du quadriceps. Excellent pour les coureurs et personnes sédentaires.* | + +⏸ *1 min 30 récupération active* + +**⏱ Bloc 3** + +| Rounds impairs | Rounds pairs | +|---|---| +| **Box jump** — saut à deux pieds sur surface surélevée stable, réception en squat, descente en marchant | **Lateral bound** — saut explosif latéral d'un pied sur l'autre le plus loin possible, réception sur un pied avec absorption | +| 📋 *Descendre en marchant — ne pas sauter en arrière. Sauter en arrière pour descendre multiplie les contraintes articulaires.* | 📋 *Exercice de prévention des entorses par renforcement proprioceptif. Regard fixe droit devant.* | + +⏸ *1 min 30 récupération active* + +**⏱ Bloc 4** + +| Rounds impairs | Rounds pairs | +|---|---| +| **Broad jump + recul** — saut vers l'avant le plus loin possible à deux pieds, reculer en marche contrôlée, relancer immédiatement | **Single leg deadlift sans poids** — debout sur une jambe, basculer le buste en levant la jambe libre derrière, dos plat, descendre vers le sol | +| 📋 *Le recul contrôlé est aussi important que le saut. Il renforce les stabilisateurs de cheville sous fatigue.* | 📋 *Exercice fondamental de proprioception. Si le dos s'arrondit avant de toucher le sol : réduire l'amplitude. Qualité > profondeur.* | + +**Retour au calme — 6 min** +- 2 min — Douche froide sur les jambes si possible +- 1 min 30 — Étirement ischio-jambiers dynamique puis statique (chaque jambe) +- 1 min — Massage des mollets et du pied +- 30 sec — Respiration guidée récupération + +--- + +#### Séance 3B — Haut du corps athlétique + +**Échauffement — 6 min** +- 1 min — Cercles d'épaules complets avec résistance +- 1 min — Face pulls avec élastique (rétraction scapulaire) +- 1 min — Pompes lentes x6 (descente 4 secondes) +- 1 min — Dips lents x6 sur chaise +- 1 min — Planche dynamique haute ↔ basse x6 +- 1 min — Rotation thoracique en position de fente basse + +**⏱ Bloc 1** + +| Rounds impairs | Rounds pairs | +|---|---| +| **Pompes à un bras assistées** — une main au sol, l'autre sur support surélevé, alterner les côtés à mi-bloc | **Pike push-up** — en V inversé (hanches hautes), fléchir les coudes pour descendre la tête vers le sol | +| 📋 *L'asymétrie révèle les faiblesses de stabilisation scapulaire. L'épaule du bras porteur ne s'affaisse pas.* | 📋 *Simule le développé épaules. Contre-indiqué si syndrome d'accrochage sous-acromial. Amplitude réduite au départ.* | + +⏸ *1 min 30 récupération active* + +**⏱ Bloc 2** + +| Rounds impairs | Rounds pairs | +|---|---| +| **Pompe plyométrique** — pompe explosive avec les mains qui décollent du sol, réception souple, enchaîner immédiatement | **Around the world planche** — en planche haute, déplacer les mains pour faire un tour complet imaginaire | +| 📋 *Poignets en parfait alignement — échauffement spécifique des poignets non négociable. En cas de douleur : version sur genoux.* | 📋 *Ultra-exigeant pour les rotateurs de l'épaule et les dentelés antérieurs.* | + +⏸ *1 min 30 récupération active* + +**⏱ Bloc 3** + +| Rounds impairs | Rounds pairs | +|---|---| +| **Archer push-up complet** — pompes larges en ramenant tout le poids sur un bras, l'autre tendu, alterner | **Planche latérale avec rotation** — en planche latérale, amener le bras libre sous le corps en rotation, revenir en ouverture vers le plafond | +| 📋 *Maintenir l'alignement corps-bras porteur parfait.* | 📋 *Sollicite simultanément obliques, carré des lombes et rotateurs de l'épaule.* | + +⏸ *1 min 30 récupération active* + +**⏱ Bloc 4** + +| Rounds impairs | Rounds pairs | +|---|---| +| **Pseudo planche push-up** — mains plus basses vers les hanches, corps incliné avant, pompe avec bras le long du corps | **Superman dynamique battement** — allongé ventre, lever et descendre rapidement bras et jambes en battements contrôlés | +| 📋 *Charge extrême sur les triceps et pectoraux inférieurs. Commencer par 3–4 répétitions propres.* | 📋 *Travail des extenseurs dorsaux sous fatigue. Maintenir le cou dans l'axe.* | + +**Retour au calme — 6 min** +- 1 min — Étirement rotateurs externes d'épaule contre mur (chaque côté) +- 2 min — Mobilisation thoracique sur rouleau +- 1 min — Étirement grand pectoral profond (chaque côté) + +--- + +#### Séance 3C — Corps entier haute intensité + +**Échauffement — 6 min** +Activation neurologique progressive : jumping jacks → high knees → skaters → burpee modifié → 2 burpees complets → mobilisation chevilles/poignets → 10 hollow body holds 5 secondes + +**⏱ Bloc 1** + +| Rounds impairs | Rounds pairs | +|---|---| +| **Burpee avec saut groupé** — burpee complet, à la montée ramener les genoux vers la poitrine | **V-up** — allongé, lever simultanément jambes tendues et buste, toucher les orteils au sommet | +| 📋 *Le saut groupé augmente la charge lombaire à la réception. Atterrir genoux fléchis, jamais en extension.* | 📋 *Si douleur au bas du dos : revenir au hollow body ou dead bug. Contre-indiqué si psoas irrité.* | + +⏸ *1 min 30 récupération active* + +**⏱ Bloc 2** + +| Rounds impairs | Rounds pairs | +|---|---| +| **Tuck jump** — sauts avec genoux ramenés au maximum vers la poitrine, rythme rapide, atterrissage silencieux | **Mountain climber croisé** — en planche haute, ramener le genou droit vers le coude gauche et vice versa | +| 📋 *Si syndrome de l'essuie-glace (IT band) : éviter et substituer par jumping squats.* | 📋 *Plus difficile que le MC classique car la rotation engage les obliques. Hanches basses.* | + +⏸ *1 min 30 récupération active* + +**⏱ Bloc 3** + +| Rounds impairs | Rounds pairs | +|---|---| +| **Devil's press poids de corps** — burpee, en planche ramener les deux genoux simultanément (grenouille), se relever, sauter | **Bear crawl en déplacement** — à quatre pattes genoux décollés, avancer 4 pas et reculer 4 pas rapidement | +| 📋 *Enchaînement fluide entre les phases. Pas de pause entre le grenouille et le relever.* | 📋 *Gainage parfait malgré la vitesse. Genoux à 3 cm du sol.* | + +⏸ *1 min 30 récupération active* + +**⏱ Bloc 4** + +| Rounds impairs | Rounds pairs | +|---|---| +| **Sprawl** — depuis debout, jeter les mains au sol, projeter les hanches vers le bas (ventre au sol), remonter en explosif | **Hollow body rocks** — depuis hollow body, se balancer d'avant en arrière comme un berceau sans perdre la position | +| 📋 *Exercice issu du MMA. La projection vers le bas doit être contrôlée — ne jamais s'écraser.* | 📋 *La continuité du gainage pendant le balancement est l'objectif. Si la position se casse : reprendre le hollow body statique.* | + +**Retour au calme — 6 min** +- 2 min — Foam roller colonne vertébrale +- 1 min 30 — Supine twist (torsion au sol) chaque côté +- 2 min — Savasana avec respiration guidée + +--- + +#### Séance 3D — Gainage profond & mobilité avancée + +> ℹ️ **Format spécial — Pas de blocs 20/10.** 35 minutes de travail structuré de qualité. La séance qui sépare les sportifs qui durent de ceux qui se blessent. + +**Gainage profond — 15 min** +- Hollow body progressif : 5×10 sec → 5×15 sec → 3×20 sec +- Dead bug avec résistance imaginaire : 3×10 répétitions très lentes +- Pallof press anti-rotation debout : 3×10 chaque côté +- Copenhagen plank (pied sur chaise) : 3×20 sec chaque côté +📋 *Le Copenhagen plank est l'exercice de prévention des adducteurs le plus efficace existant. Très peu connu du grand public.* + +**Mobilité active — 15 min** +- 90/90 stretching (mobilité profonde de hanche) : 2 min chaque côté +- Squat profond asiatique maintenu : 2 min progressifs +- Brettzel (rotation thoracique + fléchisseur de hanche) : 2 min chaque côté +- Mobilisation du thorax en extension sur rouleau : 2 min + +**Récupération — 5 min** +- Nidra yoga : scan corporel allongé, relâchement segment par segment + +--- + +#### Séance 3E — MetCon 20 minutes (AMRAP) + +> 📚 **MetCon — Metabolic Conditioning** : réaliser autant de tours que possible en 20 minutes. Teste l'endurance de force sur la durée. Le nombre de tours complets est le KPI de progression. + +Circuit à répéter en continu pendant 20 minutes : +- 5 — Burpees complets +- 10 — Squats jump +- 10 — Mountain climbers croisés (5 chaque côté) +- 5 — Pompes explosives +- 10 — V-ups + +> ⚠️ Ne jamais sacrifier la technique sur les burpees et les pompes sous fatigue — c'est là que les blessures d'épaule surviennent. Si la forme s'effondre : marcher 15 secondes et reprendre. + +--- + +### SEMAINE 2 — Densification + +**Format :** 5 blocs tabata + 1 min récup +**Durée totale :** ~50 minutes + +#### Exercices introduits en semaine 2 + +**Handstand push-up contre le mur** — en équilibre dos au mur, fléchir les coudes pour descendre la tête. Commencer par amplitude réduite de 5 cm. +📋 *Vérifier l'absence de douleur cervicale. Ne jamais toucher le sol avec force.* + +**Single leg burpee** — burpee complet sur une seule jambe, l'autre reste décollée du sol pendant toute la séquence. +📋 *Test ultime de force, coordination et proprioception. L'asymétrie G/D est visible immédiatement.* + +**Dragon flag partiel** — allongé, mains sous les épaules, lever le corps en planche depuis les épaules. Version partielle = fléchir les genoux. +📋 *Ne jamais forcer si douleur lombaire. L'exercice de Bruce Lee.* + +--- + +### SEMAINE 3 — Pic d'intensité & Complexes + +**Format :** 5 blocs tabata + MetCon étendu à 25 minutes + +> 📚 **Qu'est-ce qu'un complexe ?** Deux exercices différents enchaînés sans pause, comptés comme une seule répétition. Outil favori des préparateurs physiques de haut niveau : combine force, puissance et endurance. La fatigue s'accumule très vite. + +#### Complexes de la semaine 3 + +**🔥 Complexe 1 — Lower body power** +Squat jump + fente sautée : squat jump, atterrissage en fente droite, saut retour en squat, recommencer. + +**🔥 Complexe 2 — Push + core** +Pompe explosive + mountain climber ×2 : pompe avec mains décollées, atterrissage, 2 MC croisés rapides, recommencer. + +**🔥 Complexe 3 — Total body** +Burpee + broad jump : burpee complet, dans l'élan du saut se propulser vers l'avant le plus loin possible, reculer en marchant, recommencer. + +> ⚠️ Si la technique s'effondre au round 5 : réduire le complexe à un seul exercice pour finir le bloc proprement. La qualité prime toujours. + +--- + +### SEMAINE 4 — Décharge & Tests finaux + +**Format :** 3 blocs tabata. Exercices connus, focus sur la technique parfaite. Tests de performance complets. + +#### Tests finaux du Programme Avancé + +| Test | Protocole | Objectif avancé | Signal d'alerte | +|---|---|---|---| +| Endurance de force | Burpees en 3 minutes | 35+ répétitions | < 25 = revoir sem 3 | +| Force relative | Pistol squat complet G et D | 5 reps propres chaque côté | Écart > 20% = déséquilibre | +| Gainage dynamique | Planche + MC croisé 2 minutes | Maintien sans perte de position | Bascule hanche = fatigue | +| Puissance | Broad jump mesuré | Progression vs test intermédiaire | +10 cm minimum | +| Coordination | Single leg DL × 8 chaque côté | Sans poser le pied ni tomber | Chronométrer les yeux fermés | +| Asymétrie | Tous tests G vs D | Écart < 20% partout | Si > 20% : programme correctif | + +--- + +### Récapitulatif Programme Avancé + +| Semaine | Blocs/séance | Min effectives | Séances/sem | Type exercices | Durée totale | +|---|---|---|---|---|---| +| Semaine 1 | 4 blocs | 16 min | 5 | Unilatéral + plyos | ~45 min | +| Semaine 2 | 5 blocs | 20 min | 5 | Handstand + complexes légers | ~50 min | +| Semaine 3 | 5 blocs + complexes | 20 min+ | 5 | Complexes complets | ~50 min | +| Semaine 4 | 3 blocs | 12 min | 5 | Bilan + tests | ~35 min | + +--- + +## 5. Programme Post-Partum — 6 semaines + +> ⚠️ **AVERTISSEMENT MÉDICAL OBLIGATOIRE** +> Ce programme est conçu pour les femmes ayant accouché il y a minimum **8 semaines (voie basse)** ou **12 semaines (césarienne)**, avec accord de leur médecin ou sage-femme lors de la visite post-natale. En cas de douleur pelvienne, fuites urinaires, sensation de pesanteur ou cicatrice douloureuse : consulter un kinésithérapeute périnéal avant de commencer. + +**Objectif :** reconnecter le cerveau au périnée et aux abdominaux profonds, rééduquer la sangle abdominale, corriger les déséquilibres posturaux de la grossesse, retrouver progressivement le mouvement en toute sécurité. + +### Contexte kiné — Ce que le corps a vécu + +**Le périnée** a subi une distension importante, parfois une déchirure ou épisiotomie. Doit être réhabilité avant tout travail de gainage ou d'impact. La reprise trop précoce des abdominaux classiques est l'erreur n°1. + +**La sangle abdominale** présente souvent un diastasis des droits — écartement de la ligne blanche. Faire des crunchs avec un diastasis non résolu aggrave la situation. Test requis avant phase 2. + +**Les ligaments** restent laxes plusieurs mois après l'accouchement (relaxine encore présente). Les articulations sont plus vulnérables. Aucun impact avant récupération ligamentaire. + +**La posture** a été modifiée par 9 mois de grossesse : hyperlordose lombaire, épaules enroulées, bassin antéversé. Le programme corrige ces déséquilibres, ne les aggrave pas. + +--- + +### PHASE 1 — Semaines 1-2 : Réveil du corps + +**Objectif :** reconnecter le cerveau au périnée et aux abdominaux profonds. + +> **Format spécial — Protocole INVERSÉ : 10 sec effort / 20 sec repos.** +> Pourquoi ? Les muscles profonds (transverse, plancher pelvien) ont besoin de contractions courtes et qualitatives, pas de résistance à la fatigue. L'objectif est neuromusculaire, pas cardiovasculaire. + +**4 séances/semaine — Durée totale : 20 minutes** + +#### Échauffement — 5 min +- Respiration diaphragmatique en décubitus : inspirer en laissant le ventre se gonfler, expirer en rentrant doucement le nombril. 10 respirations conscientes. +- Bascules de bassin allongée : aplatir puis creuser doucement le bas du dos. Réapprendre la proprioception lombaire. +- Rotations de chevilles et poignets. +- Mobilisation de la nuque et des épaules (tensions fréquentes du portage et de l'allaitement). + +#### ⏱ Bloc principal — 10 min | Protocole INVERSÉ 10 sec effort / 20 sec repos + +**Exercice 1 — Hypopressif de base** +Debout, légère flexion des genoux, dos neutre. Inspirer profondément, expirer complètement puis rentrer le ventre au maximum sans bloquer la respiration. Maintenir 8 secondes. +📋 *Les exercices hypopressifs créent une dépression abdominale qui remonte le plancher pelvien sans pression vers le bas. Base de la rééducation périnéale. Absent de toutes les apps tabata concurrentes.* + +**Exercice 2 — Pont fessier doux coordonné** +Allongée, pieds à plat. Montée lente du bassin avec contraction simultanée du périnée. 3 sec montée / 3 sec maintien / 3 sec descente. +📋 *Associer la contraction périnéale à la montée du bassin est le premier réflexe postural à reconstruire. Fondamental pour prévenir les fuites urinaires à long terme.* + +**Exercice 3 — Clamshell** +Allongée sur le côté, genoux fléchis, ouvrir et fermer le genou supérieur. Renforcement du moyen fessier sans contrainte pelvienne. + +**Exercice 4 — Dead bug modifié (un seul membre)** +Dos au sol, un seul membre à la fois (bras OU jambe, pas les deux simultanément). Colonne lombaire en contact avec le sol. +📋 *La version complète (bras et jambe opposés) viendra en phase 2 uniquement si le diastasis est inférieur à 2 cm.* + +#### Retour au calme — 5 min +- Étirement du psoas allongée (genoux vers la poitrine alternativement) +- Respiration guidée 2 minutes +- Automassage nuque et épaules + +--- + +### PHASE 2 — Semaines 3-4 : Reconstruction + +**Objectif :** réintroduire le gainage global, augmenter l'intensité cardiovasculaire. Retour au protocole tabata classique 20/10 sur des exercices sans impact. + +> 📋 **Test diastasis obligatoire avant phase 2.** Allongée en crunch partiel, placer les doigts sur la ligne blanche. Si l'écartement dépasse 2 doigts : rester en phase 1 deux semaines supplémentaires et consulter un kiné périnéal. Ce n'est pas un échec — c'est de la prudence médicale. + +#### Nouveaux exercices introduits en Phase 2 + +**Bird dog progressif (deux membres)** — bras droit + jambe gauche simultanément si le diastasis le permet. Bassin parfaitement horizontal. +📋 *La version un membre de la phase 1 reste disponible en cas de doute.* + +**Squat avec respiration coordonnée** — inspirer en descendant, expirer EN REMONTANT avec contraction périnéale. +📋 *La majorité des fuites urinaires à l'effort viennent d'une dissociation entre effort et contraction périnéale. Ce squat "respiré" est thérapeutique.* + +**Fente statique basse tenue** — sans saut, sans impact. 20 secondes de maintien. Renforcement sans pression pelvienne verticale. + +**Planche sur genoux et avant-bras** — 20 secondes de maintien en respirant normalement. Pas de planche complète sur orteils avant la semaine 5. + +--- + +### PHASE 3 — Semaines 5-6 : Retour au Tabata + +**Objectif :** réintégrer un vrai protocole tabata avec exercices à intensité modérée. Format identique au programme Débutant semaines 1-2. + +**Ce qui reste exclu jusqu'à la fin du programme :** +- Tous les sauts et impacts — même légers +- Les crunchs, sit-ups, V-ups, relevés de buste classiques +- La planche complète sur orteils avant semaine 5 +- Les exercices avec pression intra-abdominale forte + +**Exercices de la phase 3 :** +- Squat avec respiration coordonnée (périnée) +- Pont fessier bilatéral avec contraction périnéale +- Bird dog complet +- Planche sur orteils (introduction semaine 5 uniquement) +- Fente avant statique +- Dead bug complet (si diastasis < 2 doigts confirmé) + +> ⚠️ *La sensation subjective de récupération est toujours en avance sur la réalité tissulaire. Même si l'utilisatrice se sent prête pour les sauts : attendre 3 mois de rééducation périnéale.* + +--- + +### Récapitulatif Programme Post-Partum + +| Phase | Semaines | Protocole | Séances/sem | Impacts | Focus principal | +|---|---|---|---|---|---| +| Phase 1 | Sem. 1-2 | 10 sec / 20 sec (inversé) | 4 | ❌ Aucun | Périnée + transverse | +| Phase 2 | Sem. 3-4 | 20 sec / 10 sec | 4 | ❌ Aucun | Gainage global | +| Phase 3 | Sem. 5-6 | 20 sec / 10 sec | 4 | ❌ Aucun | Retour tabata doux | + +**Après le programme :** accès au programme Débutant standard. Parcours logique : Post-partum → Débutant → Intermédiaire → Avancé. + +--- + +## 6. Programme Seniors — 4 semaines + +> ⚠️ **Avertissement médical.** Programme destiné aux personnes de 60 ans et plus, actives ou en reprise d'activité, sans contre-indication médicale majeure. Si vous n'avez pas pratiqué de sport depuis plus de 2 ans ou si vous avez des antécédents cardiovasculaires : consulter votre médecin avant de commencer. + +**Objectif :** lutter contre la sarcopénie, améliorer l'équilibre et la proprioception pour prévenir les chutes, renforcer les muscles fonctionnels du quotidien, maintenir ou améliorer la mobilité articulaire. + +### Les 4 réalités physiologiques qui guident ce programme + +**Sarcopénie** — perte de ~1% de masse musculaire par an après 50 ans. Le tabata adapté est l'un des outils les plus efficaces pour la contrer. + +**Proprioception** — l'équilibre décline avec l'âge. Les chutes sont la 1ère cause de perte d'autonomie. Chaque séance contient un exercice de prévention des chutes. + +**Récupération** — plus lente : 48–72h contre 24–48h chez le jeune adulte. Maximum 3 séances/semaine, jamais 2 jours consécutifs. + +**Mobilité articulaire** — amplitudes réduites, cartilages plus fragiles. Chaque exercice est réalisable dans les amplitudes disponibles — pas les amplitudes théoriques d'un adulte jeune. + +### Les 3 règles non-négociables + +- **ZÉRO impact** tout le programme — pas de sauts, pas de burpees, pas de réceptions +- **Protocole modifié** : 20 sec / 15 sec (semaines 1-2) puis 20/10 (semaines 3-4) +- **Travail d'équilibre** dans chaque séance — non négociable + +--- + +### SEMAINE 1 — Éveil et repères + +**Format :** 2 blocs tabata (20/15) par séance. 3 séances/semaine. +**Durée totale :** ~25 minutes + +--- + +#### Séance Senior A — Membres inférieurs & équilibre + +**Échauffement — 6 min** +- 2 min — Marche sur place avec bras actifs +- 1 min — Montées de genoux lentes en tenant le dossier d'une chaise +- 1 min — Flexions-extensions de chevilles assis +- 1 min — Cercles de hanches debout +- 1 min — Transferts de poids latéraux (balancement doux d'un pied sur l'autre) + +**⏱ Bloc 1 — 20 sec effort / 15 sec repos** + +| Rounds impairs | Rounds pairs | +|---|---| +| **Squat assisté avec chaise** — se lever et s'asseoir lentement d'une chaise sans se laisser tomber, contrôler la descente jusqu'au bout | **Équilibre unipodal** — se tenir sur un pied en tenant légèrement un support, 10 secondes chaque pied | +| 📋 *C'est le mouvement fonctionnel le plus important de la vie quotidienne. RÈGLE : ne jamais s'écraser — contrôler la descente jusqu'au bout.* | 📋 *Fermer les yeux progressivement augmente considérablement la difficulté proprioceptive — progression naturelle pour les semaines suivantes.* | + +⏸ *1 min récupération active — marche lente* + +**⏱ Bloc 2 — 20 sec effort / 15 sec repos** + +| Rounds impairs | Rounds pairs | +|---|---| +| **Fente statique tenue avec appui** — un pied devant, l'autre derrière, légère flexion, tenir 20 secondes, alterner | **Marche talon-orteil** — marcher en ligne en posant le talon immédiatement devant l'orteil de l'autre pied | +| 📋 *Tenir un support de la main non-travaillante. L'appui sécurise et permet de se concentrer sur l'amplitude.* | 📋 *Exercice de coordination vestibulaire utilisé en rééducation neurologique. Prévoir un mur à portée de main.* | + +**Retour au calme — 5 min** +- Étirements en position assise (jambes, dos) +- Respiration guidée +- Automassage des pieds (essentiels pour la proprioception) + +--- + +#### Séance Senior B — Haut du corps & gainage doux + +**Échauffement — 6 min** +- Mobilisation complète des épaules, poignets, nuque +- Activation des rhomboïdes : pincer les omoplates 10 fois +- Chat-chameau en position assise (mobilité lombaire) + +**⏱ Bloc 1 — 20 sec / 15 sec** + +| Rounds impairs | Rounds pairs | +|---|---| +| **Pompes contre le mur** — debout à 50 cm d'un mur, mains à hauteur d'épaules | **Rowing avec serviette** — simuler le geste de rameur en tirant les coudes vers l'arrière, omoplates rapprochées | +| 📋 *À l'angle correct (corps incliné à 30°), la charge sur pectoraux et triceps est significative sans contrainte sur les poignets.* | 📋 *Renforcement des trapèzes moyens et rhomboïdes — muscles clés de la posture. Contre les épaules enroulées.* | + +⏸ *1 min récupération active* + +**⏱ Bloc 2 — 20 sec / 15 sec** + +| Rounds impairs | Rounds pairs | +|---|---| +| **Planche contre le mur** — corps incliné, avant-bras contre le mur, maintenir la position | **Rotation thoracique assise** — assis, bras croisés sur la poitrine, rotation lente droite-gauche, bassin fixe | +| 📋 *Alternative idéale à la planche au sol pour les personnes avec difficultés à descendre ou douleurs aux poignets.* | 📋 *Mobilité thoracique essentielle pour la conduite, les gestes du quotidien et la prévention des douleurs cervicales.* | + +--- + +#### Séance Senior C — Corps entier fonctionnel + +> 💡 Cette séance travaille les **mouvements de la vie quotidienne**. C'est ce qu'aucune autre app tabata ne propose — et c'est précisément ce dont les seniors ont besoin. + +**⏱ Bloc 1 — 20 sec / 15 sec** + +| Rounds impairs | Rounds pairs | +|---|---| +| **Ramasser au sol** — descendre pour simuler le ramassage d'un objet EN FLÉCHISSANT LES GENOUX, pas en arrondissant le dos | **Monter-descendre une marche** — monter et descendre une marche basse alternativement | +| 📋 *C'est le mouvement le plus souvent réalisé incorrectement — l'une des principales causes de lumbago. Ce programme enseigne le bon geste.* | 📋 *Tenir un mur ou une rambarde si nécessaire. La sécurité prime sur la difficulté.* | + +⏸ *1 min récupération active* + +**⏱ Bloc 2 — 20 sec / 15 sec** + +| Rounds impairs | Rounds pairs | +|---|---| +| **Porter et poser simulé** — tenir un livre ou bouteille, le poser à hauteur d'épaule (étagère simulée), le reprendre | **Rotation avec objet léger** — tenir un objet, rotation droite-gauche en portant l'objet d'un côté à l'autre | +| 📋 *Travaille la coordination œil-main, stabilité d'épaule et contraction abdominale réflexe. Directement transférable à la vie quotidienne.* | 📋 *Maintenir le bassin immobile — seul le tronc tourne.* | + +--- + +### SEMAINE 2 — Renforcement + +Passage au protocole 20/10 classique. Nouveaux exercices : +- **Squat sans chaise** — même mouvement mais sans support. Chaise derrière soi comme filet de sécurité. +- **Équilibre unipodal yeux fermés** — 5 secondes chaque pied. +- **Pompes contre plan incliné (table)** — angle plus difficile, charge plus importante. +- **Semi-squat unilatéral avec appui** — une jambe légèrement fléchie, l'autre levée légèrement. + +### SEMAINE 3 — Progression & confiance + +3 blocs tabata par séance. Exercices debout plus dynamiques — toujours sans impact. Nouveaux exercices : +- **Marche rapide avec bras pompants** — simuler une marche athlétique intense sur place. Excellent pour la FC sans impact. +- **Squat avec rotation** — au sommet du squat, rotation du buste à 45°. Travail combiné jambes + tronc. +- **Deadlift fonctionnel avec objet léger** — charnière de hanche en avant. Prévient les douleurs lombaires chroniques. +📋 *Le deadlift fonctionnel est le geste de se pencher en avant. Le renforcer prévient directement les douleurs lombaires chroniques, très fréquentes après 60 ans.* +- **Élévation latérale des bras** — bras tendus, lever latéralement à hauteur d'épaule. Maintien de la capacité à porter. + +### SEMAINE 4 — Décharge & autonomie + +Retour à 2 blocs. Exercices connus. Tests de fin de programme. + +#### Tests cliniques de fin de programme + +| Test clinique | Protocole | Objectif | +|---|---|---| +| Five Times Sit to Stand | Se lever/s'asseoir d'une chaise, compter en 30 secondes | 12+ répétitions | +| Équilibre unipodal | Tenir sur chaque pied yeux ouverts | 20 secondes sans appui | +| Force haut du corps | Pompes contre le mur en 20 secondes | 12+ répétitions | + +> 📋 Ces trois tests sont des indicateurs cliniques réels utilisés en bilan kinésithérapeutique. Les intégrer dans l'app donne une valeur médicale concrète aux résultats. + +--- + +### Récapitulatif Programme Seniors + +| Semaine | Blocs/séance | Protocole | Séances/sem | Nouveautés | Durée totale | +|---|---|---|---|---|---| +| Semaine 1 | 2 blocs | 20/15 | 3 | Bases fonctionnelles | ~25 min | +| Semaine 2 | 2 blocs | 20/10 | 3 | Sans chaise, incliné | ~25 min | +| Semaine 3 | 3 blocs | 20/10 | 3 | Mouvements dynamiques | ~30 min | +| Semaine 4 | 2 blocs | 20/10 | 3 | Tests cliniques | ~25 min | + +--- + +## 7. Programme Bureau — 4 semaines + +**Objectif :** intégrer le mouvement comme réflexe dans la journée de travail. 10 minutes de mouvement actif réduisent les douleurs lombaires de 30%, améliorent la concentration de 20% et contrebalancent partiellement les effets d'une journée sédentaire. + +### Les 5 contraintes de conception + +- **🔇 Silence** — pas de sauts, pas d'impacts, pas de chutes au sol, niveau sonore d'un bureau normal +- **🚫 Pas de sol** — tous les exercices debout ou assis sur une chaise, zéro exercice au sol +- **💧 Pas de sueur visible** — intensité calibrée pour élever la FC sans transpiration abondante +- **⏱ 10 ou 20 min max** — deux formats selon la disponibilité +- **👔 Tenue de bureau** — aucun exercice qui déforme une veste ou froisse un pantalon + +--- + +### FORMAT A — 10 minutes au bureau + +**Protocole :** 20 sec effort / 10 sec repos. 4 blocs de 2 minutes. Pendant une pause, sans bouger de sa zone de travail. + +#### Échauffement — 1 minute (assis, discret) +- Cercles de poignets dans les deux sens +- Mobilisation cervicale : inclinaisons et rotations douces +- Ouverture de poitrine : bras en arrière, omoplates rapprochées + +#### ⏱ Bloc 1 — Activation profonde (assis) + +| Rounds impairs | Rounds pairs | +|---|---| +| **Contraction abdominale isométrique** — rentrer le nombril, maintenir en respirant normalement, invisible de l'extérieur | **Serrage fessier** — serrer les fessiers et maintenir 20 secondes, discret, invisible | +| 📋 *C'est le transverse. Le contracter régulièrement en position assise combat directement les douleurs lombaires liées à la sédentarité.* | 📋 *Contre la rétroversion du bassin liée à la position assise prolongée.* | + +#### ⏱ Bloc 2 — Membres inférieurs (assis) + +| Rounds impairs | Rounds pairs | +|---|---| +| **Extension de jambe** — assis, lever une jambe tendue à hauteur de hanche, maintenir, alterner | **Élévation de talons assis** — pieds à plat, lever les talons en contractant les mollets | +| 📋 *Renforcement du quadriceps. Ajouter une contraction du pied (orteils vers soi) pour activer les tibias antérieurs.* | 📋 *Active la pompe veineuse des jambes. Prévention des jambes lourdes et des varices.* | + +#### ⏱ Bloc 3 — Membres inférieurs (debout, silencieux) + +| Rounds impairs | Rounds pairs | +|---|---| +| **Wall sit (chaise invisible)** — dos au mur, cuisses parallèles au sol, maintenir | **Élévation de talons debout** — montées sur la pointe des pieds, descente lente en 3 secondes | +| 📋 *Aucun bruit, aucun mouvement visible de l'extérieur, intensité maximale pour les quadriceps. Respirer calmement.* | 📋 *Renforcement des soléaires et gastrocnémiens. Bras tendus devant soi pour l'équilibre si nécessaire.* | + +#### ⏱ Bloc 4 — Haut du corps (debout) + +| Rounds impairs | Rounds pairs | +|---|---| +| **Pompes contre le bureau** — mains sur le bureau, corps incliné à 30°, silencieux, propre | **Pull apart imaginaire** — bras tendus devant, simuler l'écartement d'une résistance élastique en rétractant les omoplates | +| 📋 *S'assurer que le bureau est stable avant de commencer. Plus incliné = plus facile.* | 📋 *Contre le syndrome de l'épaule roulée du bureau. Ouvrir la poitrine au maximum.* | + +#### Retour au calme — 1 minute +- Étirement cervical latéral doux (chaque côté) +- Étirement des poignets (extenseurs et fléchisseurs) +- 3 grandes respirations diaphragmatiques + +--- + +### FORMAT B — 20 minutes en espace calme + +**Protocole :** tabata classique 20/10. 5 blocs de 4 minutes. Plus de liberté de mouvement, toujours zéro impact. + +#### Exercices spécifiques du Format B + +**Squat silencieux avec tempo ralenti** — tempo 3-3 pour rester sous le seuil de transpiration tout en maintenant l'efficacité musculaire. + +**Fente statique avec rotation de buste** — fente basse tenue + rotation du tronc vers le genou avant. Mobilité thoracique et renforcement simultanés. + +**Bureau dips** — mains sur le bureau derrière soi, corps décollé, fléchir les coudes. Triceps et stabilisateurs d'épaule. +📋 *Vérifier la stabilité du bureau avant de commencer.* + +**Calf raises avec déséquilibre** — montées sur la pointe des pieds avec les yeux fermés. Double effet : renforcement + proprioception. + +**Isométrie fessiers debout** — contracter les fessiers alternativement sans bouger les jambes. Activation du moyen fessier inhibé par la position assise. + +**Rotation de buste debout rapide** — bras croisés sur la poitrine, rotation droite-gauche rapide. Active les obliques et échauffe les disques intervertébraux. + +--- + +### FORMAT C — Walking Meeting (20 minutes) + +> Format conçu pour être utilisé pendant une marche. L'app guide uniquement en **audio** — aucun besoin de regarder l'écran. + +**Structure :** alterner des phases de marche rapide tabata (20 sec intensité maximale) et des phases de marche normale (10 sec récup), sur 5 blocs de 4 minutes. + +| Type de marche | Utilisation | Intensité | +|---|---|---| +| Marche normale | Phase de repos (10 sec) | ⬜ Faible | +| Marche rapide | Phase d'effort standard | 🟡 Modérée | +| Marche genoux hauts | Phase d'effort intensifié | 🟠 Élevée | +| Marche en fente | Pas le plus long possible | 🔴 Haute | +| Montée d'escaliers | Si disponibles | 🔴 Haute | + +📋 *La marche active à 6–7 km/h suffit à atteindre 70–80% de la fréquence cardiaque maximale chez un adulte sédentaire. Amplement suffisant pour les bénéfices cardiovasculaires du HIIT sans impact traumatisant.* + +--- + +### Progression sur 4 semaines + +| Semaine | Format A | Format B | Format C | Objectif | +|---|---|---|---|---| +| Semaine 1 | 3×/semaine | — | — | Créer l'habitude de la pause active | +| Semaine 2 | 2×/semaine | 1×/semaine | — | Introduction du format long | +| Semaine 3 | 1×/semaine | 2×/semaine | 1×/semaine | Walking meeting intégré | +| Semaine 4 | Libre | Libre | Libre | Autonomie — choisir selon la semaine | + +> 💡 **L'objectif final** n'est pas de suivre un programme — c'est d'intégrer le mouvement comme réflexe dans la journée de travail. La semaine 4 sans structure fixe est intentionnelle : c'est la semaine de la prise d'autonomie. + +--- + +## 8. Récapitulatif global + +| Programme | Durée | Séances/sem | Blocs max | Impacts | Protocole | Tier | Exercices signature | +|---|---|---|---|---|---|---|---| +| 🟢 Débutant | 4 sem | 3 | 3 | ❌ | 20/10 | Gratuit | Squat, pompes genoux, pont fessier, planche AV, bird dog, dead bug | +| 🔵 Intermédiaire | 4 sem | 4 | 4 | ⚡ | 20/10 | Premium | Squat jump, fente sautée, burpee, hollow body, pistol squat assisté | +| 🔴 Avancé | 4 sem | 5 | 5 | 🔥 | 20/10 | Premium | Nordic curl, pistol squat complet, pompe plyométrique, complexes, MetCon | +| 🩷 Post-partum | 6 sem | 4 | 3 | ❌ | 10/20 → 20/10 | Kiné+ | Hypopressifs, pont périnéal, dead bug 1 membre, bird dog progressif | +| 🟤 Seniors | 4 sem | 3 | 3 | ❌ | 20/15 → 20/10 | Kiné+ | Squat chaise, équilibre unipodal, pompes mur, marche talon-orteil | +| 🟡 Bureau | 4 sem | 3–5 | 5 | ❌ | 20/10 | Premium | Wall sit, pompes bureau, pull apart, extension de jambe assis | + +### Parcours utilisateurs recommandés + +**Parcours Standard** +Débutant → Intermédiaire → Avancé + +**Parcours Maman** +Post-partum → Débutant → Intermédiaire → Avancé + +**Parcours Senior** +Seniors → Débutant (si capacité) → Maintenance Seniors cyclique + +**Parcours Actif Sédentaire** +Bureau → Débutant → Intermédiaire → Bureau en maintenance + +--- + +> *Ce guide représente 26 semaines de contenu kiné structuré. Chaque exercice est médicalement raisonné. Chaque progression est physiologiquement justifiée. C'est ce qu'aucune app tabata concurrente ne propose aujourd'hui.* + +--- +*Document élaboré en avril 2026 — App Tabata Kiné — Tous droits réservés* diff --git a/admin-login.png b/admin-login.png deleted file mode 100644 index eddcb58..0000000 Binary files a/admin-login.png and /dev/null differ diff --git a/admin-web/app/api/ai/generate-avatar/route.ts b/admin-web/app/api/ai/generate-avatar/route.ts new file mode 100644 index 0000000..4bfc71d --- /dev/null +++ b/admin-web/app/api/ai/generate-avatar/route.ts @@ -0,0 +1,86 @@ +import { GoogleGenAI } from '@google/genai' +import { NextResponse } from 'next/server' +import { supabase } from '@/lib/supabase' + +export async function POST(request: Request) { + try { + const { prompt, trainerId, filename } = await request.json() + + const apiKey = process.env.GEMINI_API_KEY + if (!apiKey) { + return NextResponse.json( + { error: 'GEMINI_API_KEY not configured' }, + { status: 500 } + ) + } + + const ai = new GoogleGenAI({ apiKey }) + + const config = { + imageConfig: { + aspectRatio: '1:1', + imageSize: '1K', + }, + responseModalities: ['IMAGE', 'TEXT'] as string[], + } + + const response = await ai.models.generateContentStream({ + model: 'gemini-3.1-flash-image-preview', + config, + contents: [{ role: 'user', parts: [{ text: prompt }] }], + }) + + const images: { buffer: Buffer; mimeType: string }[] = [] + + for await (const chunk of response) { + const parts = chunk.candidates?.[0]?.content?.parts + if (!parts) continue + + for (const part of parts) { + if (part.inlineData) { + images.push({ + buffer: Buffer.from(part.inlineData.data || '', 'base64'), + mimeType: part.inlineData.mimeType || 'image/png', + }) + } + } + } + + if (images.length === 0) { + return NextResponse.json( + { error: 'No images generated' }, + { status: 500 } + ) + } + + // Save first image to storage + const image = images[0] + const path = `${trainerId}/${filename}` + + const { error } = await supabase.storage + .from('trainer-avatars') + .upload(path, image.buffer, { + contentType: image.mimeType, + upsert: true, + }) + + if (error) { + return NextResponse.json( + { error: `Failed to upload avatar: ${error.message}` }, + { status: 500 } + ) + } + + const { data: { publicUrl } } = supabase.storage + .from('trainer-avatars') + .getPublicUrl(path) + + return NextResponse.json({ url: publicUrl }) + } catch (error) { + console.error('Avatar generation failed:', error) + return NextResponse.json( + { error: error instanceof Error ? error.message : 'Generation failed' }, + { status: 500 } + ) + } +} diff --git a/admin-web/app/api/ai/generate-video/route.ts b/admin-web/app/api/ai/generate-video/route.ts new file mode 100644 index 0000000..0e5df9a --- /dev/null +++ b/admin-web/app/api/ai/generate-video/route.ts @@ -0,0 +1,297 @@ +import { GoogleGenAI, VideoGenerationReferenceType } from '@google/genai' +import { NextResponse } from 'next/server' +import { supabase } from '@/lib/supabase' + +interface Exercise { + name: string + duration: number +} + +interface GeneratedVideo { + exerciseName: string + videoType: 'exercise' | 'rest' + videoUrl: string + videoPath: string + durationSeconds: number +} + +async function pollOperation(ai: GoogleGenAI, operation: any): Promise { + while (!operation.done) { + await new Promise(resolve => setTimeout(resolve, 10000)) + operation = await ai.operations.getVideosOperation({ operation }) + } + return operation +} + +async function uploadVideo( + bucket: string, + path: string, + buffer: Buffer +): Promise { + const { error } = await supabase.storage + .from(bucket) + .upload(path, buffer, { + contentType: 'video/mp4', + upsert: true, + }) + + if (error) { + throw new Error(`Failed to upload video: ${error.message}`) + } + + const { data: { publicUrl } } = supabase.storage + .from(bucket) + .getPublicUrl(path) + + return publicUrl +} + +async function getMimeTypeFromUrl(url: string): Promise { + try { + const urlPath = new URL(url).pathname + const extension = urlPath.split('.').pop()?.toLowerCase() + switch (extension) { + case 'png': + return 'image/png' + case 'jpg': + case 'jpeg': + return 'image/jpeg' + case 'webp': + return 'image/webp' + case 'gif': + return 'image/gif' + default: + return 'image/png' + } + } catch { + return 'image/png' + } +} + +async function generateVideoWithReference( + ai: GoogleGenAI, + apiKey: string, + prompt: string, + avatarUrl: string, + durationSeconds: number = 8 +): Promise<{ uri: string; buffer: Buffer } | null> { + // Fetch avatar image from URL and convert to base64 + const avatarResponse = await fetch(avatarUrl) + const avatarBuffer = await avatarResponse.arrayBuffer() + const avatarBase64 = Buffer.from(avatarBuffer).toString('base64') + const mimeType = await getMimeTypeFromUrl(avatarUrl) + + const operation = await ai.models.generateVideos({ + model: 'veo-3.1-fast-generate-preview', + prompt, + config: { + numberOfVideos: 1, + aspectRatio: '16:9', + resolution: '1080p', + durationSeconds, + referenceImages: [{ + image: { + imageBytes: avatarBase64, + mimeType, + }, + referenceType: 'character' as any, + }], + }, + }) + + const completedOperation = await pollOperation(ai, operation) + const videoUri = completedOperation.response?.generatedVideos?.[0]?.video?.uri + + if (!videoUri) { + return null + } + + const response = await fetch(`${videoUri}&key=${apiKey}`) + const arrayBuffer = await response.arrayBuffer() + const videoBuffer = Buffer.from(arrayBuffer) + + return { uri: videoUri, buffer: videoBuffer } +} + +async function extendVideo( + ai: GoogleGenAI, + apiKey: string, + videoUri: string, + prompt: string, + durationSeconds: number = 8 +): Promise<{ uri: string; buffer: Buffer } | null> { + const operation = await ai.models.generateVideos({ + model: 'veo-3.1-fast-generate-preview', + prompt, + video: videoUri as any, + config: { + numberOfVideos: 1, + durationSeconds, + }, + }) + + const completedOperation = await pollOperation(ai, operation) + const newVideoUri = completedOperation.response?.generatedVideos?.[0]?.video?.uri + + if (!newVideoUri) { + return null + } + + const response = await fetch(`${newVideoUri}&key=${apiKey}`) + const arrayBuffer = await response.arrayBuffer() + const videoBuffer = Buffer.from(arrayBuffer) + + return { uri: newVideoUri, buffer: videoBuffer } +} + +export async function POST(request: Request) { + try { + const { workoutId, trainerId, trainerAvatarUrl, exercises } = await request.json() + + if (!trainerAvatarUrl) { + return NextResponse.json( + { error: 'Trainer avatar URL is required' }, + { status: 400 } + ) + } + + const apiKey = process.env.GEMINI_API_KEY + if (!apiKey) { + return NextResponse.json( + { error: 'GEMINI_API_KEY not configured' }, + { status: 500 } + ) + } + + const ai = new GoogleGenAI({ apiKey }) + const generatedVideos: GeneratedVideo[] = [] + + for (const exercise of exercises) { + const exerciseName = exercise.name + + console.log(`Processing exercise: ${exerciseName}`) + + const safeName = exerciseName.toLowerCase().replace(/[^a-z0-9]/g, '_') + + // 1. Generate 8s exercise video with avatar reference + console.log(`Generating base exercise video for: ${exerciseName}`) + const exercisePrompt = `A fitness trainer demonstrating ${exerciseName} exercise with correct form and technique. The person should be energetic and perform the exercise properly.` + + let exerciseVideo = await generateVideoWithReference( + ai, + apiKey, + exercisePrompt, + trainerAvatarUrl, + 8 + ) + + if (!exerciseVideo) { + console.error(`Failed to generate base exercise video for: ${exerciseName}`) + continue + } + + // 2. Extend exercise video to 22s (8s + 7s + 7s) + console.log(`Extending exercise video for: ${exerciseName}`) + + const extendPrompt1 = `Continue the ${exerciseName} exercise motion seamlessly` + let extended1 = await extendVideo(ai, apiKey, exerciseVideo.uri, extendPrompt1, 8) + + if (extended1) { + const extendPrompt2 = `Continue the ${exerciseName} exercise motion seamlessly` + const extended2 = await extendVideo(ai, apiKey, extended1.uri, extendPrompt2, 8) + + if (extended2) { + exerciseVideo = extended2 + } + } + + const exercisePath = `${trainerId}/${workoutId}/${safeName}.mp4` + const exerciseUrl = await uploadVideo('trainer-videos', exercisePath, exerciseVideo.buffer) + + generatedVideos.push({ + exerciseName, + videoType: 'exercise', + videoUrl: exerciseUrl, + videoPath: exercisePath, + durationSeconds: 22, + }) + + console.log(`Exercise video uploaded: ${exerciseUrl}`) + + // 3. Generate 8s rest video with avatar reference + console.log(`Generating rest video for: ${exerciseName}`) + const restPrompt = `A fitness trainer resting, standing still, breathing calmly with arms at sides. The person looks relaxed.` + + const restVideo = await generateVideoWithReference( + ai, + apiKey, + restPrompt, + trainerAvatarUrl, + 8 + ) + + if (restVideo) { + const restPath = `${trainerId}/${workoutId}/${safeName}_rest.mp4` + const restUrl = await uploadVideo('trainer-videos', restPath, restVideo.buffer) + + generatedVideos.push({ + exerciseName, + videoType: 'rest', + videoUrl: restUrl, + videoPath: restPath, + durationSeconds: 8, + }) + + console.log(`Rest video uploaded: ${restUrl}`) + } else { + console.error(`Failed to generate rest video for: ${exerciseName}`) + } + } + + if (generatedVideos.length === 0) { + return NextResponse.json( + { error: 'No videos were generated' }, + { status: 500 } + ) + } + + // Save all videos to exercise_videos table + for (const video of generatedVideos) { + await (supabase.from('exercise_videos') as any) + .insert({ + workout_id: workoutId, + trainer_id: trainerId, + exercise_name: video.exerciseName, + video_url: video.videoUrl, + video_path: video.videoPath, + video_type: video.videoType, + duration_seconds: video.durationSeconds, + }) + } + + // Update workout with primary video_url (first exercise video) + const primaryVideo = generatedVideos.find(v => v.videoType === 'exercise') + if (primaryVideo) { + await (supabase.from('workouts') as any) + .update({ video_url: primaryVideo.videoUrl }) + .eq('id', workoutId) + } + + // Mark workout as generated in program_workouts if applicable + await (supabase.from('program_workouts') as any) + .update({ video_generated: true }) + .eq('workout_id', workoutId) + + return NextResponse.json({ + workoutId, + videos: generatedVideos, + totalVideos: generatedVideos.length, + }) + } catch (error) { + console.error('Video generation failed:', error) + return NextResponse.json( + { error: error instanceof Error ? error.message : 'Generation failed' }, + { status: 500 } + ) + } +} diff --git a/admin-web/app/programs/CLAUDE.md b/admin-web/app/programs/CLAUDE.md new file mode 100644 index 0000000..dfdf83c --- /dev/null +++ b/admin-web/app/programs/CLAUDE.md @@ -0,0 +1,11 @@ + +# Recent Activity + + + +### Apr 16, 2026 + +| ID | Time | T | Title | Read | +|----|------|---|-------|------| +| #6319 | 9:38 PM | 🔵 | Discovered admin UI program management pages created | ~267 | + \ No newline at end of file diff --git a/admin-web/app/programs/[id]/CLAUDE.md b/admin-web/app/programs/[id]/CLAUDE.md new file mode 100644 index 0000000..dfdf83c --- /dev/null +++ b/admin-web/app/programs/[id]/CLAUDE.md @@ -0,0 +1,11 @@ + +# Recent Activity + + + +### Apr 16, 2026 + +| ID | Time | T | Title | Read | +|----|------|---|-------|------| +| #6319 | 9:38 PM | 🔵 | Discovered admin UI program management pages created | ~267 | + \ No newline at end of file diff --git a/admin-web/app/programs/[id]/edit/CLAUDE.md b/admin-web/app/programs/[id]/edit/CLAUDE.md new file mode 100644 index 0000000..dfdf83c --- /dev/null +++ b/admin-web/app/programs/[id]/edit/CLAUDE.md @@ -0,0 +1,11 @@ + +# Recent Activity + + + +### Apr 16, 2026 + +| ID | Time | T | Title | Read | +|----|------|---|-------|------| +| #6319 | 9:38 PM | 🔵 | Discovered admin UI program management pages created | ~267 | + \ No newline at end of file diff --git a/admin-web/app/programs/[id]/edit/page.tsx b/admin-web/app/programs/[id]/edit/page.tsx new file mode 100644 index 0000000..0624584 --- /dev/null +++ b/admin-web/app/programs/[id]/edit/page.tsx @@ -0,0 +1,81 @@ +import { Metadata } from "next" +import Link from "next/link" +import { notFound } from "next/navigation" +import { ArrowLeft } from "lucide-react" + +import { Button } from "@/components/ui/button" +import ProgramForm from "@/components/program-form" +import { supabase } from "@/lib/supabase" + +interface EditProgramPageProps { + params: Promise<{ + id: string + }> +} + +async function getProgram(id: string) { + const { data, error } = await (supabase.from("workout_programs") as any) + .select(` + *, + program_tabatas (*) + `) + .eq("id", id) + .single() + + if (error || !data) { + return null + } + + // Sort tabatas by position + if (data.program_tabatas) { + data.program_tabatas.sort((a: any, b: any) => a.position - b.position) + } + + return data +} + +export async function generateMetadata({ params }: EditProgramPageProps): Promise { + const resolvedParams = await params + const program = await getProgram(resolvedParams.id) + + if (!program) { + return { + title: "Program Not Found | TabataFit Admin", + } + } + + return { + title: `Edit ${program.title} | TabataFit Admin`, + } +} + +export default async function EditProgramPage({ params }: EditProgramPageProps) { + const resolvedParams = await params + const program = await getProgram(resolvedParams.id) + + if (!program) { + notFound() + } + + return ( +
+
+ + +

Edit Program

+

+ Update the details for "{program.title}" +

+
+ +
+ +
+
+ ) +} diff --git a/admin-web/app/programs/[id]/page.tsx b/admin-web/app/programs/[id]/page.tsx new file mode 100644 index 0000000..d0566bd --- /dev/null +++ b/admin-web/app/programs/[id]/page.tsx @@ -0,0 +1,292 @@ +import { Metadata } from "next" +import Link from "next/link" +import { notFound } from "next/navigation" +import { ArrowLeft, Edit, Trash2, Clock, Flame, Dumbbell, Zap, Timer, Target } from "lucide-react" + +import { Button } from "@/components/ui/button" +import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" +import { Badge } from "@/components/ui/badge" +import { supabase } from "@/lib/supabase" + +interface ProgramDetailPageProps { + params: Promise<{ + id: string + }> +} + +const BODY_ZONE_COLORS: Record = { + "upper-body": "bg-green-500/20 text-green-500", + "lower-body": "bg-purple-500/20 text-purple-500", + "full-body": "bg-orange-500/20 text-orange-500", +} + +const LEVEL_COLORS: Record = { + "Beginner": "bg-emerald-500/20 text-emerald-500", + "Intermediate": "bg-yellow-500/20 text-yellow-500", + "Advanced": "bg-red-500/20 text-red-500", +} + +async function getProgram(id: string) { + const { data, error } = await (supabase.from("workout_programs") as any) + .select(` + *, + program_tabatas (*) + `) + .eq("id", id) + .single() + + if (error || !data) { + return null + } + + // Sort tabatas by position + if (data.program_tabatas) { + data.program_tabatas.sort((a: any, b: any) => a.position - b.position) + } + + return data +} + +export async function generateMetadata({ params }: ProgramDetailPageProps): Promise { + const resolvedParams = await params + const program = await getProgram(resolvedParams.id) + + if (!program) { + return { + title: "Program Not Found | TabataFit Admin", + } + } + + return { + title: `${program.title} | TabataFit Admin`, + } +} + +export default async function ProgramDetailPage({ params }: ProgramDetailPageProps) { + const resolvedParams = await params + const program = await getProgram(resolvedParams.id) + + if (!program) { + notFound() + } + + const tabatas = program.program_tabatas || [] + + return ( +
+ {/* Header */} +
+
+ + +
+ {program.accent_color && ( +
+ )} +

{program.title}

+ + {program.is_free ? "Free" : "Premium"} + +
+ +
+ + {program.body_zone} + + | + + {program.level} + +
+ + {program.description && ( +

{program.description}

+ )} +
+ +
+ +
+
+ + {/* Stats Grid */} +
+ + +
+ + Duration +
+

{program.estimated_duration} min

+

estimated total

+
+
+ + + +
+ + Calories +
+

{program.estimated_calories}

+

estimated burn

+
+
+ + + +
+ + Tabatas +
+

{tabatas.length}

+

exercise pairs

+
+
+ + + +
+ + Sort Order +
+

{program.sort_order}

+

display position

+
+
+
+ + {/* Tabatas */} +
+ {tabatas.map((tabata: any) => ( + + +
+
+
+ {tabata.position} +
+ Tabata {tabata.position} +
+
+ + + {tabata.rounds} rounds + + + + {tabata.work_time}s work + + + + {tabata.rest_time}s rest + +
+
+
+ +
+ {/* Exercise 1 */} +
+
+ + Exercise 1 + +
+
+

{tabata.exercise_1_name}

+ {tabata.exercise_1_name_en && ( +

{tabata.exercise_1_name_en}

+ )} +
+ {tabata.exercise_1_tip && ( +
+

Tip

+

{tabata.exercise_1_tip}

+ {tabata.exercise_1_tip_en && ( +

{tabata.exercise_1_tip_en}

+ )} +
+ )} + {tabata.exercise_1_modification && ( +
+

Modification

+

{tabata.exercise_1_modification}

+ {tabata.exercise_1_modification_en && ( +

{tabata.exercise_1_modification_en}

+ )} +
+ )} + {tabata.exercise_1_progression && ( +
+

Progression

+

{tabata.exercise_1_progression}

+ {tabata.exercise_1_progression_en && ( +

{tabata.exercise_1_progression_en}

+ )} +
+ )} +
+ + {/* Exercise 2 */} +
+
+ + Exercise 2 + +
+
+

{tabata.exercise_2_name}

+ {tabata.exercise_2_name_en && ( +

{tabata.exercise_2_name_en}

+ )} +
+ {tabata.exercise_2_tip && ( +
+

Tip

+

{tabata.exercise_2_tip}

+ {tabata.exercise_2_tip_en && ( +

{tabata.exercise_2_tip_en}

+ )} +
+ )} + {tabata.exercise_2_modification && ( +
+

Modification

+

{tabata.exercise_2_modification}

+ {tabata.exercise_2_modification_en && ( +

{tabata.exercise_2_modification_en}

+ )} +
+ )} + {tabata.exercise_2_progression && ( +
+

Progression

+

{tabata.exercise_2_progression}

+ {tabata.exercise_2_progression_en && ( +

{tabata.exercise_2_progression_en}

+ )} +
+ )} +
+
+
+
+ ))} +
+
+ ) +} diff --git a/admin-web/app/programs/new/CLAUDE.md b/admin-web/app/programs/new/CLAUDE.md new file mode 100644 index 0000000..dfdf83c --- /dev/null +++ b/admin-web/app/programs/new/CLAUDE.md @@ -0,0 +1,11 @@ + +# Recent Activity + + + +### Apr 16, 2026 + +| ID | Time | T | Title | Read | +|----|------|---|-------|------| +| #6319 | 9:38 PM | 🔵 | Discovered admin UI program management pages created | ~267 | + \ No newline at end of file diff --git a/admin-web/app/programs/new/page.tsx b/admin-web/app/programs/new/page.tsx new file mode 100644 index 0000000..d7988c5 --- /dev/null +++ b/admin-web/app/programs/new/page.tsx @@ -0,0 +1,34 @@ +import { Metadata } from "next" +import Link from "next/link" +import { ArrowLeft } from "lucide-react" + +import { Button } from "@/components/ui/button" +import ProgramForm from "@/components/program-form" + +export const metadata: Metadata = { + title: "New Program | TabataFit Admin", + description: "Create a new workout program", +} + +export default function NewProgramPage() { + return ( +
+
+ +

Create New Program

+

+ Fill in the details below to create a new workout program with 3 tabatas +

+
+ +
+ +
+
+ ) +} diff --git a/admin-web/app/programs/page.tsx b/admin-web/app/programs/page.tsx new file mode 100644 index 0000000..c8cf62f --- /dev/null +++ b/admin-web/app/programs/page.tsx @@ -0,0 +1,318 @@ +"use client"; + +import { useEffect, useState } from "react"; +import Link from "next/link"; +import { useRouter } from "next/navigation"; +import { supabase } from "@/lib/supabase"; +import { Button } from "@/components/ui/button"; +import { Card, CardContent } from "@/components/ui/card"; +import { Badge } from "@/components/ui/badge"; +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from "@/components/ui/table"; +import { Select } from "@/components/ui/select"; +import { Plus, Trash2, Edit, Loader2, Eye } from "lucide-react"; +import { toast } from "sonner"; +import type { Database } from "@/lib/supabase"; +import { + Dialog, + DialogContent, + DialogDescription, + DialogFooter, + DialogHeader, + DialogTitle, +} from "@/components/ui/dialog"; + +type WorkoutProgram = Database["public"]["Tables"]["workout_programs"]["Row"]; + +const BODY_ZONE_OPTIONS = [ + { value: "all", label: "All Zones" }, + { value: "upper-body", label: "Upper Body" }, + { value: "lower-body", label: "Lower Body" }, + { value: "full-body", label: "Full Body" }, +] + +const LEVEL_OPTIONS = [ + { value: "all", label: "All Levels" }, + { value: "Beginner", label: "Beginner" }, + { value: "Intermediate", label: "Intermediate" }, + { value: "Advanced", label: "Advanced" }, +] + +export default function ProgramsPage() { + const router = useRouter(); + const [programs, setPrograms] = useState([]); + const [loading, setLoading] = useState(true); + const [deletingId, setDeletingId] = useState(null); + const [deleteDialogOpen, setDeleteDialogOpen] = useState(false); + const [programToDelete, setProgramToDelete] = useState(null); + const [filterZone, setFilterZone] = useState("all"); + const [filterLevel, setFilterLevel] = useState("all"); + + useEffect(() => { + fetchPrograms(); + }, []); + + const fetchPrograms = async () => { + try { + const { data, error } = await (supabase.from("workout_programs") as any) + .select(` + *, + program_tabatas (id) + `) + .order("sort_order", { ascending: true }); + + if (error) throw error; + setPrograms(data || []); + } catch (error) { + console.error("Failed to fetch programs:", error); + } finally { + setLoading(false); + } + }; + + const openDeleteDialog = (program: WorkoutProgram) => { + setProgramToDelete(program); + setDeleteDialogOpen(true); + }; + + const handleDelete = async () => { + if (!programToDelete) return; + + setDeletingId(programToDelete.id); + try { + // Delete tabatas first (foreign key constraint) + const { error: tabataError } = await (supabase.from("program_tabatas") as any) + .delete() + .eq("program_id", programToDelete.id); + if (tabataError) throw tabataError; + + const { error } = await (supabase.from("workout_programs") as any) + .delete() + .eq("id", programToDelete.id); + if (error) throw error; + + setPrograms(programs.filter((p) => p.id !== programToDelete.id)); + toast.success("Program deleted", { + description: "The program has been removed successfully." + }); + } catch (error) { + console.error("Failed to delete program:", error); + toast.error("Failed to delete program"); + } finally { + setDeletingId(null); + setDeleteDialogOpen(false); + setProgramToDelete(null); + } + }; + + const getBodyZoneColor = (zone: string) => { + const colors: Record = { + "upper-body": "bg-green-500/20 text-green-500", + "lower-body": "bg-purple-500/20 text-purple-500", + "full-body": "bg-orange-500/20 text-orange-500", + }; + return colors[zone] || "bg-neutral-500/20 text-neutral-500"; + }; + + const getLevelColor = (level: string) => { + const colors: Record = { + "Beginner": "bg-emerald-500/20 text-emerald-500", + "Intermediate": "bg-yellow-500/20 text-yellow-500", + "Advanced": "bg-red-500/20 text-red-500", + }; + return colors[level] || "bg-neutral-500/20 text-neutral-500"; + }; + + const filteredPrograms = programs.filter((p) => { + if (filterZone !== "all" && p.body_zone !== filterZone) return false; + if (filterLevel !== "all" && p.level !== filterLevel) return false; + return true; + }); + + return ( +
+
+
+

Programs

+

Manage your workout programs

+
+ +
+ + {/* Filters */} +
+
+ +
+
+ + + + {loading ? ( +
+ +
+ ) : filteredPrograms.length === 0 ? ( +
+ {programs.length === 0 + ? "No programs yet. Create your first program to get started." + : "No programs match your filters."} +
+ ) : ( + + + + Title + Body Zone + Level + Access + Duration + Calories + Tabatas + Actions + + + + {filteredPrograms.map((program) => ( + router.push(`/programs/${program.id}`)} + > + +
+ {program.accent_color && ( +
+ )} + {program.title} +
+ + + + {program.body_zone} + + + + + {program.level} + + + + + {program.is_free ? "Free" : "Premium"} + + + {program.estimated_duration} min + {program.estimated_calories} + + {program.program_tabatas?.length || 0} + + +
e.stopPropagation()}> + + + +
+
+ + ))} + +
+ )} +
+
+ + {/* Delete Confirmation Dialog */} + + + + Delete Program + + Are you sure you want to delete "{programToDelete?.title}"? This will also delete all associated tabatas. This action cannot be undone. + + + + + + + + +
+ ); +} diff --git a/admin-web/app/trainers/[id]/edit/page.tsx b/admin-web/app/trainers/[id]/edit/page.tsx new file mode 100644 index 0000000..fa26f23 --- /dev/null +++ b/admin-web/app/trainers/[id]/edit/page.tsx @@ -0,0 +1,66 @@ +import { Metadata } from "next" +import Link from "next/link" +import { notFound } from "next/navigation" +import { ArrowLeft } from "lucide-react" + +import { Button } from "@/components/ui/button" +import TrainerForm from "@/components/trainer-form" +import { supabase } from "@/lib/supabase" + +interface EditTrainerPageProps { + params: Promise<{ + id: string + }> +} + +async function getTrainer(id: string) { + const { data, error } = await (supabase.from("trainers") as any) + .select("*") + .eq("id", id) + .single() + + if (error || !data) { + return null + } + + return data +} + +export async function generateMetadata({ params }: EditTrainerPageProps): Promise { + const resolvedParams = await params + const trainer = await getTrainer(resolvedParams.id) + + if (!trainer) { + return { + title: "Trainer Not Found | TabataFit Admin", + } + } + + return { + title: `Edit ${trainer.name} | TabataFit Admin`, + } +} + +export default async function EditTrainerPage({ params }: EditTrainerPageProps) { + const resolvedParams = await params + const trainer = await getTrainer(resolvedParams.id) + + if (!trainer) { + notFound() + } + + return ( +
+ + +

Edit Trainer

+ + +
+ ) +} diff --git a/admin-web/app/trainers/new/page.tsx b/admin-web/app/trainers/new/page.tsx new file mode 100644 index 0000000..12fcbc6 --- /dev/null +++ b/admin-web/app/trainers/new/page.tsx @@ -0,0 +1,10 @@ +import TrainerForm from "@/components/trainer-form" + +export default function NewTrainerPage() { + return ( +
+

Add New Trainer

+ +
+ ) +} diff --git a/admin-web/app/trainers/page.tsx b/admin-web/app/trainers/page.tsx index 11f6999..670b630 100644 --- a/admin-web/app/trainers/page.tsx +++ b/admin-web/app/trainers/page.tsx @@ -16,6 +16,7 @@ import { Plus, Trash2, Edit, Loader2, Users, AlertCircle } from "lucide-react"; import Link from "next/link"; import { toast } from "sonner"; import type { Database } from "@/lib/supabase"; +import { useRouter } from "next/navigation"; type Trainer = Database["public"]["Tables"]["trainers"]["Row"]; @@ -145,12 +146,21 @@ export default function TrainersPage() {
-
- {trainer.name[0]} -
+ {trainer.avatar_url ? ( + {trainer.name} + ) : ( +
+ {trainer.name[0]} +
+ )}

{trainer.name}

{trainer.specialty}

@@ -161,9 +171,11 @@ export default function TrainersPage() {
- + + + + +

Generate Workout Video

+ + + +
+ {workout.title} + {videoStatus?.inProgram && ( + + In Program + + )} +
+
+ +
+ {trainer?.avatar_url && ( + {trainer.name} + )} +
+

{trainer?.name}

+

{trainer?.specialty}

+
+
+ + {videoStatus?.inProgram && ( +
+ +
+

Workout is in a program

+

+ The video_generated flag will be set to true after generation. +

+
+
+ )} + +
+

Exercises

+
+ {workout.exercises?.map((ex, i) => ( +
+ + {i + 1} + + {ex.name} + {ex.duration}s +
+ ))} +
+
+ + {videoStatus?.hasVideo && videoStatus.videoUrl && !generating && ( +
+

Generated Video

+
+ )} + + {needsGeneration && ( +
+ {status === "generating" ? ( +
+
+ + Generating video with Veo 3.1... +
+
+
+
+
+
+

+ This may take up to 2 minutes. Please wait... +

+
+ ) : ( + + )} +
+ )} + + {status === "done" && ( +
+ + Video generated and saved! +
+ )} + + {status === "error" && ( +
+ + Video generation failed. Check console for details. +
+ )} + + +
+ ) +} diff --git a/admin-web/app/workouts/[id]/page.tsx b/admin-web/app/workouts/[id]/page.tsx index d78717e..f6260f2 100644 --- a/admin-web/app/workouts/[id]/page.tsx +++ b/admin-web/app/workouts/[id]/page.tsx @@ -1,7 +1,7 @@ import { Metadata } from "next" import Link from "next/link" import { notFound } from "next/navigation" -import { ArrowLeft, Edit, Trash2, Clock, Flame, Dumbbell, Music } from "lucide-react" +import { ArrowLeft, Edit, Trash2, Clock, Flame, Dumbbell, Music, Video } from "lucide-react" import { Button } from "@/components/ui/button" import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card" @@ -23,8 +23,7 @@ const CATEGORY_COLORS: Record = { } async function getWorkout(id: string) { - const { data, error } = await supabase - .from("workouts") + const { data, error } = await (supabase.from("workouts") as any) .select(` *, trainers (name, specialty, color) @@ -95,6 +94,12 @@ export default async function WorkoutDetailPage({ params }: WorkoutDetailPagePro
+