Aller au contenu

PD-226 — Plan d'implémentation


📚 Navigation User Story | Document | | | ---------- | -- | | 📋 [Spécification](PD-226-specification.md) | | | 🛠️ **Plan d'implémentation** | *(ce document)* | | ✅ [Critères d'acceptation](PD-226-acceptability.md) | | | 📝 [Retour d'expérience](PD-226-rex.md) | | [← Retour à site-vitrine](../PD-225-epic.md) · [↑ Index User Story](index.md)

1. Découpage en composants

Structure projet Astro

ProbatioVault-site/
├── astro.config.mjs          # Configuration Astro (output: static)
├── tsconfig.json             # TypeScript strict
├── package.json              # Dépendances (Astro 5.16+)
├── src/
│   ├── pages/                # Pages auto-routées
│   ├── layouts/              # BaseLayout.astro
│   ├── components/           # Composants réutilisables
│   ├── styles/               # CSS global + tokens
│   └── assets/               # Polices locales, images
├── public/                   # Assets statiques (favicon, robots.txt)
└── dist/                     # Build output (gitignored)

Composants clés

Composant Responsabilité
astro.config.mjs Configuration SSG, pas d'adapter serveur
BaseLayout.astro Structure HTML commune, chargement CSS/fonts
public/_headers Headers de sécurité (CSP, COOP/COEP)
src/assets/fonts/ Polices @fontsource locales

2. Flux techniques

Build statique

npm run build
astro build (SSG)
    ├── Compile pages/*.astro → dist/*.html
    ├── Bundle CSS → dist/_astro/*.css
    ├── Copy public/ → dist/
    └── Aucun JS framework runtime
dist/ (fichiers statiques purs)

Validation no-SSR

astro check
Vérifie absence d'adapter serveur
Vérifie absence d'API routes dynamiques
Vérifie output: 'static' dans config

3. Mapping invariants → mécanismes

Invariant Mécanisme technique
INV-1 : Site entièrement statique output: 'static' dans astro.config.mjs, aucun adapter
INV-2 : Fonctionnel sans JS HTML sémantique, <details> pour accordéons, CSS-only menus
INV-3 : Ressources locales @fontsource/inter, @fontsource/space-grotesk dans src/assets
INV-4 : CSP whitelist _headers avec Content-Security-Policy restrictive

Configuration Astro

// astro.config.mjs
export default defineConfig({
  output: 'static',  // INV-1 : pas de SSR
  build: {
    inlineStylesheets: 'auto'
  },
  vite: {
    build: {
      cssCodeSplit: false  // Un seul fichier CSS
    }
  }
});

Headers de sécurité

# public/_headers
/*
  Content-Security-Policy: default-src 'self'; script-src 'self' https://www.googletagmanager.com; connect-src 'self' https://api.brevo.com; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'
  X-Frame-Options: DENY
  X-Content-Type-Options: nosniff
  Referrer-Policy: strict-origin-when-cross-origin

4. Gestion des erreurs

Erreur Cause Mitigation
Build fail Erreur TypeScript astro check en pre-commit
SSR détecté Adapter présent CI vérifie output: 'static'
Font externe URL google fonts Lint interdit domaines externes
JS obligatoire Composant React Interdire frameworks client

Script de validation

#!/bin/bash
# scripts/validate-static.sh

# Vérifier qu'aucun adapter n'est installé
if grep -q "adapter" astro.config.mjs; then
  echo "ERROR: Adapter détecté, le site doit être statique"
  exit 1
fi

# Vérifier output static
if ! grep -q "output.*static" astro.config.mjs; then
  echo "ERROR: output doit être 'static'"
  exit 1
fi

# Vérifier absence de dépendances externes dans CSS
if grep -rE "url\(.*https?://" src/styles/; then
  echo "ERROR: URL externe détectée dans CSS"
  exit 1
fi

5. Impacts sécurité

Aspect Mesure
CSP Whitelist stricte : self + GA + Brevo uniquement
XSS Pas de JS dynamique, échappement Astro natif
Données Aucune donnée utilisateur côté serveur
HTTPS Forcé via GitLab Pages

6. Hypothèses techniques

Hypothèse Justification
Node.js 20+ disponible Requis par Astro 5.x
npm 10+ disponible Lockfile v3
Astro 5.16 stable Version cible spécifiée
GitLab Pages supporte _headers Format Netlify compatible

7. Points de vigilance

Point Risque Action
Upgrade Astro Breaking changes Fixer version exacte dans package.json
Polices Téléchargement externe Vérifier @fontsource local uniquement
Analytics Tracking sans consentement Conditionnel au consentement cookie
Formulaires Dépendance Brevo JS Fallback mailto: sans JS
Images CDN externe Toutes images dans public/ ou src/assets

Fichiers à créer

Fichier Description
astro.config.mjs Configuration SSG stricte
tsconfig.json TypeScript strict mode
package.json Dépendances minimales
public/_headers CSP et headers sécurité
src/layouts/BaseLayout.astro Layout HTML de base
scripts/validate-static.sh Validation CI