CognxSafeTrack
docs: add audit_production.md + plan_implementation_prod.md; fix admin phone field
f1a06cd | # Audit Complet — État de la Codebase | |
| *Date : 2026-02-22 — Commit base : `c286b2d`* | |
| --- | |
| ## 1. Architecture globale | |
| ``` | |
| apps/ | |
| api/ → Fastify REST API (Railway — port 3001) | |
| whatsapp-worker/ → BullMQ Worker (Railway — même container) | |
| admin/ → Dashboard React (Vite + Tailwind) | |
| web/ → Landing page + portail étudiant (Vite + Tailwind) | |
| packages/ | |
| database/ → Prisma schema (PostgreSQL) + migrations | |
| shared-types/ → Types TypeScript partagés | |
| tsconfig/ → Config TS commune | |
| ui/ → (vide) | |
| ``` | |
| --- | |
| ## 2. Ce qui fonctionne ✅ | |
| | Composant | État | | |
| |---|---| | |
| | Webhook WhatsApp (GET verify + POST events) | ✅ Implémenté | | |
| | Onboarding : INSCRIPTION → langue → secteur | ✅ | | |
| | Menus interactifs LIST (boutons natifs) | ✅ Titre ≤ 24 chars corrigé | | |
| | Download audio Meta Graph API (Railway) | ✅ | | |
| | Transcription Whisper via `/v1/ai/transcribe` | ✅ | | |
| | Feedback AI `generateFeedback()` + 429 fallback | ✅ | | |
| | Timeout IA 10s (Promise.race) | ✅ | | |
| | TTS leçon → audio R2 | ✅ | | |
| | Personnalisation leçon par secteur | ✅ | | |
| | SUITE / DAY_CONTINUE → jour suivant | ✅ Regex fixé | | |
| | REPLAY → réécoute leçon | ✅ | | |
| | EXERCISE → invite réponse | ✅ | | |
| | Dock génération OnePager PDF + PitchDeck PPTX | ✅ | | |
| | Paiements Stripe (checkout + webhook) | ✅ Implémenté | | |
| | Admin dashboard (stats + enrollments + CSV export) | ✅ | | |
| | Dockerfile combiné API + Worker (Railway) | ✅ | | |
| | Scheduler cron leçons quotidiennes | ✅ (basique) | | |
| | Stockage audio R2 via `/v1/ai/store-audio` | ✅ Ajouté | | |
| --- | |
| ## 3. Problèmes identifiés ❌ | |
| ### 3.1 Critiques (bloquants en prod) | |
| | # | Fichier | Problème | Solution | | |
| |---|---|---|---| | |
| | C1 | `Railway vars` | `WHATSAPP_APP_SECRET` non défini → HMAC skip (warning) | Ajouter la variable | | |
| | C2 | `Railway vars` | `DISABLE_WHATSAPP_SEND=true` encore présent → aucun envoi | Supprimer la variable | | |
| | C3 | Base de données | **Aucun contenu (Track/TrackDay) en production** → enrollement impossible | Seed ou admin content manager | | |
| | C4 | `api/src/services/stripe.ts` | STRIPE_SECRET_KEY et STRIPE_WEBHOOK_SECRET non vérifiés au démarrage | Ajouter à Railway vars | | |
| | C5 | Meta webhook | URL pas encore validée si container 502 | Corriger après Railway restart | | |
| ### 3.2 Importants (fonctionnalités incomplètes) | |
| | # | Composant | Problème | | |
| |---|---|---| | |
| | I1 | `apps/admin` | **Pas de gestion de contenu (Tracks/TrackDays)** — impossible de créer des leçons via l'interface | | |
| | I2 | `apps/admin` | `env.user?.whatsappId` utilisé mais le modèle User a `phone` (pas `whatsappId`) → colonne vide dans le tableau | | |
| | I3 | `apps/web` | **Portail étudiant `/login` est factice** — `handleLogin` fait un fake `alert` avec `setTimeout`, n'appelle aucune API | | |
| | I4 | `apps/web` | Pas de page de succès paiement Stripe (`/payment/success`) | | |
| | I5 | `whatsapp-worker/src/scheduler.ts` | Cron envoie les leçons mais **sans logique de vérification du jour courant** — risque d'envoyer à des utilisateurs déjà complétés | | |
| | I6 | `apps/api/routes/admin.ts` | Pas de route pour **créer/modifier des Tracks ou TrackDays** API-side | | |
| | I7 | `packages/ui` | Package vide — prévu pour composants partagés mais non utilisé | | |
| ### 3.3 Mineurs (dette technique) | |
| | # | Problème | | |
| |---|---| | |
| | M1 | `Enrollment` et `UserProgress` sont deux tables qui trackent le même `currentDay` et `exerciseStatus` — duplication de données | | |
| | M2 | `admin/src/App.tsx` ligne 108 : import `lucide-react` collé avec une déclaration d'interface (mauvais formatage) | | |
| | M3 | `Message` modèle Prisma non utilisé nulle part dans le code (payload jamais stocké) | | |
| | M4 | `web/src` n'a pas de `VITE_API_URL` configuré par défaut → fallback `localhost:3001` en prod | | |
| | M5 | Pas de gestion du cas où un utilisateur envoie `INSCRIPTION` alors qu'il est déjà inscrit à une formation active | | |
| --- | |
| ## 4. Variables d'environnement — état complet | |
| ### Railway (whatsapp-worker service) | |
| | Variable | Statut | Action | | |
| |---|---|---| | |
| | `WHATSAPP_VERIFY_TOKEN` | ✅ | OK | | |
| | `WHATSAPP_ACCESS_TOKEN` | ✅ | OK | | |
| | `WHATSAPP_PHONE_NUMBER_ID` | ✅ | OK | | |
| | `WHATSAPP_APP_SECRET` | ⚠️ Non défini | **Ajouter** (Meta App → Basic Settings → App Secret) | | |
| | `ADMIN_API_KEY` | ✅ (confirmé) | OK | | |
| | `DATABASE_URL` | ✅ | OK | | |
| | `REDIS_URL` | ✅ | OK | | |
| | `OPENAI_API_KEY` | ✅ | OK | | |
| | `API_URL` | ✅ | OK (doit pointer vers URL Railway publique) | | |
| | `DISABLE_WHATSAPP_SEND` | ❌ Présent | **Supprimer** | | |
| | `STRIPE_SECRET_KEY` | ❓ Non confirmé | Ajouter si Stripe actif | | |
| | `STRIPE_WEBHOOK_SECRET` | ❓ Non confirmé | Ajouter si Stripe actif | | |
| | `NODE_ENV` | ✅ | OK | | |
| | `R2_*` variables | ✅ | OK | | |
| ### HuggingFace (api service — inbound webhook désactivé) | |
| | Variable | Statut | | |
| |---|---| | |
| | `DISABLE_WHATSAPP_SEND` | ✅ `true` (correct) | | |
| | `OPENAI_API_KEY` | ✅ | | |
| | `DATABASE_URL` | ✅ | | |
| | Autres | Même que Railway | | |
| --- | |
| ## 5. Déploiements | |
| | Service | Plateforme | URL | État | | |
| |---|---|---|---| | |
| | API + Worker (webhook + BullMQ) | Railway | `whatsapp-worker-production-0bc0.up.railway.app` | 🟡 En restart | | |
| | Landing + Portail | HF / Netlify ? | À confirmer | ❓ | | |
| | Admin Dashboard | HF / Netlify ? | À confirmer | ❓ | | |