DOCUMENTATION COMPLÈTE - Projet Format IT Nuxt3
Table des Matières
- Vue d'ensemble
- Architecture et Structure
- Technologies Utilisées
- Fonctionnalités Principales
- Configuration
- Scripts NPM
- APIs et Routes Serveur
- Composables
- Composants Vue
- Pages
- Base de Données Supabase
- Authentification et Sécurité
- Déploiement
- Guide de Démarrage
- Maintenance et Évolutions
1. Vue d'ensemble
Présentation du Projet
Format IT est une plateforme web moderne de formation professionnelle spécialisée dans les métiers de la tech. Le projet est développé avec Nuxt 3 (Vue 3 + TypeScript) et propose une interface complète pour :
- Les visiteurs : découvrir les formations, candidater, contacter l'organisme
- Les administrateurs : gérer les formations et les options de financement
Informations Techniques
- Framework : Nuxt 3.4.1
- Langage : TypeScript, Vue 3
- Styling : Tailwind CSS 6.14
- Base de données : Supabase (PostgreSQL)
- Email : Nodemailer + SMTP Google Workspace
- Déploiement : Vercel
- Port développement : 4000
Localisation
/mnt/d/save/projets/PERSO/nuxt/Format IT/format-it-nuxt32. Architecture et Structure
Arborescence du Projet
format-it-nuxt3/
├── assets/ # Ressources statiques CSS
│ └── css/
│ └── main.css # CSS global avec Tailwind
│
├── components/ # Composants Vue réutilisables
│ ├── AdminNav.vue # Navigation admin
│ ├── AppHeader.vue # En-tête avec navigation
│ ├── AppFooter.vue # Pied de page
│ ├── FormationCardSkeleton.vue
│ ├── FormationCardSkeletonHome.vue
│ └── PatternSvg.vue # Décoration SVG
│
├── composables/ # Logique métier réutilisable
│ └── useFormations.ts # Gestion des formations
│
├── layouts/ # Layouts Vue
│ └── default.vue # Layout par défaut
│
├── pages/ # Pages du site (routing automatique)
│ ├── index.vue # Accueil
│ ├── organisme.vue # À propos
│ ├── faq.vue # Questions fréquentes
│ ├── financement.vue # Options de financement
│ ├── candidature.vue # Formulaire candidature
│ ├── nous-contacter.vue # Formulaire contact
│ └── admin/
│ ├── index.vue # Connexion admin
│ ├── formations.vue # Gestion formations (CRUD)
│ └── financements.vue # Gestion financements
│
├── plugins/ # Plugins Nuxt
│ └── router-scroll.client.ts # Scroll automatique
│
├── public/ # Assets publics
│ ├── data/ # Données JSON
│ ├── file/ # Fichiers PDF
│ ├── fonts/ # Polices personnalisées
│ ├── icon/ # Icônes SVG
│ └── img/ # Images
│
├── server/ # Backend API Nitro
│ └── api/
│ ├── formations.get.ts
│ ├── formations.post.ts
│ ├── formations.delete.ts
│ ├── financements.get.ts
│ ├── financements.post.ts
│ ├── send-candidature.post.ts
│ ├── send-contact.post.ts
│ └── upload-image.post.ts
│
├── utils/ # Utilitaires
│ └── supabase.ts # Client Supabase
│
├── .env # Variables d'environnement (PRIVÉ)
├── .env.example # Template .env
├── nuxt.config.ts # Configuration Nuxt
├── tailwind.config.js # Configuration Tailwind
├── tsconfig.json # Configuration TypeScript
├── package.json # Dépendances
├── vercel.json # Configuration Vercel
├── supabase-setup.sql # Script SQL tables
└── DOCUMENTATION.md # Ce fichierPrincipe de Routing
Nuxt 3 utilise le file-based routing :
- Chaque fichier dans
/pagesdevient automatiquement une route - Exemple :
pages/organisme.vue→http://localhost:4000/organisme - Les dossiers créent des segments :
pages/admin/formations.vue→/admin/formations
3. Technologies Utilisées
Stack Technique
Frontend
| Technologie | Version | Usage |
|---|---|---|
| Nuxt 3 | 4.1.2 | Framework full-stack |
| Vue 3 | 3.5.22 | Framework UI |
| TypeScript | Latest | Typage statique |
| Tailwind CSS | 6.14 | Framework CSS utilitaire |
| Vue Router | 4.5.1 | Routing (inclus dans Nuxt) |
Backend
| Technologie | Version | Usage |
|---|---|---|
| Nitro | Inclus | Serveur backend Nuxt |
| Supabase JS | 2.48.1 | Client base de données |
| Nodemailer | 7.0.9 | Envoi d'emails |
Base de Données
| Technologie | Usage |
|---|---|
| Supabase | PostgreSQL managé + Storage |
| PostgreSQL | Base de données relationnelle |
Outils de Développement
- pnpm : Gestionnaire de paquets (10.12.1)
- ESLint : Linter JavaScript/TypeScript
- Git : Contrôle de version
Charte Graphique
Couleurs
/* Couleurs principales */
--brand: #F0D300; /* Jaune (boutons, accents) */
--text: #2A2C32; /* Gris foncé (texte) */
--bg: #FCFBF8; /* Beige clair (fond) */
/* Couleurs badges */
--badge-court: #B9CBFE; /* Bleu clair (cycle court) */
--badge-long: #B9FEC0; /* Vert clair (cycle long) */Typographie
- Police par défaut : Outfit (Google Fonts)
- Weights : 300, 400, 500, 600, 700
- Police titres/logo : Jumper PERSONAL USE ONLY
- Fichier :
public/fonts/Jumper.woff2
- Fichier :
4. Fonctionnalités Principales
Pour les Visiteurs
4.1 Consultation des Formations
- Page : Accueil (
/) - Fonctionnalités :
- Affichage dynamique des formations depuis Supabase
- Filtrage par type (cycle court / cycle long)
- Cartes avec badges colorés
- Détails : objectifs, durée, prérequis
4.2 Candidature
- Page :
/candidature - Processus :
- Étape 1 : Sélection d'une formation
- Radio buttons avec aperçu complet
- Badge, titre, descriptions, infos
- Étape 2 : Formulaire de candidature
- Champs obligatoires : Email *, Téléphone *
- Champs facultatifs : Société, Nom, Prénom, Ville, Adresse
- Validation : Envoi email à l'administrateur
- Confirmation : Page de remerciement
- Étape 1 : Sélection d'une formation
- API :
POST /api/send-candidature
4.3 Contact
- Page :
/nous-contacter - Champs :
- Obligatoires : Email *, Téléphone *
- Facultatifs : Société, Nom, Prénom, Ville, Adresse, Message
- API :
POST /api/send-contact
4.4 Financement
- Page :
/financement - Sections :
- Particuliers : CPF, Transitions Pro, Pôle Emploi, Auto-financement
- Entreprises : OPCO, Plan de développement, Auto-financement
- Affichage : Onglets avec cartes détaillées
- API :
GET /api/financements
4.5 FAQ
- Page :
/faq - Fonctionnalités :
- Accordéons animés
- Questions/réponses sur les formations
- Responsive mobile/desktop
4.6 À Propos
- Page :
/organisme - Contenu :
- Mission de Format IT
- 4 valeurs : Inclusion, Emploi, Pratique, Impact
- Certification Qualiopi
Pour les Administrateurs
4.7 Gestion des Formations
- Page :
/admin/formations - Fonctionnalités :
- Liste : Toutes les formations avec aperçu
- Créer : Nouvelle formation
- Type (court/long)
- Badge, titre, couleur
- Upload image vers Supabase Storage
- Descriptions multiples (titre + contenu)
- Infos multiples (titre + contenu)
- Modifier : Édition formulaire pré-rempli
- Supprimer : Suppression avec confirmation
- APIs :
GET /api/formationsPOST /api/formationsDELETE /api/formations?id={id}POST /api/upload-image
4.8 Gestion des Financements
- Page :
/admin/financements - Fonctionnalités :
- CRUD options de financement
- Filtre particuliers/entreprises
- Édition sections JSON
- API :
POST /api/financements
4.9 Authentification Admin
- Page :
/admin(connexion) - Mot de passe :
formatit2025 - Stockage : localStorage (
admin_authenticated) - Protection : Redirection si non authentifié
5. Configuration
5.1 Fichier nuxt.config.ts
export default defineNuxtConfig({
compatibilityDate: '2024-07-15',
devtools: { enabled: true },
// Modules
modules: ['@nuxtjs/tailwindcss'],
// CSS global
css: ['~/assets/css/main.css'],
// Port de développement
devServer: {
port: 4000
},
// Variables d'environnement
runtimeConfig: {
// Variables serveur (privées)
smtpHost: process.env.SMTP_HOST,
smtpPort: process.env.SMTP_PORT,
smtpSecure: process.env.SMTP_SECURE,
smtpUser: process.env.SMTP_USER,
smtpPass: process.env.SMTP_PASS,
smtpFrom: process.env.SMTP_FROM,
adminEmail: process.env.ADMIN_EMAIL,
// Variables publiques (accessibles client)
public: {
supabaseUrl: process.env.SUPABASE_URL,
supabaseKey: process.env.SUPABASE_KEY
}
},
// Meta et SEO
app: {
head: {
title: 'Format IT - Transformez votre avenir',
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ name: 'description', content: 'Format IT - Organisme de formation professionnelle' }
],
link: [
{ rel: 'icon', type: 'image/png', href: '/img/format-it-logo.png' },
{ rel: 'preconnect', href: 'https://fonts.googleapis.com' },
{
rel: 'stylesheet',
href: 'https://fonts.googleapis.com/css2?family=Outfit:wght@300;400;500;600;700&display=swap'
}
]
}
}
})5.2 Variables d'Environnement (.env)
⚠️ IMPORTANT : Le fichier .env ne doit JAMAIS être commité sur Git.
# Supabase
SUPABASE_URL=https://kfvjidatbjieiuqpzvix.supabase.co
SUPABASE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
# SMTP Google Workspace
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_SECURE=false
SMTP_USER=Administratif@format-it.com
SMTP_PASS=jozh bojp kxqk kbof
SMTP_FROM=Administratif@format-it.com
ADMIN_EMAIL=Administratif@format-it.comPour créer votre .env :
cp .env.example .env
# Éditer avec vos vraies credentials5.3 Configuration Tailwind (tailwind.config.js)
export default {
content: [
"./components/**/*.{js,vue,ts}",
"./layouts/**/*.vue",
"./pages/**/*.vue",
"./plugins/**/*.{js,ts}",
"./app.vue",
"./error.vue"
],
theme: {
extend: {
colors: {
'brand': '#F0D300', // Jaune
'text': '#2A2C32', // Gris/Noir
'bg': '#FCFBF8' // Beige clair
},
fontFamily: {
'jumper': ['Jumper PERSONAL USE ONLY', 'Arial', 'sans-serif'],
'outfit': ['Outfit', 'sans-serif']
}
}
},
plugins: []
}6. Scripts NPM
6.1 Scripts Disponibles
{
"scripts": {
"build": "nuxt build", // Compilation production
"dev": "nuxt dev", // Serveur de développement
"generate": "nuxt generate", // Génération statique
"preview": "nuxt preview", // Preview du build
"postinstall": "nuxt prepare" // Auto-exec après install
}
}6.2 Commandes Courantes
# Installation des dépendances
pnpm install
# Lancer le serveur de développement
pnpm dev
# → http://localhost:4000
# Build pour la production
pnpm build
# Tester le build en local
pnpm preview
# Script de démarrage rapide
./start.sh7. APIs et Routes Serveur
7.1 Architecture des APIs
Les APIs suivent la convention file-based routing de Nitro :
- Fichier :
server/api/[nom].[method].ts - URL :
http://localhost:4000/api/[nom] - Méthodes : GET, POST, PUT, DELETE
7.2 Endpoints Disponibles
GET /api/formations
Fichier : server/api/formations.get.ts
Description : Récupère toutes les formations depuis Supabase
Réponse :
Formation[] // Tableau trié par IDCode exemple :
const response = await fetch('/api/formations')
const formations = await response.json()POST /api/formations
Fichier : server/api/formations.post.ts
Description : Crée ou met à jour des formations
Requête :
Formation | Formation[]Logique :
- Si
idexiste → UPDATE - Sinon → INSERT avec auto-génération d'ID
Réponse :
{
success: boolean,
data?: Formation[]
}DELETE /api/formations
Fichier : server/api/formations.delete.ts
Description : Supprime une formation
Paramètres : Query ?id={id}
Réponse :
{
success: boolean
}GET /api/financements
Fichier : server/api/financements.get.ts
Description : Récupère les options de financement
Réponse :
{
particuliers: FinancementOption[],
entreprises: FinancementOption[]
}POST /api/financements
Fichier : server/api/financements.post.ts
Description : Admin - Crée/modifie options de financement
Requête :
{
particuliers: FinancementOption[],
entreprises: FinancementOption[]
}POST /api/send-candidature
Fichier : server/api/send-candidature.post.ts
Description : Envoie un email de candidature à l'admin
Requête :
{
formData: {
societe?: string,
nom?: string,
prenom?: string,
ville?: string,
adresse?: string,
telephone: string, // Requis
email: string // Requis
},
formation: {
badge: string,
titre: string
}
}Validation :
- Email et téléphone obligatoires
- Validation format email
Fonctionnement :
- Validation des champs requis
- Configuration Nodemailer avec SMTP
- Génération template HTML élégant
- Envoi à
ADMIN_EMAIL - Retour
{ success: true, messageId }
Template Email :
- En-tête Format IT avec logo
- Section formation sélectionnée (badge + titre)
- Informations candidat (affiche uniquement les champs remplis)
- Footer avec date d'envoi
POST /api/send-contact
Fichier : server/api/send-contact.post.ts
Description : Envoie un email de contact
Requête :
{
societe?: string,
nom?: string,
prenom?: string,
ville?: string,
adresse?: string,
telephone: string, // Requis
email: string, // Requis
message?: string
}Fonctionnement : Similaire à send-candidature
Template Email :
- Informations de contact (uniquement champs remplis)
- Message (si présent)
- Reply-to : email du visiteur
POST /api/upload-image
Fichier : server/api/upload-image.post.ts
Description : Upload une image vers Supabase Storage
Requête : FormData avec file
Fonctionnement :
- Validation du fichier (type, taille)
- Génération nom unique :
formation-{timestamp}.{ext} - Upload dans bucket
formation-images - Retour URL publique
Réponse :
{
success: boolean,
url?: string, // URL publique Supabase
error?: string
}Exemple d'utilisation :
const formData = new FormData()
formData.append('file', imageFile)
const response = await fetch('/api/upload-image', {
method: 'POST',
body: formData
})
const { url } = await response.json()8. Composables
8.1 useFormations.ts
Fichier : composables/useFormations.ts
Description : Gestion centralisée des formations avec Composition API
État Global
const formations = ref<Formation[]>([])
const loading = ref(false)
const error = ref<string | null>(null)Type Formation
interface Formation {
id: number
type: 'court' | 'long'
badge: string // "Cycle court" ou "Cycle long"
badgeColor: string // Couleur hex
titre: string
image: string // URL Supabase
descriptions: Array<{
titre: string
contenu: string
}>
infos: Array<{
titre: string
contenu: string
}>
}Méthodes
loadFormations()
async loadFormations(): Promise<void>- Charge toutes les formations depuis l'API
- Met à jour
formations.value - Gère les états
loadingeterror
Usage :
const { loadFormations, formations } = useFormations()
await loadFormations()getFormationsByType()
getFormationsByType(type: 'court' | 'long' | 'tout'): Formation[]- Filtre les formations par type
'tout': retourne toutes les formations
Usage :
const formationsCourt = getFormationsByType('court')saveFormations()
async saveFormations(formationsToSave: Formation[]): Promise<{
success: boolean
error?: string
}>- Sauvegarde un tableau de formations
- Appelle
POST /api/formations
addFormation()
async addFormation(formation: Omit<Formation, 'id'>): Promise<{
success: boolean
error?: string
}>- Ajoute une nouvelle formation
- ID auto-généré
updateFormation()
async updateFormation(
id: number,
updates: Partial<Formation>
): Promise<{
success: boolean
error?: string
}>- Met à jour une formation existante
deleteFormation()
async deleteFormation(id: number): Promise<{
success: boolean
error?: string
}>- Supprime une formation
- Appelle
DELETE /api/formations?id={id}
9. Composants Vue
9.1 AppHeader.vue
Description : En-tête du site avec navigation
Fonctionnalités :
- Logo Format IT
- Navigation desktop : Accueil, Organisme, Financement, Candidatez (CTA)
- Menu hamburger mobile avec animation
- Sticky header avec backdrop blur
Props : Aucune
9.2 AppFooter.vue
Description : Pied de page du site
Sections :
- Newsletter : Formulaire d'inscription
- Coordonnées : Adresse, téléphone
- Réseaux sociaux : Facebook, Twitter, LinkedIn
- Liens : CGV, Financement, Réclamation, FAQ, Contact, Certificat
- Certification : Logo Qualiopi
9.3 AdminNav.vue
Description : Navigation admin
Liens :
- Formations
- Financements
- Déconnexion
Visibilité : Uniquement si authentifié
9.4 FormationCardSkeleton.vue
Description : Placeholder animé pendant le chargement
Utilisation :
<FormationCardSkeleton v-for="n in 6" :key="n" />9.5 PatternSvg.vue
Description : Décoration SVG pattern en arrière-plan
Fonctionnalités :
- Pattern répété
- Mix-blend-mode: darken
- Position absolute
10. Pages
10.1 Pages Publiques
/ - Accueil
Fichier : pages/index.vue
Sections :
- Hero avec titre principal "Formez-vous... au monde de demain"
- Section testimonies avec cartes flottantes
- CTA "Contacter-nous"
/organisme - À Propos
Fichier : pages/organisme.vue
Contenu :
- Mission de l'organisme
- 4 valeurs : Inclusion, Emploi, Pratique, Impact
- Certification Qualiopi
/faq - Questions Fréquentes
Fichier : pages/faq.vue
Fonctionnalités :
- Accordéons animés avec transitions smooth
- Questions sur certifications, rythme, prérequis
- Responsive
/financement - Options de Financement
Fichier : pages/financement.vue
Fonctionnalités :
- Onglets : Particuliers / Entreprises
- Cartes dynamiques depuis API
- Détails : Pourquoi, Fonctionnement, Avantages
- Numérotation avec gradient
/candidature - Candidature
Fichier : pages/candidature.vue
Processus Multi-Steps :
Étape 1 : Sélection Formation
- Cartes formations avec radio buttons
- Badge, titre, descriptions, infos
- Validation : formation sélectionnée
Étape 2 : Formulaire
- Champs obligatoires : Email *, Téléphone *
- Champs facultatifs : Société, Nom, Prénom, Ville, Adresse
- Validation avant soumission
Étape 3 : Confirmation
- Message de remerciement
- Illustration
- Bouton "Continuer ma navigation"
Gestion d'État :
const formData = ref({
societe: '',
nom: '',
prenom: '',
ville: '',
adresse: '',
telephone: '',
email: ''
})
const selectedFormation = ref<number | null>(null)
const formSubmitted = ref(false)/nous-contacter - Contact
Fichier : pages/nous-contacter.vue
Formulaire :
- Champs obligatoires : Email *, Téléphone *
- Champs facultatifs : Société, Nom, Prénom, Ville, Adresse, Message
- Validation email
- Message d'erreur dynamique
- Page de confirmation
10.2 Pages Admin
/admin - Connexion
Fichier : pages/admin/index.vue
Fonctionnalités :
- Formulaire de connexion simple
- Mot de passe :
formatit2025 - Stockage :
localStorage.setItem('admin_authenticated', 'true') - Redirection automatique si déjà authentifié
/admin/formations - Gestion Formations
Fichier : pages/admin/formations.vue
Fonctionnalités :
Liste :
- Affichage de toutes les formations
- Image preview
- Badge et titre
- Boutons Modifier / Supprimer
Modal Ajout/Édition :
- Select type (court/long)
- Input titre, badge
- Color picker pour badge
- Upload image :
- Sélection fichier
- Preview
- Upload vers Supabase Storage
- URL générée automatiquement
- Descriptions :
- Champs dynamiques (titre + contenu)
- Boutons Ajouter / Supprimer
- Infos :
- Champs dynamiques (titre + contenu)
- Boutons Ajouter / Supprimer
- Validation formulaire
- Sauvegarde via
useFormations()
Modal Suppression :
- Confirmation avant suppression
- Appel
deleteFormation(id)
/admin/financements - Gestion Financements
Fichier : pages/admin/financements.vue
Fonctionnalités :
- CRUD options financement
- Filtre particuliers/entreprises
- Édition sections JSON
- Toggle visibilité
11. Base de Données Supabase
11.1 Configuration
URL : https://kfvjidatbjieiuqpzvix.supabase.co
Client : utils/supabase.ts
import { createClient } from '@supabase/supabase-js'
const config = useRuntimeConfig()
export const supabase = createClient(
config.public.supabaseUrl,
config.public.supabaseKey
)11.2 Tables
Table formations
Structure :
CREATE TABLE formations (
id BIGINT PRIMARY KEY,
type TEXT NOT NULL, -- 'court' ou 'long'
badge TEXT NOT NULL, -- "Cycle court" / "Cycle long"
badge_color TEXT NOT NULL, -- Couleur hex
titre TEXT NOT NULL,
image TEXT NOT NULL, -- URL Supabase Storage
descriptions JSONB NOT NULL, -- [{titre, contenu}, ...]
infos JSONB NOT NULL, -- [{titre, contenu}, ...]
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);Index :
typecreated_at
RLS (Row Level Security) :
- Read : Public
- Write/Update/Delete : Open (⚠️ À sécuriser)
Exemple de données :
{
"id": 1,
"type": "court",
"badge": "Cycle court",
"badge_color": "#B9CBFE",
"titre": "Business Developer initiation à l'IA",
"image": "https://kfvjidatbjieiuqpzvix.supabase.co/storage/v1/object/public/formation-images/formation-1234567890.png",
"descriptions": [
{
"titre": "Objectifs",
"contenu": "Intégrer l'IA dans le cycle de vente"
}
],
"infos": [
{
"titre": "Durée",
"contenu": "14 heures (2 jours)"
}
]
}Table financements
Structure :
CREATE TABLE financements (
id SERIAL PRIMARY KEY,
type TEXT NOT NULL, -- 'particuliers' ou 'entreprises'
numero TEXT NOT NULL, -- '1', '2', '3', '4'
visible BOOLEAN DEFAULT true,
titre TEXT NOT NULL, -- "CPF", "OPCO", etc.
sections JSONB NOT NULL, -- [{titre, contenu}, ...]
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);Exemple de données :
{
"id": 1,
"type": "particuliers",
"numero": "1",
"visible": true,
"titre": "CPF",
"sections": [
{
"titre": "Pourquoi choisir le CPF ?",
"contenu": "Le Compte Personnel de Formation..."
},
{
"titre": "Comment ça fonctionne ?",
"contenu": "Connectez-vous à votre espace..."
}
]
}11.3 Storage
Bucket : formation-images
Configuration :
- Public : Oui
- Max file size : 5MB
- Allowed types : image/png, image/jpeg, image/webp
URL Pattern :
https://kfvjidatbjieiuqpzvix.supabase.co/storage/v1/object/public/formation-images/{filename}12. Authentification et Sécurité
12.1 Système Actuel
Admin Login
- Page :
/admin - Méthode : Mot de passe simple
- Credentials :
formatit2025 - Stockage :
localStorage.setItem('admin_authenticated', 'true')
Protection des Routes
// Dans pages/admin/*.vue
onMounted(() => {
const isAuthenticated = localStorage.getItem('admin_authenticated')
if (!isAuthenticated) {
navigateTo('/admin')
}
})12.2 Problèmes de Sécurité Identifiés
⚠️ ATTENTION : Le système actuel présente des vulnérabilités :
- Mot de passe en clair dans le code source
- localStorage facilement modifiable via DevTools
- RLS Supabase trop permissif (INSERT/UPDATE/DELETE open)
- Pas de JWT ou token serveur
- Variables sensibles dans
vercel.json
12.3 Recommandations de Sécurité
Court terme
// 1. Ajouter middleware Nuxt
// server/middleware/auth.ts
export default defineEventHandler((event) => {
const path = event.node.req.url
if (path?.startsWith('/admin') && path !== '/admin') {
const auth = getCookie(event, 'admin_token')
if (!auth) {
return sendRedirect(event, '/admin')
}
}
})
// 2. Utiliser httpOnly cookies au lieu de localStorage
const token = useCookie('admin_token', { httpOnly: true })Long terme
- Implémenter Supabase Auth avec email/password
- Utiliser JWT tokens avec expiration
- Restreindre RLS policies :sql
-- Exemple RLS restrictif CREATE POLICY "Admin only write" ON formations FOR ALL USING (auth.role() = 'authenticated'); - Déplacer variables sensibles vers Vercel Secrets
- Implémenter RBAC (Role-Based Access Control)
13. Déploiement
13.1 Configuration Vercel
Fichier : vercel.json
{
"buildCommand": "pnpm build",
"outputDirectory": ".output/public",
"devCommand": "pnpm dev",
"installCommand": "pnpm install",
"framework": "nuxtjs"
}13.2 Variables d'Environnement Vercel
Dashboard Vercel → Settings → Environment Variables
Ajouter :
SUPABASE_URLSUPABASE_KEYSMTP_HOSTSMTP_PORTSMTP_SECURESMTP_USERSMTP_PASSSMTP_FROMADMIN_EMAIL
⚠️ Important : Ne jamais commiter .env sur Git
13.3 Processus de Déploiement
Via GitHub (Recommandé)
Push sur GitHub
bashgit add . git commit -m "Deploy to Vercel" git push origin mainVercel détecte automatiquement
- Build avec
pnpm build - Deploy serverless functions Nitro
- Build avec
URL de production
- Vercel génère automatiquement
- Custom domain configurable
Via CLI Vercel
# Installation
npm i -g vercel
# Login
vercel login
# Deploy
vercel
# Production
vercel --prod13.4 Build Output
.output/
├── public/ # Assets statiques
├── server/ # Fonctions serverless Nitro
└── nitro.json # Config Nitro13.5 Vérifications Post-Déploiement
✅ Checklist :
- [ ] Variables d'environnement configurées
- [ ] Connexion Supabase fonctionnelle
- [ ] Envoi d'emails opérationnel
- [ ] Upload d'images vers Supabase Storage
- [ ] Admin login fonctionnel
- [ ] Toutes les pages accessibles
- [ ] Responsive mobile/desktop
- [ ] Performance Lighthouse > 90
14. Guide de Démarrage
14.1 Prérequis
- Node.js : v18 ou supérieur
- pnpm : v8 ou supérieur
- Git : Pour le versioning
- Compte Supabase : Pour la base de données
- Compte Google Workspace : Pour SMTP (optionnel)
14.2 Installation
# 1. Cloner/Accéder au projet
cd /mnt/d/save/projets/PERSO/nuxt/Format\ IT/format-it-nuxt3
# 2. Installer pnpm (si nécessaire)
npm install -g pnpm
# 3. Installer les dépendances
pnpm install
# 4. Créer le fichier .env
cp .env.example .env
# 5. Éditer .env avec vos credentials
nano .env # ou votre éditeur préféré14.3 Configuration Supabase
Créer un Projet Supabase
- Aller sur supabase.com
- Créer un nouveau projet
- Copier
URLetanon key - Coller dans
.env
Créer les Tables
# Exécuter le script SQL
# Dans Supabase Dashboard → SQL Editor
# Copier le contenu de supabase-setup.sql et exécuterCréer le Bucket Storage
- Storage → New bucket
- Nom :
formation-images - Public : ✅ Oui
- Allowed types : image/*
14.4 Configuration SMTP (Optionnel)
Google Workspace
- Activer l'authentification à deux facteurs
- Générer un "Mot de passe d'application"
- Copier dans
.env→SMTP_PASS
Autre fournisseur
- Mettre à jour
SMTP_HOST,SMTP_PORT, etc.
14.5 Lancer le Projet
# Démarrage dev server
pnpm dev
# Ouvrir dans le navigateur
# http://localhost:400014.6 Accès Admin
URL : http://localhost:4000/admin
Mot de passe : formatit202515. Maintenance et Évolutions
15.1 Tâches de Maintenance
Quotidiennes
- Vérifier les emails de candidature/contact
- Surveiller les logs Vercel
Hebdomadaires
- Backup Supabase (automatique)
- Vérifier les performances (Lighthouse)
Mensuelles
- Mettre à jour les dépendances :bash
pnpm update - Réviser les formations actives
- Analyser les statistiques (Google Analytics)
15.2 Évolutions Futures Suggérées
Fonctionnalités
Niveau 1 (Court terme)
- [ ] Authentification admin sécurisée (Supabase Auth)
- [ ] Dashboard statistiques (candidatures, visites)
- [ ] Export CSV des candidatures
- [ ] Système de notifications email admin
- [ ] Recherche/filtres avancés formations
- [ ] Newsletter fonctionnelle (intégration Mailchimp/Brevo)
Niveau 2 (Moyen terme)
- [ ] Espace candidat avec suivi
- [ ] Calendrier des sessions
- [ ] Paiement en ligne (Stripe)
- [ ] Blog/Actualités
- [ ] Témoignages dynamiques
- [ ] Multi-langue (i18n)
Niveau 3 (Long terme)
- [ ] Plateforme e-learning intégrée
- [ ] Vidéos de présentation formations
- [ ] Chat support en ligne
- [ ] Mobile app (React Native/Flutter)
- [ ] API publique pour partenaires
Améliorations Techniques
Performance
- [ ] Optimisation images (WebP, lazy loading)
- [ ] Code splitting avancé
- [ ] PWA (Progressive Web App)
- [ ] CDN pour assets statiques
SEO
- [ ] Meta tags dynamiques par page
- [ ] Schema.org markup
- [ ] Sitemap XML
- [ ] Open Graph pour réseaux sociaux
Sécurité
- [ ] Middleware auth robuste
- [ ] Rate limiting APIs
- [ ] CSRF protection
- [ ] Headers sécurité (CSP, HSTS)
- [ ] Audit sécurité régulier
Tests
- [ ] Tests unitaires (Vitest)
- [ ] Tests E2E (Playwright)
- [ ] CI/CD GitHub Actions
- [ ] Coverage > 80%
15.3 Gestion des Bugs
Processus
- Reproduction : Documenter les étapes
- Priorité : Critical / High / Medium / Low
- Fix : Créer une branche dédiée
- Test : Vérifier localement
- Deploy : Merge + déploiement
Outils Recommandés
- Sentry : Monitoring erreurs
- LogRocket : Session replay
- GitHub Issues : Tracking bugs
15.4 Documentation du Code
Conventions
Nommage :
// Composants : PascalCase
AppHeader.vue
// Pages : kebab-case
nous-contacter.vue
// Variables : camelCase
const formData = ref({})
// Constantes : UPPER_SNAKE_CASE
const API_BASE_URL = '/api'Commentaires :
// ✅ Bon
/**
* Envoie un email de candidature à l'admin
* @param formData - Données du formulaire
* @param formation - Formation sélectionnée
* @returns Promise avec status et messageId
*/
async function sendCandidature(formData, formation) {}
// ❌ Éviter
// Fonction qui envoie email
async function sendCandidature() {}15.5 Contacts et Support
Équipe Projet
- Développeur : [Votre Nom]
- Client : Format IT
- Email Admin : Administratif@format-it.com
Ressources
- Documentation Nuxt : https://nuxt.com/docs
- Documentation Supabase : https://supabase.com/docs
- Documentation Tailwind : https://tailwindcss.com/docs
- Documentation Vue 3 : https://vuejs.org
Annexes
A. Glossaire
- Nuxt : Framework Vue.js full-stack
- Nitro : Moteur serveur de Nuxt
- Supabase : Backend-as-a-Service (PostgreSQL + Storage)
- RLS : Row Level Security (sécurité au niveau ligne)
- SSR : Server-Side Rendering
- SMTP : Simple Mail Transfer Protocol
- CRUD : Create, Read, Update, Delete
- JWT : JSON Web Token
B. Commandes Git
# Status
git status
# Commit
git add .
git commit -m "feat: ajouter nouvelle fonctionnalité"
# Push
git push origin main
# Pull
git pull origin main
# Branches
git checkout -b feature/nouvelle-fonctionnalite
git merge feature/nouvelle-fonctionnaliteC. Dépannage
Le serveur ne démarre pas
# Vérifier Node.js
node -v # Doit être >= 18
# Nettoyer node_modules
rm -rf node_modules .nuxt
pnpm install
# Vérifier .env
cat .envErreur de connexion Supabase
- Vérifier
SUPABASE_URLetSUPABASE_KEY - Tester dans Supabase Dashboard
- Vérifier les RLS policies
Emails non envoyés
- Vérifier credentials SMTP
- Tester avec un email de test
- Consulter les logs Vercel
Version : 1.0 Date : Janvier 2025 Auteur : Équipe Format IT
Cette documentation est un document vivant. N'hésitez pas à la mettre à jour au fur et à mesure des évolutions du projet.
