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.
68 lines
2.5 KiB
PHP
68 lines
2.5 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace DoctrineMigrations;
|
|
|
|
use Doctrine\DBAL\Schema\Schema;
|
|
use Doctrine\Migrations\AbstractMigration;
|
|
|
|
final class Version20260217090323 extends AbstractMigration
|
|
{
|
|
public function getDescription(): string
|
|
{
|
|
return 'Create super_admins and establishments tables for multi-establishment management (Story 2.10)';
|
|
}
|
|
|
|
public function up(Schema $schema): void
|
|
{
|
|
$this->addSql(<<<'SQL'
|
|
CREATE TABLE IF NOT EXISTS super_admins (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
email VARCHAR(255) NOT NULL UNIQUE,
|
|
password_hash VARCHAR(255) NOT NULL,
|
|
first_name VARCHAR(100) NOT NULL DEFAULT '',
|
|
last_name VARCHAR(100) NOT NULL DEFAULT '',
|
|
status VARCHAR(20) NOT NULL DEFAULT 'active',
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
last_login_at TIMESTAMPTZ
|
|
)
|
|
SQL);
|
|
|
|
$this->addSql(<<<'SQL'
|
|
CREATE TABLE IF NOT EXISTS establishments (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
tenant_id UUID NOT NULL UNIQUE,
|
|
name VARCHAR(255) NOT NULL,
|
|
subdomain VARCHAR(100) NOT NULL UNIQUE,
|
|
database_name VARCHAR(100) NOT NULL UNIQUE,
|
|
status VARCHAR(20) NOT NULL DEFAULT 'active',
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
created_by UUID REFERENCES super_admins(id),
|
|
last_activity_at TIMESTAMPTZ
|
|
)
|
|
SQL);
|
|
|
|
$this->addSql('CREATE INDEX IF NOT EXISTS idx_establishments_subdomain ON establishments(subdomain)');
|
|
$this->addSql('CREATE INDEX IF NOT EXISTS idx_establishments_status ON establishments(status)');
|
|
|
|
$this->addSql(<<<'SQL'
|
|
CREATE TABLE IF NOT EXISTS establishment_metrics (
|
|
establishment_id UUID PRIMARY KEY REFERENCES establishments(id) ON DELETE CASCADE,
|
|
user_count INT NOT NULL DEFAULT 0,
|
|
student_count INT NOT NULL DEFAULT 0,
|
|
teacher_count INT NOT NULL DEFAULT 0,
|
|
last_login_at TIMESTAMPTZ,
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
|
|
)
|
|
SQL);
|
|
}
|
|
|
|
public function down(Schema $schema): void
|
|
{
|
|
$this->addSql('DROP TABLE IF EXISTS establishment_metrics');
|
|
$this->addSql('DROP TABLE IF EXISTS establishments');
|
|
$this->addSql('DROP TABLE IF EXISTS super_admins');
|
|
}
|
|
}
|