diff --git a/README.md b/README.md index ed2e99d..ec33b3d 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,10 @@ Dalibi est un outil complet libre et open-source de gestion pour les établissements scolaires du Togo et d'Afrique (primaire, collège, lycée). Élèves, notes & bulletins, présences, examens officiels, comptabilité & écolage, emploi du temps, documents PDF, stockage local/S3 et sauvegardes planifiées +## 📚 Documentation + +La documentation technique vit dans **[`documentations/`](documentations/README.md)** (prise en main, administration, exploitation, architecture). La référence de l'**API du portail** est à part, dans [`docs/api/`](docs/api/README.md). + ## 🛠️ Stack technique - **Backend** : Laravel 12, PHP 8.3+ @@ -10,7 +14,7 @@ Dalibi est un outil complet libre et open-source de gestion pour les établissem - **Base de données** : PostgreSQL 12+ - **Auth** : Laravel Sanctum + 2FA, Spatie Laravel Permission - **Files d'attente** : e-mails et sauvegardes manuelles traités en arrière-plan (worker) -- **Observabilité** (optionnelle) : logs JSON pour Loki/Grafana + capture d'exceptions Sentry/GlitchTip — voir [`documentations/OBSERVABILITY.md`](documentations/OBSERVABILITY.md) +- **Observabilité** (optionnelle) : logs JSON pour Loki/Grafana + capture d'exceptions Sentry/GlitchTip — voir [`documentations/exploitation/observabilite.md`](documentations/exploitation/observabilite.md) ## 🎓 Fonctionnalités diff --git a/documentations/IMPLEMENTATION_SUMMARY.md b/documentations/IMPLEMENTATION_SUMMARY.md deleted file mode 100644 index 431a191..0000000 --- a/documentations/IMPLEMENTATION_SUMMARY.md +++ /dev/null @@ -1,314 +0,0 @@ -# Service de Génération des Matricules - Résumé de l'Implémentation - -## 📦 Fichiers créés et modifiés - -### 1️⃣ Core Service & Traits - -#### ✅ `app/Services/MatriculeService.php` (NEW) - -- **Lignes**: 141 -- **Responsabilité**: Service principal pour la génération et gestion des matricules -- **Méthodes clés**: - - `generateUserMatricule(string $role)`: Génère matricule utilisateur - - `generateStudentMatricule(string $schoolCode, string $classCode)`: Matricule élève - - `generateRegistrationNumber(string $schoolCode, string $classCode)`: Numéro d'enregistrement - - `parseMatricule(string $matricule)`: Parse un matricule - - `getRoleFromMatricule(string $matricule)`: Extrait le rôle - - `matriculeExists(string $matricule)`: Vérification d'unicité - - Méthodes de validation et péfixes statiques - -#### ✅ `app/Traits/HasMatricule.php` (NEW) - -- **Lignes**: 20 -- **Responsabilité**: Trait pour auto-génération de matricule -- **Hook**: `bootHasMatricule()` sur l'événement `creating` -- **Implémentation**: Appelle `generateMatricule()` si le champ est vide - -### 2️⃣ Modèles améliorés - -#### ✅ `app/Models/User.php` (MODIFIED) - -- **Additions**: - - Import du trait `HasMatricule` - - Méthode `generateMatricule()`: Récupère le rôle et appelle le service - - Méthodes helper: `isAdministrator()`, `isTeacher()`, `isAccounting()`, `isSecretariat()`, `isDirector()` - -#### ✅ `app/Models/Student.php` (MODIFIED) - -- **Additions**: - - Import du trait `HasMatricule` - - Méthode `generateMatricule()`: Appelle le service - - Méthode `generateRegistrationNumber()`: Génère le numéro d'enregistrement - - Hook `boot()`: Auto-génère `registration_number` avant la sauvegarde - -### 3️⃣ Commandes Artisan - -#### ✅ `app/Console/Commands/GenerateUserMatricule.php` (NEW) - -- **Classe**: `GenerateUserMatricule extends Command` -- **Signature**: `matricule:generate-user` -- **Options**: - - `--user-id=VALUE`: Générer pour un utilisateur spécifique - - `--all`: Générer pour tous les utilisateurs sans matricule - - `--force`: Forcer la régénération (remplacer existants) -- **Fonctionnalités**: - - Barre de progression - - Validation et gestion d'erreurs - - Rapports détaillés - -#### ✅ `app/Console/Commands/GenerateStudentMatricule.php` (NEW) - -- **Classe**: `GenerateStudentMatricule extends Command` -- **Signature**: `matricule:generate-student` -- **Options**: - - `--class-id=VALUE`: Générer pour une classe spécifique - - `--all`: Générer pour tous les élèves - - `--force`: Forcer la régénération -- **Fonctionnalités**: - - Génère aussi les numéros d'enregistrement - - Barre de progression - - Rapports de succès/erreurs - -### 4️⃣ Validation - -#### ✅ `app/Rules/ValidMatriculeFormat.php` (NEW) - -- **Interface**: `ValidationRule` -- **Règle**: Valide le format d'un matricule -- **Message**: Message d'erreur français -- **Utilisation**: Dans les Form Requests - -#### ✅ `app/Rules/UniqueMatricule.php` (NEW) - -- **Interface**: `ValidationRule` -- **Fonctionnalité**: Vérifie l'unicité du matricule -- **Support**: Permet l'exception pour les mises à jour (même ID) -- **Messages**: Français - -### 5️⃣ Exceptions - -#### ✅ `app/Exceptions/MatriculeException.php` (NEW) - -- **Méthodes statiques**: - - `generationFailed(string $role)`: Erreur de génération - - `invalidFormat(string $matricule)`: Format invalide - - `alreadyExists(string $matricule)`: Matricule existe - - `roleNotFound(string $role)`: Rôle introuvable - - `parsingFailed(string $matricule)`: Parse impossible - - `modelNotFound(string $type, string $id)`: Modèle non trouvé - -### 6️⃣ Événements et Observers - -#### ✅ `app/Events/MatriculeGenerated.php` (NEW) - -- **Propriétés**: - - `$matricule`: Le matricule généré - - `$type`: 'user' ou 'student' - - `$modelId`: ID du modèle - - `$role`: Rôle (pour les users) - - `$registrationNumber`: Numéro d'enregistrement (pour les students) - -#### ✅ `app/Observers/UserObserver.php` (NEW) - -- **Événements**: - - `created()`: Dispatch `MatriculeGenerated` event - - Prêt pour autres événements (updated, deleted, etc.) - -#### ✅ `app/Observers/StudentObserver.php` (NEW) - -- **Événements**: - - `created()`: Dispatch `MatriculeGenerated` event - - Inclut le numéro d'enregistrement - -### 7️⃣ Configuration et Provider - -#### ✅ `config/matricule.php` (NEW) - -- **Sections**: - - `enabled`: Activation du service - - `user`: Paramètres pour matricules utilisateurs - - `student`: Paramètres pour matricules élèves - - `registration`: Paramètres numéros d'enregistrement - - `role_prefixes`: Mapping rôle → préfixe - - `database`: Noms des tables et colonnes - - `validation`: Configuration de validation - -#### ✅ `app/Providers/AppServiceProvider.php` (MODIFIED) - -- **Additions**: - - Import des Observers - - Méthode `registerObservers()` - - Enregistrement des observers dans `boot()` - -### 8️⃣ Base de données - -#### ✅ `database/migrations/2026_02_16_150000_add_unique_indexes_to_matricules.php` (NEW) - -- **Créations d'index**: - - Index unique sur `users.natricule` - - Index unique sur `students.registration_number` -- **Nettoyage**: Suppression des index lors du rollback - -### 9️⃣ Tests - -#### ✅ `tests/Unit/MatriculeServiceTest.php` (NEW) - -- **Tests**: 18 tests unitaires -- **Couverture**: - - Génération de matricules - - Parsing de matricules - - Extraction de rôles - - Validation de formats - - Vérification d'unicité - - Récupération des préfixes - - Unicité des matricules générés - -#### ✅ `tests/Feature/MatriculeGenerationTest.php` (NEW) - -- **Tests**: 12 tests d'intégration -- **Couverture**: - - Génération automatique par rôle - - Préfixes corrects par rôle - - Inclusion de l'année - - Unicité des matricules - - Identification du rôle à partir du matricule - -### 🔟 Documentation - -#### ✅ `MATRICULE_SERVICE.md` (NEW) - -- **Contenu**: - - Guide d'utilisation complet - - Exemples de code - - Formats des matricules - - Préfixes par rôle - - Commandes Artisan - - Cas d'usage avancés - - Validations personnalisées - - Notes importantes - -#### ✅ `MATRICULE_README.md` (NEW) - -- **Contenu**: - - Vue d'ensemble - - Caractéristiques principales - - Démarrage rapide - - Structure des matricules - - Commandes Artisan détaillées - - Cas d'usage courants - - Configuration - - Tests - - API des méthodes - - Dépannage - - Support et changelog - -## 📊 Statistiques d'implémentation - -| Catégorie | Fichiers | Lignes | Description | -| ---------- | -------- | ---------- | -------------------------------------- | -| Services | 1 | 141 | MatriculeService | -| Traits | 1 | 20 | HasMatricule | -| Modèles | 2 | ~50 | User + Student modifications | -| Commandes | 2 | ~200 | Generate User + Student | -| Validation | 2 | ~50 | ValidMatriculeFormat + UniqueMatricule | -| Exceptions | 1 | 35 | MatriculeException | -| Events | 1 | 20 | MatriculeGenerated | -| Observers | 2 | ~40 | UserObserver + StudentObserver | -| Config | 1 | 60 | matricule.php | -| Migrations | 1 | 30 | Unique indexes | -| Tests | 2 | ~250 | Unit + Feature tests | -| Docs | 2 | ~500 | Documentation | -| **TOTAL** | **18** | **~1,400** | **Implémentation complète** | - -## 🚀 Déploiement - -### Étapes de déploiement - -1. **Migrations**: - -```bash -php artisan migrate -``` - -2. **Seeders** (si nécessaire): - -```bash -php artisan db:seed --class=RolesAndPermissionsSeeder -php artisan db:seed --class=SchoolDemoSeeder -``` - -3. **Configuration** (.env): - -```env -MATRICULE_SERVICE_ENABLED=true -MATRICULE_AUTO_GENERATE_USER=true -MATRICULE_AUTO_GENERATE_STUDENT=true -MATRICULE_COUNTRY_CODE=TG -``` - -4. **Cache** (production): - -```bash -php artisan config:cache -``` - -5. **Génération en masse** (optionnel): - -```bash -php artisan matricule:generate-user --all -php artisan matricule:generate-student --all -``` - -## ✅ Vérification post-déploiement - -```bash -# Tester le service -php artisan tinker - -# Dans tinker: ->>> $service = app(\App\Services\MatriculeService::class); ->>> $matricule = $service->generateUserMatricule('enseignant'); ->>> dd($matricule); -=> "PROF26001" - -# Tester une génération utilisateur ->>> $user = App\Models\User::create([...]); ->>> $user->assignRole('enseignant'); ->>> $user->generateMatricule(); ->>> $user->refresh(); ->>> $user->natricule -=> "PROF26001" -``` - -## 📋 Checklist de validation - -- [x] Service principal créé et fonctionnel -- [x] Trait HasMatricule implémenté -- [x] Modèles enrichis (User, Student) -- [x] Commandes Artisan créées -- [x] Validation des formats -- [x] Exceptions personnalisées -- [x] Observers pour tracking -- [x] Configuration centralisée -- [x] Index unique en base de données -- [x] Tests unitaires complets -- [x] Tests d'intégration complets -- [x] Documentation complète -- [x] Examples d'utilisation fournis - -## 🔄 Intégration future - -### Modules à intégrer avec le matricule - -1. **API REST**: Créer des endpoints pour CRUD des utilisateurs/élèves -2. **Rapports**: Générer des rapports avec les matricules -3. **Notifications**: Envoyer les matricules par email -4. **Export**: Exporter les matricules en CSV/PDF -5. **Audit**: Logger toutes les générations et modifications -6. **QR Codes**: Générer des QR codes des matricules - -## 📞 Contact & Support - -- **Email**: support@ecoliotogo.tg -- **Documentation**: Voir MATRICULE_SERVICE.md et MATRICULE_README.md -- **Tests**: Pour valider, run `php artisan test` diff --git a/documentations/LARAVEL_PERMISSION_SETUP.md b/documentations/LARAVEL_PERMISSION_SETUP.md deleted file mode 100644 index 37b2750..0000000 --- a/documentations/LARAVEL_PERMISSION_SETUP.md +++ /dev/null @@ -1,209 +0,0 @@ -# Configuration de Laravel Permission - -## Installation - -Le package `spatie/laravel-permission` est déjà inclus dans le `composer.json` du projet. - -### Étapes d'installation - -1. **Exécuter les migrations** (incluses dans `2025_02_16_000004_add_role_to_users_table.php`): - - ```bash - php artisan migrate - ``` - -2. **Publier la configuration** (optionnel si vous voulez personnaliser): - - ```bash - php artisan vendor:publish --provider="Spatie\Permission\PermissionServiceProvider" - ``` - -3. **Créer les rôles et permissions initiaux**: - - ```bash - php artisan db:seed --class=RolesAndPermissionsSeeder - ``` - -4. **Créer les données de démo** (optionnel): - ```bash - php artisan db:seed --class=SchoolDemoSeeder - ``` - -Ou tout d'un coup: - -```bash -php artisan db:seed -``` - -## Configuration du Modèle User - -Le modèle `User` inclut déjà le trait `HasRoles`: - -```php -use Spatie\Permission\Traits\HasRoles; - -class User extends Authenticatable -{ - use HasRoles; -} -``` - -## Guard par défaut - -Par défaut, le guard est `web`. Si vous utilisez des guards différents, configurez-le dans le modèle: - -```php -class User extends Authenticatable -{ - protected $guard_name = 'web'; -} -``` - -## Constantes de rôles et permissions - -Utilisez les classes de constantes pour éviter les erreurs de typage: - -```php -use App\Constants\Roles; -use App\Constants\Permissions; - -// Rôles -$user->assignRole(Roles::TEACHER); // Au lieu de 'enseignant' - -// Permissions -$user->givePermissionTo(Permissions::EDIT_GRADES); -``` - -## Vérification du cache - -Les rôles et permissions sont cachés. Après les avoir modifiés directement en base de données, oubliez le cache: - -```php -// Dans le contrôleur ou ailleurs -app()['cache']->forget('spatie.permission.cache'); - -// Ou -\Spatie\Permission\PermissionRegistrar::forgetCachedPermissions(); - -// Ou en CLI -php artisan cache:clear -``` - -## Erreurs courantes - -### 1. Role not found - -``` -Spatie\Permission\Exceptions\RoleDoesNotExist: There is no role named `example`. -``` - -**Solution**: Vérifiez que le rôle a été créé en base de données avant de l'assigner. - -### 2. Permission not found - -``` -Spatie\Permission\Exceptions\PermissionDoesNotExist: There is no permission named `example`. -``` - -**Solution**: Vérifiez que la permission a été créée en base de données. - -### 3. Le cache ne se met pas à jour - -**Solution**: Exécutez `php artisan cache:clear` - -## Personnalisation - -### Ajouter un nouveau rôle - -```php -use Spatie\Permission\Models\Role; - -// Créer le rôle -$role = Role::create(['name' => 'nouveau_role']); - -// Ou utliser les constantes et mettre à jour la classe -// app/Constants/Roles.php -``` - -### Ajouter une nouvelle permission - -```php -use Spatie\Permission\Models\Permission; - -// Créer la permission -$permission = Permission::create(['name' => 'nouvelle_permission']); - -// Ou util utiliser les constantes et mettre à jour la classe -// app/Constants/Permissions.php -``` - -### Assigner une permission à un rôle - -```php -$role = Role::findByName('enseignant'); -$role->givePermissionTo('edit_grades'); -``` - -## Vérifications courantes - -```php -$user = User::find(1); - -// Vérifier un rôle -$user->hasRole('admin'); -$user->hasRole(['admin', 'directeur']); - -// Vérifier une permission -$user->hasPermissionTo('edit_students'); -$user->can('edit_students'); - -// Via rôle -$user->roleIs('admin'); - -// Obtenir les rôles -$user->getRoleNames(); - -// Obtenir les permissions -$user->getAllPermissions(); -``` - -## Middleware - -### Protéger une route par rôle - -```php -Route::group(['middleware' => 'role:admin'], function () { - Route::get('/admin', 'AdminController@index'); -}); -``` - -### Protéger une route par permission - -```php -Route::group(['middleware' => 'permission:edit_students'], function () { - Route::put('/students/{id}', 'StudentController@update'); -}); -``` - -### Combinaison - -```php -// L'utilisateur doit avoir TOUS les rôles et permissions -Route::group(['middleware' => 'role:admin|directeur;permission:edit_students,view_reports'], function () { - // Routes -}); -``` - -## Ressources - -- [Documentation officielle](https://spatie.be/docs/laravel-permission/) -- [GitHub Repository](https://github.com/spatie/laravel-permission) -- [Changelog](https://github.com/spatie/laravel-permission/releases) - -## Support - -Si vous rencontrez des problèmes: - -1. Consultez la [documentation officielle](https://spatie.be/docs/laravel-permission/) -2. Vérifiez les [issues GitHub](https://github.com/spatie/laravel-permission/issues) -3. Contactez: support@ecoliotogo.tg diff --git a/documentations/MATRICULE_FILES_INVENTORY.md b/documentations/MATRICULE_FILES_INVENTORY.md deleted file mode 100644 index 176558a..0000000 --- a/documentations/MATRICULE_FILES_INVENTORY.md +++ /dev/null @@ -1,297 +0,0 @@ -# Fichiers du Service de Matricule - Inventaire Complet - -## 📦 Fichiers CRÉÉS (15 nouveaux fichiers) - -### Services & Traits (2) - -1. ✅ `app/Services/MatriculeService.php` - Service principal (141 lignes) -2. ✅ `app/Traits/HasMatricule.php` - Trait pour auto-génération (20 lignes) - -### Commandes Artisan (2) - -3. ✅ `app/Console/Commands/GenerateUserMatricule.php` - Génère matricules utilisateurs -4. ✅ `app/Console/Commands/GenerateStudentMatricule.php` - Génère matricules élèves - -### Validation (2) - -5. ✅ `app/Rules/ValidMatriculeFormat.php` - Valide format matricule -6. ✅ `app/Rules/UniqueMatricule.php` - Valide unicité matricule - -### Exceptions & Events (3) - -7. ✅ `app/Exceptions/MatriculeException.php` - Exceptions personnalisées -8. ✅ `app/Events/MatriculeGenerated.php` - Événement de génération -9. ✅ `app/Observers/UserObserver.php` - Observer pour utilisateurs -10. ✅ `app/Observers/StudentObserver.php` - Observer pour élèves - -### Configuration (1) - -11. ✅ `config/matricule.php` - Configuration centralisée - -### Base de données (1) - -12. ✅ `database/migrations/2026_02_16_150000_add_unique_indexes_to_matricules.php` - Index uniques - -### Tests (2) - -13. ✅ `tests/Unit/MatriculeServiceTest.php` - 18 tests unitaires -14. ✅ `tests/Feature/MatriculeGenerationTest.php` - 12 tests intégration - -### Documentation (4) - -15. ✅ `MATRICULE_SERVICE.md` - Guide d'utilisation -16. ✅ `MATRICULE_README.md` - Documentation complète -17. ✅ `IMPLEMENTATION_SUMMARY.md` - Résumé technique -18. ✅ `ENV_CONFIGURATION.md` - Configuration .env -19. ✅ `DEPLOYMENT_GUIDE.md` - Guide de déploiement -20. ✅ `MATRICULE_FILES_INVENTORY.md` - Ce fichier (inventaire) - -**Total: 20 fichiers CRÉÉS** - -## 🔄 Fichiers MODIFIÉS (4 fichiers) - -1. ✅ `app/Models/User.php` - - Import du trait `HasMatricule` - - Méthode `generateMatricule()` - - Méthodes helper (isAdministrator, isTeacher, etc.) - -2. ✅ `app/Models/Student.php` - - Import du trait `HasMatricule` - - Méthode `generateMatricule()` - - Méthode `generateRegistrationNumber()` - - Hook `boot()` pour auto-génération - -3. ✅ `app/Providers/AppServiceProvider.php` - - Import des Observers - - Enregistrement des Observers - - Méthode `registerObservers()` - -4. ✅ `app/Constants/Roles.php` (si modifiés) - - 5 rôles en français (administrateur, directeur, enseignant, comptabilité, secrétariat) - -**Total: 4 fichiers MODIFIÉS** - -## 📊 Statistiques - -``` -Fichiers créés: 20 -Fichiers modifiés: 4 -Fichiers totaux: 24 - -Lignes de code: ~1,400 -Tests: 30 (18 unitaires + 12 intégration) -Documentation: ~1,500 lignes - -Couverture: -├── Service: 100% (MatriculeService) -├── Traits: 100% (HasMatricule) -├── Modèles: 100% (User, Student) -├── Commandes: 100% (2 commands) -├── Validation: 100% (2 rules) -├── Exceptions: 100% (MatriculeException) -└── Events/Observers: 100% (2 observers) -``` - -## 🗂️ Structure de répertoires créée - -``` -app/ -├── Services/ -│ └── MatriculeService.php [NEW] -├── Traits/ -│ └── HasMatricule.php [NEW] -├── Rules/ -│ ├── ValidMatriculeFormat.php [NEW] -│ └── UniqueMatricule.php [NEW] -├── Exceptions/ -│ └── MatriculeException.php [NEW] -├── Events/ -│ └── MatriculeGenerated.php [NEW] -├── Observers/ -│ ├── UserObserver.php [NEW] -│ └── StudentObserver.php [NEW] -├── Console/Commands/ -│ ├── GenerateUserMatricule.php [NEW] -│ └── GenerateStudentMatricule.php [NEW] -├── Models/ -│ ├── User.php [MODIFIED] -│ └── Student.php [MODIFIED] -└── Providers/ - └── AppServiceProvider.php [MODIFIED] - -config/ -└── matricule.php [NEW] - -database/migrations/ -└── 2026_02_16_150000_add_unique_indexes_to_matricules.php [NEW] - -tests/ -├── Unit/ -│ └── MatriculeServiceTest.php [NEW] -└── Feature/ - └── MatriculeGenerationTest.php [NEW] - -documentations/ -├── MATRICULE_SERVICE.md [NEW] -├── MATRICULE_README.md [NEW] -├── IMPLEMENTATION_SUMMARY.md [NEW] -├── ENV_CONFIGURATION.md [NEW] -├── DEPLOYMENT_GUIDE.md [NEW] -└── MATRICULE_FILES_INVENTORY.md [NEW - ce fichier] -``` - -## 🎯 Fonctionnalités par fichier - -### Service Principal - -- **MatriculeService**: - - 12 méthodes publiques - - Génération matricules utilisateurs - - Génération matricules élèves - - Numéros d'enregistrement - - Parsing et validation - - Gestion des préfixes par rôle - -### Trait Bootable - -- **HasMatricule**: - - Auto-génération sur création - - Appel transparent du service - - Integration avec Eloquent lifecycle - -### Commandes CLI - -- **GenerateUserMatricule**: - - Options: --user-id, --all, --force - - Barre de progression - - Gestion d'erreurs - -- **GenerateStudentMatricule**: - - Options: --class-id, --all, --force - - Génère aussi registration_number - - Barre de progression - -### Validation - -- **ValidMatriculeFormat**: Valide format "PROF26001" -- **UniqueMatricule**: Vérifie pas de doublon - -### Tests - -- **MatriculeServiceTest**: 18 tests du service -- **MatriculeGenerationTest**: 12 tests d'intégration - -## 📋 Checklist avant utilisation - -- [ ] Fichiers copiés dans le projet -- [ ] Migrations exécutées: `php artisan migrate` -- [ ] Seeders lancés: `php artisan db:seed` -- [ ] Tests passants: `php artisan test` -- [ ] `.env` configuré avec variables matricule -- [ ] Cache redessiné: `php artisan config:cache` -- [ ] Documentation lue (MATRICULE_SERVICE.md) - -## 🚀 Démarrage rapide - -```bash -# 1. Migrations -php artisan migrate - -# 2. Seeders (données démo) -php artisan db:seed --class=RolesAndPermissionsSeeder -php artisan db:seed --class=SchoolDemoSeeder - -# 3. Tests -php artisan test - -# 4. Générer matricules existants -php artisan matricule:generate-user --all -php artisan matricule:generate-student --all - -# 5. Vérifier -php artisan tinker ->>> $user = App\Models\User::first(); ->>> $user->natricule; -=> "ADM26001" -``` - -## 📖 Documentation - -### Pour démarrer - -👉 Lire: `DEPLOYMENT_GUIDE.md` - -### Pour utiliser - -👉 Lire: `MATRICULE_SERVICE.md` - -### Pour comprendre l'architecture - -👉 Lire: `IMPLEMENTATION_SUMMARY.md` - -### Pour configurer - -👉 Lire: `ENV_CONFIGURATION.md` - -### Pour toutes les détails - -👉 Lire: `MATRICULE_README.md` - -## 🔗 Dépendances - -### Fichiers du projet requis - -- `app/Constants/Roles.php` - Définition des rôles -- `app/Models/User.php` - Modèle utilisateur -- `app/Models/Student.php` - Modèle élève -- `app/Models/School.php` - Modèle école (pour contexte) - -### Packages Laravel requuis - -- `spatie/laravel-permission` - Gestion des rôles -- `illuminate/database` - ORM Eloquent -- `illuminate/console` - Commandes Artisan - -### Aucune dépendance externe supplémentaire! - -## ✅ État de l'implémentation - -- [x] Service principal créé -- [x] Traits implémentés -- [x] Commandes Artisan créées -- [x] Validation mise en place -- [x] Exceptions personnalisées -- [x] Observers enregistrés -- [x] Configuration externalisée -- [x] Migrations DB créées -- [x] Tests unitaires complets -- [x] Tests intégration complets -- [x] Documentation complète - -## 🎉 Prochaines étapes après matricule - -1. Créer contrôleurs API (StudentController, UserController) -2. Implémenter endpoints CRUD avec matricule auto-génération -3. Ajouter notifications/emails avec matricule -4. Implémenter QR codes des matricules -5. Ajouter rapports/exports -6. Audit trail des générations -7. UI d'administration des matricules - -## 📞 Support - -- Voir les fichiers documentation -- Email: support@ecoliotogo.tg -- Tests: `php artisan test` -- Debug: `php artisan tinker` - -## 📝 Changelog - -### v1.0.0 (Initial Release) - -- ✅ Service complet MatriculeService -- ✅ Auto-génération via trait -- ✅ Commandes batch generation -- ✅ Validation et exceptions -- ✅ Tests complets -- ✅ Documentation diff --git a/documentations/MATRICULE_SERVICE.md b/documentations/MATRICULE_SERVICE.md deleted file mode 100644 index 1d59b24..0000000 --- a/documentations/MATRICULE_SERVICE.md +++ /dev/null @@ -1,291 +0,0 @@ -# Guide d'utilisation du Service Matricule - -## Vue d'ensemble - -Le service `MatriculeService` permet de générer automatiquement les matricules uniques pour les utilisateurs et les élèves selon un format spécifique. - -## Formats de Matricules - -### Matricule Utilisateur -Format: `{PREFIXE}{ANNEE}{SEQUENCE}` - -Exemples: -- **Administrateur**: `ADM26001` (Administrateur, 2026, sequence 001) -- **Professeur**: `PROF26001` (Professeur, 2026, sequence 001) -- **Comptable**: `COMPT26002` (Comptabilité, 2026, sequence 002) -- **Secrétaire**: `SEC26001` (Secrétariat, 2026, sequence 001) -- **Directeur**: `DIR26001` (Directeur, 2026, sequence 001) - -### Matricule Élève -Format: `{CODE_ECOLE}STU{ANNEE}{SEQUENCE}` - -Exemples: -- `ECOSTU26001` (Élève à l'école ECO, 2026, sequence 001) -- `LOMESTU26002` (Élève à Lomé, 2026, sequence 002) - -### Numéro d'Enregistrement -Format: `REG-{CODE_PAYS}-{ANNEE}-{SEQUENCE}` - -Exemples: -- `REG-TG-2026-001` (Togo 2026, sequence 001) -- `REG-LO-2026-002` (Lomé 2026, sequence 002) - -## Utilisation dans le Code - -### 1. Génération Automatique - -#### Pour les Utilisateurs -```php -use App\Models\User; - -// Créer un utilisateur -$user = User::create([ - 'firstname' => 'Jean', - 'lastname' => 'Dupont', - 'email' => 'jean@example.com', - 'password' => bcrypt('password'), -]); - -// Le matricule est généré automatiquement dans la migration des rôles -$user->assignRole('enseignant'); -$user->natricule = $user->generateMatricule(); -$user->save(); - -echo $user->natricule; // PROF26001 -``` - -#### Pour les Élèves -```php -use App\Models\Student; -use App\Models\User; - -// Créer l'utilisateur d'abord -$userStudent = User::create([ - 'firstname' => 'Ahmed', - 'lastname' => 'Ouedraogo', - 'email' => 'ahmed@example.com', - 'password' => bcrypt('password'), -]); - -// Créer l'enregistrement d'élève -$student = Student::create([ - 'user_id' => $userStudent->id, - 'class_id' => $class->id, - 'parent_name' => 'Maman Ahmed', - 'parent_phone' => '+228 22 123 456', - 'enrollment_date' => now(), -]); - -// Le numéro d'enregistrement est généré automatiquement -echo $student->registration_number; // REG-TG-2026-001 -``` - -### 2. Génération Manuelle - -```php -use App\Services\MatriculeService; - -$matriculeService = app(MatriculeService::class); - -// Générer un matricule utilisateur -$userMatricule = $matriculeService->generateUserMatricule('enseignant', 'ECOL001'); -// Résultat: PROF26001 - -// Générer un matricule élève -$studentMatricule = $matriculeService->generateStudentMatricule('ECOL001', 'CM1A'); -// Résultat: ECSTU26001 - -// Générer un numéro d'enregistrement -$regNumber = $matriculeService->generateRegistrationNumber('ECOL001', 'CM1A'); -// Résultat: REG-EC-2026-001 -``` - -### 3. Vérification d'Existence - -```php -use App\Services\MatriculeService; - -$matriculeService = app(MatriculeService::class); - -// Vérifier si un matricule existe -if ($matriculeService->matriculeExists('PROF26001')) { - echo 'Ce matricule existe déjà'; -} - -// Vérifier si un numéro d'enregistrement existe -if ($matriculeService->registrationNumberExists('REG-TG-2026-001')) { - echo 'Ce numéro d\'enregistrement existe'; -} -``` - -### 4. Parser un Matricule - -```php -use App\Services\MatriculeService; - -$matriculeService = app(MatriculeService::class); - -$info = $matriculeService->parseMatricule('PROF26001'); - -// Résultat: -// [ -// 'prefix' => 'PROF', -// 'year' => '2026', -// 'sequence' => 1, -// ] -``` - -### 5. Obtenir le Rôle à partir du Matricule - -```php -use App\Services\MatriculeService; - -$matriculeService = app(MatriculeService::class); - -$role = $matriculeService->getRoleFromMatricule('PROF26001'); -// Résultat: 'enseignant' -``` - -## Commandes Artisan - -### Générer les Matricules pour les Utilisateurs - -```bash -# Générer pour un utilisateur spécifique -php artisan matricule:generate-user --user-id=1 - -# Générer pour tous les utilisateurs sans matricule -php artisan matricule:generate-user --all - -# Forcer la régénération d'un matricule existant -php artisan matricule:generate-user --user-id=1 --force -``` - -### Générer les Matricules pour les Élèves - -```bash -# Générer pour tous les élèves -php artisan matricule:generate-student --all - -# Générer pour une classe spécifique -php artisan matricule:generate-student --class-id=1 - -# Générer aussi les numéros d'enregistrement -php artisan matricule:generate-student --all --registration - -# Forcer la régénération -php artisan matricule:generate-student --all --force -``` - -## Préfixes par Rôle - -| Rôle | Préfixe | Exemple | -|------|---------|---------| -| Administrateur | ADM | ADM26001 | -| Directeur | DIR | DIR26001 | -| Enseignant | PROF | PROF26001 | -| Comptabilité | COMPT | COMPT26001 | -| Secrétariat | SEC | SEC26001 | - -## Constantes Disponibles - -```php -use App\Services\MatriculeService; - -// Obtenir les préfixes disponibles -$prefixes = MatriculeService::getPrefixes(); - -// Résultat: -// [ -// 'administrateur' => 'ADM', -// 'directeur' => 'DIR', -// 'enseignant' => 'PROF', -// 'comptabilité' => 'COMPT', -// 'secrétariat' => 'SEC', -// ] -``` - -## Validations Personnalisées - -### Validator pour le Matricule - -```php -use Illuminate\Validation\Rule; - -$validated = $request->validate([ - 'natricule' => [ - 'required', - 'string', - 'unique:users,natricule', - 'regex:/^([A-Z]{3,4}[0-9]{2}[0-9]{3})$/', - ], -]); -``` - -### Request Personnalisée - -```php -namespace App\Http\Requests; - -use Illuminate\Foundation\Http\FormRequest; - -class StoreUserRequest extends FormRequest -{ - public function rules() - { - return [ - 'natricule' => [ - 'required', - 'unique:users,natricule', - 'regex:/^([A-Z]{3,4}[0-9]{2}[0-9]{3})$/', - ], - ]; - } -} -``` - -## Cas d'Usage Avancés - -### Générer un Matricule Aléatoire Sécurisé - -```php -use App\Services\MatriculeService; - -$matriculeService = app(MatriculeService::class); - -// Pour les cas spéciaux qui nécessitent un format différent -$randomMatricule = $matriculeService->generateRandomMatricule('CUSTOM'); -// Résultat: CUSTOM-1708098544-1A2B3C4D -``` - -### Migration en Masse - -```php -use App\Models\User; -use App\Services\MatriculeService; - -// Dans une commande ou un seeder -$matriculeService = app(MatriculeService::class); - -User::whereNull('natricule')->each(function ($user) use ($matriculeService) { - $user->update([ - 'natricule' => app(MatriculeService::class)->generateUserMatricule( - $user->roles->first()?->name ?? 'administrator' - ), - ]); -}); -``` - -## Besoin d'Aide? - -Consultez: -- [Laravel Documentation](https://laravel.com/docs) -- Application: support@ecoliotogo.tg - -## Notes Importantes - -1. ⚠️ Les matricules sont **uniques** et ne peuvent pas être dupliqués -2. ✅ L'année change automatiquement chaque année civile -3. ✅ La séquence s'incrémente automatiquement -4. ✅ Les matricules incluent le rôle dans le préfixe -5. ✅ Compatible avec les migrations et les seeders diff --git a/documentations/PERMISSIONS.md b/documentations/PERMISSIONS.md deleted file mode 100644 index 8a343e1..0000000 --- a/documentations/PERMISSIONS.md +++ /dev/null @@ -1,300 +0,0 @@ -# Guide d'utilisation de Laravel Permission - -## Configuration de Lararel Permission - -L'application utilise **[Spatie Laravel Permission](https://spatie.be/docs/laravel-permission/v6/introduction)** pour gérer les rôles et permissions. - -## Rôles Disponibles - -### 1. Admin (Administrateur) - -- **Accès complet** à tous les modules -- Gestion des utilisateurs, rôles et permissions -- Configuration du système - -### 2. Directeur (Directeur d'école) - -- Gestion de l'école -- Création et modification des années académiques -- Gestion des classes -- Suivi des étudiants -- Consultation des rapports - -### 3. Enseignant (Professeur) - -- Visualisation de ses classes -- Saisie des notes -- Gestion des présences -- Consultation des informations étudiants - -### 4. Comptable (Agent financier) - -- Gestion financière -- Consultation des étudiants -- Visualisation des rapports -- Export de rapports - -### 5. Secrétaire - -- Gestion des étudiants -- Gestion des utilisateurs -- Consultation des classes et présences -- Visualisation des rapports - -### 6. Étudiant - -- Consultation de ses notes -- Visualisation de ses présences - -## Utilisation dans le Code - -### Vérifier un rôle - -```php -// Vérification simple -if ($user->hasRole('admin')) { - // L'utilisateur a le rôle admin -} - -// Méthodes pratiques -if ($user->isAdmin()) { } -if ($user->isTeacher()) { } -if ($user->isAccountant()) { } -if ($user->isSecretary()) { } -if ($user->isDirector()) { } - -// Vérifier plusieurs rôles (OU) -if ($user->hasAnyRole(['admin', 'directeur'])) { - // L'utilisateur a l'un de ces rôles -} - -// Vérifier tous les rôles (ET) -if ($user->hasAllRoles(['admin', 'enseignant'])) { - // L'utilisateur a TOUS ces rôles -} -``` - -### Assigner des rôles - -```php -// Assigner un rôle -$user->assignRole('enseignant'); - -// Assigner plusieurs rôles -$user->assignRole(['directeur', 'enseignant']); - -// En masse -$user->syncRoles(['admin']); // Remplace tous les rôles -``` - -### Retirer des rôles - -```php -// Retirer un rôle -$user->removeRole('enseignant'); - -// Retirer plusieurs rôles -$user->removeRole(['directeur', 'enseignant']); - -// Vider tous les rôles -$user->syncRoles([]); -``` - -## Permissions - -### Vérifier une permission - -```php -// Vérification simple -if ($user->hasPermission('edit_students')) { - // L'utilisateur a la permission -} - -// Via can() -if ($user->can('edit_students')) { - // L'utilisateur peut éditer les étudiants -} - -// Vérifier plusieurs permissions (OU) -if ($user->hasAnyPermission(['edit_students', 'delete_students'])) { } - -// Vérifier toutes les permissions (ET) -if ($user->hasAllPermissions(['edit_students', 'view_students'])) { } -``` - -### Assigner des permissions - -```php -// Au rôle -$role = Role::findByName('enseignant'); -$role->givePermissionTo('edit_grades'); - -// À l'utilisateur -$user->givePermissionTo('edit_grades'); - -// Multiple -$user->givePermissionTo(['edit_grades', 'view_grades']); -``` - -### Retirer des permissions - -```php -// Du rôle -$role->revokePermissionTo('edit_grades'); - -// De l'utilisateur -$user->revokePermissionTo('edit_grades'); -``` - -## Utilisation dans les Routes - -### Middleware de Rôle - -```php -Route::group(['middleware' => 'role:admin'], function () { - Route::get('/admin', 'AdminController@index'); -}); - -// Plusieurs rôles (OU) -Route::group(['middleware' => 'role:admin|directeur'], function () { - // Accessible aux admins et directeurs -}); -``` - -### Middleware de Permission - -```php -Route::group(['middleware' => 'permission:edit_students'], function () { - Route::post('/students/{student}', 'StudentController@update'); -}); - -// Plusieurs permissions (ET) -Route::group(['middleware' => 'permission:edit_students,view_students'], function () { - // L'utilisateur doit avoir TOUTES ces permissions -}); -``` - -### Combiné - -```php -Route::group(['middleware' => 'role:admin|directeur;permission:edit_students'], function () { - // Doit avoir le rôle AND la permission -}); -``` - -## Utilisation dans les Contrôleurs - -```php -public function edit($id) -{ - // Vérifier la permission - if (!auth()->user()->can('edit_students')) { - abort(403, 'Non autorisé'); - } - - // Ou utiliser authorize() - $this->authorize('edit_students'); - - // Code... -} -``` - -## Utilisation dans les Blade Templates - -```blade -@can('edit_students') - -@endcan - -@role('admin') - -@endrole - -@hasrole('directeur') - Rapports -@endhasrole - -@cannot('delete_students') -

Vous n'avez pas la permission de supprimer

-@endcannot -``` - -## Exemple Complet - -### Création d'un nouveau rôle avec permissions - -```php -use Spatie\Permission\Models\Role; -use Spatie\Permission\Models\Permission; - -// Créer les permissions -Permission::create(['name' => 'view_custom']); -Permission::create(['name' => 'create_custom']); -Permission::create(['name' => 'edit_custom']); - -// Créer le rôle -$customRole = Role::create(['name' => 'custom_role']); - -// Assigner les permissions au rôle -$customRole->givePermissionTo(['view_custom', 'create_custom', 'edit_custom']); - -// Assigner le rôle à un utilisateur -$user->assignRole('custom_role'); -``` - -## Ajouter un rôle personnalisé (sans code) - -Le contrôle d'accès est **piloté par les permissions**, pas par les rôles : un rôle -personnalisé doté des bonnes permissions fonctionne automatiquement pour les menus, -les routes (`can:*`), les cartes d'accueil et les sections du tableau de bord. - -1. **Créer le rôle et lui accorder des permissions** depuis l'interface - (Administration → Rôles & permissions, gardée par `manage_roles_permissions`). -2. **Assigner le rôle** à des utilisateurs (Administration → Utilisateurs) : la liste - des rôles est lue depuis la base, votre rôle y apparaît immédiatement. - -> Il n'existe **pas** de super-rôle « magique » : même l'administrateur tire son accès -> de permissions accordées par le seeder. Ajouter une permission à un rôle suffit. - -### Préfixe de matricule pour un rôle personnalisé - -Par défaut, les utilisateurs d'un rôle inconnu reçoivent le préfixe générique `USR`. -Pour attribuer un préfixe dédié, ajoutez une entrée dans `config/matricule.php` : - -```php -'role_prefixes' => [ - 'censeur' => 'CENS', - 'surveillant' => 'SURV', -], -``` - -### Limites connues (couplages spécifiques au métier) - -- Les listes déroulantes « enseignant » (affectations, emploi du temps) recensent les - utilisateurs ayant la permission **`create_marks`** — donnez cette permission au rôle - pour qu'il soit sélectionnable comme enseignant. - -## Cache - -Les rôles et permissions sont cachés. Après les avoir modifiés en base de données, actualisez le cache: - -```php -app()['cache']->forget('spatie.permission.cache'); -// ou -\Spatie\Permission\PermissionRegistrar::forgetCachedPermissions(); -``` - -Ou dans l'application: - -```bash -php artisan cache:clear -``` - -## Ressources - -- [Documentation Spatie Permission](https://spatie.be/docs/laravel-permission/v6/introduction) -- [GitHub](https://github.com/spatie/laravel-permission) - -## Support - -Pour les questions, contactez: support@ecoliotogo.tg diff --git a/documentations/README.md b/documentations/README.md new file mode 100644 index 0000000..cb665f6 --- /dev/null +++ b/documentations/README.md @@ -0,0 +1,38 @@ +# Documentation Dalibi + +Documentation technique de **Dalibi** — logiciel libre de gestion scolaire. + +> La **référence de l'API du portail** vit à part, dans [`docs/api/`](../docs/api/README.md) (spécification OpenAPI). + +Légende : ✅ disponible · 🚧 à rédiger. + +## 🚀 Prise en main +- ✅ [Configuration `.env`](prise-en-main/configuration-env.md) +- 🚧 Installation locale — voir le [README](../README.md) +- 🚧 Premiers pas — créer une école, une année, un premier élève + +## 🛠️ Administration +- ✅ [Rôles & permissions](administration/roles-permissions.md) +- 🚧 Paramétrage de l'école — classes, matières, frais, années +- 🚧 Stockage S3 / R2 +- 🚧 Modèles de documents — en-tête, filigrane + +## ⚙️ Exploitation +- ✅ [Déploiement](exploitation/deploiement.md) +- ✅ [Observabilité](exploitation/observabilite.md) +- 🚧 Sauvegarde & restauration (runbook) — voir la section Sauvegardes du [README](../README.md) +- 🚧 Mises à jour + +## 🏗️ Architecture +- ✅ [Matricule](architecture/matricule.md) +- 🚧 Vue d'ensemble — stack & modules +- 🚧 Modèle de données — voir le dictionnaire des tables dans le [README](../README.md) +- 🚧 Services métier — GradingService, PayrollService, BackupService… + +## 🔌 API +- ✅ [API du portail (parents & élèves)](../docs/api/README.md) + +## 🤝 Contribuer +- ✅ [Guide de contribution](../CONTRIBUTING.md) +- ✅ [Code de conduite](../CODE_OF_CONDUCT.md) +- ✅ [Politique de sécurité](../SECURITY.md) diff --git a/documentations/administration/roles-permissions.md b/documentations/administration/roles-permissions.md new file mode 100644 index 0000000..52f8ec3 --- /dev/null +++ b/documentations/administration/roles-permissions.md @@ -0,0 +1,147 @@ +# Rôles & permissions + +Dalibi utilise **[Spatie Laravel Permission](https://spatie.be/docs/laravel-permission/v6/introduction)**. Le contrôle d'accès est **piloté par les permissions** (`{capacité}_{module}`, ex. `view_students`, `create_archives`, `delete_backups`), pas par les rôles : un rôle doté des bonnes permissions fonctionne automatiquement pour les menus, les routes (`can:*`), les cartes d'accueil et le tableau de bord. **~145 permissions** au total (voir `App\Constants\Permissions`). + +> **Une permission par verbe.** Les routes appliquent une permission distincte selon l'action : un droit de lecture (`view_*`) ne permet jamais de créer, modifier ou supprimer. + +## Rôles fournis par défaut + +| Rôle | Portée | +| --- | --- | +| **Administrateur** | Accès complet ; gestion des utilisateurs, rôles et permissions ; configuration système | +| **Directeur** | Gestion de l'école, années académiques, classes, suivi des élèves, rapports | +| **Enseignant** | Ses classes, saisie des notes, présences, consultation des élèves | +| **Comptable** | Gestion financière, consultation des élèves, rapports et exports | +| **Secrétaire** | Élèves & inscriptions, utilisateurs, consultation classes/présences, rapports | +| **Étudiant / Parent** | Consultation des notes et présences (portail) | + +> Il n'existe **pas** de super-rôle « magique » : même l'administrateur tire son accès des permissions accordées par le seeder. + +### Garde-fous sur les comptes à privilèges + +- Seul un **administrateur** peut modifier ou supprimer un compte administrateur. +- Un mot de passe défini par un tiers impose un **changement à la première connexion**. +- Le **rôle administrateur** ne peut être ni renommé ni dépouillé de ses permissions (sans quoi l'instance serait verrouillée sans recours). + +## Installation & seeding + +Le package `spatie/laravel-permission` est déjà inclus dans le `composer.json`. + +```bash +# 1. Migrations (rôles/permissions inclus) +php artisan migrate + +# 2. Créer rôles & permissions initiaux +php artisan db:seed --class=RolesAndPermissionsSeeder + +# 3. Production : données de référence complètes (catalogues inclus) +php artisan db:seed --class=ReferenceDataSeeder +``` + +Le modèle `User` inclut déjà le trait `HasRoles` et le guard `web` par défaut. + +> Les seeders de **démonstration** sont automatiquement ignorés quand `APP_ENV=production`, y compris avec `--force`. + +### Constantes typées + +Utilisez les classes de constantes plutôt que des chaînes brutes : + +```php +use App\Constants\Roles; +use App\Constants\Permissions; + +$user->assignRole(Roles::TEACHER); // au lieu de 'enseignant' +$user->givePermissionTo(Permissions::EDIT_GRADES); +``` + +## Utilisation dans le code + +### Rôles + +```php +$user->assignRole('enseignant'); +$user->syncRoles(['administrateur']); // remplace tous les rôles +$user->removeRole('enseignant'); + +$user->hasRole('administrateur'); +$user->hasAnyRole(['administrateur', 'directeur']); // OU +$user->hasAllRoles(['administrateur', 'enseignant']); // ET +$user->getRoleNames(); +``` + +### Permissions + +```php +$role = Role::findByName('enseignant'); +$role->givePermissionTo('edit_grades'); +$user->givePermissionTo(['edit_grades', 'view_grades']); +$role->revokePermissionTo('edit_grades'); + +$user->can('edit_students'); +$user->hasAnyPermission(['edit_students', 'delete_students']); // OU +$user->hasAllPermissions(['edit_students', 'view_students']); // ET +``` + +### Routes + +```php +Route::group(['middleware' => 'permission:edit_students'], function () { /* … */ }); + +// Une permission par verbe sur une ressource : +Route::resource('students', StudentController::class) + ->middleware('can:view_students') + ->middlewareFor(['create', 'store'], 'can:create_students') + ->middlewareFor(['edit', 'update'], 'can:edit_students') + ->middlewareFor('destroy', 'can:delete_students'); +``` + +`middlewareFor` **fusionne** avec le middleware de base : `destroy` exige donc *view + delete*. + +### Contrôleurs & Blade + +```php +$this->authorize('edit_students'); // ou : abort_unless($request->user()->can('edit_students'), 403); +``` + +```blade +@can('edit_students') @endcan +@role('administrateur') @endrole +``` + +## Ajouter un rôle personnalisé (sans code) + +1. **Créer le rôle et lui accorder des permissions** depuis l'interface (Administration → Rôles & permissions, gardée par `manage_roles_permissions`). +2. **Assigner le rôle** à des utilisateurs (Administration → Utilisateurs) : la liste des rôles est lue depuis la base, votre rôle y apparaît immédiatement. + +### Préfixe de matricule d'un rôle personnalisé + +Par défaut, un rôle inconnu reçoit le préfixe générique `USR`. Pour un préfixe dédié, ajoutez une entrée dans `config/matricule.php` (voir [Matricule](../architecture/matricule.md)) : + +```php +'role_prefixes' => [ + 'censeur' => 'CENS', + 'surveillant' => 'SURV', +], +``` + +### Limites connues (couplages métier) + +- Les listes déroulantes « enseignant » (affectations, emploi du temps) recensent les utilisateurs ayant la permission **`create_marks`** — donnez cette permission au rôle pour qu'il soit sélectionnable comme enseignant. +- **Cloisonnement enseignant** : un utilisateur porteur d'affectations ne saisit notes et appels que dans ses classes. Les profils sans aucune affectation (administration, vie scolaire) restent transverses. + +## Cache + +Les rôles et permissions sont mis en cache. Après une modification directe en base : + +```bash +php artisan cache:clear +``` + +```php +\Spatie\Permission\PermissionRegistrar::forgetCachedPermissions(); +``` + +## Ressources + +- [Documentation Spatie Permission](https://spatie.be/docs/laravel-permission/v6/introduction) +- [GitHub du package](https://github.com/spatie/laravel-permission) diff --git a/documentations/MATRICULE_README.md b/documentations/architecture/matricule.md similarity index 94% rename from documentations/MATRICULE_README.md rename to documentations/architecture/matricule.md index a820299..9e12030 100644 --- a/documentations/MATRICULE_README.md +++ b/documentations/architecture/matricule.md @@ -389,25 +389,6 @@ php artisan matricule:generate-user --user-id=1 --force ## 📞 Support -Pour toutes les questions ou problèmes: +Pour toute question : ouvrez une issue sur [le dépôt GitHub](https://github.com/wearedalibi/dalibi/issues). -- Consultez la documentation complète: [MATRICULE_SERVICE.md](MATRICULE_SERVICE.md) -- Ouvrez une issue sur GitHub -- Contactez: support@ecoliotogo.tg - -## 📜 Changelog - -### Version 1.0.0 - -- ✅ Service principal MatriculeService -- ✅ Trait HasMatricule pour auto-génération -- ✅ Commandes Artisan pour batch generation -- ✅ Observers pour tracking -- ✅ Validation Rules -- ✅ Configuration centralisée -- ✅ Tests complets -- ✅ Documentation - -## 📄 License - -Spécifiez votre license (MIT, Apache 2.0, etc.) +Voir aussi : [Rôles & permissions](../administration/roles-permissions.md) — préfixe de matricule d'un rôle personnalisé. diff --git a/documentations/DEPLOYMENT_GUIDE.md b/documentations/exploitation/deploiement.md similarity index 100% rename from documentations/DEPLOYMENT_GUIDE.md rename to documentations/exploitation/deploiement.md diff --git a/documentations/OBSERVABILITY.md b/documentations/exploitation/observabilite.md similarity index 100% rename from documentations/OBSERVABILITY.md rename to documentations/exploitation/observabilite.md diff --git a/documentations/ENV_CONFIGURATION.md b/documentations/prise-en-main/configuration-env.md similarity index 100% rename from documentations/ENV_CONFIGURATION.md rename to documentations/prise-en-main/configuration-env.md diff --git a/package-lock.json b/package-lock.json index c984a96..1a03897 100644 --- a/package-lock.json +++ b/package-lock.json @@ -18,8 +18,6 @@ "@radix-ui/react-select": "^2.1.6", "@radix-ui/react-separator": "^1.1.2", "@radix-ui/react-slot": "^1.2.3", - "@radix-ui/react-toggle": "^1.1.2", - "@radix-ui/react-toggle-group": "^1.1.2", "@radix-ui/react-tooltip": "^1.1.8", "@tailwindcss/vite": "^4.1.11", "@tiptap/extension-text-align": "^3.26.1", @@ -2625,157 +2623,6 @@ } } }, - "node_modules/@radix-ui/react-toggle": { - "version": "1.1.10", - "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle/-/react-toggle-1.1.10.tgz", - "integrity": "sha512-lS1odchhFTeZv3xwHH31YPObmJn8gOg7Lq12inrr0+BH/l3Tsq32VfjqH1oh80ARM3mlkfMic15n0kg4sD1poQ==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-use-controllable-state": "1.2.2" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-toggle-group": { - "version": "1.1.11", - "resolved": "https://registry.npmjs.org/@radix-ui/react-toggle-group/-/react-toggle-group-1.1.11.tgz", - "integrity": "sha512-5umnS0T8JQzQT6HbPyO7Hh9dgd82NmS36DQr+X/YJ9ctFNCiiQd6IJAYYZ33LUwm8M+taCz5t2ui29fHZc4Y6Q==", - "license": "MIT", - "dependencies": { - "@radix-ui/primitive": "1.1.3", - "@radix-ui/react-context": "1.1.2", - "@radix-ui/react-direction": "1.1.1", - "@radix-ui/react-primitive": "2.1.3", - "@radix-ui/react-roving-focus": "1.1.11", - "@radix-ui/react-toggle": "1.1.10", - "@radix-ui/react-use-controllable-state": "1.2.2" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-toggle-group/node_modules/@radix-ui/react-context": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/@radix-ui/react-context/-/react-context-1.1.2.tgz", - "integrity": "sha512-jCi/QKUM2r1Ju5a3J64TH2A5SpKAgh0LpknyqdQ4m6DCV0xJ2HG1xARRwNGPQfi1SLdLWZ1OJz6F4OMBBNiGJA==", - "license": "MIT", - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-toggle-group/node_modules/@radix-ui/react-primitive": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", - "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-slot": "1.2.3" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-toggle-group/node_modules/@radix-ui/react-slot": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", - "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-compose-refs": "1.1.2" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-toggle/node_modules/@radix-ui/react-primitive": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-primitive/-/react-primitive-2.1.3.tgz", - "integrity": "sha512-m9gTwRkhy2lvCPe6QJp4d3G1TYEUHn/FzJUtq9MjH46an1wJU+GdoGC5VLof8RX8Ft/DlpshApkhswDLZzHIcQ==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-slot": "1.2.3" - }, - "peerDependencies": { - "@types/react": "*", - "@types/react-dom": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc", - "react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - }, - "@types/react-dom": { - "optional": true - } - } - }, - "node_modules/@radix-ui/react-toggle/node_modules/@radix-ui/react-slot": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@radix-ui/react-slot/-/react-slot-1.2.3.tgz", - "integrity": "sha512-aeNmHnBxbi2St0au6VBVC7JXFlhLlOnvIIlePNniyUNAClzmtAUEY8/pBiK3iHjufOlwA+c20/8jngo7xcrg8A==", - "license": "MIT", - "dependencies": { - "@radix-ui/react-compose-refs": "1.1.2" - }, - "peerDependencies": { - "@types/react": "*", - "react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, "node_modules/@radix-ui/react-tooltip": { "version": "1.2.8", "resolved": "https://registry.npmjs.org/@radix-ui/react-tooltip/-/react-tooltip-1.2.8.tgz", diff --git a/package.json b/package.json index 2552b2a..c5d5ef1 100644 --- a/package.json +++ b/package.json @@ -41,8 +41,6 @@ "@radix-ui/react-select": "^2.1.6", "@radix-ui/react-separator": "^1.1.2", "@radix-ui/react-slot": "^1.2.3", - "@radix-ui/react-toggle": "^1.1.2", - "@radix-ui/react-toggle-group": "^1.1.2", "@radix-ui/react-tooltip": "^1.1.8", "@tailwindcss/vite": "^4.1.11", "@tiptap/extension-text-align": "^3.26.1", diff --git a/resources/js/components/Schools/school-drawer.tsx b/resources/js/components/Schools/school-drawer.tsx deleted file mode 100644 index 681d3f3..0000000 --- a/resources/js/components/Schools/school-drawer.tsx +++ /dev/null @@ -1,247 +0,0 @@ -import { useForm } from '@inertiajs/react'; -import { useEffect } from 'react'; -import { CreateDrawer } from '@/components/create-drawer'; -import { Button } from '@/components/ui/button'; -import { Input } from '@/components/ui/input'; -import { Textarea } from '@/components/ui/textarea'; -import { route } from '@/helpers/route'; - -interface SchoolData { - id?: string; - name: string; - code: string; - email: string | null; - phone: string | null; - address: string | null; -} - -interface SchoolDrawerProps { - isOpen: boolean; - onOpenChange: (open: boolean) => void; - school?: SchoolData | null; - onSuccess?: () => void; -} - -export function SchoolDrawer({ - isOpen, - onOpenChange, - school, - onSuccess, -}: Readonly) { - const isEditing = !!school?.id; - - const { data, setData, post, put, processing, reset, errors } = useForm({ - name: school?.name || '', - code: school?.code || '', - email: school?.email || '', - phone: school?.phone || '', - address: school?.address || '', - }); - - // Réinitialiser le formulaire quand school change ou le drawer s'ouvre - useEffect(() => { - if (isOpen && school?.id) { - setData({ - name: school.name, - code: school.code, - email: school.email || '', - phone: school.phone || '', - address: school.address || '', - }); - } else if (isOpen && !school?.id) { - reset(); - } - }, [school?.id, isOpen]); - - const handleSubmit = (e: React.SubmitEvent) => { - e.preventDefault(); - - if (isEditing && school?.id) { - put(route('schools.update', school.id), { - onSuccess: () => { - reset(); - onOpenChange(false); - onSuccess?.(); - }, - }); - } else { - post(route('schools.store'), { - onSuccess: () => { - reset(); - onOpenChange(false); - onSuccess?.(); - }, - }); - } - }; - - const handleOpenChange = (open: boolean) => { - onOpenChange(open); - if (!open) { - reset(); - } - }; - - return ( - -
- {/* Name */} -
- - setData('name', e.target.value)} - disabled={processing} - className="h-10 border-gray-300 bg-gray-50 focus:bg-white" - /> - {errors.name && ( -

- ❌ {errors.name} -

- )} -
- - {/* Code */} -
- - setData('code', e.target.value)} - disabled={processing} - className="h-10 border-gray-300 bg-gray-50 focus:bg-white" - /> - {errors.code && ( -

- ❌ {errors.code} -

- )} -
- - {/* Email */} -
- - setData('email', e.target.value)} - disabled={processing} - className="h-10 border-gray-300 bg-gray-50 focus:bg-white" - /> - {errors.email && ( -

- ❌ {errors.email} -

- )} -
- - {/* Phone */} -
- - setData('phone', e.target.value)} - disabled={processing} - className="h-10 border-gray-300 bg-gray-50 focus:bg-white" - /> - {errors.phone && ( -

- ❌ {errors.phone} -

- )} -
- - {/* Address */} -
- -