Files
mesreleves-php/CLAUDE.md
T
yann64 7609d35287 Initial scaffold : Laravel 12 + PostgreSQL + auth + domaine métier (étapes 1-5)
- 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>
2026-06-04 16:16:37 +02:00

159 lines
6.9 KiB
Markdown

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