Référence de déploiement, configuration et administration pour AI Reality Check.
AI Reality Check est déployé sur Railway avec un service web Next.js et une base de données PostgreSQL. L'application est construite avec `npm run build` et démarrée avec `npm start`.
Comme le déploiement automatique de Railway depuis GitHub peut cesser silencieusement de fonctionner, déployez toujours manuellement : `cd ai-reality-check && railway up`. Cela construit et déploie en une seule étape.
Le domaine de production est airealitycheck.ai, configuré dans les paramètres de domaine personnalisé de Railway. Le SSL est géré automatiquement via Let's Encrypt (TLS 1.3).
DATABASE_URL — chaîne de connexion PostgreSQL (fournie par Railway). ENCRYPTION_KEY — clé hexadécimale de 32 octets pour le chiffrement AES-256-GCM. ANTHROPIC_API_KEY — clé API pour Claude (bilan de confiance + chatbot). NEXT_PUBLIC_APP_URL — https://airealitycheck.ai. RESEND_API_KEY — clé API pour les e-mails lien magique.
GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET — identifiants OAuth Google. GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET — identifiants OAuth GitHub. Toutes les URI de redirection OAuth doivent pointer vers /api/auth/callback/google et /api/auth/callback/github respectivement.
Ne committez jamais les variables d'environnement dans git. Tous les secrets sont gérés via les paramètres de variables d'environnement de Railway. L'ENCRYPTION_KEY doit faire exactement 64 caractères hexadécimaux (32 octets). Générez-en une avec : openssl rand -hex 32
Prisma 6 est utilisé pour l'accès à la base de données. Le schéma se trouve dans prisma/schema.prisma. Exécutez `npx prisma db push` pour synchroniser les modifications du schéma (pas de migrations nécessaires pour le développement).
User, AuthToken, Session, Result, AuditLog, WaitlistEntry, ChatConversation, ChatMessage. Toutes les données utilisateur sont chiffrées au repos avec AES-256-GCM avant le stockage.
Utilisez Docker pour PostgreSQL en local : `docker run -d -p 5432:5432 -e POSTGRES_PASSWORD=postgres -e POSTGRES_DB=airealitycheck postgres:16`. Définissez DATABASE_URL=postgresql://postgres:postgres@localhost:5432/airealitycheck dans .env.
Toutes les données de résultats et messages de chat sont chiffrés avec AES-256-GCM avant le stockage en base de données. Les clés sont gérées via les variables d'environnement et ne sont jamais exposées au client. Le texte original du bilan de confiance n'est jamais stocké.
Les en-têtes de sécurité sont appliqués via le middleware : CSP, X-Frame-Options DENY, HSTS, X-Content-Type-Options nosniff, Referrer-Policy, Permissions-Policy. Le CSP autorise 'self' pour les scripts, styles, images, polices et connexions.
Toutes les routes API modifiant l'état valident un jeton CSRF. Le jeton est généré côté serveur et rafraîchi automatiquement via le composant CsrfRefresh. Les jetons expirent après 24 heures.
Limiteur de débit en mémoire avec des limites par endpoint : bilan de confiance 10/h, bilan de maturité/dépenses 20/h, lien magique 5/15 min, chatbot 30/h. Adapté au déploiement mono-instance.
Authentification par e-mail via Resend. L'utilisateur saisit son e-mail, reçoit un lien magique, clique pour vérifier. Le jeton est haché avec bcrypt et expire en 15 minutes. Le cookie de session est défini lors de la vérification.
Google et GitHub OAuth sont pris en charge. Les cookies de session utilisent SameSite=Lax (requis pour les redirections OAuth inter-origines). Les cookies sont définis directement sur les objets de réponse pour les réponses de redirection.
Les sessions durent 24 heures. Paramètres des cookies : HttpOnly, Secure (production), SameSite=Lax, Path=/. Les enregistrements de session sont stockés en base de données avec userId et date d'expiration.
Accédez à /admin/marketing (nécessite la variable ADMIN_EMAIL + authentification). Sélectionnez une plateforme (X, LinkedIn, Facebook) et un sujet, puis Claude génère du contenu de réseaux sociaux prêt à publier avec des accroches, des hashtags et des CTA.
POST vers /api/marketing/waitlist-blast envoie des e-mails de lancement à tous les abonnés du waitlist non encore notifiés. Envoi par lots de 50, suivi de notifiedAt pour éviter les envois en double. Protégé par authentification admin + CSRF.
Définissez la variable d'environnement ADMIN_EMAIL sur Railway avec votre adresse e-mail. Seuls les utilisateurs authentifiés correspondant à cet e-mail peuvent accéder aux outils marketing. Toutes les actions sont protégées par CSRF et journalisées.
Créez un nouveau fichier .ts dans src/data/blog-content/ avec les champs titre, slug, description, contenu et relatedCheck. Ajoutez l'import dans le fichier index.ts. Le sitemap et le flux RSS se mettent à jour automatiquement.
Les articles utilisent des données TypeScript statiques (pas de CMS, pas de base de données). Chaque article renvoie à un bilan associé via un CTA. Le contenu supporte les titres, paragraphes, listes et texte en gras. Les articles sont uniquement en anglais (non traduits).
Le sitemap sur /sitemap.xml et le flux RSS sur /feed.xml incluent automatiquement les nouveaux articles. Aucune mise à jour manuelle nécessaire — les deux lisent le tableau de contenu du blog au moment de la compilation.
Quatre modèles d'e-mails dans src/lib/emails.ts : e-mail de bienvenue (à l'inscription), résumé des résultats (après un bilan), relance (pour les utilisateurs incomplets) et envoi massif au waitlist (annonce de lancement). Tous utilisent du HTML de marque avec le thème sombre de l'application.
Déclenchez via /api/marketing/waitlist-blast. Envoie à tous les enregistrements WaitlistEntry où notifiedAt est nul. Lots de 50 avec délais pour éviter les limites de débit. Chaque envoi réussi met à jour notifiedAt pour empêcher les ré-envois.
Sans RESEND_API_KEY définie, tous les e-mails s'affichent dans la console au lieu d'être envoyés. Utilisez cela pour le développement local afin de vérifier le contenu et les déclencheurs d'e-mails sans envoyer réellement de messages.
Les schémas JSON-LD FAQ, Breadcrumb et Product sont appliqués sur les pages de bilans et de tarification. Testez avec l'outil de test des résultats enrichis de Google (search.google.com/test/rich-results) pour vérifier que les données structurées s'affichent correctement.
Images OG dynamiques générées via /api/og/result?type={bilan}&score={score}. Images OG basées sur des fichiers dans les répertoires de layout pour les pages statiques. Testez avec les débogueurs de réseaux sociaux (Twitter Card Validator, LinkedIn Post Inspector).
Ajoutez airealitycheck.ai à Google Search Console, vérifiez via DNS et soumettez le sitemap. Surveillez l'état d'indexation, les erreurs de couverture et les performances de recherche. Vérifiez les problèmes de données structurées dans l'onglet Améliorations.
Toutes les actions significatives sont enregistrées dans la table audit_logs : connexion, soumission de bilans, consultation de résultats, utilisation du chatbot. Chaque entrée inclut userId, action, endpoint, hash IP et métadonnées.
Consultez les journaux de l'application avec `railway logs -n 50`. Vérifiez le tableau de bord Railway pour le statut de déploiement, l'utilisation des ressources et le suivi des erreurs.
Vérifiez que l'application fonctionne en accédant à la page d'accueil. Vérifiez /sitemap.xml et /robots.txt pour vous assurer que la génération statique fonctionne.
Vérifiez que SameSite est défini sur Lax (pas Strict). Vérifiez que les URI de redirection OAuth correspondent exactement. Vérifiez que le CSP form-action inclut les domaines des fournisseurs OAuth. Voir docs/issues/google-oauth-login-broken.md pour le compte-rendu complet.
Le déploiement automatique de Railway depuis GitHub peut cesser silencieusement de fonctionner. Utilisez toujours `railway up` depuis le répertoire ai-reality-check comme solution de secours fiable. Vérifiez `railway logs` pour confirmer que la nouvelle version est en cours d'exécution.
Vérifiez que DATABASE_URL est correctement défini dans l'environnement Railway. Pour le développement local, assurez-vous que le conteneur Docker PostgreSQL est en cours d'exécution. Exécutez `npx prisma db push` pour synchroniser le schéma.
Vérifiez que ANTHROPIC_API_KEY est défini et valide. Vérifiez les limites de débit (10/heure par utilisateur). Assurez-vous que le texte saisi fait moins de 5 000 caractères. Consultez les journaux Railway pour les erreurs API spécifiques.