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.
82 lines
2.4 KiB
TypeScript
82 lines
2.4 KiB
TypeScript
import { getApiBaseUrl } from '$lib/api/config';
|
|
import { authenticatedFetch } from '$lib/auth/auth.svelte';
|
|
|
|
const apiUrl = getApiBaseUrl();
|
|
|
|
export interface EstablishmentData {
|
|
id: string;
|
|
tenantId: string;
|
|
name: string;
|
|
subdomain: string;
|
|
databaseName?: string;
|
|
status: string;
|
|
createdAt?: string;
|
|
lastActivityAt?: string;
|
|
}
|
|
|
|
export interface EstablishmentMetrics {
|
|
establishmentId: string;
|
|
name: string;
|
|
status: string;
|
|
userCount: number;
|
|
studentCount: number;
|
|
teacherCount: number;
|
|
lastLoginAt: string | null;
|
|
}
|
|
|
|
export interface CreateEstablishmentInput {
|
|
name: string;
|
|
subdomain: string;
|
|
adminEmail: string;
|
|
}
|
|
|
|
export async function getEstablishments(): Promise<EstablishmentData[]> {
|
|
const response = await authenticatedFetch(`${apiUrl}/super-admin/establishments`);
|
|
if (!response.ok) {
|
|
throw new Error('Erreur lors du chargement des établissements');
|
|
}
|
|
const data = await response.json();
|
|
return data['hydra:member'] ?? data['member'] ?? data;
|
|
}
|
|
|
|
export async function getEstablishment(id: string): Promise<EstablishmentData> {
|
|
const response = await authenticatedFetch(`${apiUrl}/super-admin/establishments/${id}`);
|
|
if (!response.ok) {
|
|
throw new Error('Établissement introuvable');
|
|
}
|
|
return response.json();
|
|
}
|
|
|
|
export async function createEstablishment(input: CreateEstablishmentInput): Promise<EstablishmentData> {
|
|
const response = await authenticatedFetch(`${apiUrl}/super-admin/establishments`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify(input)
|
|
});
|
|
if (!response.ok) {
|
|
const error = await response.json().catch(() => null);
|
|
throw new Error(error?.message ?? 'Erreur lors de la création');
|
|
}
|
|
return response.json();
|
|
}
|
|
|
|
export async function getMetrics(): Promise<EstablishmentMetrics[]> {
|
|
const response = await authenticatedFetch(`${apiUrl}/super-admin/metrics`);
|
|
if (!response.ok) {
|
|
throw new Error('Erreur lors du chargement des métriques');
|
|
}
|
|
const data = await response.json();
|
|
return data['hydra:member'] ?? data['member'] ?? data;
|
|
}
|
|
|
|
export async function switchTenant(tenantId: string): Promise<void> {
|
|
const response = await authenticatedFetch(`${apiUrl}/super-admin/switch-tenant`, {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify({ tenantId })
|
|
});
|
|
if (!response.ok) {
|
|
throw new Error('Erreur lors du basculement de contexte');
|
|
}
|
|
}
|