Development Guide — Mobile (mobile-staging/)
Prerequisites
- Node.js ≥ 20 (Expo 54 compatible)
- npm ≥ 10
- Expo CLI :
npm i -g eas-cli(≥ 18.12.3) - iOS : macOS + Xcode (pour simulator) — Apple Developer account si build
- Android : Android Studio + emulator OU device physique (USB debugging)
- Compte Expo (account
ouattaradfabriceconfiguré sur projectwari-mobile) - Apple Developer (Team
9HTKV7262K, ascAppId6768885815) - Firebase project (
wari-mobile-911d2) avecgoogle-services.jsoncommité
Source de vérité dev
⚠️ Ne pas développer dans
mobile-staging/sur le VPS.
Le code mobile vit sur la machine fabrice (fabrice@192.168.1.152, user fabrice), dans ~/DEVELOPPEMENT/. Le dossier mobile-staging/ sur le VPS est un miroir pour consultation.
Accès depuis le VPS via reverse SSH tunnel établi par le user :
ssh -p 2222 fabrice@127.0.0.1
cd ~/DEVELOPPEMENTRepo distant : git@github.com:ouattaradfabrice/wari-mobile.git, branche main.
Installation locale (machine fabrice)
cd ~/DEVELOPPEMENT
npm install
# Configuration Expo / EAS
npx expo login # compte ouattaradfabrice
eas login # idem
# Vérifier projet
cat app.json | grep -A2 expo.extra.eas
# Doit afficher projectId: 4d8772a8-77f0-4fb1-818e-576a2f755fe1Lancement dev
# Dev server LAN (test sur Expo Go ou dev client iOS/Android)
npx expo start --lan
# Tunnel (ngrok, accessible de n'importe où)
npx expo start --tunnel
# iOS simulator (macOS uniquement)
npm run ios
# Android emulator / device USB
npm run android
# Web : NON SUPPORTÉ (BUG-134 — app.json platforms = ["ios","android"])Reactotron (debug réseau + Redux/Zustand) : reactotron-app & sur le bureau Ubuntu, se connecte sur 192.168.1.152:9090.
Scripts npm
{
"start": "expo start",
"android": "expo start --android",
"ios": "expo start --ios",
"test": "jest",
"test:watch": "jest --watch",
"lint": "eslint .",
"lint:fix": "eslint . --fix",
"typecheck": "tsc --noEmit"
}Workflow Git mobile
cd ~/DEVELOPPEMENT
git status
git add . # ou fichiers spécifiques
git commit -m "feat: <description courte>
- détail 1
- détail 2"
git push origin main⚠️ Toujours SSH (git@github.com:...), jamais HTTPS+PAT. Configurer une fois :
git remote set-url origin git@github.com:ouattaradfabrice/wari-mobile.git
git remote -v # → doit afficher git@github.com:... (pas https://)
ssh -T git@github.com # → "Hi ouattaradfabrice!"
git config user.email 'ouattaradfabrice@gmail.com'
git config user.name 'ouattaradfabrice'⚠️ Vérifier .gitignore couvre node_modules/, .expo/, .env*, ios/, android/ avant git add ..
Builds EAS
Profiles dans eas.json :
development → APK Android + dev client (channel development)
preview → APK Android internal + iOS device (channel preview)
production → App Bundle Android (Play Store) + iOS Release autoIncrement buildNumber (channel production)Builds OTA (cas 95%)
Pour la majorité des releases, OTA suffit (pas de rebuild natif requis) :
cd ~/DEVELOPPEMENT
eas update --branch production --message "fix: BUG-XXX label court"
# ~5 min, push sur tous les devices via channel productionCas où OTA suffit : changements TS/TSX, ajout/modif strings i18n, fix UI, changement comportement business, ajout/suppression écrans expo-router (file-based), ajout/modif hooks, refactor.
Cas où il faut un build natif (rare) :
- Ajout/modif permissions iOS (
infoPlist) ou Android (AndroidManifest) - Ajout d'un package Expo natif (ex.
expo-haptics) - Bump SDK Expo (52 → 54 → 55...)
- Changement icône / splash screen
- Changement bundle identifier / scheme deep link
- Changement Firebase google-services.json
Build natif iOS production
cd ~/DEVELOPPEMENT
eas build --platform ios --profile production
# 30-90 min (free tier queue) - notification quand prêt
# Le build est uploadé sur Apple, dispo dans App Store Connect (Activities)Submit TestFlight
eas submit --platform ios --latest
# Push le dernier build vers TestFlight automatiquement
# Apple processing ~10-30 minBuild Android
eas build --platform android --profile production
# App Bundle (.aab) pour Play Store
# Play Store config pas encore active V1Conventions code
Tirées de ~/DEVELOPPEMENT/CLAUDE.md (sur machine fabrice) + règles racine VPS :
- Icônes : Phosphor uniquement via
lib/icons.ts(DEC-133/134/135) — jamais Ionicons/MaterialIcons/FontAwesome/emojis comme icônes UI - Filtres :
<FilterChip />+<FilterSheet />partout (DEC-137/138) - Bottom sheets clavier-safe :
keyboardShouldPersistTaps="handled",keyboardDismissMode="on-drag", pas deKeyboardAvoidingViewsur position absolute,Keyboard.addListeneriOS seulement (DEC-170) ctaPaddingBottom2 variantes selon contexte Modal vs GerantLayout (DEC-174 — éviter double safe area)- TopBar absolute : tout ScrollView tab doit lire
useUIStore().topbarHeightet appliquerpaddingTop: topbarHeight + SPACING.sm(DEC-153) - Touch targets ≥ 44×44 partout
- API client : utiliser
apiFetchdelib/api.ts— jamais throw, retourne{ data, error, status } - Routes constants dans
lib/constants.ts(VITRINE_*, API_URL) - Stores Zustand : 16 stores existants, pattern
selectIsTenantetc. Pas de Context API. - Hooks React Query : 1 par domaine, staleTime tuné 60s pour Android mid-range
- Pas de commentaires sauf WHY non-évident (cohérent avec backend)
Tests
cd ~/DEVELOPPEMENT
npm test # jest --watchAll=false par défaut
npm run test:watch
npm run typecheck # tsc --noEmit
npm run lint
npm run lint:fixTests : __tests__/ avec jest + @testing-library/react-native. Setup dans jest.setup.js + jest.config.js. Couverture partielle (UI + stores + hooks). Pas de tests E2E (Detox/Maestro pas configurés).
QA manuel = TestFlight + sessions test pratique (fixtures tests-pratiques/ côté VPS).
i18n
Fichiers dans locales/<lng>/translation.json (fr, en, ar, pt). Strings extraites avec t('namespace.key') via react-i18next.
import { useTranslation } from 'react-i18next';
function MyScreen() {
const { t } = useTranslation();
return <Text>{t('vitrine.title')}</Text>;
}Push notifications dev
En Expo Go, expo-notifications log un ERROR au boot (limitation SDK 53+). En dev build (apk via eas build --profile development), tout fonctionne (BUG-118 fix : require conditionnel).
Pour tester en local :
# Avec dev build seulement
eas build --platform android --profile development
# Installer l'APK sur device + scanner QR ExpoDebug commun
| Problème | Diagnostic |
|---|---|
Bundle Metro fail Cannot find module 'react-dom/server.node' | app.json.web block présent — supprimer + platforms: ["ios","android"] (BUG-134) |
expo-notifications ERROR au boot | Normal en Expo Go SDK 53+ ; OK en dev build/TestFlight (BUG-118) |
| Header Stack inattendu sur écran | Manque Stack.Screen dans app/_layout.tsx racine avec headerShown: false (BUG-116) |
| Bouton "Se connecter" no-op | Route doit être /auth pas /auth/login (BUG-117) |
| Bearer 401 après cold start | Vérifier AuthHydrator mount + getToken() cache mémoire Android |
| Push pas reçu en dev | Vérifier Firebase google-services.json + APNs cert prod + token register dans /api/mobile/push-tokens/register avec session.role correct (BUG-120/124) |
| Photo masquée pas blurrée fiche détail | ProduitGalerie prop masque à passer depuis parent (BUG-132) |
Liens utiles
- App Store Connect : https://appstoreconnect.apple.com/apps/6768885815
- Expo dashboard : https://expo.dev/accounts/ouattaradfabrice/projects/wari-mobile
- Firebase console : https://console.firebase.google.com/project/wari-mobile-911d2
- Repo : https://github.com/ouattaradfabrice/wari-mobile
- Privacy Policy URL : https://wari.pro/legal/confidentialite