7609d35287
- Laravel 12 sur PHP 8.5, Breeze (Blade/Tailwind/Alpine.js) - Docker Compose dev (PostgreSQL 18 + Redis) et prod (stack complète + nginx) - Migrations et models : lieux, sections, dépôts, source_types/fields, sources, relevés - Colonne JSONB data sur releves avec colonnes générées indexées (nom, prenom, date_evenement) - Index GIN pour la recherche fulltext - Enums : UserRole, SourceStatus (avec transitions), CalendarType, FieldType - RoleMiddleware (alias `role`) + helpers isAdmin/isSectionManager sur User - CRUD Lieux (arbre hiérarchique, calcul nom_long en cascade) - CRUD admin : Sections (+ gestion membres), Dépôts, Types de sources (+ champs dynamiques, drag & drop) - CRUD Sources : visibilité filtrée par rôle, assignation membres, workflow de statut Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
6.9 KiB
6.9 KiB
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
# 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_longest 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 surdatapour la recherche fulltext. - Pagination obligatoire (25 par page minimum), jamais de
SELECT *sansLIMIT.
Dates
- Chaque date stocke :
{ "valeur": "1792-09-22", "calendrier": "republicain" } - Calendriers supportés :
gregorien,julien,republicain - Service
DateConversionServicegè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é)
- Scaffold Laravel + config PostgreSQL + auth Breeze + middleware rôles
- Migrations et modèles :
lieux,sections,users,depots,source_types,source_type_fields,sources,source_user,releves - CRUD Lieux (avec arbre hiérarchique et calcul
nom_long) - CRUD Sections, Dépôts, Types de sources (admin)
- CRUD Sources + assignation de membres
- Formulaire de saisie dynamique des relevés (piloté par
source_type_fields) - Workflow de statut + notifications
- Recherche dans les relevés (fulltext PostgreSQL)
- Export GEDCOM
- Interface admin (gestion utilisateurs, statistiques)