Source Tree — wari.pro
Annotation des dossiers critiques pour les 2 parts du projet.
Racine monorepo
superApp_V1/
├── app/ # Part `backend` — Next.js 16
├── mobile-staging/ # Part `mobile` — Expo (miroir VPS de ~/DEVELOPPEMENT)
├── docker-compose.yml # Orchestration prod : postgres + redis + minio + nextjs + typesense
├── .env # Variables compose (POSTGRES_*, REDIS_PORT, MINIO_*, NEXTJS_PORT, ...)
├── .env.vonage # Token SMS (séparé)
├── postgres/data/ # Volume monté postgres15-alpine
├── minio/data/ # Volume monté minio
├── CLAUDE.md # Règle racine : doc visuelle Excalidraw à maintenir
├── README.md # Procédure VPS (docker compose, prisma migrate, perms)
├── _bmad/ # Framework BMAD installé (44 skills, module bmm FR)
├── _bmad-output/ # Artefacts BMAD (planning + implementation)
├── docs/ # Documentation projet (ce dossier)
├── tests-pratiques/ # Fixtures sessions QA TestFlight (cils-et-or/, ...)
├── Captures/ # Screenshots, mockups
└── .claude/skills/ # Skills Claude Code locales (BMAD + custom)Part backend (app/)
app/
├── package.json # next 16.2.2, prisma 7.6, @sentry/nextjs, @aws-sdk/client-s3, ...
├── next.config.ts # Config Turbopack + standalone + Sentry
├── tsconfig.json # TS strict
├── eslint.config.mjs # ESLint 9 flat config (bloquant en CI depuis P0 hardening)
├── vitest.config.ts # Tests unitaires lib/
├── vitest.setup.ts
├── instrumentation.ts # Sentry server init
├── instrumentation-client.ts # Sentry browser init
├── Dockerfile # Multi-stage prod (P0 hardening 2026-05-20)
├── Dockerfile.dev # Dev container
│
├── CLAUDE.md # **CRITIQUE** : pitch + 3 piliers, règles auth, stack, conventions, IDs WP/BUG/DEC
├── AGENTS.md # Notice Next.js 16 (breaking changes vs training data)
├── README.md
│
├── prisma/
│ ├── schema.prisma # 72 models, 36 enums (1939 LOC)
│ ├── seed.ts # Fixtures idempotentes (profiles minimal/demo/full)
│ ├── seeds/ # Sous-seeds spécialisés
│ └── migrations/ # 73 migrations (init → restaurant → RDV → stories → typesense)
│
├── src/
│ ├── app/ # App Router Next.js
│ │ ├── layout.tsx # Root layout (Sentry, i18n, PostHog)
│ │ ├── page.tsx # Home marketplace
│ │ │
│ │ ├── [slug]/ # **Pages vitrine publiques par tenant** (catch-all subdomain)
│ │ │ ├── page.tsx # Vitrine renderer (snapshot PUBLISHED ou preview live)
│ │ │ └── ...
│ │ │
│ │ ├── admin/ # **Back-office gérant** (TENANT_ADMIN)
│ │ │ ├── layout.tsx # AdminShell : sidebar + topbar + bottom-nav mobile + Cmd+K + toasts
│ │ │ ├── page.tsx # Dashboard (KPI + sparkline + top produits)
│ │ │ ├── login/ # Saga Login + onboarding wizard 7 étapes
│ │ │ ├── catalogue/ # CRUD produits + variantes + modèles + catégories
│ │ │ ├── services/ # CRUD prestations (refonte Shopify-like 2026-05-12)
│ │ │ ├── commandes/
│ │ │ ├── clientes/ # Mes Clientes agrégés
│ │ │ ├── medias/ # Médiathèque tenant
│ │ │ ├── parametres/ # Réglages (Vitrine / Contact / Accès / Avancé)
│ │ │ ├── acces/ # Demandes d'accès SUR_DEMANDE/INVITATION
│ │ │ ├── reset-mdp/
│ │ │ ├── setup/
│ │ │ └── vitrine/builder/ # **Builder visuel** (snapshot draft + autosave + isDirty)
│ │ │ ├── page.tsx
│ │ │ ├── components/ # builder-shell, canvas, header, panels, sidebar
│ │ │ └── hooks/ # use-builder-store, use-vitrine-sync
│ │ │
│ │ ├── superadmin/ # **SuperAdmin shell bleu nuit** (Saga SA 1→7)
│ │ │ ├── layout.tsx # AdminShell SA + dark mode partagé + Cmd+K
│ │ │ ├── page.tsx # Dashboard (4 KPIs + setup pending)
│ │ │ ├── tenants/ # Filtres statut/modules/période
│ │ │ ├── users/
│ │ │ ├── categories/ # Gestion CategorieWari (12 + 67 sous-cat)
│ │ │ ├── logs/ # Audit log table + helper non-bloquant
│ │ │ └── health/
│ │ │
│ │ └── api/ # **280 routes API** (186 sous /api/mobile/*)
│ │ ├── admin/ # Routes admin web — gestion tenant courant
│ │ ├── superadmin/ # Routes superadmin
│ │ ├── auth/ # Magic link, verify, OTP, sessions
│ │ ├── mobile/ # **186 routes /api/mobile/*** (toutes prefixées Bearer)
│ │ │ ├── auth/ # /api/mobile/auth (token → Bearer)
│ │ │ ├── session/ # /api/mobile/session
│ │ │ ├── vitrine/ # **Routes gérant mobile** (Bearer TENANT_ADMIN)
│ │ │ ├── vitrines/ # Listing public (filtré niveauAcces=PUBLIC)
│ │ │ ├── [slug]/ # Détail vitrine par subdomain (peut retourner teaser)
│ │ │ ├── catalogue/ # Liste produits paginée + filtres
│ │ │ ├── produit/[id]/
│ │ │ ├── prestation/ # GET + GET [id]
│ │ │ ├── prestations/ # LIST public
│ │ │ ├── commandes/ # POST création + GET historique client
│ │ │ ├── reservations/ # POST + GET + DELETE
│ │ │ ├── restaurant/ # carte/[slug], commandes, table/[qrToken], mes-commandes
│ │ │ ├── home/ # Route agrégée Accueil (vitrines + produits + prestations + categories)
│ │ │ ├── feed-vitrines-suivies/
│ │ │ ├── abonnements/ # Follow vitrines/produits/clients
│ │ │ ├── acces/ # Demandes accès SUR_DEMANDE + mes-demandes
│ │ │ ├── push-tokens/ # register / delete
│ │ │ ├── search/ # Recherche texte + image (Anthropic Vision V1)
│ │ │ ├── stories/ # 5 routes Stories vitrines
│ │ │ ├── chat/ # Messagerie (Realtime SSE)
│ │ │ ├── realtime/ # SSE endpoints
│ │ │ ├── markets/ # Listing markets (i18n foundation 2026-05-18)
│ │ │ └── ... # health, parrainage, reviews, cashback, videos, ...
│ │ ├── panier/ # Web panier (cookie superapp_session)
│ │ ├── ical/ # Feed iCal tenant + per-reservation single-event
│ │ ├── paydunya/ # Webhook + redirect paydunya
│ │ ├── og/ # OpenGraph dynamiques (image previews vitrine)
│ │ └── cron/ # Crons internes (rappels RDV, stories expiration, ...)
│ │
│ ├── components/ # 33 components racine (admin/, vitrine/, ...)
│ │ ├── admin/ # AdminShell, sidebar, topbar, dashboard cards, notif-bell, ...
│ │ ├── vitrine/ # Renderer vitrine (snapshot → HTML)
│ │ ├── recherche/
│ │ ├── superadmin/
│ │ └── landing/
│ │
│ └── lib/ # **Helpers métier** (source de vérité)
│ ├── prisma/ # Prisma client + helpers
│ ├── auth/ # session.ts (getSessionFromRequest cookie+Bearer)
│ ├── canaux.ts # Source de vérité types canaux (WHATSAPP/SNAP/INSTA/TELEGRAM/EMAIL/...)
│ ├── acces-vitrine.ts # verifierAccesTenant + filtreTenantsAccessibles
│ ├── restaurant.ts # ConfigRestaurant defaults + horaires + transitions
│ ├── ical.ts # RFC 5545 generators (VEVENT, line folding, VALARM)
│ ├── paydunya.ts # PayDunya sandbox helper
│ ├── push.ts # sendPushToTenantAdmin / sendPushToClient (expo-server-sdk)
│ ├── notif/ # Notification Engine (NotifEvent dispatch)
│ ├── email/ # Resend templates (commande, paiement, accès, ...)
│ ├── sms/ # Vonage wrapper
│ ├── minio/ # S3 client + presigned URLs
│ ├── medias/ # Upload/conversion sharp
│ ├── cron/ # Crons (rappels-rdv, ...)
│ ├── i18n/ # next-intl setup + markets
│ ├── market.ts # Market enum + helpers (international foundation)
│ ├── money.ts # Money pattern (multi-devises)
│ ├── typesense.ts # Client Typesense (search image V2)
│ ├── embedding.ts # CLIP HuggingFace
│ ├── anthropic-vision.ts # Recherche par image V1
│ ├── ussd.ts # Codes USSD opérateurs BF
│ ├── format-prix.ts
│ ├── tags.ts
│ ├── theme.ts
│ ├── parrainage.ts
│ ├── beta-testers.ts
│ ├── snap-to-list.ts # OCR Gemini → catalogue
│ ├── cache.ts / redis.ts # Cache Redis
│ ├── sentry.ts
│ ├── realtime/ # SSE helpers
│ └── __tests__/ # Tests vitest lib/
│
├── public/ # Assets statiques
├── Docs/ # **Diagrammes Excalidraw** (architecture-gerant + architecture-client + tests)
├── docs/ # Beta testing guide + runbook backups + snapshots tests
├── scripts/ # backup-postgres.sh + backup-minio.sh + seed-admin.ts + wari-backup.cron
├── infra/ # Snapshot Nginx + docker-compose (versionnés pour traçabilité)
└── cache/ # Cache build (ignoré git)Points d'entrée backend
- App Router :
src/app/layout.tsx(root),src/app/page.tsx(marketplace home) - Vitrines tenants :
src/app/[slug]/page.tsx(subdomain catch-all) - Admin gérant :
src/app/admin/layout.tsx+src/app/admin/page.tsx - SuperAdmin :
src/app/superadmin/layout.tsx - Builder visuel :
src/app/admin/vitrine/builder/page.tsx - API REST :
src/app/api/**/route.ts(Next.js Route Handlers, App Router convention)
Part mobile (mobile-staging/)
mobile-staging/
├── package.json # expo ~54, react 19.1, RN 0.81.5, zustand, react-query, ...
├── app.json # name "wari.pro", slug "wari-mobile", bundleId pro.wari.mobile
├── eas.json # 3 profiles : development / preview / production (channels homonymes)
├── tsconfig.json
├── babel.config.js
├── jest.config.js + jest.setup.js
├── eslint.config.js
├── google-services.json # Firebase FCM (Android push)
├── PrivacyInfo.xcprivacy # Apple App Privacy declarations
├── AppStoreInfo.plist # Metadata App Store Connect
├── ReactotronConfig.ts # Debugger réseau dev
├── docs/ # Docs internes mobile
├── locales/ # Traductions i18next (fr, en, ar, pt, ...)
├── assets/ # Icons (1024², adaptive, splash) + images
├── bascule/ # Variants/legacy
│
├── app/ # **Routes file-based** (expo-router v6)
│ ├── _layout.tsx # Root : QueryClient + AuthHydrator + HistoryHydrator + Sentry + i18n init
│ ├── (tabs)/ # **5 onglets client**
│ │ ├── _layout.tsx # Topbar absolue glass + AnimatedTabBar + SearchOverlay
│ │ ├── index.tsx # Accueil (3 horizontales + grille catégories + banner)
│ │ ├── activite.tsx # Commandes en cours + nouveautés vitrines suivies + favoris
│ │ ├── panier.tsx # Panier local Zustand (multi-tenants)
│ │ ├── explorer.tsx # 3 tabs internes (Vitrines / Produits / Prestations) + FilterSheet
│ │ ├── compte.tsx # Auth + profil + accès Ma Vitrine (si isTenant) + switcher (M15)
│ │ ├── commandes.tsx
│ │ └── recherche.tsx
│ │
│ ├── (onboarding)/ # Flow onboarding gérant post-magic link
│ ├── auth/ # OTP 6 cases + canal selector + verify + profil
│ ├── compte/ # Sous-écrans compte (édition profil, notifications, ...)
│ ├── commande/checkout.tsx # Paiement USSD orchestré (WP-225)
│ ├── produit/[id].tsx # Fiche détail Zalando-like
│ ├── prestation/[id].tsx # Fiche prestation publique (modeContact aware)
│ ├── prestation/[id]/creneaux.tsx # Sélecteur Doctolib (date row + grille 3 cols)
│ ├── reservation/confirmer.tsx
│ ├── vitrine/[slug].tsx # Vitrine mini-site (header + tabs Boutique/Services/Menu + cards)
│ ├── vitrine-inactive.tsx + vitrine-privee.tsx
│ ├── restaurant/[slug]/ # carte / panier / suivi/[id] / table/[qrToken]
│ ├── evenement/ # Pages événements
│ ├── conversation/ # Messagerie 1-to-1
│ ├── messages.tsx # Boîte messages
│ ├── story/ # Stories viewer + composer client
│ ├── favoris.tsx
│ ├── invitation/ # Acceptation invitation magic link
│ ├── explorer/ # Sous-routes explorer
│ ├── search/ # Recherche texte + image
│ │
│ └── vitrine-pro/ # **Espace gérant in-app** (TENANT_ADMIN, in-app pas Stack standard)
│ ├── _layout.tsx # Guard isTenant + header + GerantTabBar dynamique selon modulesActifs
│ ├── dashboard.tsx # KPIs + sparkline + top produits + alertes stock
│ ├── commandes.tsx # Liste + filtres + modal détail + StatutSheet
│ ├── catalogue.tsx # Produits + variantes + modèles
│ ├── catalogue-categories.tsx
│ ├── services.tsx + services-categories.tsx
│ ├── clientes.tsx
│ ├── cuisine.tsx # Kanban restauration (RECUE → EN_PREPARATION → PRETE → ...)
│ ├── carte.tsx # Carte restau (sections + plats + options)
│ ├── tables.tsx # QR tables restau (génération QR via react-native-qrcode-svg)
│ ├── disponibilites.tsx # Créneaux + indisponibilités RDV
│ ├── rdv.tsx # Liste réservations gérant
│ ├── evenements.tsx
│ ├── stories.tsx + story/ # Composer + liste stories vitrines
│ ├── arrivages.tsx + notifier.tsx
│ ├── medias.tsx # Médiathèque
│ ├── modeles.tsx + modeles/
│ ├── tags.tsx
│ ├── acces.tsx # Demandes accès vitrine
│ ├── builder.tsx # WebView builder web embedded (DEC mobile builder)
│ └── ...
│
├── components/ # **239 components**
│ ├── ui/ # Badge, Button, FilterChip, FilterSheet, SafeImage, EmptyState, CategoriesChips, WizardSteps, ...
│ ├── navigation/ # AnimatedTabBar, StickySearchBar, SearchOverlay
│ ├── home/ # SectionHeader, banners
│ ├── boutique/ # BoutiqueCard
│ ├── produit/ # ProduitCard, ProduitGalerie, VarianteSelector, CTAsDynamiques, ContactVendeur, WhatsAppCTA
│ ├── vitrine/ # VitrineHeader, CanauxRow
│ ├── activite/ # CommandeRowCompact, RdvRowCompact, DemandeAccesRowCompact, ...
│ ├── compte/ # ProfileCard, MaVitrineButton
│ ├── panier/ # PanierRepasFlottant (restaurant)
│ ├── search/ # SearchOverlay, ResultRow
│ ├── stories/ # StoryViewer, StoryBandeau, StoryComposer
│ ├── chat/ # MessageBubble, QuickReplies, ChatComposer
│ ├── restaurant/ # CarteMenu, PlatCard, OptionsModal, SuiviCommandeRepas
│ ├── reviews/ # ReviewCard, RatingStars
│ ├── notif/ # InboxBadge, NotifList
│ ├── feedback/ # Toasts, snackbars
│ ├── acces/ # AccesRequis, DemandeAccesBanner
│ ├── onboarding/ # OnboardingWizard, SetupChecklist
│ └── vitrine-pro/ # **Composants espace gérant** (BoutiqueActivite, BoutiqueCatalogue, GerantLayout, GerantTabBar, StatutBadge, StatutSheet, PrestationFormModal, ProduitFormModal, ModeleSheet, VariantesSheet, dashboard*, parametres*, ...)
│
├── store/ # **16 stores Zustand**
│ ├── authStore.ts # user, tenant, token (+ hydrate + selectIsTenant)
│ ├── cartStore.ts # Panier produits
│ ├── panierRepasStore.ts # Panier restau séparé (DEC-219)
│ ├── favorisStore.ts # Favoris locaux (AsyncStorage)
│ ├── historyStore.ts # 20 derniers produits consultés
│ ├── gerantStore.ts # Mode gérant + tab actif + selectedCommande + activeReglagesTab
│ ├── explorerStore.ts # activeTab + pendingCategorieId
│ ├── inboxArchiveStore.ts # Archive Inbox gérant
│ ├── notesClientsStore.ts
│ ├── offlineQueueStore.ts # Queue actions offline (V2)
│ ├── networkStore.ts # NetInfo state
│ ├── themeStore.ts # Light/dark/system
│ ├── uiStore.ts # topbarHeight + autres dimensions partagées
│ ├── villeStore.ts
│ └── geoStore.ts # Géoloc utilisateur
│
├── hooks/ # ~60 hooks métier (useAuth, useCart, useBoutiques, useProduits, useVitrine, useNotifications, useRdv, useRestaurant, useStoriesFeed, ...)
│
├── lib/ # api.ts (apiFetch retourne { data, error, status }), auth.ts, constants.ts, icons.ts (re-export Phosphor central), dates.ts, canaux.ts, restaurant.ts, ...
│
├── types/ # api.ts (TypeScript types des payloads backend)
│
└── __tests__/ # Tests Jest (composants + stores + hooks)Points d'entrée mobile
- Root :
app/_layout.tsx(QueryClient + Sentry + i18n + AuthHydrator + ThemeHydrator) - Espace client :
app/(tabs)/_layout.tsx(5 onglets) - Espace gérant :
app/vitrine-pro/_layout.tsx(guardisTenant, TabBar dynamique) - Auth flow :
app/auth/(magic link OTP 6 cases) - Builder visuel :
app/vitrine-pro/builder.tsx(WebView embarquant l'admin web)
Folders critiques (résumé)
| Folder | Pourquoi critique |
|---|---|
app/prisma/schema.prisma | 72 modèles. Source de vérité unique du schéma multi-tenant. |
app/src/app/api/mobile/ | 186 routes. Tout le contrat mobile passe ici. Ne JAMAIS modifier sans coordonner avec mobile-staging/types/api.ts. |
app/src/lib/ | Tous les helpers métier (auth, canaux, acces-vitrine, restaurant, ical, push, notif, email, ...). Pattern source-of-truth unique. |
app/src/app/admin/vitrine/builder/ | Builder visuel — snapshots JSONB, isDirty, autosave. |
app/Docs/ | Diagrammes Excalidraw à maintenir après chaque feature gérant/client (règle CLAUDE.md racine). |
mobile-staging/app/(tabs)/ | 5 onglets client — surface d'entrée principale. |
mobile-staging/app/vitrine-pro/ | Espace gérant — duplique en mobile la logique de app/src/app/admin/. |
mobile-staging/components/vitrine-pro/ | Composants espace gérant — pattern GerantLayout + GerantTabBar dynamique. |
mobile-staging/store/ | 16 stores Zustand. authStore et gerantStore = pivot. |
mobile-staging/types/api.ts | Types Pick/Partial des payloads. Doit rester aligné avec les routes backend. |
mobile-staging/lib/icons.ts | Re-export central Phosphor — interdit d'importer Phosphor directement ailleurs. |