Files
Classeo/backend/src/SuperAdmin/Domain/Model/SuperAdmin/SuperAdmin.php
Mathias STRASSER 0951322d71 feat: Permettre au super admin de se connecter et accéder à son dashboard
Le super admin (table super_admins, master DB) ne pouvait pas se connecter
via /api/login car ce firewall n'utilisait que le provider tenant. De même,
le JWT n'était pas enrichi pour les super admins, l'endpoint /api/me/roles
les rejetait, et le frontend redirigeait systématiquement vers /dashboard.

Un chain provider (super_admin + tenant) résout l'authentification,
le JwtPayloadEnricher et MyRolesProvider gèrent désormais les deux types
d'utilisateurs, et le frontend redirige selon le rôle après login.
2026-02-18 10:15:47 +01:00

126 lines
3.6 KiB
PHP

<?php
declare(strict_types=1);
namespace App\SuperAdmin\Domain\Model\SuperAdmin;
use App\Shared\Domain\AggregateRoot;
use App\SuperAdmin\Domain\Event\SuperAdminCree;
use App\SuperAdmin\Domain\Event\SuperAdminDesactive;
use App\SuperAdmin\Domain\Exception\SuperAdminDejaActifException;
use App\SuperAdmin\Domain\Exception\SuperAdminNonActifException;
use DateTimeImmutable;
/**
* Aggregate Root for Super Admin — lives in the master database, not per-tenant.
*
* A Super Admin can manage all establishments and switch between tenant contexts.
* Authentication is separate from regular users (different user provider, different table).
*/
final class SuperAdmin extends AggregateRoot
{
public private(set) ?DateTimeImmutable $lastLoginAt = null;
private function __construct(
public private(set) SuperAdminId $id,
public private(set) string $email,
public private(set) string $hashedPassword,
public private(set) string $firstName,
public private(set) string $lastName,
public private(set) SuperAdminStatus $status,
public private(set) DateTimeImmutable $createdAt,
) {
}
public static function creer(
string $email,
string $hashedPassword,
string $firstName,
string $lastName,
DateTimeImmutable $createdAt,
): self {
$superAdmin = new self(
id: SuperAdminId::generate(),
email: $email,
hashedPassword: $hashedPassword,
firstName: $firstName,
lastName: $lastName,
status: SuperAdminStatus::ACTIF,
createdAt: $createdAt,
);
$superAdmin->recordEvent(new SuperAdminCree(
superAdminId: $superAdmin->id,
email: $superAdmin->email,
occurredOn: $createdAt,
));
return $superAdmin;
}
public function enregistrerConnexion(DateTimeImmutable $at): void
{
if ($this->status !== SuperAdminStatus::ACTIF) {
throw SuperAdminNonActifException::pourConnexion($this->id);
}
$this->lastLoginAt = $at;
}
public function desactiver(DateTimeImmutable $at): void
{
if ($this->status !== SuperAdminStatus::ACTIF) {
throw SuperAdminNonActifException::pourDesactivation($this->id);
}
$this->status = SuperAdminStatus::INACTIF;
$this->recordEvent(new SuperAdminDesactive(
superAdminId: $this->id,
occurredOn: $at,
));
}
public function reactiver(DateTimeImmutable $at): void
{
if ($this->status === SuperAdminStatus::ACTIF) {
throw SuperAdminDejaActifException::pourReactivation($this->id);
}
$this->status = SuperAdminStatus::ACTIF;
}
public function peutSeConnecter(): bool
{
return $this->status === SuperAdminStatus::ACTIF;
}
/**
* @internal For Infrastructure use only
*/
public static function reconstitute(
SuperAdminId $id,
string $email,
string $hashedPassword,
string $firstName,
string $lastName,
SuperAdminStatus $status,
DateTimeImmutable $createdAt,
?DateTimeImmutable $lastLoginAt = null,
): self {
$superAdmin = new self(
id: $id,
email: $email,
hashedPassword: $hashedPassword,
firstName: $firstName,
lastName: $lastName,
status: $status,
createdAt: $createdAt,
);
$superAdmin->lastLoginAt = $lastLoginAt;
return $superAdmin;
}
}