Documentation

Dashboard admin

Vue d'ensemble admin, stats live, sections et impersonation.

Le dashboard admin vit sous /admin. Accès gardé par role === "ADMIN" || role === "MODERATOR" dans le layout (app/[locale]/(dashboard)/layout.tsx).

Navigation : les ADMIN et MODERATOR arrivent par défaut sur l'espace utilisateur /account (UserShell). Le panneau Administration (slide-in dans la sidebar user) donne accès aux sections admin sans quitter l'espace personnel. Naviguer vers /admin charge le DashboardShell complet.

Voir Rôles & permissions pour la matrice complète des accès ADMIN / MODERATOR.

Stats live

Calculées par lib/dashboard-stats.ts, cache unstable_cache 60s :

StatSource
Total usersprisma.user.count()
Inscriptions 30jComparé aux 30j précédents (delta %)
Sessions activesUserSession.lastActiveAt dans les 30 dernières min
Abonnés payantsSubscription.status["active", "trialing"]

Le delta de signups est rendu en vert (positif) ou rouge (négatif) avec flèche. Si pas de données pour la période précédente, le delta est masqué.

Sections

/admin — Home

Stats + Activité récente — feed paginé (DataList) des 3 types d'événements :

TypeSourceAffichage
subscriptionAuditLog action subscription.createdbadge émeraude CreditCard
credit_purchaseCreditTransaction raison credit_pack_purchasebadge bleu ShoppingCart + montant crédits
credit_spendCreditTransaction négative (hors admin)badge ambré Zap + montant crédits

API : GET /api/admin/dashboard/activity?cursor=... — fenêtre 30 jours, 15 items par page, pagination cursor ISO date. Guard requireApiAuth({ moderator: true }).

/admin/users

Liste DataList avec search + filtres role (USER/ADMIN) et status (active/blocked/locked).

Click sur une row → sheet 5 onglets :

  • Info — métadonnées + tags (édition inline)
  • Notes — notes admin internes
  • Emails — 50 derniers envois pour cet user
  • Historique — login history
  • Actions — block/unblock/revoke/unlock/export RGPD

Voir Gestion des utilisateurs pour le détail.

Bulk API disponible (POST /api/admin/users/bulk) pour les actions en masse — pas encore en UI multi-select.

/admin/audit

Liste DataList des AuditLog. Voir Audit log.

/admin/emails

Éditeur des templates emails. Voir Emails.

/admin/emails/logs

Tracking des envois (statut Resend, bounces, opens). Voir Email logs.

/admin/plans

CRUD plans tarifaires multi-langue. Voir Plans.

/admin/coupons

CRUD coupons. Voir Coupons.

/admin/billing

KPI MRR/ARR/churn + liste des subs avec actions (refund, comp days, cancel). Voir Facturation.

/admin/sessions

Sessions actives globales avec révocation par filtre / par session. Voir Sessions globales.

/admin/feature-flags

Création + toggle + rollout % par flag. Voir Feature flags.

/admin/system

Health checks externes (DB / Stripe / Resend / OneSignal) + métriques 24h. Voir Santé système.

/admin/announcements

Bannière site-wide + mode maintenance. Voir Annonces & maintenance.

/admin/settings

Tabs admin :

  1. Site — appName, appUrl, supportEmail, logo
  2. Theme — palette, dark/light defaults

/admin/jobs

Visualisation des jobs Trigger.dev (si module activé).

Impersonation

Action Impersonate sur un user → POST /api/admin/impersonate. Effets :

  1. User.impersonatedBy = adminId sur la cible
  2. La session admin est swap : session.user.id = targetUserId
  3. Audit user.impersonate (qui par qui)

Un bandeau jaune <ImpersonationBanner> s'affiche en haut de toute page, avec un bouton "Quitter l'impersonation" qui restaure la session admin. Tant que impersonatedBy est rempli, le bandeau reste.

Geo-IP enrichment

Les pages /users et /audit affichent country / city quand dispo, récupérés via lib/geoip.ts au login (stockés dans UserSession).

Sessions tracking

UserSession log : userAgent, ip, country, city, lastActiveAt. Mis à jour par le proxy à chaque requête authentifiée. Listée dans /account/settings onglet Sécurité (côté user) et utilisée pour les stats sessions actives (côté admin).

Allez plus loin

On this page