Aller au contenu principal

Architecture technique

Stack

CoucheTechnologieVersion
FrameworkNext.js16 (App Router, output standalone)
LangageReact + TypeScript19 + 5.x
StylesTailwind CSS4.x
CarteLeaflet + React-LeafletPour l'agenda événements
AuthNextAuth v5Lecture seule du cookie LeHub
EmailResendFormulaire contact
AnalyticsPlausible auto-hébergéMesure audience sans cookies
InfrastructureDocker Compose + NginxPort 3002, reverse proxy apex

Où vit quoi

Répertoires de premier niveau

CheminResponsabilité
app/Routes Next.js App Router (UI + API minimale)
components/Composants React (pages, widgets, cartes)
lib/Utilitaires (config URLs, auth hub, fetch API, cache)
.github/workflows/CI/CD (deploy automatique)
public/Assets statiques (favicon, OG image)

Structure de app/

Pages publiques

CheminRôle
app/page.tsxAccueil
app/evenements/page.tsxAgenda filtrable
app/evenements/[slug]/page.tsxFiche atelier
app/blog/page.tsxActualités
app/blog/[slug]/page.tsxArticle individuel
app/mediatheque/page.tsxMédiathèque
app/ateliers/page.tsxPrésentation ateliers
app/ateliers/citoyen/page.tsxAtelier citoyen
app/a-propos/page.tsxÀ propos de l'association
app/contact/page.tsxFormulaire contact
app/accessibilite/page.tsxDéclaration accessibilité
app/mentions-legales/page.tsxMentions légales
app/confirmation/page.tsxPage retour après paiement HelloAsso
app/chantier/page.tsxPage mode chantier
app/annulation/[token]/page.tsxConfirmation annulation inscription

Routes API

CheminRôle
app/api/meExpose session hub reconnue
app/api/contactRéception formulaire contact
app/api/revalidateWebhook LeHub, revalidation ISR
app/api/site-modeÉtat mode chantier

Autres routes (/api/checkout, /api/discount-codes/, etc.) : rewrites vers LeHub.

Structure de components/

RépertoireContenu
components/workshops/Composants agenda (liste, carte, filtres, détail)
components/ (racine)Composants pages (Header, Footer, AccordionFaq, SystemicLoops, IcebergDiagram, ChantierBar, etc.)

Structure de lib/

FichierResponsabilité
config.tsURLs publiques (SITE_URL, HUB_URL)
hub-auth.tsLecture du cookie de session LeHub, ponte d'auth
events.tsAppels à l'API publique LeHub (workshops, articles, resources)
cart-context.tsxPanier d'inscription (client-side, optionnel)

Rendez et cache

LeSite utilise l'ISR (Incremental Static Regeneration) de Next.js :

  • Les pages de contenu (articles, ateliers) sont générées statiquement au build.
  • Elles sont servies depuis le cache et régénérées au plus toutes les 5 minutes (revalidate: 300).
  • Lors d'une publication dans l'admin LeHub, un appel à /api/revalidate force la revalidation immédiate (secret partagé pour sécurité).

Le site reste donc performant et disponible même si LeHub redémarre.

Conventions UI

  • Tokens CSS : uniquement Tailwind utilitaires. Zéro tokens personnalisés.
  • Composants : composants Next.js natifs (Link, Image avec optimisation).
  • Carte : Leaflet pour la localisation d'ateliers.

Authentification et pont d'auth

Session partagée

  • Domaine : .fresquesystemique.org en prod (cookie partagé avec LeHub).
  • Nom du cookie : __Secure-fresque.session-token (configurable via AUTH_SESSION_COOKIE_NAME).
  • Chiffrement : JWE A256CBC-HS512 (NextAuth).

lib/hub-auth.ts déchiffre le cookie avec le NEXTAUTH_SECRET :

const payload = await decode({ token, secret, salt: COOKIE_NAME })
// Extrait isAdmin, id, firstName, role

Deux noms de cookies sont tentés :

  1. __Secure-fresque.session-token (NextAuth prod).
  2. authjs.session-token (fallback).

Les gros cookies sont réassemblés (Auth.js fragmente les gros jetons en .0, .1, etc.).

Utilisation

  • Menu compte (/api/me) : expose le firstName et rôle de l'utilisateur connecté.
  • Mode chantier (middleware.ts) : reconnaît les admins (isAdmin=true) pour les laisser voir le vrai site.
  • Barre de bascule (ChantierBar) : visible pour les admins en mode chantier.
Le nom du cookie de session est dupliqué

Le nom du cookie de session est codé en dur à trois endroits : lib/auth.ts côté LeHub, middleware.ts côté LeSite et lib/hub-auth.ts côté LeSite. Les trois doivent rester strictement synchronisés ; une divergence casse silencieusement le contournement administrateur du mode chantier.

Routes Next.js

  • Pas de groupes de routes ((name)) : structure plate pour la simplicité.
  • Slugs dynamiques ([slug]) pour articles et ateliers, en lecture seule depuis LeHub.

SEO et partage

  • Métadonnées par défaut : template de titre %s · La Fresque Systémique, Open Graph/Twitter.
  • Données structurées : JSON-LD Event (fiches ateliers) et Article (actualités).
  • Indexation : pilotée par NEXT_PUBLIC_ALLOW_INDEXING. Le site reste en noindex tant qu'elle ne vaut pas "true".
  • Image de partage : public/og-default.png (1200×630).

Accessibilité

LeSite publie une déclaration d'accessibilité (/accessibilite) et suit une logique de sobriété :

  • Pages statiques quand possible.
  • Pas de cookies de suivi.
  • Analytics Plausible (consentement implicite, pas de consentement cookie).