En vous promenant sur Beamreactor, nous stockons votre IP 48h pour des raisons de sécurité.

Lector Markdown

Base de conocimiento › BEAMREACTOR_DASHBOARD

Beamreactor Dashboard

Diagnostics du panneau de contrôle #

Version: 1.0 — 2026-09-25

Public : développeurs de plugins

Depuis : BeamReactor 3.0.0-alpha

Le panneau de contrôle (login_success) montre d'un coup d'œil ce qui attend le membre : commandes à expédier, tickets jamais vus, cron muet, rendez-vous du jour. Pas une ligne de texte. Juste des pastilles (une icône, un nombre), un petit numéro sur la tuile du plugin, et un liseré qui passe au rouge quand c'est critique.

Chaque plugin fournit ses propres diagnostics. Le panneau ne connaît aucun plugin : il demande, il filtre, il affiche.

1. Ce que voit le membre

ÉlémentOùSignification
Pastillezone « Diagnostics et actualités »icône + nombre ; le texte n'est que dans l'infobulle
Numérocoin de la tuile du pluginle nombre de sa gravité la plus haute
Liseré rougebas de la tuileau moins un signal critique
Pulsationpastille et liserédu nouveau depuis la dernière visite du plugin

Les couleurs portent la gravité :

  • information : la couleur de la catégorie du plugin (celle du liseré de sa tuile), on apprend à trier d'un coup d'œil ;
  • à traiter : orange ;
  • critique : rouge.

La pulsation est réservée au nouveau. Un signal qui clignote en permanence (trois tickets ouverts toute la semaine) devient du bruit qu'on ne voit plus. Elle est coupée pour les membres qui demandent à réduire les animations (prefers-reduced-motion).

Les diagnostics sont chargés après l'affichage de la page : le panneau ne paie pas les requêtes des plugins.

2. Ajouter un diagnostic à son plugin

Un dossier dashboard/ dans le plugin, deux sortes de fichiers :

text
plugins/monplugin/
└── dashboard/
    ├── monplugin.dash.php        ← renvoie les signaux
    ├── monplugin.dash.fr.json    ← ses textes, une langue par fichier
    ├── monplugin.dash.en.json
    ├── monplugin.dash.de.json
    ├── monplugin.dash.pt.json
    └── monplugin.dash.es.json

Un plugin absent du serveur n'a pas de diagnostic, sans rien configurer : c'est ce qui permet à un site sans IA de ne rien afficher de l'IA.

2.1 Le fournisseur #

monplugin.dash.php renvoie un tableau de signaux, rien d'autre : pas d'echo, pas de HTML.

php
<?php
use Beamreactor\Database\SQL;
use Beamreactor\Dashboard\Dashboard;

$since = $lastSeen ?? '1970-01-01 00:00:00';

$r = SQL::queryFirst(
	"SELECT COUNT(*) n, SUM(created_at > ?) nv FROM mes_demandes WHERE status = 'open'",
	[$since],
	['string']
);
if (!$r) return [];   // la couche SQL rend false en cas d'échec : pas de signal inventé

return [
	[
		'count' => (int)$r['n'],
		'new'   => (int)$r['nv'],
		'level' => (int)$r['nv'] > 0 ? 'critical' : 'todo',
		'title' => Dashboard::t($dial, 'open', (int)$r['n']),
	],
];

Le fournisseur tourne dans sa propre portée et reçoit :

VariableContenu
$userIdle membre
$userLevelson niveau (entier)
$lastSeensa dernière visite de la page du plugin, 'Y-m-d H:i:s', ou null s'il ne l'a jamais ouverte
$dialles textes de monplugin.dash.<langue>.json
$cfgla configuration du site

2.2 Un signal #

CléObligatoireRôle
countouile nombre affiché ; 0 = rien à montrer, le signal est ignoré
leveloui'info', 'todo' ou 'critical'
titleouil'infobulle, seul texte du panneau
newnonla part du compte postérieure à $lastSeen ; > 0 déclenche la pulsation
iconnonun émoji ; sinon l'icône du plugin (monplugin.svg ou .png)
urlnonle lien ; sinon ?obj=monplugin

Un signal mal formé (clé manquante, gravité inconnue) est écarté et signalé dans le journal d'erreurs. Une exception dans le fournisseur ne fait tomber que ses propres signaux, elle aussi signalée.

2.3 Les textes #

json
{
    "_ver": "$VER: monplugin.dash.fr 1.0 (25.09.2026)",
    "open": "%d demande(s) ouverte(s)"
}

Dashboard::t($dial, 'clé', ...$args) applique vsprintf. Une clé absente s'affiche telle quelle, et un fichier de langue absent est signalé : on voit le trou, il n'y a pas de langue de repli silencieuse.

3. Choisir la gravité

GravitéQuandExemples livrés
criticalquelqu'un attend, ou quelque chose est cassécommandes payées à expédier, tickets jamais vus, erreurs fatales des dernières 24 h, cron muet
todoune action est attendue, sans urgencecommandes en attente de paiement, réponses du support à lire, rappels
infode l'information, pas une tâchevisiteurs en ligne, rendez-vous de la semaine, IP bannies en 24 h

Une même source peut produire plusieurs signaux (la boutique en donne trois : payées, en attente, expédiées).

4. Qui voit quoi

Le filtrage se fait avant l'inclusion du fournisseur : un plugin que le membre ne voit pas ne calcule rien.

  1. le niveau d'affichage du plugin ($basedisplevel de sa conf) doit être atteint ;
  2. le plugin doit être permis par les groupes du membre (UserGroups::allows).

Les finesses internes restent au fournisseur, par secure() : le support montre aux modérateurs les tickets à traiter et aux membres les réponses à lire ; la santé du LLM n'est montrée qu'aux administrateurs, même si le plugin est ouvert aux membres.

php
if (!secure('BASE_LEVEL_ADMIN')) return [];

Voir Droits d'accès.

5. Le « vu »

La table dashboard_seen garde, pour chaque membre et chaque plugin, la date de sa dernière visite de la page du plugin. Le moteur la met à jour tout seul quand un membre connecté ouvre la page d'un plugin qui a un dossier dashboard/.

Le fournisseur n'a qu'à comparer ses dates à $lastSeen :

  • null : le membre n'a jamais ouvert le plugin, tout est nouveau (ou une fenêtre raisonnable, comme les 30 derniers jours pour la modération) ;
  • sinon : est nouveau ce qui est postérieur.

Il n'y a rien à acquitter : ouvrir le plugin, c'est avoir vu.

6. Les rappels

Un rappel n'est pas une tâche à cocher : c'est « la dernière activité est plus vieille que X jours ». Le plugin connaît déjà sa dernière activité réelle (le dernier édito, la date du sitemap, la dernière indexation). Il suffit de la comparer à un seuil dans la conf du plugin :

php
// plugins/edito/conf/edito.conf.inc.php
$GLOBALS['edito_conf']['DASH_REMIND_DAYS'] = 30;

Le rappel s'éteint de lui-même quand la chose est faite. Seuil absent de la conf : le fournisseur le signale et ne rappelle rien (pas de valeur par défaut cachée).

7. Règles

  • Rapide : une ou deux requêtes indexées. Le panneau interroge tous les fournisseurs du membre à chaque ouverture.
  • Pas de faux signal : sur un échec SQL (false), return []. Une donnée périmée n'est pas un état : la santé du LLM se tait quand son dernier contrôle a plus de 7 h et que la surveillance est coupée.
  • Pas de HTML, pas d'echo : le fournisseur renvoie des données.
  • Conf du plugin : un fournisseur peut l'inclure (include_once) si elle n'a pas d'effet de bord ; celle de llm_connector, qui charge toute la couche RAG, ne l'est pas.

8. Sous le capot

PièceRôle
lib/dashboard/Dashboard.class.phpcollecte (filtrage, inclusion isolée, validation des signaux), « vu »
lib/dashboard/sql/migrations/001_dashboard_seen.sqlla table du « vu »
modules/dashboard.mod.phples signaux en JSON pour le membre connecté
index.phpnote la visite à l'ouverture de la page d'un plugin doté de dashboard/
members/login_success.phppastilles, numéros, liserés

Réponse de ?obj=dashboard.mod :

json
{"plugins": {"support_ticket": {"icon": "plugins/support_ticket/support_ticket.svg",
  "signals": [{"count": 2, "level": "critical", "new": 1, "title": "2 ticket(s) à traiter, dont 1 jamais vu(s)", "icon": "", "url": "?obj=support_ticket"}]}}}

Fournisseurs livrés avec la 3.0.0-alpha #

support_ticket, orders_admin, abuse, moderation, current_users, scheduler, error_logs, calendar, llm_connector, banna, et les rappels edito, sitemap et siteindexer. Ce sont les meilleurs exemples pour démarrer.

de en es fr pt