feat: Provisionner automatiquement un nouvel établissement
Some checks failed
CI / Backend Tests (push) Has been cancelled
CI / Frontend Tests (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
CI / Naming Conventions (push) Has been cancelled
CI / Build Check (push) Has been cancelled

Lorsqu'un super-admin crée un établissement via l'interface, le système
doit automatiquement créer la base tenant, exécuter les migrations,
créer le premier utilisateur admin et envoyer l'invitation — le tout
de manière asynchrone pour ne pas bloquer la réponse HTTP.

Ce mécanisme rend chaque établissement opérationnel dès sa création
sans intervention manuelle sur l'infrastructure.
This commit is contained in:
2026-04-08 13:55:41 +02:00
parent bec211ebf0
commit dc2be898d5
171 changed files with 11703 additions and 700 deletions

View File

@@ -0,0 +1,64 @@
<?php
declare(strict_types=1);
namespace App\Scolarite\Application\Service;
use App\Scolarite\Application\Query\GetClassStatisticsDetail\ClassStatisticsDetailDto;
use function fclose;
use function fopen;
use function fputcsv;
use function fwrite;
use function rewind;
use function stream_get_contents;
final class StatisticsExporter
{
/**
* Exporte les statistiques d'une classe au format CSV.
*
* Structure : Nom, Moyenne, En difficulté, Tendance
* En-tête avec résumé : Moyenne de classe, Taux de réussite
*/
public function exportClassToCsv(
ClassStatisticsDetailDto $stats,
string $className,
string $subjectName,
): string {
$handle = fopen('php://temp', 'r+');
if ($handle === false) {
return '';
}
// BOM UTF-8 pour compatibilité Excel sur Windows
fwrite($handle, "\xEF\xBB\xBF");
fputcsv($handle, ['Statistiques - ' . $className . ' - ' . $subjectName], separator: ';');
fputcsv($handle, [], separator: ';');
fputcsv($handle, ['Moyenne de classe', $stats->average !== null ? (string) $stats->average : 'N/A'], separator: ';');
fputcsv($handle, ['Taux de réussite', $stats->successRate . '%'], separator: ';');
fputcsv($handle, [], separator: ';');
fputcsv($handle, ['Élève', 'Moyenne', 'En difficulté', 'Tendance'], separator: ';');
foreach ($stats->students as $student) {
fputcsv($handle, [
$student->studentName,
$student->average !== null ? (string) $student->average : 'N/A',
$student->inDifficulty ? 'Oui' : 'Non',
match ($student->trend) {
'improving' => 'Progression',
'declining' => 'Régression',
default => 'Stable',
},
], separator: ';');
}
rewind($handle);
$csv = stream_get_contents($handle);
fclose($handle);
return $csv !== false ? $csv : '';
}
}