Lovable で作ったアプリ向け
サーバーはありません。それでもバグはあります。
あなたのアプリがやることは、普通の監視ツールには見えない2か所で起きています。ブラウザと Supabase です。Sixty はその両方をページの内側から測ります — クエリと、それが返すもの、リアルタイムのチャンネル、人が何を押してそれが効いたかどうか、そしてそのどれもがどれだけ速かったか。そして公開ごとに1つ前と比較し、見つけたものをコードを書いたエージェントに渡します。
何を測るか
- ページが出すすべての Supabase クエリ
- 1回の操作あたり何本走り、それぞれ何行返し、レスポンスがどれだけ大きく、どれだけ時間がかかったか。「遅くなった」の正体は、ほぼ必ずここにあります。
- ページの速さを、ルートごとに
- 読み込んだ全員にわたる実際の p75 での LCP、INP、CLS、TTFB — 1台のマシンによるラボの点数ではありません。国別に分解します。あなたのところでは問題ないページが、遅延の大きい場所では使い物にならないことがあるからです。
- 人が何を押し、それが効いたかどうか
- 何も起きなかったクリック、同じ操作部品への繰り返しのクリック、そしてページを何百回も描き直す操作。
- 認証、ストレージ、Edge Function、リアルタイム
- Supabase のアプリは1つではなく4つのサービスです。エージェントは各エンドポイントが何をするかを理解していて、いくらかかったかだけを見ているのではありません — だから拒否されたサインイン、存在しないカラム、却下された書き込み、購読に失敗したチャンネルが、それぞれ匿名の「失敗したリクエスト」ではなく、そのものとして届きます。
- 動く前のコード
- ハンドラのないボタン、依存関係のせいで永遠に回り続けることが確定している副作用、後片付けされない購読。これらは実行時に何も出しません — 一度も取り付けられなかったハンドラは測れません — ので、ビルド時にソースから読み取り、そのファイルが実際に受けているトラフィック順に並べます。
何を見つけるか
どれも1つ前のリリースと比較されます。だから検出結果は、日付ではなく変更を名指しします。
すべてを返し始めたクエリ
書き直しの途中でフィルタが消え、30行を返していたクエリが30,000行を返す。あなたのプロジェクトの数行が相手なら一瞬なので、本物のデータが後ろにつくまで何もおかしく見えません。
レンダーの内側で生まれた N+1
取得処理がリストの中に移り、1本のクエリが40本になる。どれも速いので、1つのリクエストとして見ればおかしなところはありません — おかしいのは回数だけで、その回数こそ、他に導入できるどんなものも見せてくれないものです。
ユーザーが他人の行を見ている — あるいは誰の行も見ていない
行レベルセキュリティのポリシーが抜けていたり間違っていたりしても、Postgres はエラーを出しません。あるはずのない行を返すか、1行も返さないかで、ページは空のまま描画されます。Sixty はその両側を見ます。ポリシーの下でデータベースが拒否した文と、許可されて、以前は中身があったのに空で返ってくる文の両方です。
いつまでも読み込みが終わらないページ
表示から12秒たってもまだ画面にある読み込み表示 — たいていは catch の中で失敗したリクエストか、true にしたまま戻されなかった読み込みフラグです。
コードの下でずれていくスキーマ
コードが期待していて、データベースにはもうないカラム・テーブル・リレーション。実行時に、ブラウザで、そのページを開いた人のところで失敗します。
誰も報告しなかったエラー
コードのどこから出たかでまとめます。何もクラッシュさせない React の失敗も含めて — エラーバウンダリが捕まえ、空の領域を出し、記録します。
同じリアルタイムチャンネルを、三重に購読
副作用が購読を開き、一度も後片付けしないので、レンダーのたびに1つ増えます。何も throw されず、何も遅くなりません。ただ、新しいメッセージが3回ずつ表示されるのを本人が見ている間に、接続数は機能全体を止める上限へ向かって増えていきます。
測ってみると何もしていないボタン
押されたのに、リクエストは出ず、データも変わらず、ページも動かない — たいていは一度も配線されなかったハンドラです。そのあとに続く連打も一緒に。最初のクリックが何も起きなかったように見えたとき、人はそうするからです。
1回のクリックでページを何百回も描き直す
レンダーのループです。エラーにもならず、リクエストも失敗しません。ただ、その電話を持っている人のバッテリーを空にします。
拒否されているセッション
あるエンドポイントへの呼び出しのうち一定の割合が 401 か 403 で返る、あるいは必要な場所でトークンが期限切れになっている。サーバーのないアプリでは、拒否が目に見える場所はここだけです。
フィードに何が届くか
読むためのダッシュボードではありません。検出1件につきカード1枚。数値と、それを変えたリリースと、コーディングエージェントが修正を書くのに必要な証拠が付いています。
再構成したものです。これらは公開済みの Supabase アプリから検出器が実際に出す不具合ですが、Node の例と違って、あなたが走らせられるスクリプトの出力ではありません。だから引用ではなく作図です。
select:ordersこのクエリはテーブルの全注文を返し、ブラウザ側で絞り込んでいます。40行しかないプロジェクトに対して書かれたもので、そこでは一瞬で終わっていました。
/orders で、前々回の公開以降
select:invoices昨日は請求書を返していた同じクエリが、今日は1件も返しません。何も失敗していません。あるポリシーがすべてを絞り込み始め、ページは空のまま描画されています。
/invoices で、前回の公開以降
導入方法
これは手作業では入れません。Lovable のチャットにプロンプトを1つ貼れば、エージェントが組み込まれます — Vite プラグイン、init の呼び出し、そしてテレメトリを転送するルート。おかげでキーがバンドルに乗ることは一度もありません。ログインすれば、そのプロンプトはあなたのキーを入れた状態で書かれます。
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',
})そのあと2回公開してください。比較は時計ではなく公開に紐づいているので、最初の検出は次の公開のあとに届きます — バージョンが1つだけでは比べる相手がありません。
できないこと
- 公開ビルドからの検出は、クエリとルートを指します。ソースの行は指しません。本番のバンドルは圧縮されていて、それを元に戻すソースマップはまだ読んでいないので、「このファイルの40行目」ではなく「このページのこのクエリ」になります。
- Lovable のプレビューでは足りません。指紋付きのアセットを持たない開発サーバーで動くため、比較を固定できるバージョンが存在しません — 比較には本物の公開が2回必要です。
- ここではサーバーを見張っていません。あなたにサーバーがないからです。あとから自前の Edge Function を足す場合、それが見えるようになるには Node のエージェントが要ります。
これが理由でここに来たのなら
Lovable のアプリが、変更後に遅くなった
昨日までは普通でした。機能をもう1つ頼んで、公開したら、あるページに数秒かかるようになった — あるいは読み込み中のまま終わらない。エディタ上ではどこもおかしく見えず、エージェントに「もっと速くして」と頼むと、原因ではなかった部分が書き換わります。.
ユーザーが他人のデータを見られてしまう
誰かがログインして、自分のものではない一覧を見た — 他人の注文、他人のメッセージ。あるいはまだ起きていないが、その可能性にいま思い当たった。これを読むには後者のほうがよいタイミングです。.
ページは開くのに、中身が空
誰かがページを開くと、何もありません。エラーメッセージも、止まったままの読み込み表示も、コンソールの赤字もない — 以前は行があった場所が空の一覧になっている。再読み込みしても直らず、自分のアカウントでは問題なく動きます。.
最後の変更が何をしたのか、確かめてください。
試してみる別のものを作っていますか? Node のサービス、React Native のアプリ のページもあります — 見えるものが違うので、内容も違います。