sixty

pour les applications construites sur Lovable

Votre appli n’a pas de serveur. Elle a quand même des bugs.

Tout ce que fait votre application se passe à deux endroits qu’un outil de surveillance normal ne peut pas voir : le navigateur, et Supabase. Sixty mesure les deux depuis l’intérieur de la page — les requêtes et ce qu’elles renvoient, les canaux temps réel, ce sur quoi les gens ont cliqué et si ça a marché, et la vitesse de tout cela —, compare chaque publication à la précédente, et remet ce qu’il trouve à l’agent qui a écrit le code.

Ce qu’il mesure

Chaque requête Supabase que fait la page
Combien s’exécutent par interaction, combien de lignes chacune renvoie, quelle taille fait la réponse et combien de temps ça a pris. C’est là que « c’est devenu lent » se trouve presque toujours.
La vitesse de la page, par route
LCP, INP, CLS et TTFB au vrai p75 sur tous ceux qui l’ont chargée — pas un score de laboratoire depuis une machine. Ventilé par pays, parce qu’une page qui va bien chez vous peut être inutilisable là où la latence est pire.
Ce sur quoi les gens ont cliqué, et si ça a marché
Des clics qui n’ont rien fait, des clics répétés sur le même contrôle, et des interactions qui redessinent la page des centaines de fois.
Auth, stockage, fonctions edge et temps réel
Une application Supabase, ce sont quatre services et non un, et l’agent comprend ce que fait chaque point d’entrée plutôt que seulement ce qu’il a coûté — une connexion refusée, une colonne manquante, une écriture rejetée et un canal qui n’a pas réussi à s’abonner arrivent donc chacun tels qu’ils sont, au lieu d’arriver comme une requête échouée anonyme.
Le code, avant qu’il ne tourne
Un bouton sans gestionnaire, un effet dont les dépendances garantissent qu’il bouclera indéfiniment, un abonnement qui n’est jamais démonté. Ceux-là n’émettent rien à l’exécution — un gestionnaire qui n’a jamais été attaché ne peut pas être mesuré —, ils sont donc lus dans le source à la compilation et classés selon le trafic que le fichier sert réellement.

Ce qu’il trouve

Chacune de ces choses est comparée à la version précédente : le constat nomme donc le changement plutôt que le jour.

Une requête qui s’est mise à tout renvoyer

Un filtre disparaît lors d’une réécriture et une requête qui renvoyait 30 lignes en renvoie 30 000. Sur la poignée de lignes de votre projet c’est instantané, donc rien n’a l’air anormal jusqu’à ce qu’il y ait de vraies données derrière.

Un N+1 né à l’intérieur d’un rendu

Un chargement se déplace dans une liste et une requête en devient quarante. Chacune est rapide, donc aucune requête prise seule n’a l’air fausse — seul le nombre l’est, et le nombre est justement ce que rien d’autre que vous puissiez installer ne vous montrera.

Des utilisateurs qui voient les lignes des autres — ou celles de personne

Quand une règle de sécurité au niveau des lignes manque ou est fausse, Postgres ne lève pas d’erreur. Il renvoie des lignes qui ne devraient pas être là, ou aucune, et la page s’affiche vide. Sixty voit les deux moitiés : les requêtes que la base refuse sous une règle, et celles qu’elle autorise et qui reviennent vides là où elles revenaient pleines.

Une page qui ne finit jamais de charger

Un indicateur de chargement encore à l’écran douze secondes après son apparition — le plus souvent une requête tombée dans un catch, ou un drapeau de chargement mis à vrai et jamais remis.

Le schéma qui dérive sous le code

Une colonne, une table ou une relation que le code attend et que la base n’a plus. Ça échoue à l’exécution, dans le navigateur, chez celui qui a chargé cette page.

Des erreurs que personne n’a signalées

Groupées par l’endroit du code d’où elles viennent, y compris les défaillances React qui ne font rien planter — la barrière d’erreur les attrape, affiche une zone vide, et journalise.

Le même canal temps réel, abonné trois fois

Un effet ouvre un abonnement et ne le démonte jamais, donc chaque rendu en ajoute un. Rien ne lève d’exception et rien n’est lent : la personne regarde simplement chaque nouveau message arriver trois fois, pendant que le nombre de connexions grimpe vers la limite qui coupera la fonctionnalité pour tout le monde.

Un bouton qui, mesuré, ne fait rien

Cliqué, et aucune requête n’est partie, aucune donnée n’a changé, aucune page n’a bougé — en général un gestionnaire jamais branché. Plus les clics répétés qui suivent, ce que les gens font quand le premier a paru ne rien faire.

Un clic qui redessine la page des centaines de fois

Une boucle de rendu. Elle ne lève jamais d’erreur et ne fait jamais échouer de requête ; elle vide la batterie de celui qui tient le téléphone.

Des sessions refusées

Une part des appels vers un point d’entrée qui reviennent en 401 ou 403, ou un jeton expiré là où il en fallait un. Dans une application sans serveur, c’est le seul endroit où un refus est visible.

Ce qui arrive dans votre fil

Pas un tableau de bord à lire. Une carte par constat, avec les chiffres, la version qui les a changés, et les preuves dont votre agent de code a besoin pour écrire le correctif.

Reconstitué. Ce sont des défaillances que le détecteur produit réellement à partir d’une application Supabase publiée — mais contrairement aux exemples Node, ce n’est pas la sortie d’un script que vous pouvez lancer, donc c’est dessiné plutôt que cité.

lignesselect:orders
30 lignes30 000 lignes1000×

Cette requête renvoie toutes les commandes de la table et les filtre dans le navigateur. Elle a été écrite contre un projet de quarante lignes, où c’était instantané.

sur /orders, depuis l’avant-dernière publication

ne renvoie rienselect:invoices
12 lignes0 ligne

La même requête qui renvoyait des factures hier n’en renvoie plus aucune. Rien n’a échoué : une règle s’est mise à tout filtrer, et la page s’affiche vide.

sur /invoices, depuis la dernière publication

Comment ça s’installe

Vous n’installez pas ça à la main. Collez un prompt dans le chat de Lovable et il branche l’agent — un plugin Vite, un appel d’initialisation, et une route qui relaie la télémétrie pour qu’aucune clé n’arrive jamais dans votre bundle. En vous connectant, ce prompt est écrit pour vous avec votre clé déjà dedans.

npm install @sixty-sh/supabase

// vite.config.ts
import drift from '@sixty-sh/supabase/vite'
export default defineConfig({ plugins: [react(), drift()] })

// src/integrations/supabase/client.ts — the file every Lovable app has
import { withSixty } from '@sixty-sh/supabase'

export const supabase = withSixty(createClient(URL, ANON_KEY), {
  key: 'sixty_pk_…',
  service: 'my-app',
  endpoint: 'https://ingest.sixty.sh',
})

Ensuite publiez deux fois. La comparaison est ancrée aux publications plutôt qu’à l’horloge, donc le premier constat arrive après la suivante — il n’y a rien à quoi comparer une version isolée.

Ce qu’il ne fait pas

  • Les constats issus d’un build publié pointent vers la requête et la route, pas vers une ligne de votre source. Les bundles de production sont minifiés et la sourcemap qui défairait cela n’est pas encore lue : vous obtenez donc « cette requête sur cette page » plutôt que « ce fichier, ligne 40 ».
  • L’aperçu Lovable ne suffit pas. Il tourne sur un serveur de développement sans ressources empreintées, il n’y a donc aucune version sur laquelle ancrer une comparaison — la comparaison a besoin de deux vraies publications.
  • Rien ici ne surveille de serveur, parce que vous n’en avez pas. Si vous ajoutez plus tard vos propres fonctions edge, elles ont besoin de l’agent Node pour être visibles.

Si vous êtes ici pour l’une de ces raisons

Découvrez ce qu’a fait votre dernier changement.

Essayez !

Vous construisez autre chose ? Voyez services Node ou applications React Native — ces pages sont différentes, et ce que nous voyons aussi.

Surveillance des performances pour les applications Lovable et Supabase — Sixty