Lovable + Supabase : Créer un espace d’administration (backend) pour gérer l’ensemble de votre site web
Votre site web est connecté à une base de données… mais comment permettre à un administrateur de gérer facilement son contenu sans modifier le code ?
Dans cette séance, vous allez apprendre à créer un espace d’administration complet avec Lovable et Supabase pour piloter votre site web depuis un véritable backend.
Vous allez découvrir comment :
- Créer une interface d’administration personnalisée
- Gérer les contenus de votre site depuis un tableau de bord
- Ajouter, modifier et supprimer des informations dynamiques
- Connecter l’administration à votre base de données Supabase
- Transformer un site généré par IA en une solution professionnelle et évolutive
Une étape essentielle pour rendre votre site totalement autonome, maintenable et prêt pour un usage réel.
Objectif : créer un backend d’administration permettant de contrôler l’ensemble de votre site web sans toucher au code.
Prompt :
Implémenter un système d’administration complet avec Supabase, sans casser le design public existant, en rendant tout le contenu du site modifiable depuis un back-office sécurisé.
Fonctionnalités à implémenter
1. Authentification admin
- Créer une page `/admin/login` (email + mot de passe).
- Créer un espace admin protégé sous `/admin/` (dashboard, gestion du contenu).
- Seuls les utilisateurs avec le rôle `admin` peuvent accéder au back-office.
- Redirection automatique vers `/admin/login` si non authentifié.
- Déconnexion sécurisée.
- Gestion des sessions via Supabase Auth (JWT côté serveur Supabase, pas de logique d’auth maison côté client).
2. Gestion du contenu (CRUD complet)
Permettre d’ajouter, modifier et supprimer dynamiquement :
Contenu textuel
- Titres, sous-titres, paragraphes
- Coordonnées (téléphone, email)
- Textes du footer
- Métadonnées SEO (title, description, og:)
etc..
Contenu visuel
- Logo
- Image
Structure des pages
- Sections de la page d’accueil
- Possibilité de :
- réordonner les sections (ordre d’affichage)
- activer / désactiver une section
- modifier le contenu de chaque section
- Prévoir une structure extensible pour ajouter d’autres pages plus tard (ex. `/about`, `/programme`)
CRUD
- Permet d’ajouter, de modifier et de supprimer des informations de manière dynamique et intuitive.
3. Interface admin
Créer un dashboard admin moderne, cohérent avec shadcn/ui :
- `/admin` — tableau de bord (aperçu rapide)
- `/admin/sections` — gestion des sections de page (ajouter, modifier supprimer)
- `/admin/settings` — paramètres globaux (dates, contact, SEO, URL inscription)
- `/admin/media` — upload et gestion des images
Chaque écran doit inclure :
- formulaires de création / édition
- confirmation avant suppression
- messages de succès / erreur (toasts)
- états de chargement
- validation des champs (Zod + react-hook-form)
4. Site public dynamique
- Il faut que l’intégralité du contenu du site (textes, images, vidéos, icônes, liens, paramètres et tout autre élément) soit entièrement modifiable depuis le panneau d’administration.
- Ne laisse aucun contenu statique ni aucune valeur codée en dur dans le code. Tout le contenu doit être chargé dynamiquement depuis la base de données et géré via l’interface d’administration, afin de pouvoir être modifié sans intervenir sur le code source.
- Conserver le design et les classes CSS existantes.
- Afficher un fallback élégant si la base est vide ou inaccessible.
- Utiliser React Query pour le cache et le rafraîchissement.
Architecture Supabase
Base de données (PostgreSQL)
Proposer et implémenter un schéma clair, par exemple :
- `site_settings` — paramètres globaux (clé/valeur ou colonnes dédiées)
- `page_sections` — sections de page (slug, titre, ordre, visible, contenu JSON)
- `admin_profiles` — user_id (FK auth.users), role, display_name
Inclure :
- `created_at`, `updated_at`
- contraintes d’intégrité
- index utiles
- migrations SQL dans un dossier `supabase/migrations/`
Storage Supabase
- Bucket `public-assets` pour images publiques (logo, hero, équipe, partenaires)
- Bucket `admin-uploads` si nécessaire, avec règles strictes
- Validation : types MIME (jpg, png, webp), taille max (ex. 5 Mo)
- Noms de fichiers sécurisés (UUID, pas de noms utilisateur bruts)
Auth
- Créer les admins uniquement via Supabase Auth (pas d’inscription publique)
- Désactiver l’inscription publique (`signUp` côté client interdit)
- Rôle `admin` stocké dans `admin_profiles` ou via `app_metadata` / custom claims
- Vérifier le rôle admin à chaque accès aux routes et opérations sensibles
Règles de sécurité STRICTES (obligatoires)
Secrets et variables d’environnement
- JAMAIS exposer la clé `service_role` dans le frontend.
- JAMAIS committer `.env` ou secrets dans Git.
- Fournir un `.env.example` avec :
- `VITE_SUPABASE_URL`
- `VITE_SUPABASE_ANON_KEY` (seule clé publique autorisée côté client)
- Les secrets serveur (`SUPABASE_SERVICE_ROLE_KEY`, etc.) uniquement dans :
- Supabase Edge Functions
- ou un backend serveur séparé (si créé)
- jamais dans des variables `VITE_`
Row Level Security (RLS)
Activer RLS sur toutes les tables et définir des policies explicites :
- Lecture publique : uniquement sur contenu publié/actif (`is_active = true`, `is_visible = true`)
- Écriture : uniquement pour utilisateurs authentifiés avec rôle `admin`
- Suppression : uniquement admin
- admin_profiles : lecture limitée à l’utilisateur connecté ou admin
- Aucune policy `USING (true)` sans restriction sur tables sensibles
Instructions Supabase / RLS à respecter dans ce projet :
- RLS est activé automatiquement sur toute nouvelle table du schéma public via un event trigger (ensure_rls). Ne jamais désactiver cette sécurité ni faire ALTER TABLE ... DISABLE ROW LEVEL SECURITY sauf si je te le demande explicitement pour une table de référence publique (ex: liste de pays, catégories).
- Chaque CREATE TABLE doit être immédiatement suivi d’au moins une CREATE POLICY dans la même migration. Ne jamais créer une table sans définir ses policies dans la foulée — sinon elle sera inaccessible via l’API (résultats vides, sans erreur).
- Policies par défaut à appliquer selon le type de données :
- Données liées à un utilisateur (ex: user_id) → policy basée sur auth.uid() = user_id, pour SELECT, INSERT, UPDATE, DELETE séparément.
- Données de référence publiques en lecture seule → CREATE POLICY ... FOR SELECT TO anon, authenticated USING (true), sans policy d’écriture.
- Données multi-tenant (équipe/organisation) → policy basée sur l’appartenance à l’équipe, pas de jointure lourde dans la policy (utiliser une fonction SECURITY DEFINER si besoin de performance).
- Toujours indexer les colonnes utilisées dans les policies (user_id, team_id, etc.) pour éviter les scans séquentiels.
- Ne jamais utiliser la service_role key côté client/frontend. Elle contourne RLS entièrement et ne doit être utilisée que côté serveur (edge functions, backend), jamais dans le code exposé au navigateur.
- Pour UPDATE, toujours définir à la fois USING et WITH CHECK, pas seulement l’un des deux.
Authentification côté serveur
- La connexion doit passer par Supabase Auth (pas de vérification mot de passe en JS pur).
- Ne jamais stocker de mot de passe en clair.
- Utiliser `supabase.auth.signInWithPassword()` côté client, mais la validation du JWT et les permissions doivent être enforceées par RLS côté Supabase.
- Pour toute opération sensible (création d’admin, envoi d’email, logique métier critique), utiliser des Supabase Edge Functions avec la `service_role` key côté serveur uniquement.
Protection des routes frontend
- Créer un composant `ProtectedRoute` qui :
- vérifie la session Supabase
- vérifie le rôle admin
- redirige vers `/admin/login` si échec
- Ne pas se fier uniquement au masquage UI : la sécurité réelle = RLS + Auth Supabase.
Upload de fichiers
- Upload réservé aux admins authentifiés
- Policies Storage : lecture publique pour assets du site, écriture/suppression admin only
- Scanner/valider type et taille avant upload
- Pas d’exécution de fichiers uploadés
Autres
- Protéger contre XSS : échapper/sanitizer le contenu riche si applicable
- Rate limiting sur login (via Supabase ou Edge Function)
- Logs d’audit optionnels : `content_audit_log` (qui a modifié quoi, quand)
- HTTPS obligatoire en production
- Headers de sécurité recommandés pour le déploiement
Décisions prises à l’avance (ne pas me redemander)
Méthode de mise en œuvre
- Procède par étapes, pas tout en un bloc.
- Commence par Étape 1 : Auth + Settings globaux.
- Avant de commencer, donne-moi la liste complète des étapes prévues (ex. Étape 2 : sections éditables + média, Étape 3 : audit log, etc.) pour que j’aie une vue d’ensemble.
- N’attends pas ma validation entre chaque étape technique mineure (nommage de tables, structure de dossiers, choix de libellés) tant que les règles de sécurité définies plus haut sont respectées. Demande-moi seulement une confirmation avant d’exécuter une migration SQL ou une action irréversible.
Premier compte administrateur
- Adresse email du premier admin : "Ajouter Votre email"
- Crée ce compte directement via une migration SQL, avec un mot de passe temporaire aléatoire.
- Je définirai mon propre mot de passe ensuite via « Mot de passe oublié » depuis `/admin/login`. Pas besoin de me redemander l’email.
Confirmation d’email (Auth)
- Désactive l’option « Confirm email » dans Supabase (Authentication → Providers → Email) pour permettre une connexion admin instantanée en développement.
- Rappelle-moi explicitement, à la toute fin de la dernière étape (avant mise en production), de réactiver cette option pour la sécurité.
Format de tes réponses
- Après chaque étape terminée, donne-moi un résumé court : ce qui a été fait, ce qu’il me reste à faire manuellement (ex. côté dashboard Supabase), et la commande/action pour tester que ça fonctionne.
- Si un choix impacte directement la sécurité des données (ex. policy RLS ambiguë, exposition d’une clé), arrête-toi et demande-moi avant de continuer — c’est la seule exception à "ne pas me redemander".
Dites-nous en commentaire : quelles sections de votre site aimeriez-vous gérer depuis un espace d’administration ?