Aller au contenu principal

Déploiement

Vercel (recommandé), variables d'environnement, 26 crons, configuration domaine.

Vercel (recommandé)

Étapes de déploiement

  1. Créer un projet Vercel et connecter le repository Git

  2. Configurer le Framework Preset : Next.js (auto-détecté)

  3. Build Command (automatique) :

    pnpm build
    
  4. Node.js Version : 20.x

  5. Configurer les variables d'environnement (voir section suivante)

  6. Déployer — Vercel lance automatiquement le build à chaque push

Build settings

Le build nécessite 7 GB de RAM (configuré dans package.json) :

{
  "build": "NODE_OPTIONS=--max-old-space-size=7168 next build"
}

Prisma sur Vercel

Le binary target rhel-openssl-3.0.x est nécessaire pour l'environnement Vercel :

generator client {
  provider      = "prisma-client-js"
  output        = "../generated/prisma"
  binaryTargets = ["native", "rhel-openssl-3.0.x"]
}

npx prisma generate est automatiquement exécuté lors du postinstall.

Variables d'environnement (production)

Obligatoires

VariableDescriptionExemple
DATABASE_URLPostgreSQL (pgBouncer)postgresql://...?pgbouncer=true
DIRECT_URLPostgreSQL (direct, migrations)postgresql://...
AUTH_SECRETSecret NextAuth (≥32 chars)openssl rand -base64 32
NEXTAUTH_URLURL de l'apphttps://app.votre-domaine.fr
NEXT_PUBLIC_APP_URLURL publiquehttps://app.votre-domaine.fr
STRIPE_SECRET_KEYClé secrète Stripesk_live_xxxx
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEYClé publique Stripepk_live_xxxx
STRIPE_WEBHOOK_SECRETSecret webhook Stripewhsec_xxxx
RESEND_API_KEYClé API Resendre_xxxx
UPSTASH_REDIS_REST_URLURL Redis (rate limiting)https://xxxx.upstash.io
UPSTASH_REDIS_REST_TOKENToken RedisAXxxxx
TOKEN_ENCRYPTION_KEYAES-256-GCM (64 hex chars)openssl rand -hex 32
CRON_SECRETSecret des crons (≥32 chars)openssl rand -base64 32

Stripe Price IDs

Chaque plan/module nécessite ses Price IDs Stripe (monthly + annual) :

# Plans
STRIPE_PRICE_STARTER="price_xxxx"
STRIPE_PRICE_STARTER_ANNUAL="price_xxxx"
STRIPE_PRICE_CORE="price_xxxx"
STRIPE_PRICE_CORE_ANNUAL="price_xxxx"
STRIPE_PRICE_BUSINESS="price_xxxx"
STRIPE_PRICE_BUSINESS_ANNUAL="price_xxxx"
STRIPE_PRICE_ENTERPRISE="price_xxxx"
STRIPE_PRICE_ENTERPRISE_ANNUAL="price_xxxx"
 
# Utilisateur supplémentaire
STRIPE_PRICE_EXTRA_USER="price_xxxx"
STRIPE_PRICE_EXTRA_USER_ANNUAL="price_xxxx"
 
# Modules (16 × 2 = 32 variables)
STRIPE_PRICE_MODULE_DEVIS="price_xxxx"
STRIPE_PRICE_MODULE_DEVIS_ANNUAL="price_xxxx"
# ... (voir .env.example pour la liste complète)

Optionnelles (mais recommandées)

VariableDescription
MISTRAL_API_KEYCopilote IA (Mistral)
PUSHER_APP_ID / PUSHER_SECRET / NEXT_PUBLIC_PUSHER_KEYTemps réel
GOOGLE_CLIENT_ID / GOOGLE_CLIENT_SECRETOAuth Google
MICROSOFT_CLIENT_ID / MICROSOFT_CLIENT_SECRETOAuth Microsoft
SUPABASE_URL / SUPABASE_SERVICE_KEYStorage Supabase
WEBHOOK_SECRETHMAC webhooks sortants
ADMIN_CHALLENGE_SECRET2FA panel admin

Crons (tâches planifiées)

HeartCo utilise 26 crons Vercel configurés dans vercel.json :

Quotidiens

CronScheduleDescription
/api/cron/demo-reset03:00Reset données de démo
/api/relances/cron08:00Envoi des relances automatiques
/api/cron/bill-usage02:00Facturation de l'usage
/api/cron/calendar-reminders08:00Rappels événements calendrier
/api/cron/check-trial09:00Vérification état des trials
/api/cron/publish-articles07:00Publication articles programmés
/api/cron/expire-quotes00:00Expiration des devis
/api/cron/recurring-transactions06:00Transactions récurrentes
/api/cron/appointment-reminders07:00Rappels rendez-vous
/api/cron/recurring-invoices07:00Génération factures récurrentes
/api/cron/trial-expiry06:00Downgrade des trials expirés
/api/cron/trial-reminder08:00Rappels J-7 et J-2
/api/cron/email-processor06:00Traitement file d'emails
/api/cron/inactivity-checker07:00Détection utilisateurs inactifs
/api/cron/sequence-processor10:00Exécution séquences email
/api/cron/renew-watches06:00Renouvellement watches Gmail
/api/cron/iopole-sync01:00Synchronisation e-facturation
/api/cron/iopole-fetch02:00Récupération factures entrantes
/api/dunning/enroll03:00Inscription relance auto
/api/dunning/execute03:30Exécution étapes relance
/api/dunning/winback09:00Campagnes win-back

Mensuels

CronScheduleDescription
/api/cron/reset-usage1er du mois, 00:00Reset quotas freemium
/api/cron/generate-payslips1er du mois, 05:00Génération fiches de paie
/api/cron/leave-accrual1er du mois, 01:00Accumulation congés
/api/cron/e-reporting-reminder5 du mois, 09:00Rappel e-reporting

Hebdomadaires

CronScheduleDescription
/api/cron/privilege-auditLundi 09:00Audit des permissions

Timeouts

DuréeRoutes
30s (défaut)invoice send, reset-usage, webhooks Stripe/Resend
60srelances, demo-reset, bill-usage, dunning, recurring-invoices, iopole-sync, privilege-audit

Configuration domaine

Architecture recommandée

votre-domaine.fr          → Landing page / marketing
app.votre-domaine.fr      → Dashboard (application SaaS)

Redirections automatiques

HeartCo gère automatiquement dans le middleware :

Domaine sourceDestination
heartco.ch / www.heartco.ch301 → heartco.fr
heartco.com301 → app.heartco.fr
app.heartco.fr/dashboard/*Autorisé (application)
heartco.fr/dashboard301 → app.heartco.fr/dashboard

CORS (app mobile)

Les origines autorisées pour l'app mobile Expo :

// Production
"heartco.fr", "heartco.com", "app.heartco.fr"
 
// Développement
"localhost", "192.168.*", "10.*", "172.*"

Méthodes : GET, POST, DELETE, OPTIONS Headers : Content-Type, Authorization, x-trpc-source

Checklist déploiement

  • Toutes les variables obligatoires sont configurées
  • Les Price IDs Stripe correspondent à l'environnement (live, pas test)
  • NEXTAUTH_URL pointe vers l'URL de production
  • NEXT_PUBLIC_APP_URL est identique
  • Le webhook Stripe est configuré pour l'URL de production
  • Le DNS pointe vers Vercel
  • SSL est activé (automatique avec Vercel)
  • Les crons fonctionnent (vérifier les logs Vercel)
  • Le seed de production est exécuté (si nécessaire)
  • Le domaine email (Resend) est vérifié