feat: Gestion des classes scolaires
Permet aux administrateurs de créer, modifier et supprimer des classes pour organiser les élèves par niveau. L'archivage soft-delete préserve l'historique tout en masquant les classes obsolètes. Inclut la validation des noms (2-50 caractères), les niveaux scolaires du CP à la Terminale, et les contrôles d'accès par rôle.
This commit is contained in:
37
backend/src/Administration/Domain/Event/ClasseArchivee.php
Normal file
37
backend/src/Administration/Domain/Event/ClasseArchivee.php
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Administration\Domain\Event;
|
||||
|
||||
use App\Administration\Domain\Model\SchoolClass\ClassId;
|
||||
use App\Shared\Domain\DomainEvent;
|
||||
use App\Shared\Domain\Tenant\TenantId;
|
||||
use DateTimeImmutable;
|
||||
use Override;
|
||||
use Ramsey\Uuid\UuidInterface;
|
||||
|
||||
/**
|
||||
* Événement émis lors de l'archivage d'une classe (soft delete).
|
||||
*/
|
||||
final readonly class ClasseArchivee implements DomainEvent
|
||||
{
|
||||
public function __construct(
|
||||
public ClassId $classId,
|
||||
public TenantId $tenantId,
|
||||
private DateTimeImmutable $occurredOn,
|
||||
) {
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function occurredOn(): DateTimeImmutable
|
||||
{
|
||||
return $this->occurredOn;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function aggregateId(): UuidInterface
|
||||
{
|
||||
return $this->classId->value;
|
||||
}
|
||||
}
|
||||
41
backend/src/Administration/Domain/Event/ClasseCreee.php
Normal file
41
backend/src/Administration/Domain/Event/ClasseCreee.php
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Administration\Domain\Event;
|
||||
|
||||
use App\Administration\Domain\Model\SchoolClass\ClassId;
|
||||
use App\Administration\Domain\Model\SchoolClass\ClassName;
|
||||
use App\Administration\Domain\Model\SchoolClass\SchoolLevel;
|
||||
use App\Shared\Domain\DomainEvent;
|
||||
use App\Shared\Domain\Tenant\TenantId;
|
||||
use DateTimeImmutable;
|
||||
use Override;
|
||||
use Ramsey\Uuid\UuidInterface;
|
||||
|
||||
/**
|
||||
* Événement émis lors de la création d'une classe.
|
||||
*/
|
||||
final readonly class ClasseCreee implements DomainEvent
|
||||
{
|
||||
public function __construct(
|
||||
public ClassId $classId,
|
||||
public TenantId $tenantId,
|
||||
public ClassName $name,
|
||||
public ?SchoolLevel $level,
|
||||
private DateTimeImmutable $occurredOn,
|
||||
) {
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function occurredOn(): DateTimeImmutable
|
||||
{
|
||||
return $this->occurredOn;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function aggregateId(): UuidInterface
|
||||
{
|
||||
return $this->classId->value;
|
||||
}
|
||||
}
|
||||
40
backend/src/Administration/Domain/Event/ClasseModifiee.php
Normal file
40
backend/src/Administration/Domain/Event/ClasseModifiee.php
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Administration\Domain\Event;
|
||||
|
||||
use App\Administration\Domain\Model\SchoolClass\ClassId;
|
||||
use App\Administration\Domain\Model\SchoolClass\ClassName;
|
||||
use App\Shared\Domain\DomainEvent;
|
||||
use App\Shared\Domain\Tenant\TenantId;
|
||||
use DateTimeImmutable;
|
||||
use Override;
|
||||
use Ramsey\Uuid\UuidInterface;
|
||||
|
||||
/**
|
||||
* Événement émis lors de la modification du nom d'une classe.
|
||||
*/
|
||||
final readonly class ClasseModifiee implements DomainEvent
|
||||
{
|
||||
public function __construct(
|
||||
public ClassId $classId,
|
||||
public TenantId $tenantId,
|
||||
public ClassName $ancienNom,
|
||||
public ClassName $nouveauNom,
|
||||
private DateTimeImmutable $occurredOn,
|
||||
) {
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function occurredOn(): DateTimeImmutable
|
||||
{
|
||||
return $this->occurredOn;
|
||||
}
|
||||
|
||||
#[Override]
|
||||
public function aggregateId(): UuidInterface
|
||||
{
|
||||
return $this->classId->value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Administration\Domain\Exception;
|
||||
|
||||
use RuntimeException;
|
||||
|
||||
use function sprintf;
|
||||
|
||||
final class ClassNameInvalideException extends RuntimeException
|
||||
{
|
||||
public static function pourLongueur(string $value, int $min, int $max): self
|
||||
{
|
||||
return new self(sprintf(
|
||||
'Le nom de classe "%s" doit contenir entre %d et %d caractères.',
|
||||
$value,
|
||||
$min,
|
||||
$max,
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Administration\Domain\Exception;
|
||||
|
||||
use App\Administration\Domain\Model\SchoolClass\ClassName;
|
||||
use RuntimeException;
|
||||
|
||||
use function sprintf;
|
||||
|
||||
final class ClasseDejaExistanteException extends RuntimeException
|
||||
{
|
||||
public static function avecNom(ClassName $name): self
|
||||
{
|
||||
return new self(sprintf(
|
||||
'Une classe avec le nom "%s" existe déjà pour cette année scolaire.',
|
||||
$name,
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Administration\Domain\Exception;
|
||||
|
||||
use App\Administration\Domain\Model\SchoolClass\ClassId;
|
||||
use RuntimeException;
|
||||
|
||||
use function sprintf;
|
||||
|
||||
final class ClasseNonSupprimableException extends RuntimeException
|
||||
{
|
||||
public static function carElevesAffectes(ClassId $classId, int $nombreEleves): self
|
||||
{
|
||||
return new self(sprintf(
|
||||
'La classe "%s" ne peut pas être supprimée car %d élève(s) y sont encore affectés. Veuillez d\'abord réaffecter les élèves.',
|
||||
$classId,
|
||||
$nombreEleves,
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Administration\Domain\Exception;
|
||||
|
||||
use App\Administration\Domain\Model\SchoolClass\ClassId;
|
||||
use RuntimeException;
|
||||
|
||||
use function sprintf;
|
||||
|
||||
final class ClasseNotFoundException extends RuntimeException
|
||||
{
|
||||
public static function withId(ClassId $classId): self
|
||||
{
|
||||
return new self(sprintf(
|
||||
'La classe avec l\'ID "%s" n\'a pas été trouvée.',
|
||||
$classId,
|
||||
));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Administration\Domain\Model\SchoolClass;
|
||||
|
||||
use App\Shared\Domain\EntityId;
|
||||
|
||||
/**
|
||||
* Identifiant unique d'une année scolaire.
|
||||
*/
|
||||
final readonly class AcademicYearId extends EntityId
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Administration\Domain\Model\SchoolClass;
|
||||
|
||||
use App\Shared\Domain\EntityId;
|
||||
|
||||
final readonly class ClassId extends EntityId
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Administration\Domain\Model\SchoolClass;
|
||||
|
||||
use App\Administration\Domain\Exception\ClassNameInvalideException;
|
||||
|
||||
use function assert;
|
||||
use function mb_strlen;
|
||||
use function trim;
|
||||
|
||||
/**
|
||||
* Value Object représentant le nom d'une classe.
|
||||
*
|
||||
* Contraintes :
|
||||
* - Entre 2 et 50 caractères
|
||||
* - Non vide après trim
|
||||
*
|
||||
* Note: Les property hooks PHP 8.5 ne sont pas compatibles avec readonly.
|
||||
* La validation reste dans le constructeur pour préserver l'immutabilité du Value Object.
|
||||
*/
|
||||
final readonly class ClassName
|
||||
{
|
||||
private const int MIN_LENGTH = 2;
|
||||
private const int MAX_LENGTH = 50;
|
||||
|
||||
/** @var non-empty-string */
|
||||
public string $value;
|
||||
|
||||
public function __construct(string $value)
|
||||
{
|
||||
$trimmed = trim($value);
|
||||
$length = mb_strlen($trimmed);
|
||||
|
||||
if ($length < self::MIN_LENGTH || $length > self::MAX_LENGTH) {
|
||||
throw ClassNameInvalideException::pourLongueur($value, self::MIN_LENGTH, self::MAX_LENGTH);
|
||||
}
|
||||
|
||||
// After validation, $trimmed is guaranteed to be non-empty (MIN_LENGTH >= 2)
|
||||
assert($trimmed !== '');
|
||||
$this->value = $trimmed;
|
||||
}
|
||||
|
||||
public function equals(self $other): bool
|
||||
{
|
||||
return $this->value === $other->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return non-empty-string
|
||||
*/
|
||||
public function __toString(): string
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Administration\Domain\Model\SchoolClass;
|
||||
|
||||
/**
|
||||
* Statut du cycle de vie d'une classe.
|
||||
*/
|
||||
enum ClassStatus: string
|
||||
{
|
||||
case ACTIVE = 'active';
|
||||
case ARCHIVED = 'archived';
|
||||
|
||||
/**
|
||||
* Détermine si la classe peut recevoir des élèves.
|
||||
*/
|
||||
public function peutRecevoirEleves(): bool
|
||||
{
|
||||
return $this === self::ACTIVE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Détermine si la classe est visible dans les listes actives.
|
||||
*/
|
||||
public function estVisible(): bool
|
||||
{
|
||||
return $this === self::ACTIVE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retourne le libellé pour affichage.
|
||||
*/
|
||||
public function label(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::ACTIVE => 'Active',
|
||||
self::ARCHIVED => 'Archivée',
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,210 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Administration\Domain\Model\SchoolClass;
|
||||
|
||||
use App\Administration\Domain\Event\ClasseArchivee;
|
||||
use App\Administration\Domain\Event\ClasseCreee;
|
||||
use App\Administration\Domain\Event\ClasseModifiee;
|
||||
use App\Shared\Domain\AggregateRoot;
|
||||
use App\Shared\Domain\Tenant\TenantId;
|
||||
use DateTimeImmutable;
|
||||
|
||||
/**
|
||||
* Aggregate Root représentant une classe scolaire.
|
||||
*
|
||||
* Une classe appartient à un établissement (tenant), une école et une année scolaire.
|
||||
* Elle peut recevoir des élèves et est organisée par niveau scolaire.
|
||||
*
|
||||
* @see FR73: Organiser les élèves par groupes pédagogiques
|
||||
*/
|
||||
final class SchoolClass extends AggregateRoot
|
||||
{
|
||||
public private(set) ?string $description = null;
|
||||
public private(set) DateTimeImmutable $updatedAt;
|
||||
public private(set) ?DateTimeImmutable $deletedAt = null;
|
||||
|
||||
private function __construct(
|
||||
public private(set) ClassId $id,
|
||||
public private(set) TenantId $tenantId,
|
||||
public private(set) SchoolId $schoolId,
|
||||
public private(set) AcademicYearId $academicYearId,
|
||||
public private(set) ClassName $name,
|
||||
public private(set) ?SchoolLevel $level,
|
||||
public private(set) ?int $capacity,
|
||||
public private(set) ClassStatus $status,
|
||||
public private(set) DateTimeImmutable $createdAt,
|
||||
) {
|
||||
$this->updatedAt = $createdAt;
|
||||
}
|
||||
|
||||
/**
|
||||
* Crée une nouvelle classe scolaire.
|
||||
*/
|
||||
public static function creer(
|
||||
TenantId $tenantId,
|
||||
SchoolId $schoolId,
|
||||
AcademicYearId $academicYearId,
|
||||
ClassName $name,
|
||||
?SchoolLevel $level,
|
||||
?int $capacity,
|
||||
DateTimeImmutable $createdAt,
|
||||
): self {
|
||||
$class = new self(
|
||||
id: ClassId::generate(),
|
||||
tenantId: $tenantId,
|
||||
schoolId: $schoolId,
|
||||
academicYearId: $academicYearId,
|
||||
name: $name,
|
||||
level: $level,
|
||||
capacity: $capacity,
|
||||
status: ClassStatus::ACTIVE,
|
||||
createdAt: $createdAt,
|
||||
);
|
||||
|
||||
$class->recordEvent(new ClasseCreee(
|
||||
classId: $class->id,
|
||||
tenantId: $class->tenantId,
|
||||
name: $class->name,
|
||||
level: $class->level,
|
||||
occurredOn: $createdAt,
|
||||
));
|
||||
|
||||
return $class;
|
||||
}
|
||||
|
||||
/**
|
||||
* Renomme la classe.
|
||||
*/
|
||||
public function renommer(ClassName $nouveauNom, DateTimeImmutable $at): void
|
||||
{
|
||||
if ($this->name->equals($nouveauNom)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$ancienNom = $this->name;
|
||||
$this->name = $nouveauNom;
|
||||
$this->updatedAt = $at;
|
||||
|
||||
$this->recordEvent(new ClasseModifiee(
|
||||
classId: $this->id,
|
||||
tenantId: $this->tenantId,
|
||||
ancienNom: $ancienNom,
|
||||
nouveauNom: $nouveauNom,
|
||||
occurredOn: $at,
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifie le niveau scolaire de la classe.
|
||||
*/
|
||||
public function changerNiveau(?SchoolLevel $niveau, DateTimeImmutable $at): void
|
||||
{
|
||||
if ($this->level === $niveau) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->level = $niveau;
|
||||
$this->updatedAt = $at;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modifie la capacité maximale de la classe.
|
||||
*/
|
||||
public function changerCapacite(?int $capacity, DateTimeImmutable $at): void
|
||||
{
|
||||
if ($this->capacity === $capacity) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->capacity = $capacity;
|
||||
$this->updatedAt = $at;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ajoute ou modifie la description de la classe.
|
||||
*/
|
||||
public function decrire(?string $description, DateTimeImmutable $at): void
|
||||
{
|
||||
$this->description = $description;
|
||||
$this->updatedAt = $at;
|
||||
}
|
||||
|
||||
/**
|
||||
* Archive la classe (soft delete).
|
||||
*
|
||||
* Note: La vérification des élèves affectés doit être faite par l'Application Layer
|
||||
* via une Query avant d'appeler cette méthode.
|
||||
*/
|
||||
public function archiver(DateTimeImmutable $at): void
|
||||
{
|
||||
if ($this->status === ClassStatus::ARCHIVED) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->status = ClassStatus::ARCHIVED;
|
||||
$this->deletedAt = $at;
|
||||
$this->updatedAt = $at;
|
||||
|
||||
$this->recordEvent(new ClasseArchivee(
|
||||
classId: $this->id,
|
||||
tenantId: $this->tenantId,
|
||||
occurredOn: $at,
|
||||
));
|
||||
}
|
||||
|
||||
/**
|
||||
* Vérifie si la classe est active.
|
||||
*/
|
||||
public function estActive(): bool
|
||||
{
|
||||
return $this->status === ClassStatus::ACTIVE;
|
||||
}
|
||||
|
||||
/**
|
||||
* Vérifie si la classe peut recevoir des élèves.
|
||||
*/
|
||||
public function peutRecevoirEleves(): bool
|
||||
{
|
||||
return $this->status->peutRecevoirEleves();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reconstitue une SchoolClass depuis le stockage.
|
||||
*
|
||||
* @internal Pour usage Infrastructure uniquement
|
||||
*/
|
||||
public static function reconstitute(
|
||||
ClassId $id,
|
||||
TenantId $tenantId,
|
||||
SchoolId $schoolId,
|
||||
AcademicYearId $academicYearId,
|
||||
ClassName $name,
|
||||
?SchoolLevel $level,
|
||||
?int $capacity,
|
||||
ClassStatus $status,
|
||||
?string $description,
|
||||
DateTimeImmutable $createdAt,
|
||||
DateTimeImmutable $updatedAt,
|
||||
?DateTimeImmutable $deletedAt,
|
||||
): self {
|
||||
$class = new self(
|
||||
id: $id,
|
||||
tenantId: $tenantId,
|
||||
schoolId: $schoolId,
|
||||
academicYearId: $academicYearId,
|
||||
name: $name,
|
||||
level: $level,
|
||||
capacity: $capacity,
|
||||
status: $status,
|
||||
createdAt: $createdAt,
|
||||
);
|
||||
|
||||
$class->description = $description;
|
||||
$class->updatedAt = $updatedAt;
|
||||
$class->deletedAt = $deletedAt;
|
||||
|
||||
return $class;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Administration\Domain\Model\SchoolClass;
|
||||
|
||||
use App\Shared\Domain\EntityId;
|
||||
|
||||
/**
|
||||
* Identifiant unique d'un établissement scolaire.
|
||||
*/
|
||||
final readonly class SchoolId extends EntityId
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Administration\Domain\Model\SchoolClass;
|
||||
|
||||
/**
|
||||
* Niveau scolaire selon le référentiel Éducation Nationale.
|
||||
*
|
||||
* Primaire : CP, CE1, CE2, CM1, CM2
|
||||
* Collège : 6ème, 5ème, 4ème, 3ème
|
||||
* Lycée : 2nde, 1ère, Terminale
|
||||
*/
|
||||
enum SchoolLevel: string
|
||||
{
|
||||
// Primaire
|
||||
case CP = 'CP';
|
||||
case CE1 = 'CE1';
|
||||
case CE2 = 'CE2';
|
||||
case CM1 = 'CM1';
|
||||
case CM2 = 'CM2';
|
||||
|
||||
// Collège
|
||||
case SIXIEME = '6ème';
|
||||
case CINQUIEME = '5ème';
|
||||
case QUATRIEME = '4ème';
|
||||
case TROISIEME = '3ème';
|
||||
|
||||
// Lycée
|
||||
case SECONDE = '2nde';
|
||||
case PREMIERE = '1ère';
|
||||
case TERMINALE = 'Terminale';
|
||||
|
||||
/**
|
||||
* Retourne le libellé du niveau pour affichage.
|
||||
*/
|
||||
public function label(): string
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Détermine si le niveau appartient au cycle primaire.
|
||||
*/
|
||||
public function estPrimaire(): bool
|
||||
{
|
||||
return match ($this) {
|
||||
self::CP, self::CE1, self::CE2, self::CM1, self::CM2 => true,
|
||||
default => false,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Détermine si le niveau appartient au cycle collège.
|
||||
*/
|
||||
public function estCollege(): bool
|
||||
{
|
||||
return match ($this) {
|
||||
self::SIXIEME, self::CINQUIEME, self::QUATRIEME, self::TROISIEME => true,
|
||||
default => false,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Détermine si le niveau appartient au cycle lycée.
|
||||
*/
|
||||
public function estLycee(): bool
|
||||
{
|
||||
return match ($this) {
|
||||
self::SECONDE, self::PREMIERE, self::TERMINALE => true,
|
||||
default => false,
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Retourne le cycle d'enseignement.
|
||||
*/
|
||||
public function cycle(): string
|
||||
{
|
||||
return match ($this) {
|
||||
self::CP, self::CE1, self::CE2, self::CM1, self::CM2 => 'Primaire',
|
||||
self::SIXIEME, self::CINQUIEME, self::QUATRIEME, self::TROISIEME => 'Collège',
|
||||
self::SECONDE, self::PREMIERE, self::TERMINALE => 'Lycée',
|
||||
};
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Administration\Domain\Model\SchoolClass;
|
||||
|
||||
/**
|
||||
* Liste des niveaux scolaires valides selon le référentiel Éducation Nationale.
|
||||
*
|
||||
* Utilisé pour :
|
||||
* - L'enum SchoolLevel
|
||||
* - La validation API Platform
|
||||
* - Le frontend (formulaires)
|
||||
*/
|
||||
final class SchoolLevels
|
||||
{
|
||||
/**
|
||||
* @var list<string>
|
||||
*/
|
||||
public const array ALL = [
|
||||
'CP',
|
||||
'CE1',
|
||||
'CE2',
|
||||
'CM1',
|
||||
'CM2',
|
||||
'6ème',
|
||||
'5ème',
|
||||
'4ème',
|
||||
'3ème',
|
||||
'2nde',
|
||||
'1ère',
|
||||
'Terminale',
|
||||
];
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Administration\Domain\Repository;
|
||||
|
||||
use App\Administration\Domain\Model\SchoolClass\AcademicYearId;
|
||||
use App\Administration\Domain\Model\SchoolClass\ClassId;
|
||||
use App\Administration\Domain\Model\SchoolClass\ClassName;
|
||||
use App\Administration\Domain\Model\SchoolClass\SchoolClass;
|
||||
use App\Shared\Domain\Tenant\TenantId;
|
||||
|
||||
interface ClassRepository
|
||||
{
|
||||
public function save(SchoolClass $class): void;
|
||||
|
||||
/**
|
||||
* @throws \App\Administration\Domain\Exception\ClasseNotFoundException
|
||||
*/
|
||||
public function get(ClassId $id): SchoolClass;
|
||||
|
||||
public function findById(ClassId $id): ?SchoolClass;
|
||||
|
||||
/**
|
||||
* Recherche une classe par nom dans un tenant et une année scolaire.
|
||||
*/
|
||||
public function findByName(
|
||||
ClassName $name,
|
||||
TenantId $tenantId,
|
||||
AcademicYearId $academicYearId,
|
||||
): ?SchoolClass;
|
||||
|
||||
/**
|
||||
* Retourne toutes les classes actives d'un tenant pour une année scolaire.
|
||||
*
|
||||
* @return SchoolClass[]
|
||||
*/
|
||||
public function findActiveByTenantAndYear(
|
||||
TenantId $tenantId,
|
||||
AcademicYearId $academicYearId,
|
||||
): array;
|
||||
|
||||
/**
|
||||
* Supprime une classe du repository.
|
||||
*/
|
||||
public function delete(ClassId $id): void;
|
||||
}
|
||||
Reference in New Issue
Block a user