# CLAUDE.md This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. ## Project Overview **MesRelevés** — Application web PHP/PostgreSQL pour une association de généalogie. Elle permet la saisie systématique de relevés d'actes (naissance, mariage, décès, etc.), la recherche dans ces relevés, et l'export au format GEDCOM. ## Tech Stack - **Backend** : PHP 8.2+, framework **Laravel 11** - **Base de données** : **PostgreSQL 16** (JSONB pour les champs variables des relevés, full-text search natif) - **Frontend** : Blade templates + **Alpine.js** (interactivité légère) + **Tailwind CSS** - **Auth** : Laravel Breeze (sessions, middleware de rôles custom) - **Cache** : Redis (Laravel Cache) pour les listes de lieux et requêtes fréquentes ## Development Commands ```bash # Installation composer install npm install && npm run build cp .env.example .env && php artisan key:generate # Base de données php artisan migrate php artisan migrate:fresh --seed # reset + données de test # Serveur de développement php artisan serve # http://localhost:8000 npm run dev # Vite en watch (CSS/JS) # Tests php artisan test # tous les tests php artisan test --filter=NomTest # un test précis php artisan test --testsuite=Feature # Qualité de code ./vendor/bin/pint # formatage PHP (Laravel Pint) ./vendor/bin/phpstan analyse # analyse statique ``` ## Architecture ``` app/ Models/ # Eloquent models Http/ Controllers/ # un controller par entité métier Middleware/ # RoleMiddleware (admin, section_manager, member) Requests/ # Form requests avec validation Policies/ # Autorisation par modèle (Laravel Gates/Policies) Services/ # Logique métier complexe (ex: GedcomExportService, DateConversionService) Enums/ # SourceStatus, UserRole, CalendarType database/ migrations/ seeders/ resources/ views/ layouts/ sections/ sources/ releves/ # formulaires dynamiques pilotés par source_type lieux/ admin/ routes/ web.php # routes principales admin.php # routes admin (prefix /admin, middleware admin) ``` ## Domain Model (entités clés) ### Utilisateurs et rôles - `users` : id, name, email, role (`admin` | `section_manager` | `member`) - `section_user` (pivot) : user_id, section_id, role_in_section - Un utilisateur peut appartenir à plusieurs sections locales. ### Sections locales - Champs : nom, lieu_id (FK), adresse, email_contact, url ### Dépôts d'archives - Champs : nom, description, adresse_postale, url ### Lieux - Champs : nom, code, lieu_parent_id (FK self-référentiel), nom_long (calculé), latitude, longitude, note - `nom_long` est généré automatiquement en concaténant les noms des ancêtres (ex. "Bordeaux, Gironde, France"). ### Types de sources (SourceType) - Définissent les **champs dynamiques** du formulaire de saisie. - Stocké comme : `source_types` (id, nom, description) + `source_type_fields` (id, source_type_id, name, label, type, required, order, options JSON) - Types de champ possibles : `text`, `date`, `boolean`, `select`, `textarea`, `number` - L'ajout/modification d'un type de source ne doit pas casser les relevés existants (les champs JSONB contiennent toujours l'ancienne structure). ### Sources - Champs : nom, description, source_type_id, depot_id, cote, auteur, status - Status (enum) : `a_faire` → `en_cours` → `a_valider` → `termine` - Une source est créée uniquement par admin ou responsable de section, avec status initial `a_faire`. - Table pivot `source_user` : assignation des membres à une source. - Visibilité des relevés : status `termine` → visible par tous les membres ; sinon → visible uniquement par admin et membres de section assignés. ### Relevés (`releves`) - **Schéma** : `id`, `source_id`, `data` (JSONB — champs variables selon le source_type), `created_by`, `created_at`, `updated_by`, `updated_at` - Le JSONB est la solution retenue pour la flexibilité et la performance (pas de colonnes dynamiques, pas d'ALTER TABLE). - Les colonnes les plus recherchées (nom, prénom, date) sont extraites dans des colonnes indexées générées : `ALTER TABLE releves ADD COLUMN nom TEXT GENERATED ALWAYS AS (data->>'nom') STORED;` + index GIN sur `data` pour la recherche fulltext. - Pagination obligatoire (25 par page minimum), jamais de `SELECT *` sans `LIMIT`. ### Dates - Chaque date stocke : `{ "valeur": "1792-09-22", "calendrier": "republicain" }` - Calendriers supportés : `gregorien`, `julien`, `republicain` - Service `DateConversionService` gère la conversion vers/depuis le calendrier républicain (An I = 22 sept 1792). ## Règles d'autorisation | Action | Admin | Resp. Section | Membre assigné | Membre | Visiteur | |---|---|---|---|---|---| | Créer une source | ✓ | ✓ (sa section) | | | | | Assigner un membre à une source | ✓ | ✓ (sa section) | | | | | Saisir/modifier un relevé | ✓ | ✓ | ✓ | | | | Voir relevés (status `termine`) | ✓ | ✓ | ✓ | ✓ | | | Voir relevés (autres status) | ✓ | ✓ (sa section) | ✓ (assigné) | | | | Passer status → `a_valider` | ✓ | ✓ | ✓ (assigné) | | | | Passer status → `termine` | ✓ | ✓ (sa section) | | | | | Gérer utilisateurs / sections | ✓ | | | | | ## Workflow de statut d'une source ``` a_faire → en_cours → a_valider → termine ↑____________| (rejet possible par admin/resp.) ``` Lors du passage en `a_valider`, une notification (mail + notification interne) est envoyée à l'admin et au(x) responsable(s) de la section. ## Performance - Index GIN sur `releves.data` (recherche JSONB). - Colonnes générées stockées + index B-tree pour les champs les plus filtrés (nom, date_evenement). - Eager loading systématique (`with()`) pour éviter les requêtes N+1. - Cache Redis (TTL 1h) sur la liste des lieux (arbre hiérarchique). - Pagination curseur (keyset) plutôt qu'offset pour les listes de relevés volumineuses. ## Export GEDCOM - `GedcomExportService` : génère un fichier `.ged` à partir d'une source ou d'une sélection de relevés. - Format GEDCOM 5.5.1. - Conversion des dates : toujours en grégorien dans le GEDCOM (les calendriers julien/républicain sont convertis). ## Étapes de construction (ordre suggéré) 1. Scaffold Laravel + config PostgreSQL + auth Breeze + middleware rôles 2. Migrations et modèles : `lieux`, `sections`, `users`, `depots`, `source_types`, `source_type_fields`, `sources`, `source_user`, `releves` 3. CRUD Lieux (avec arbre hiérarchique et calcul `nom_long`) 4. CRUD Sections, Dépôts, Types de sources (admin) 5. CRUD Sources + assignation de membres 6. Formulaire de saisie dynamique des relevés (piloté par `source_type_fields`) 7. Workflow de statut + notifications 8. Recherche dans les relevés (fulltext PostgreSQL) 9. Export GEDCOM 10. Interface admin (gestion utilisateurs, statistiques)