# Story 3.1: Structure de Données JSON pour les Projets ## Status Ready for Dev ## Story **As a** développeur, **I want** définir et créer le fichier JSON contenant les données des projets, **so that** je centralise les informations et facilite la maintenance. ## Acceptance Criteria 1. Le fichier `data/projects.json` est créé avec la structure définie 2. La structure supporte : id, title, slug, category (vedette/secondaire), thumbnail, url, technologies[], context, solution, teamwork, duration, testimonial, screenshots[] 3. Au moins 2 projets de test sont ajoutés pour valider la structure 4. Une fonction PHP `getProjects()` lit et décode le JSON 5. La fonction gère les erreurs (fichier manquant, JSON invalide) ## Tasks / Subtasks - [] **Task 1 : Définir la structure JSON** (AC: 2) - [] Documenter tous les champs requis et optionnels - [] Définir les types de données pour chaque champ - [] Définir les valeurs possibles pour category - [] **Task 2 : Créer le fichier projects.json** (AC: 1, 3) - [] Créer `data/projects.json` - [] Ajouter 2-3 projets de test - [] Valider la syntaxe JSON - [] **Task 3 : Créer les fonctions PHP d'accès** (AC: 4, 5) - [] Créer `loadJsonData()` générique - [] Créer `getProjects()` - [] Créer `getProjectsByCategory()` - [] Créer `getProjectBySlug()` - [] Gérer les erreurs (fichier manquant, JSON invalide) - [] **Task 4 : Tester les fonctions** - [] Tester avec fichier valide - [] Tester avec fichier manquant - [] Tester avec JSON invalide ## Dev Notes ### Structure data/projects.json ```json { "projects": [ { "id": 1, "title": "Site E-commerce XYZ", "slug": "ecommerce-xyz", "category": "vedette", "thumbnail": "ecommerce-xyz-thumb.webp", "url": "https://example.com", "github": "https://github.com/user/project", "technologies": ["PHP", "JavaScript", "Tailwind CSS", "MySQL"], "context": "Client souhaitant moderniser sa boutique en ligne pour améliorer l'expérience utilisateur et augmenter les conversions.", "solution": "Développement d'une solution e-commerce sur mesure avec panier persistant, paiement sécurisé Stripe, et interface d'administration.", "teamwork": "Projet réalisé en collaboration avec un designer UI/UX. J'ai pris en charge l'intégration et le développement backend.", "duration": "3 mois", "screenshots": [ "ecommerce-xyz-screen-1.webp", "ecommerce-xyz-screen-2.webp", "ecommerce-xyz-screen-3.webp" ] }, { "id": 2, "title": "Application de Gestion", "slug": "app-gestion", "category": "vedette", "thumbnail": "app-gestion-thumb.webp", "url": null, "github": "https://github.com/user/app-gestion", "technologies": ["React", "Node.js", "PostgreSQL", "Docker"], "context": "Startup ayant besoin d'un outil interne pour gérer ses ressources et planifier ses projets.", "solution": "Application web full-stack avec authentification, gestion des rôles, tableaux de bord et exports PDF.", "teamwork": null, "duration": "4 mois", "screenshots": [ "app-gestion-screen-1.webp" ] }, { "id": 3, "title": "Site Vitrine Restaurant", "slug": "restaurant-vitrine", "category": "secondaire", "thumbnail": "restaurant-thumb.webp", "url": "https://restaurant-example.com", "github": null, "technologies": ["HTML", "CSS", "JavaScript"], "context": "Restaurant local souhaitant une présence en ligne simple.", "solution": null, "teamwork": null, "duration": "2 semaines", "screenshots": [] } ] } ``` ### Champs du Projet | Champ | Type | Requis | Description | |-------|------|--------|-------------| | id | number | Oui | Identifiant unique | | title | string | Oui | Titre du projet | | slug | string | Oui | URL-friendly (unique) | | category | string | Oui | "vedette" ou "secondaire" | | thumbnail | string | Oui | Nom du fichier image | | url | string/null | Non | URL du projet en ligne | | github | string/null | Non | URL du repo GitHub | | technologies | array | Oui | Liste des technos | | context | string | Oui | Description du contexte | | solution | string/null | Non | Description technique | | teamwork | string/null | Non | Travail d'équipe | | duration | string | Oui | Durée du projet | | screenshots | array | Non | Liste des captures | ### Fonctions PHP (includes/functions.php) ```php /** * Charge et parse un fichier JSON */ function loadJsonData(string $filename): array { $path = __DIR__ . "/../data/{$filename}"; if (!file_exists($path)) { error_log("JSON file not found: {$filename}"); return []; } $content = file_get_contents($path); $data = json_decode($content, true); if (json_last_error() !== JSON_ERROR_NONE) { error_log("JSON parse error in {$filename}: " . json_last_error_msg()); return []; } return $data; } /** * Récupère tous les projets */ function getProjects(): array { $data = loadJsonData('projects.json'); return $data['projects'] ?? []; } /** * Récupère les projets par catégorie */ function getProjectsByCategory(string $category): array { return array_filter(getProjects(), fn($p) => $p['category'] === $category); } /** * Récupère un projet par son slug */ function getProjectBySlug(string $slug): ?array { $projects = getProjects(); foreach ($projects as $project) { if ($project['slug'] === $slug) { return $project; } } return null; } /** * Récupère les technologies uniques de tous les projets */ function getAllTechnologies(): array { $technologies = []; foreach (getProjects() as $project) { foreach ($project['technologies'] ?? [] as $tech) { if (!in_array($tech, $technologies)) { $technologies[] = $tech; } } } sort($technologies); return $technologies; } ``` ## Testing - [] Le fichier JSON est valide (pas d'erreur de syntaxe) - [] `getProjects()` retourne un tableau de projets - [] `getProjectsByCategory('vedette')` retourne les projets vedettes - [] `getProjectBySlug('ecommerce-xyz')` retourne le bon projet - [] `getProjectBySlug('inexistant')` retourne null - [] Fichier manquant → tableau vide, pas d'exception ## Dev Agent Record ### Agent Model Used Claude Opus 4.5 (claude-opus-4-5-20251101) ### File List | File | Action | Description | |------|--------|-------------| | `data/projects.json` | Created | Fichier JSON avec 3 projets de test | | `includes/functions.php` | Modified | Ajout des fonctions d'accès aux données JSON | ### Completion Notes - Structure JSON complète avec tous les champs requis et optionnels - 3 projets de test ajoutés (2 vedettes, 1 secondaire) - Fonctions PHP: `loadJsonData()`, `getProjects()`, `getProjectsByCategory()`, `getProjectBySlug()`, `getAllTechnologies()` - Gestion des erreurs: fichier manquant et JSON invalide retournent tableau vide avec log - Tous les tests passent (8/8) ### Debug Log References Aucun problème rencontré. ## Change Log | Date | Version | Description | Author | |------|---------|-------------|--------| | 2026-01-22 | 0.1 | Création initiale | Sarah (PO) | | 2026-01-23 | 1.0 | Implémentation complète | James (Dev) |