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
}
}
});
# 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 |