Maison/Documents/Métriques personnalisées
Contrat de métriques personnalisées
Les métriques personnalisées permettent au service de votre extension de pousser les chiffres qui comptent pour cela (conversions, revenus, santé du backend, entonnoirs) dans le même panneau qui suit déjà les installations et l'état de Chrome Web Store. Le contrat est Basé sur des métadonnées et double surface : chaque métrique déclare où et comment elle apparaît à la fois sur le tableau de bord et dans l'état Telegram, le panneau reste donc un moteur de rendu générique sans code spécifique au produit.
1. Comment ça marche (double surface)
Votre service expose un point de terminaison de métriques. Ext Ops Panel est le client : il tire ce point final (jamais l’inverse) et restitue le réponse. La réponse entraîne deux surfaces à la fois :
- Onglets du tableau de bord dans la vue détaillée de l'extension : onglets, sections et types de rendu par métrique.
- Statut Telegram: lignes logiques composées à partir des mêmes métriques, filtrées et formatées par métrique.
Le panneau fusionne vos métriques avec les métriques de base propriétaires (installations / désinstallations / réinstallations / commentaires / Chrome Web Store / santé), qui vivent dans la réserve base onglet et ligne Telegram.
2. Le point de terminaison et l'authentification
Le panneau appelle votre point de terminaison avec GET et attend la v2 charge utile comme réponse 200. Deux modes de tirage partagent la même forme :
- Sur demande: déclenché lorsqu'un utilisateur ouvre Détail. Tarif limité à au maximum 1 requête par minute et par source, sur tous les forfaits y compris Gratuit.
- Surveillance: selon un planning (essai/payant uniquement), compose le statut Telegram et les alertes de bord.
L'authentification est l'un des aucun, porteur ou api_key_header. Les secrets sont stockés cryptés au repos sur le backend du panneau et ne sont jamais transmis à l'extension du tableau de bord. Si une traction échoue, le panneau se dégrade gracieusement (dernier instantané ou masqué) sans casser les métriques de base.
3. Structure de la charge utile
La charge utile de niveau supérieur contient la mise en page (onglets, sections, lignes Telegram) et le tableau de métriques.
| Champ | Taper | Remarques |
|---|---|---|
schema_version | chaîne | Requis. Doit être "2.0". |
generated_at | chaîne (date-heure) | Lorsque la charge utile a été composée (fraîcheur/détection d'inactivité). |
tabs | Languette[] | Onglets du tableau de bord. Voir la rubrique 4. |
sections | Section[] | Groupes de métriques dans un onglet (tab, id, title, order). |
telegram | TelegramMéta | Modèle header + lines[]. Voir la rubrique 7. |
metrics | Métrique[] | Les métriques elles-mêmes. Voir les sections 5 et 6. |
4. Onglets et icônes d'onglets
Un onglet est { id, title, order, icon? }. Le réservé
base l'onglet est celui du panneau
(icon="layout-dashboard"); votre service ajoute le reste. Quand beaucoup
les onglets sont ouverts, l'onglet actif affiche l'icône + le titre et les autres se réduisent au
icône uniquement (le titre reste dans l'info-bulle et l'aria-label).
La valeur icon est l'une des deux choses suivantes :
- UN Nom de l'icône Lucide en cas kebab ASCII (correspond à
^[a-z][a-z0-9-]*$), par ex.trending-up. Un bien formé mais le nom non pris en charge se dégrade en icône par défaut (square) afin que la barre ne se casse jamais. - UN seul emoji, par ex. 💰 ou 🚀, rendu sous forme de texte.
Le panel fournit un sous-ensemble organisé de 37 noms Lucide (conservés pour le bundle MV3) :
- tableau de bord de mise en page
- activité
- jauge
- couches
- prise
- signe dollar
- billet de banque
- portefeuille
- carte de crédit
- reçu
- graphique à barres-3
- graphique linéaire
- diagramme circulaire
- tendance à la hausse
- tendance à la baisse
- utilisateurs
- utilisateur
- triangle d'alerte
- cloche
- horloge
- branche git
- emballer
- boîte
- base de données
- serveur
- processeur
- zapper
- globe
- puzzle
- entonnoir
- filtre
- carré
- cercle
- hacher
- pour cent
- étiqueter
- drapeau
5. Métrique : valeur + deux blocs de placement
Une métrique comporte une valeur typée plus deux blocs indépendants :
dashboard (où et comment dans l'extension) et
telegram (où et comment dans le message). L'un ou l'autre peut être omis ou
caché via show:false, donc une métrique ne peut vivre que sur une seule surface.
| Champ | Remarques |
|---|---|
id | ID de métrique stable, unique dans la charge utile. |
kind | Type de données (section 5.1). Sélectionne les champs de valeur qui s'appliquent. |
label | Étiquette humaine canonique. |
value et champs de type | Les champs de charge utile dépendent de kind (section 5.1). |
severity | L'un des ok, info, warn, crit (mappé en couleur/emoji). |
shareable | Booléen facultatif, true par défaut. Lorsque false, la métrique est réservée au propriétaire : sur un projet partagé en lecture seule, elle est supprimée côté serveur et n'atteint jamais une vue observateur/publique (utilisation pour les métriques financières). Régit l’accès, pas le placement. |
dashboard | { show, tab, section, order, name, render, options } (section 5.2). |
telegram | { show, line, pos, format, sep, when } (articles 6 et 8). |
5.1. Types (type de données + charge utile)
Les genres sont un ensemble ouvert: un type inconnu est ignoré par le moteur de rendu (compatible ascendant).
| gentil | Champs de charge utile | Exemple d'utilisation |
|---|---|---|
number | value (+ delta en option, unit) | l'installation/les commentaires comptent |
delta | value, delta (rend 1200 (+72)) | total (+aujourd'hui) |
percent | value (0 à 100) | taux de réussite du moteur |
duration | seconds ou minutes | p50/p95/moy, fraîcheur |
bytes | bytes ou kb | taille de sortie (~ 522 Ko) |
rating | value, count | 5,0★ (1) |
money | value, currency, delta en option | MRR, dépenser |
status | state + severity | feu de signalisation sanitaire |
series | points:[{date,count}], multi en option series:[{name,points}] | installations quotidiennes, utilisateurs actifs |
intraday | series:[{name,intraday:[{minute,value}]}], step_min en option (15 par défaut), tz | aujourd'hui par tranches de 15 minutes |
hour_histogram | { weekdays:[...], start, end, tz } | conversions par heure |
funnel | steps:[{key,label,value}] | prix à la caisse |
breakdown | items:[{label,value,unit?,sub?/money?}] | sous-marins par plan, par moteur, par surface |
list | items:[{text,count?,severity?}] | erreurs récentes |
text | value (chaîne) | texte libre |
5.2. Rendu (comment afficher sur le tableau de bord)
dashboard.render sélectionne le visuel (correspond généralement à kind,
mais peut différer, par ex. afficher un percent comme un badge). Aussi
un ensemble ouvert.
| rendre | Regarder | Options (dashboard.options) |
|---|---|---|
kpi | Carte : nom + grande valeur + delta | tone |
badge | Pilule de statut / pictogramme par gravité | – |
chart | Graphique linéaire (mois/durée de vie, moyenne mobile de 7, survol) | series, defaultMode |
intraday | Aujourd'hui, par tranches (96 par UTC jour) : barres empilées ou lignes lissées, axe du temps HH:MM, lecture au survol d'une série à l'autre. | mode (bars | lines, par défaut lines) |
hour_histogram | Barres horaires, regroupées Jours de semaine / Week-end / Par jour de la semaine | series |
funnel | Étapes avec conversion entre elles | – |
breakdown | Barres catégorielles horizontales avec valeur + part du total | items |
table | Tableau (par exemple commentaires) | columns |
text | Paragraphe / en ligne | – |
status | État des feux tricolores par gravité | – |
list | Liste des éléments avec nombre/gravité facultatifs | – |
intraday contre chart. Le chart
l'axe est tous les jours (points[].date = YYYY-MM-DD) et son
La vue mensuelle coupe les 30 derniers points, de sorte que les 96 compartiments d'aujourd'hui n'y tiennent pas.
intraday est le graphique Today propriétaire exposé sous forme de contrat : le
même convention où minute compte les minutes à partir du début du jour UTC
(0, 15, …, 1425), mais les séries et données sont déclarées par la source. Envoyer uniquement
seaux non vides, le panneau densifie le reste.
Un bucket vide correspond à null, et non à 0. Pour un
moyenne (par exemple, temps de conversion moyen), un zéro serait un mensonge, donc la ligne pauses
au lieu de tomber par terre. Un bucket manquant et value: null sont
équivalent : la ligne saute, aucune barre n'est dessinée et l'affichage en survol affiche un tiret.
6. Le panneau possède la palette
Les couleurs des graphiques et des séries sont attribuées par le panneau de la marque
jetons, pas par la source. options.series[] porte uniquement l'identité
({key,label,order}); un champ color dans la charge utile est
conseil et ignoré. Les clés sémantiques correspondent aux jetons fixes
(paid pour accentuer, free pour neutre sourd,
failed/error au danger,
ready/success au succès) ; les autres clés prennent le
palette de marque catégorielle en termes de position. Le contraste reste d'au moins 4,5:1 dans les deux cas
thèmes. Cela protège la marque contre les hexagones externes arbitraires.
7. Modèles Telegram
telegram.header est l'en-tête du message ;
telegram.lines[] sont des lignes logiques
({ id, order, prefix, when }). Le compositeur rassemble toutes les métriques
avec un telegram.line donné, filtre par when, trie par
pos, restitue chacun via son modèle format et rejoint
avec le sep de chaque métrique. La ligne prefix est imprimée
d'abord. Tout est en texte brut.
| Espace réservé | Sortir |
|---|---|
{value} | Par type (numéro 1,200 ; pourcentage 99%) |
{value:k} | 1.2k / 3.0M (compact) |
{delta:+} | +72 / -3 |
{value:pct} | 99% |
{seconds:dur} | 28s / 5m 47s |
{minutes:age} | 45m / 2h 30m / never |
{bytes:size} | ~522KB / 1.4MB |
{value}★ ({count}) | 5.0★ (1) |
{sev} | Emoji de gravité : 🟢 ok, 🟡 avertir, 🔴 critique, ⚪ inactif |
{trend} | ↗ / ↘ (±5 pp contre 7j) |
8. Conditions de visibilité (quand)
when contrôle si un champ de métrique (ou une ligne Telegram entière)
montre. Valeurs:
| quand | Affiche le champ |
|---|---|
always | Toujours (par défaut). |
nonzero | Uniquement lorsque la valeur n'est pas 0 / vide. |
severity>=warn | Uniquement lorsque la gravité est avertie ou critique. |
changed | Uniquement lorsqu'il a changé depuis l'instantané précédent. |
Les valeurs when inconnues se comportent comme always (compatible ascendante).
9. Exemple de charge utile
{
"schema_version": "2.0",
"generated_at": "2026-07-02T23:17:30Z",
"tabs": [
{ "id": "conv", "title": "Conversions", "order": 1, "icon": "trending-up" }
],
"sections": [
{ "tab": "conv", "id": "by_hour", "title": "By hour", "order": 0 }
],
"telegram": {
"header": "{name} • {cws.users} • {cws.rating}★ ({cws.rating_count})",
"lines": [
{ "id": "base", "order": 0 },
{ "id": "conv", "order": 1, "prefix": "{sev} Conv " }
]
},
"metrics": [
{
"id": "conv_today",
"kind": "number",
"label": "Conversions today",
"value": 254,
"severity": "ok",
"shareable": true,
"dashboard": {
"show": true,
"tab": "conv", "section": "by_hour", "order": 10,
"name": "Today", "render": "kpi", "options": {}
},
"telegram": {
"show": true,
"line": "conv", "pos": 20,
"format": "today {value}", "sep": " • ", "when": "always"
}
}
]
}10. Le contrat lisible par machine
La description formelle et importable de ce point de terminaison est le fichier OpenAPI 3.1. Il porte la même version de contrat (2.0.0) et est le seul canonique artefact de machine, partagé entre les langues.