Système de Visibilité Starlight - Schéma et Configuration
Objet : Implémentation du champ
visibilitypour contrôler l’accès public/privé aux documents Starlight
Type : Documentation Technique (DAT)
Couche : Couche 02 (Présentation - Astro)
Emplacement :apps/web/src/content.config.ts+apps/web/src/middleware.ts
Statut : DOC (Proposé)
1. Vue d’ensemble (DOC)
Section titled “1. Vue d’ensemble (DOC)”1.1. Description
Section titled “1.1. Description”Ce système permet de marquer les documents Starlight comme public ou private via un champ personnalisé dans le frontmatter. Le middleware Astro lit cette métadonnée pour déterminer si une authentification est requise.
1.2. Objectif
Section titled “1.2. Objectif”- Permettre un contrôle granulaire de l’accès aux documents
- Garder tous les documents privés par défaut (secure by default)
- Rendre certains documents publics facilement (ex: overview, guides généraux)
- Intégration transparente avec Starlight et le middleware existant
2. Configuration et Schéma (CODE)
Section titled “2. Configuration et Schéma (CODE)”2.1. Extension Schéma Starlight
Section titled “2.1. Extension Schéma Starlight”Modifier apps/web/src/content.config.ts pour étendre le schéma docs :
import { defineCollection } from 'astro:content';import { docsLoader, i18nLoader } from '@astrojs/starlight/loaders';import { docsSchema, i18nSchema } from '@astrojs/starlight/schema';import { z } from 'astro/zod';
const blog = defineCollection({ loader: glob({ base: './src/content/blog', pattern: '**/*.{md,mdx}' }), schema: ({ image }) => z.object({ title: z.string(), description: z.string(), pubDate: z.coerce.date(), updatedDate: z.coerce.date().optional(), heroImage: z.optional(image()), }),});
const docs = defineCollection({ loader: docsLoader(), schema: docsSchema({ extend: z.object({ // Champ de visibilité : public ou private (par défaut) visibility: z.enum(['public', 'private']).default('private'), }), }),});
export const collections = { blog, docs, i18n: defineCollection({ loader: i18nLoader(), schema: i18nSchema() }),};2.2. Exemple Frontmatter
Section titled “2.2. Exemple Frontmatter”---title: "Guide de Démarrage"description: "Guide pour les nouveaux développeurs"visibility: "public" # Ce document est accessible sans authentification---
Contenu du guide...---title: "Architecture Interne"description: "Documentation technique sensible"visibility: "private" # Ce document nécessite une authentification (valeur par défaut)---
Contenu technique sensible...2.3. Modification Middleware
Section titled “2.3. Modification Middleware”Le middleware existant (apps/web/src/middleware.ts) doit être mis à jour pour lire le champ visibility :
// Dans la fonction onRequest, après avoir déterminé docIdlet isPrivate = true;
try { // Attempt to read entry frontmatter schema const entry = await getEntry('docs', docId); if (entry && entry.data) { const data = entry.data as { visibility?: 'public' | 'private' }; // Si visibility est explicitement 'public', document public if (data.visibility === 'public') { isPrivate = false; } }} catch (_e) { // En cas d'erreur, considérer comme privé (secure by default) isPrivate = true;}
// Override pour overview (public par défaut)if (docId === 'overview') { isPrivate = false;}3. Architecture et Flux
Section titled “3. Architecture et Flux”Utilisateur → Requête /docs/private-doc │ ▼ [Middleware Astro] │ ▼ [Déterminer docId depuis pathname] │ ▼ [getEntry('docs', docId)] │ ▼ [Lire entry.data.visibility] │ ┌─────────────┴─────────────┐ │ │ ▼ ▼ visibility === 'public' visibility === 'private' │ │ │ ▼ │ [Vérifier auth_session] │ │ │ ┌───────┴───────┐ │ │ │ │ ▼ ▼ │ [Session valide] [Session invalide] │ │ │ │ ▼ ▼ │ [Accès autorisé] [Redirect /login] │ │ └───────────────────────────┘ │ ▼ [Accès autorisé]4. Contrats d’Entrée/Sortie (SPEC)
Section titled “4. Contrats d’Entrée/Sortie (SPEC)”4.1. Frontmatter Schema
Section titled “4.1. Frontmatter Schema”| Champ | Type | Valeurs | Défaut | Description |
|---|---|---|---|---|
visibility |
enum | 'public' | 'private' |
'private' |
Contrôle l’accès au document |
4.2. Middleware Logic
Section titled “4.2. Middleware Logic”| Condition | Action |
|---|---|
visibility === 'public' |
Accès autorisé sans authentification |
visibility === 'private' |
Vérification auth_session requise |
docId === 'overview' |
Accès autorisé (override public) |
| Erreur lecture entry | Accès refusé (secure by default) |
4.3. TypeScript Types
Section titled “4.3. TypeScript Types”// Généré automatiquement par Astrointerface DocsEntry { id: string; slug: string; body: string; collection: 'docs'; data: { title: string; description: string; visibility: 'public' | 'private'; // Nouveau champ // ... autres champs Starlight };}5. Sécurité
Section titled “5. Sécurité”- Secure by Default : Valeur par défaut
'private'pour éviter les fuites accidentelles - Validation Zod : Schéma strict empêche les valeurs invalides
- Override explicite : Seul
overviewest explicitement public dans le middleware - Gestion d’erreurs : En cas d’erreur de lecture, document considéré privé
- TypeScript : Typage automatique prévient les erreurs de développement
6. Migration des Documents Existants
Section titled “6. Migration des Documents Existants”6.1. Stratégie
Section titled “6.1. Stratégie”- Documents privés : Aucune modification (valeur par défaut
'private') - Documents publics : Ajouter explicitement
visibility: 'public' - Overview : Déjà public via override middleware
6.2. Script de Migration (Optionnel)
Section titled “6.2. Script de Migration (Optionnel)”# Pour marquer tous les docs d'un répertoire comme publicsfind src/content/docs/docs/L1_Contenu -name "*.md" -exec sed -i '2a visibility: "public"' {} \;6.3. Documents Candidats pour Public
Section titled “6.3. Documents Candidats pour Public”overview: Déjà public- Guides Getting Started généraux : Potentiellement publics
- Documentation API publique : Potentiellement publique
- Architecture interne : Toujours privé
- Spécifications techniques : Toujours privé
7. Tests Attendus (TEST)
Section titled “7. Tests Attendus (TEST)”7.1. Tests Schéma
Section titled “7.1. Tests Schéma”- Document sans champ
visibility→ défaut'private' - Document avec
visibility: 'public'→ accessible sans auth - Document avec
visibility: 'private'→ nécessite auth - Valeur invalide → erreur de validation Zod
7.2. Tests Middleware
Section titled “7.2. Tests Middleware”- Accès document public sans cookie → 200 OK
- Accès document privé sans cookie → 302 /login
- Accès document privé avec cookie valide → 200 OK
- Accès document privé avec cookie invalide → 302 /login
7.3. Tests Starlight
Section titled “7.3. Tests Starlight”- Sidebar affiche tous les documents (publics et privés)
- Navigation fonctionne correctement
- Recherche Pagefind indexe correctement
- TypeScript typecheck réussi
8. Documentation Utilisateur
Section titled “8. Documentation Utilisateur”8.1. Pour les Éditeurs de Documentation
Section titled “8.1. Pour les Éditeurs de Documentation”---title: "Mon Document"description: "Description"visibility: "public" # ou "private" (par défaut)---
Contenu...8.2. Règles de Visibilité
Section titled “8.2. Règles de Visibilité”- Par défaut : Toujours
private(plus sécurisé) - Public : Uniquement pour documents non sensibles
- Overview : Public automatiquement via middleware
- Audit : Vérifier régulièrement les documents publics
9. Historique des Modifications
Section titled “9. Historique des Modifications”| Date | Version | Description | Auteur |
|---|---|---|---|
| 2026-09-27 | 1.0 | Création initiale DAT Système Visibilité | Team (Agent) |