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>
5.9 KiB
5.9 KiB
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 startavec 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 uniquementexpo-notificationsfonctionne 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
- Expo Go → développement UI, timer, audio, exercices (90% du dev)
- EAS Build (Development) → tester RevenueCat, notifications avancées
- 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
- Un fichier = une responsabilité — si un hook dépasse 150 lignes, il doit être découpé
- Toute logique métier dans les hooks — les composants n'ont QUE du JSX + appel de hooks
- Barrel exports — chaque feature expose un
index.tspropre - Tests colocalisés —
ComponentName.test.tsxdans le même dossier - Pas d'effet secondaire dans le render — tout dans useEffect ou les handlers
- Typage strict des events — pas de
anydans les callbacks de timer/audio
Commandes du projet
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
useTimerEngine+TimerDisplay(plein écran)useAudioEngine+ synchronisation avec timerExerciseDisplay+ données des 38 exercices- Synchronisation triple timer × audio × exercice
- Onboarding 6 écrans + mini-démo live
- Paywall RevenueCat
- Streak + historique
- Notifications de rappel