Files
tabatago/CLAUDE.md
Millian Lamiaux 31bdb1586f feat: timer engine + full-screen timer UI
Implement the core timer feature following the src/features/ architecture:

- useTimerEngine hook: drift-free Date.now() delta countdown (100ms tick),
  explicit state machine (IDLE → GET_READY → WORK → REST → COMPLETE),
  event emitter for external consumers (PHASE_CHANGED, ROUND_COMPLETED,
  COUNTDOWN_TICK, SESSION_COMPLETE), auto-pause on AppState interruption
  (phone calls, background), expo-keep-awake during session
- TimerDisplay component: full-screen animated UI with 600ms color
  transitions between phases, pulse animation on countdown, flash red
  on last 3 seconds, round progress dots, IDLE/active/COMPLETE views
- TimerControls component: stop/pause-resume/skip buttons with Ionicons
- Timer route (app/timer.tsx): fullScreenModal wiring hook → display
- Home screen: dark theme with START button navigating to /timer
- Project docs: CLAUDE.md (constitution), PRD v1.1, skill files
- Shared constants: PHASE_COLORS, TIMER_DEFAULTS, formatTime utility
- Types: TimerPhase, TimerState, TimerConfig, TimerActions, TimerEvent

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 19:05:25 +01:00

124 lines
5.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# TabataGo — CLAUDE.md
> Lis ce fichier EN ENTIER avant chaque session. C'est la constitution du projet.
## Projet
Application mobile Tabata (iOS + Android) construite avec Expo SDK 52 + Expo Router v3.
Modèle freemium via RevenueCat. Analytics via PostHog. Offline-first.
## Environnement de développement
**Test sur device physique via Expo Go** — pas de simulateur iOS.
- Scanner le QR code affiché par `npx expo start` avec l'app Expo Go sur le téléphone
- Le téléphone et le Mac doivent être sur le **même réseau Wi-Fi**
- En cas de problème réseau : `npx expo start --tunnel` (utilise ngrok, plus lent mais fiable)
### Contraintes Expo Go à respecter
- **Pas de modules natifs custom** — uniquement les modules inclus dans le SDK Expo Go
- `react-native-purchases` (RevenueCat) **ne fonctionne PAS dans Expo Go** → mocker le paywall en dev, tester sur build EAS uniquement
- `expo-notifications` fonctionne partiellement dans Expo Go → tester les notifications sur build EAS dev
- Modules **compatibles Expo Go SDK 52** (utilisables sans build) :
`expo-av`, `expo-haptics`, `expo-keep-awake`, `expo-router`, `expo-secure-store`,
`@react-native-async-storage/async-storage`, `expo-localization`, `react-native-posthog`
### Workflow de test
1. **Expo Go** → développement UI, timer, audio, exercices (90% du dev)
2. **EAS Build (Development)** → tester RevenueCat, notifications avancées
3. **EAS Build (Production)** → build final App Store / Play Store
## Stack technique — règles non-négociables
| Domaine | Solution | Interdit |
|---|---|---|
| Framework | Expo SDK 52 (managed workflow) | Bare workflow sauf si absolument nécessaire |
| Navigation | Expo Router v3 (file-based) | React Navigation seul |
| State global | Zustand + AsyncStorage | Redux, MobX, Context pour state global |
| Timer engine | Date.now() delta dans un hook isolé | setInterval seul (drift inacceptable) |
| Audio | expo-av avec AVAudioSession | expo-audio (instable), react-native-sound |
| Paiements | react-native-purchases (RevenueCat) | IAP natif direct — **MOCKER en dev Expo Go** |
| Analytics | react-native-posthog | Firebase Analytics, Amplitude |
| Styles | StyleSheet.create() | Styles inline, Tailwind, NativeWind |
| Types | TypeScript strict (`"strict": true`) | any, @ts-ignore sauf justification |
## Architecture — structure de fichiers
```
src/
features/
timer/
hooks/useTimerEngine.ts ← moteur central, AUCUN JSX
hooks/useTimerSync.ts ← synchronise audio + exercice sur les events timer
components/TimerDisplay.tsx ← affichage uniquement, reçoit tout par props
components/TimerControls.tsx ← boutons start/pause/stop/skip
types.ts ← TimerPhase, TimerState, TimerConfig
audio/
hooks/useAudioEngine.ts ← gestion expo-av, preload, crossfade
hooks/useAudioSettings.ts ← préférences utilisateur (ambiance, volume)
data/tracks.ts ← catalogue des tracks (offline)
data/sounds.ts ← catalogue des signaux de phase
types.ts
exercises/
hooks/useExercise.ts ← sélection, navigation entre exercices
components/ExerciseDisplay.tsx ← rendu selon la phase courante
components/ExerciseGif.tsx ← affichage GIF avec fallback
data/exercises.ts ← les 38 exercices (offline)
types.ts
programs/
hooks/useProgram.ts
components/ProgramBuilder.tsx
data/defaultPrograms.ts
onboarding/
hooks/useOnboarding.ts
screens/ ← 6 écrans (1 fichier par écran)
paywall/
hooks/usePaywall.ts ← RevenueCat wrapper
components/PaywallScreen.tsx
shared/
components/ ← Button, Card, Typography, etc.
hooks/ ← useHaptics, useKeepAwake, useAppState
utils/ ← formatTime, etc.
constants/ ← couleurs, durées par défaut
app/ ← Expo Router (fichiers de route uniquement)
(tabs)/
index.tsx ← Home
history.tsx
settings.tsx
timer/index.tsx
programs/[id].tsx
onboarding/index.tsx
paywall/index.tsx
```
## Règles de code
1. **Un fichier = une responsabilité** — si un hook dépasse 150 lignes, il doit être découpé
2. **Toute logique métier dans les hooks** — les composants n'ont QUE du JSX + appel de hooks
3. **Barrel exports** — chaque feature expose un `index.ts` propre
4. **Tests colocalisés**`ComponentName.test.tsx` dans le même dossier
5. **Pas d'effet secondaire dans le render** — tout dans useEffect ou les handlers
6. **Typage strict des events** — pas de `any` dans les callbacks de timer/audio
## Commandes du projet
```bash
npx expo start # dev — scanner le QR avec Expo Go
npx expo start --tunnel # si problème réseau Wi-Fi (ngrok)
npx expo start --clear # vider le cache Metro si comportement bizarre
jest --watchAll # tests en continu
eas build --profile development # build dev (pour tester RevenueCat, notifs)
eas build --platform ios # build TestFlight
npx expo export # bundle production
```
## Comment utiliser les skills
Quand tu travailles sur une feature spécifique, lis le skill correspondant :
- Timer → `.claude/skills/timer/SKILL.md`
- Audio → `.claude/skills/audio/SKILL.md`
- Exercices → `.claude/skills/exercises/SKILL.md`
- Workflow général → `.claude/skills/workflow/SKILL.md`
## Priorité d'implémentation V1
1. `useTimerEngine` + `TimerDisplay` (plein écran)
2. `useAudioEngine` + synchronisation avec timer
3. `ExerciseDisplay` + données des 38 exercices
4. Synchronisation triple timer × audio × exercice
5. Onboarding 6 écrans + mini-démo live
6. Paywall RevenueCat
7. Streak + historique
8. Notifications de rappel