new-term-radar
Daily radar for new AI terms: names of new models, products and repos, caught on X, Hugging Face, GitHub and sitemaps before keyword tools list them.
翻译准备中
尚未检测到更新。GitHub 发布版本后会显示在这里。
个人 GitHub 账号下公开仓库的所有者可以登录并验证所有权,自行管理介绍,无需管理员批准。
登录并生成验证文件,在 30 分钟内将其提交到此仓库的默认分支。其他分支或分叉仓库中的文件无效。然后在下方检查文件,即可无需管理员批准直接管理项目。请保留文件以维持管理权限。
如需登录,将前往登录页面。登录后请回到此处,再次点击所选的验证按钮。
在项目文件夹中运行 /nomorevibe verify,即可验证所有权并自行管理介绍。
一分钟完成验证正在加载完整 README。 以下为已保存的摘录。
🚀 Landing Page Generator — CMS Multi-École Plateforme de création et gestion de landing pages pour un réseau d'écoles supérieures (EFAP, Brassart, ICART, etc.), avec intégration Salesforce Marketing Cloud (SFMC) et intelligence artificielle. • Vue d'ensemble • Architecture technique • Prérequis & Installation • Configuration • Structure du projet • Fonctionnalités implémentées • Flux de sauvegarde des pages • API Reference • Base de données — Schéma • Intégration SFMC • Intelligence artificielle • Dashboard CMS • Éditeur de pages • Gestion des écoles查看完整 README ↗
Plateforme de création et gestion de landing pages pour un réseau d'écoles supérieures (EFAP, Brassart, ICART, etc.), avec intégration Salesforce Marketing Cloud (SFMC) et intelligence artificielle.
Le Landing Page Generator est un CMS headless conçu pour les consultants marketing du groupe Reetain. Il permet de :
┌─────────────────────────────────────────────────────────┐
│ FRONTEND (Browser) │
│ │
│ ┌──────────────────┐ ┌───────────────────────────┐ │
│ │ school-selector │ │ pages-dashboard.html │ │
│ │ .html │ │ (CMS Dashboard) │ │
│ └──────────────────┘ └───────────────────────────┘ │
│ │
│ ┌──────────────────────────────────────────────────┐ │
│ │ index.html (GrapesJS Editor) │ │
│ │ js/app.js · js/ai-assistant.js · js/form-... │ │
│ └──────────────────────────────────────────────────┘ │
└─────────────────────────┬───────────────────────────────┘
│ HTTP (fetch API)
┌─────────────────────────▼───────────────────────────────┐
│ BACKEND (server.js) │
│ Node.js HTTP natif — Port 8000 │
│ │
│ Routes API : │
│ /api/save /api/pages /api/schools │
│ /api/components /api/forms /api/content/* │
│ /api/ai/* /api/sfmc/* /sitemap.xml │
│ /preview/:name │
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────────┐ │
│ │ api/content │ │ api/schools │ │ lib/sfmc.js │ │
│ │ .js │ │ .js │ │ (SFMC Client) │ │
│ └─────────────┘ └─────────────┘ └─────────────────┘ │
│ │
│ ┌──────────────────┐ ┌──────────────────────────────┐ │
│ │ lib/minifier.js │ │ lib/image-optimizer.js │ │
│ └──────────────────┘ └──────────────────────────────┘ │
└────────────┬──────────────────────────┬─────────────────┘
│ │
┌────────────▼──────────┐ ┌────────────▼──────────────┐
│ Supabase (PostgreSQL) │ │ Salesforce Marketing │
│ │ │ Cloud (Content Builder) │
│ • Projects (legacy) │ │ │
│ • pages │ │ • Landing pages │
│ • page_versions │ │ • Code snippets │
│ • entities/folders │ │ • Data Extensions │
│ • Schools │ │ • Formulaires (SFMC) │
│ • components │ │ │
│ • integration_jobs │ │ │
│ • Forms │ │ │
│ • chat_history │ │ │
└────────────────────────┘ └───────────────────────────┘
# 1. Cloner le dépôt
git clone <repo-url>
cd LandingPageGenerator
# 2. Installer les dépendances (minimales — le projet utilise essentiellement vanilla JS)
npm install
# 3. Copier et configurer les variables d'environnement
cp .env.example .env
# Éditer .env avec vos credentials (voir section Configuration)
# 4. Initialiser la base de données Supabase
# Exécuter database/scalable-schema.sql dans l'éditeur SQL Supabase
# Exécuter database/migrations/*.sql dans l'ordre numérique
# 5. Démarrer le serveur
node server.js
# ou en mode dev avec auto-reload :
npm run dev
Le serveur démarre sur http://localhost:8000
Copiez .env.example en .env et remplissez les valeurs :
# ── Supabase ──────────────────────────────────────────────────────────
SUPABASE_URL=https://VOTRE-PROJECT-ID.supabase.co
SUPABASE_KEY=votre-clé-publique-anon
SUPABASE_SERVICE_ROLE_KEY=votre-service-role-key # Requis pour les opérations admin
# ── Salesforce Marketing Cloud (SFMC) ─────────────────────────────────
SFMC_SUBDOMAIN=mc6xxxxxxxxxxxxx # Sous-domaine de votre BU SFMC
SFMC_CLIENT_ID=votre-client-id # ID de votre Installed Package
SFMC_CLIENT_SECRET=votre-client-secret # Secret de votre Installed Package
SFMC_ACCOUNT_ID=123456789 # MID de votre Business Unit
SFMC_CATEGORY_NAME=PFE_Landing_Pages # Nom du dossier racine dans Content Builder
SFMC_ASSET_TYPE_ID=220 # 220 = Code Snippet, 205 = Webpage
SFMC_ASSET_TYPE_NAME=webpage
SFMC_DE_CATEGORY_ID=12345 # ID du dossier Data Extensions dans SFMC
# ── IA Gemini ─────────────────────────────────────────────────────────
GEMINI_API_KEY=votre-clé-gemini # Pour l'assistant IA
GEMINI_API_KEY_TRANSLATION=votre-clé-gemini-2 # Pour la traduction (peut être la même)
# ── Serveur ───────────────────────────────────────────────────────────
PORT=8000
Note SFMC : Si
SFMC_CLIENT_ID/SFMC_CLIENT_SECRET/SFMC_SUBDOMAINsont absents, la synchronisation SFMC est automatiquement ignorée (skipped) sans bloquer l'application.
LandingPageGenerator/
│
├── server.js # Point d'entrée — serveur HTTP + toutes les routes API
│
├── index.html # Éditeur GrapesJS (builder de pages)
├── pages-dashboard.html # Dashboard CMS (liste, gestion des pages)
├── school-selector.html # Page de sélection d'école
│
├── js/
│ ├── app.js # Logique principale de l'éditeur (1600+ lignes)
│ ├── ai-assistant.js # Assistant IA (Gemini) dans le panneau latéral
│ ├── form-generator.js # Générateur de formulaires SFMC/Salesforce Core
│ ├── export.js # Export HTML/ZIP
│ └── storage.js # Gestion du localStorage GrapesJS
│
├── css/
│ ├── builder.css # Styles de l'éditeur et du dashboard (design system)
│ └── form-generator.css # Styles du générateur de formulaires
│
├── api/
│ ├── content.js # Routes /api/content/* — schéma structuré (pages, versions)
│ ├── schools.js # Routes /api/schools/* — gestion des écoles
│ └── router.js # Routeur API partagé
│
├── lib/
│ ├── sfmc.js # Client SFMC (Auth, Content Builder, Data Extensions)
│ ├── api-shared.js # Utilitaires partagés (supabaseRequest, slugify…)
│ ├── supabase.js # Client Supabase (côté API)
│ ├── minifier.js # Minification HTML/CSS avant envoi SFMC
│ ├── image-optimizer.js # Optimisation et hébergement d'images sur SFMC
│ └── schools.js # Utilitaires écoles
│
├── blocks/ # Blocs GrapesJS par école et par type
│ ├── registry.js # Registre de tous les blocs disponibles
│ ├── index.js # Point d'entrée des blocs
│ ├── headers.js # Blocs d'en-têtes
│ ├── hero/ # Bloc Hero
│ ├── header-brassart/ # Header spécifique Brassart
│ ├── header-efap/ # Header spécifique EFAP
│ ├── footer-brassart/ # Footer spécifique Brassart
│ ├── footer-efap/ # Footer spécifique EFAP
│ ├── form-sfmc/ # Formulaire SFMC
│ ├── form-salesforce-core/ # Formulaire Salesforce Core (CRM)
│ ├── carousel/ # Carrousel d'images
│ ├── rich-text/ # Texte enrichi
│ ├── cta-button/ # Bouton d'appel à l'action
│ ├── two-column/ # Mise en page deux colonnes
│ ├── programme-list/ # Liste de programmes
│ └── ... # (et autres blocs métier)
│
├── database/
│ ├── scalable-schema.sql # Schéma complet de la base de données
│ └── migrations/
│ ├── 002_add_integration_jobs.sql
│ ├── 003_add_page_toggle.sql
│ └── 004_add_translation_groups.sql
│
├── assets/
│ ├── LogoReetain.png
│ └── block-thumbnails/ # Miniatures des blocs GrapesJS
│
├── schools.json # Configuration de base des écoles (fallback)
├── .env # Variables d'environnement (ne pas committer)
├── .env.example # Template de configuration
├── vercel.json # Configuration de déploiement Vercel
└── package.json
Lorsqu'un consultant enregistre un composant réutilisable depuis l'éditeur, il est sauvegardé uniquement dans Supabase (table components), sans envoi vers SFMC.
POST /api/componentsGET /api/components/:schoolIdsfmcResult = { skipped: true, action: 'disabled' })Deux versions du HTML sont conservées et le traitement est non-bloquant :
| Version | Où | Contenu |
|---|---|---|
| Brute (Original) | Projects.project_data | JSON GrapesJS complet |
| Optimisée | Projects.html + page_versions.html | HTML complet avec SEO, minifié |
Flux asynchrone :
integration_jobsOptimisations appliquées avant envoi SFMC :
<title>, <meta description>, <meta keywords>, <link canonical>, JSON-LD)Les images intégrées dans les pages sont traitées automatiquement en post-publication :
<img src="..."> dans le HTMLassets de SupabaseTout ce processus s'effectue via un integration_job de type optimize_images, déclenché automatiquement après la publication.
Avant tout envoi vers SFMC, le code HTML et CSS est minifié par lib/minifier.js :
La minification est transparente : l'éditeur et l'aperçu utilisent toujours la version lisible. Seul SFMC reçoit le code minifié.
Depuis la liste des pages dans pages-dashboard.html, un bouton 🔍 SEO permet de modifier les métadonnées SEO sans ouvrir l'éditeur.
Fonctionnalités de la modale SEO :
integration_jobs (évite les conflits si plusieurs modifications rapides)Routes utilisées :
PATCH /api/pages/:pageId/seo → pages structuréesPATCH /api/project/:projectName/seo → pages legacyChaque école dispose de son propre domaine pour les landing pages. L'URL publique est construite automatiquement :
{base_url_école}/{slug_page}
Exemple : https://lp.brassart.fr/journee-portes-ouvertes-2025
base_url est configuré dans la fiche de l'école (Schools.base_url / entities.base_url)slugify(title))Helper : buildPublicUrl(entityBaseUrl, pageSlug) dans server.js
Route : GET /api/pages/:pageId/url
Lorsqu'une page est traduite en plusieurs langues, toutes les versions sont regroupées dans le dashboard.
Structure :
📄 Journée Portes Ouvertes [FR] ← Source
├── 🌐 Open Day [EN] ← Traduction
└── 🌐 Jornada Puertas [ES] ← Traduction
Fonctionnalités :
is_source_page = true) et des traductions (source_page_id)Migration DB :
ALTER TABLE pages ADD COLUMN source_page_id uuid REFERENCES pages(id) ON DELETE SET NULL;
ALTER TABLE pages ADD COLUMN is_source_page boolean DEFAULT false;
Routes :
POST /api/pages/:pageId/link-translation → lier une traduction à sa sourcePendant la construction d'une page, un widget de score SEO s'affiche en temps réel dans le panneau "Propriétés" de l'éditeur.
Calcul du score (0–100) :
| Critère | Points | Description |
|---|---|---|
| Titre SEO rempli | +20 | Entre 50 et 60 caractères |
| Méta-description | +20 | Entre 120 et 160 caractères |
| Mots-clés | +15 | Au moins 3 mots-clés définis |
| H1 unique | +15 | Un seul <h1> dans la page |
Images avec alt | +15 | Toutes les images ont un texte alternatif |
| URL canonique | +15 | URL canonique définie |
Affichage :
Un administrateur peut activer ou désactiver une page publiée à tout moment depuis le dashboard.
Comportement :
Colonnes DB ajoutées :
ALTER TABLE pages ADD COLUMN is_active boolean DEFAULT true;
ALTER TABLE pages ADD COLUMN redirect_url text;
Routes :
PATCH /api/pages/:pageId/toggle → active/désactive + définit redirect_urlImpact SFMC : lors de la désactivation, un integration_job crée une page de redirection AMPscript dans Content Builder.
Un fichier sitemap est généré et mis à jour automatiquement, accessible à l'URL /sitemap.xml.
Contenu du sitemap :
status = 'published' ET is_active = trueentities.base_url + pages.slugFormat :
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://lp.brassart.fr/journee-portes-ouvertes</loc>
<lastmod>2025-05-20</lastmod>
<changefreq>weekly</changefreq>
<priority>0.8</priority>
</url>
...
</urlset>
Performances : le sitemap est mis en cache 15 minutes en mémoire pour éviter les appels Supabase répétés.
Route : GET /sitemap.xml (Content-Type: application/xml)
Interface d'administration complète pour gérer les écoles du réseau :
entities, workspaces, foldersmetadata.lifecycle[Clic "Sauvegarder" dans l'éditeur]
│
▼
[js/app.js — Collecte]
• collectProperties() → Titre, SEO title, description, keywords, canonical, schéma JSON-LD
• editor.getHtml() → HTML brut du <body>
• editor.getCss() → CSS GrapesJS
• editor.getProjectData() → JSON complet du projet (composants + structure)
• Nom du projet → "school-{id}__{titre}__{LANG}"
│
▼ POST /api/save
│
[server.js — Traitement]
│
├─ ÉTAPE 1 : buildStoredHtml()
│ Construit un HTML complet :
│ <head> : charset, viewport, title SEO, meta description,
│ meta keywords, canonical, JSON-LD, <style>CSS</style>
│ <body> : HTML GrapesJS
│
├─ ÉTAPE 2 : Supabase — table "Projects" (upsert)
│ Stocke : project_name, html (complet), css, project_data, properties
│ → Réponse rapide possible dès ici (non-bloquant pour l'utilisateur)
│
├─ ÉTAPE 3 : syncLegacyProjectToContent() → api/content.js
│ Crée/met à jour dans le schéma structuré :
│ organizations → entities → folders → pages → page_versions
│ Chaque sauvegarde = nouvelle version numérotée (version_number++)
│ pages.current_version_id → pointe vers la nouvelle version
│
└─ ÉTAPE 4 : integration_job créé dans Supabase (async)
target: 'sfmc', action: 'publish_page', status: 'pending'
Un worker traite ensuite :
1. Minification HTML/CSS
2. Optimisation images (upload SFMC Media Library)
3. Envoi vers SFMC Content Builder (PATCH/POST)
4. Mise à jour du job : status: 'done'
│
▼
[Réponse JSON au client]
{ message: 'Project saved!', projectName, sfmc: { action, id }, content: { pageId, versionId } }
| Modèle | Table Supabase | Usage |
|---|---|---|
| Legacy | Projects | Accès rapide, compatibilité ascendante |
| Structuré | pages + page_versions | Versioning, workflow, SEO séparé, traductions |
| Méthode | Route | Description |
|---|---|---|
GET | /api/pages | Liste toutes les pages (dashboard) |
GET | /api/project/:name | Récupère un projet par nom |
POST | /api/save | Sauvegarde un projet (upsert) |
POST | /api/pages/duplicate | Duplique une page |
POST | /api/pages/delete | Supprime / archive une page |
PATCH | /api/pages/:id/seo | Met à jour les données SEO |
PATCH | /api/pages/:id/toggle | Active / désactive une page |
GET | /api/pages/:id/url | Retourne l'URL publique calculée |
POST | /api/pages/:id/link-translation | Lie une traduction à sa source |
GET | /preview/:projectName | Aperçu HTML d'une page |
GET | /sitemap.xml | Sitemap XML de toutes les pages publiées |
| Méthode | Route | Description |
|---|---|---|
GET | /api/organizations | Liste les organisations |
GET | /api/entities | Liste les entités (écoles) |
POST | /api/entities | Crée/met à jour une entité |
GET | /api/folders | Liste les dossiers |
POST | /api/folders | Crée un dossier |
GET | /api/content/pages/:id | Détails d'une page + versions |
POST | /api/content/pages/:id/versions | Crée une nouvelle version |
POST | /api/content/pages/:id/restore | Restaure une version antérieure |
POST | /api/content/pages/:id/move | Déplace une page dans un dossier |
POST | /api/content/pages/:id/status | Change le statut (draft→review→published) |
GET | /api/activity | Journal d'activité |
| Méthode | Route | Description |
|---|---|---|
GET | /api/schools | Liste toutes les écoles |
GET | /api/school/:id | Détails d'une école |
POST | /api/schools | Crée une école |
PUT | /api/school/:id | Met à jour une école |
DELETE | /api/school/:id | Supprime une école (avec transfert) |
| Méthode | Route | Description |
|---|---|---|
POST | /api/components | Sauvegarde un composant réutilisable |
GET | /api/components/:schoolId | Liste les composants d'une école |
| Méthode | Route | Description |
|---|---|---|
POST | /api/forms/save-to-supabase | Sauvegarde un formulaire |
GET | /api/forms/:schoolId | Liste les formulaires d'une école |
DELETE | /api/forms/:id | Supprime un formulaire |
| Méthode | Route | Description |
|---|---|---|
POST | /api/sfmc/create-data-extension | Crée une Data Extension SFMC |
POST | /api/sfmc/create-form-asset | Crée un asset formulaire dans Content Builder |
| Méthode | Route | Description |
|---|---|---|
POST | /api/ai/generate | Génère du contenu avec Gemini |
GET | /api/ai/history | Historique des conversations |
POST | /api/ai/translate | Traduit une page HTML vers une autre langue |
-- Organisation racine (groupe Reetain)
organizations (id, name, slug, metadata, created_at, updated_at)
-- Écoles / entités du réseau
entities (id, organization_id, name, slug, type, description,
contact, base_url, brand, metadata, deleted, created_at)
-- Dossiers de classement des pages
folders (id, entity_id, parent_id, name, slug, sort_order, metadata)
-- Pages landing
pages (id, entity_id, folder_id, title, slug, language, status,
current_version_id, seo, metadata,
is_active, redirect_url, ← toggle activer/désactiver
source_page_id, is_source_page, ← groupage traductions
published_at, created_at, updated_at)
-- Versions historiques de chaque page
page_versions (id, page_id, version_number, html, css,
project_data, created_by, change_summary, metadata)
-- Jobs d'intégration asynchrones (SFMC, optimisations)
integration_jobs (id, entity_id, page_id, page_version_id,
target, action, status, payload, result,
error, attempts, scheduled_at, processed_at)
-- Référentiel des écoles (config visuelle)
"Schools" (id, name, full_name, description, contact,
base_url, color, secondary_color, color_light,
emoji, default_blocks, deleted)
-- Projets legacy (compatibilité)
"Projects" (project_name, html, css, project_data, properties, created_at)
-- Composants réutilisables par école
components (id, school_id, name, category, content, properties, created_at)
-- Formulaires SFMC
"Forms" (id, school_id, name, html, css, ampscript,
data_extension_name, created_at)
-- Historique des conversations IA
chat_history (id, sender, message, school_id, project_id, created_at)
-- Assets médias
assets (id, organization_id, entity_id, page_id, type, name, url, metadata)
draft → review → approved → published → archived
↓ ↓
└──────────────→ deleted ←───────────────┘
(corbeille)
[SFMC_CATEGORY_NAME] (ex: PFE_Landing_Pages)
├── pages/
│ ├── efap/
│ │ ├── journee-portes-ouvertes ← Landing page (Webpage asset)
│ │ └── open-day-2025
│ ├── brassart/
│ │ └── ...
│ └── icart/
│ └── ...
├── forms/
│ ├── efap/
│ │ └── formulaire-inscription ← Formulaire (Code Snippet)
│ └── ...
└── blocks/
├── efap/
│ └── mon-composant ← Composant réutilisable
└── ...
L'authentification utilise OAuth 2.0 Client Credentials :
POST https://{SFMC_SUBDOMAIN}.auth.marketingcloudapis.com/v2/token
{
"grant_type": "client_credentials",
"client_id": "...",
"client_secret": "...",
"account_id": "..."
}
Le token est mis en cache jusqu'à 60 secondes avant expiration.
Chaque asset est identifié par un customerKey unique :
slugify(titre_sans_préfixe_école)form-{schoolId}-{nom}comp-{schoolId}-{nom}Si l'asset existe → PATCH (mise à jour). Sinon → POST (création).
Accessible depuis le panneau latéral de l'éditeur. L'assistant est contextualisé par école :
chat_history)Traduit le contenu HTML d'une page vers une autre langue :
Langues supportées : FR, EN, ES, DE, IT, PT, et toutes les langues supportées par Gemini.
Accessible à /pages-dashboard.html, le dashboard offre une vue centralisée de toutes les landing pages.
| Fonction | Description |
|---|---|
| 📋 Liste des pages | Tableau avec titre, école, langue, statut, dernière mise à jour |
| 🔍 Recherche | Filtrage en temps réel par titre, nom de projet, titre SEO |
| 🏫 Filtre par école | Affichage des pages d'une école spécifique |
| 📊 Filtre par statut | Draft, En revue, Validé, Publié, Archivé |
| 📁 Navigation latérale | Organisation par école et par dossier |
| 📄 Dupliquer | Duplique une page avec son contenu et ses données SEO |
| 🗑️ Corbeille | Suppression douce — les pages sont récupérables |
| ⏱️ Historique des versions | Voir et restaurer les versions précédentes |
| 🚦 Workflow statut | Draft → En revue → Validé → Publié |
| 📁 Déplacer | Réorganiser les pages dans les dossiers |
| 🔍 Config SEO | Modifier le SEO d'une page sans ouvrir l'éditeur |
| 🟢🔴 Toggle actif | Activer / désactiver une page publiée |
| 🌐 URL publique | Afficher et copier l'URL finale de la page |
| 🗺️ Traductions | Voir toutes les versions linguistiques d'une page |
En haut du dashboard, quatre métriques sont affichées :
L'éditeur est basé sur GrapesJS, enrichi de nombreuses fonctionnalités métier.
| Panneau | Description |
|---|---|
| 🧱 Blocs | Bibliothèque de composants drag-and-drop (filtrée par école) |
| 🎨 Styles | Éditeur CSS visuel |
| 📐 Calques | Arborescence des composants de la page |
| ⚙️ Propriétés | Titre, SEO, score SEO, langue |
| 📝 Formulaires | Liste des formulaires SFMC de l'école |
| 🤖 IA | Assistant de contenu Gemini |
Communs : Hero, Rich Text, Two Column, CTA Button, Image Caption, Spacer, Programme List, Programme Editorial, Trois Raisons, Chiffres Clés, Horizontal Menu, Bande Rose, Carrousel, Carrousel Témoignages, Carrousel Campus
EFAP : Header EFAP, Footer EFAP
Brassart : Header Brassart, Footer Brassart
Formulaires : Form SFMC, Form Salesforce Core (CRM)
Composants personnalisés : chargés depuis Supabase par école
L'éditeur propose 3 modes d'affichage :
Chaque école est une entité du réseau Reetain avec sa propre identité visuelle et configuration.
| Propriété | Description | Exemple |
|---|---|---|
id | Identifiant unique (slug) | brassart |
name | Nom court | Brassart |
fullName | Nom complet | École Brassart |
color | Couleur primaire (CSS) | #e91e63 |
secondaryColor | Couleur secondaire | #1a1a1a |
baseUrl | Domaine des landing pages | https://lp.brassart.fr |
contact | Contact référent | [email protected] |
emoji | Icône représentative | 🎨 |
defaultBlocks | Blocs chargés par défaut | ["header-brassart", "hero"] |
Les couleurs de l'école sont injectées automatiquement dans l'éditeur et dans les pages générées :
:root {
--brand-primary: #e91e63;
--brand-secondary: #1a1a1a;
--brand-primary-rgb: 233, 30, 99;
}
node server.js
# ou
npm run dev # avec nodemon (si installé)
Le fichier vercel.json configure le déploiement :
{
"version": 2,
"builds": [{ "src": "server.js", "use": "@vercel/node" }],
"routes": [{ "src": "/(.*)", "dest": "/server.js" }]
}
vercel --prod
Note : En environnement Vercel (serverless), le worker de traitement des
integration_jobsutilise des Vercel Cron Jobs configurés séparément.
Projets (nom interne) :
school-{schoolId}__{titre-de-la-page}__{LANGUE}
Exemple : school-brassart__journee-portes-ouvertes__FR
Composants :
{schoolId}_{nom-du-composant}
Exemple : brassart_bandeau-inscription
CustomerKey SFMC :
slugify(titre-sans-préfixe-école)
Exemple : journee-portes-ouvertes
| Fonctionnalité | Développeur |
|---|---|
| Architecture générale & SFMC | Zahira |
| Sauvegarde composants (Supabase only) | Zahira |
| SEO config & injection HTML | Zahira |
| Gestion des écoles (CRUD) | Mouad |
| Pages source & traductions | Nada |
| Dashboard CMS (UI) | Équipe |
Projet académique — PFE (Projet de Fin d'Études) — Réseau Reetain
© 2025 — Usage interne uniquement