Architecture·13 min de lecture·2,428 mots

Analyse de l'arborescence

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 17)
│   │   │   ├── 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 (RECUEEN_PREPARATIONPRETE...)
│       ├── 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 (guard isTenant, 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é)

FolderPourquoi critique
app/prisma/schema.prisma72 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.tsTypes Pick/Partial des payloads. Doit rester aligné avec les routes backend.
mobile-staging/lib/icons.tsRe-export central Phosphor — interdit d'importer Phosphor directement ailleurs.