fullstack-debugger について
fullstack-debuggerは、Next.js 15、Cloudflare Workers、Supabase、エッジデプロイを扱う開発者向けのデバッグスキルです。証拠に基づいて層ごとに原因を絞り込み、修正を検証します。
主な機能
- 01再現から検証までの体系的な手順
- 02ブラウザー、サーバー、データベースの診断
- 03ビルドと型チェック用コマンド
- 04RLS、CORS、認証、キャッシュの調査
- 05根本原因の報告と修正の検証
活用シーン
- 01Next.jsのビルド失敗の調査
- 02SupabaseのRLSや認証問題の診断
- 03Cloudflare Workerの稼働状態とCORSの確認
- 04ハイドレーション、キャッシュ、デプロイ障害の追跡
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ curiositech/ some_claude_skills --skill fullstack-debuggerインストール後、Claude Code で/fullstack-debuggerを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
.claude-plugin/plugin.jsonreferences/debug-decision-tree.mderror-patterns.mdscripts/check-cors.shcheck-rls.jsdiagnose.shinspect-cache.sh詳細
フルスタックデバッガー
最新のウェブスタックに対応するエキスパートデバッガー:Next.js 15、Cloudflare Workers、Supabase、エッジデプロイ。体系的で証拠に基づいたトラブルシューティングを行います。
起動トリガー
次の場合に起動:「デバッグ」「動かない」「壊れている」「エラー」「500 エラー」「401」「403」「キャッシュの問題」「CORS エラー」「RLS ポリシー」「認証が機能しない」「空白ページ」「ハイドレーションエラー」「ビルド失敗」「ワーカーが応答しない」
**対象外:**機能開発 → 言語スキル | アーキテクチャ → system-architect | パフォーマンス最適化 → performance-engineer
デバッグの方針
1. REPRODUCE → Can you make it fail consistently?
2. ISOLATE → Which layer is broken?
3. EVIDENCE → What do logs/network/state show?
4. HYPOTHESIZE → What could cause this?
5. TEST → Validate one hypothesis at a time
6. FIX → Minimal change that resolves issue
7. VERIFY → Confirm fix doesn't break other things
アーキテクチャのレイヤー
┌─────────────────────────────────────────────────────────────┐
│ DEBUGGING LAYERS │
├─────────────────────────────────────────────────────────────┤
│ │
│ Layer 1: Browser/Client │
│ ├── Console errors, network tab, React DevTools │
│ ├── localStorage/sessionStorage state │
│ └── React Query cache state │
│ │
│ Layer 2: Next.js Application │
│ ├── Server components vs client components │
│ ├── Build output and static generation │
│ ├── API routes (if any) │
│ └── Hydration mismatches │
│ │
│ Layer 3: Cloudflare Workers │
│ ├── Worker logs (wrangler tail) │
│ ├── KV cache state │
│ ├── CORS headers │
│ └── Rate limiting │
│ │
│ Layer 4: Supabase │
│ ├── Auth state and JWT tokens │
│ ├── RLS policies (most common issue!) │
│ ├── Database queries and indexes │
│ └── Realtime subscriptions │
│ │
│ Layer 5: External APIs │
│ ├── Third-party service availability │
│ ├── API rate limits │
│ └── Response format changes │
│ │
└─────────────────────────────────────────────────────────────┘
クイック診断コマンド
すべてを一度に確認
# Run from next-app/ directory
echo "=== Build Check ===" && npm run build 2>&1 | tail -20
echo "=== TypeScript ===" && npx tsc --noEmit 2>&1 | head -20
echo "=== Lint ===" && npm run lint 2>&1 | head -20
echo "=== Git Status ===" && git status --short
Supabase RLS の診断
# Check if RLS is blocking queries (most common issue!)
node -e "
const { createClient } = require('@supabase/supabase-js');
const supabase = createClient(
'YOUR_SUPABASE_URL',
'YOUR_ANON_KEY'
);
async function diagnose() {
// Test as anonymous user
const { data, error, count } = await supabase
.from('YOUR_TABLE')
.select('*', { count: 'exact' })
.limit(5);
console.log('Error:', error);
console.log('Count:', count);
console.log('Sample:', data);
}
diagnose();
"
ワーカーのヘルスチェック
# Check if workers are responding
curl -s -o /dev/null -w "%{http_code}" https://YOUR-WORKER.workers.dev/health
# Check CORS headers
curl -s -D - -o /dev/null -H "Origin: https://yoursite.com" \
https://YOUR-WORKER.workers.dev/api/endpoint | grep -iE "(access-control|x-)"
# Stream worker logs
cd workers/your-worker && npx wrangler tail
キャッシュの調査
# Check Cloudflare KV cache
npx wrangler kv:key list --namespace-id=YOUR_NAMESPACE_ID | head -20
# Get specific cached value
npx wrangler kv:key get --namespace-id=YOUR_NAMESPACE_ID "cache:key"
# Clear a cached item
npx wrangler kv:key delete --namespace-id=YOUR_NAMESPACE_ID "cache:key"
よくある問題と解決策
1. RLS ポリシーによるデータのブロック(最もよくある問題です!)
症状:
- クエリでエラーは発生しないものの、空の配列が返される
- Supabase ダッシュボードでは動作するが、アプリでは動作しない
- ユーザーによって動作する場合としない場合がある
診断:
-- In Supabase SQL Editor
-- Check what policies exist
SELECT schemaname, tablename, policyname, permissive, roles, cmd, qual
FROM pg_policies
WHERE tablename = 'your_table';
-- Test as anonymous user
SET ROLE anon;
SELECT * FROM your_table LIMIT 5;
RESET ROLE;
-- Test as authenticated user
SET ROLE authenticated;
SET request.jwt.claims = '{"sub": "user-uuid-here"}';
SELECT * FROM your_table LIMIT 5;
RESET ROLE;
よくある修正方法:
-- Allow public read access
CREATE POLICY "Allow public read" ON your_table
FOR SELECT USING (true);
-- Allow authenticated users to read
CREATE POLICY "Allow authenticated read" ON your_table
FOR SELECT TO authenticated USING (true);
-- Allow users to read their own data
CREATE POLICY "Users read own data" ON your_table
FOR SELECT USING (auth.uid() = user_id);
2. CORS エラー
症状:
- 「CORS ポリシーによってフェッチへのアクセスがブロックされました」
- Postman では動作するが、ブラウザーでは動作しない
- プリフライトリクエストが失敗する
診断:
# Check what CORS headers are returned
curl -s -D - -o /dev/null \
-H "Origin: https://yoursite.com" \
-H "Access-Control-Request-Method: POST" \
-X OPTIONS \
https://your-worker.workers.dev/api/endpoint
Cloudflare Worker での修正:
// In your worker
const corsHeaders = {
'Access-Control-Allow-Origin': '*', // Or specific domain
'Access-Control-Allow-Methods': 'GET, POST, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
};
// Handle preflight
if (request.method === 'OPTIONS') {
return new Response(null, { headers: corsHeaders });
}
// Add to all responses
return new Response(data, {
headers: { ...corsHeaders, 'Content-Type': 'application/json' }
});
3. 認証状態が保持されない
症状:
- ユーザーはログインしているのに、再読み込みするとログアウト状態になる
- ローカルでは認証が機能するが、本番環境では機能しない
- セッションがランダムに消える
診断:
// In browser console
console.log('Session:', await supabase.auth.getSession());
console.log('User:', await supabase.auth.getUser());
console.log('LocalStorage:', Object.keys(localStorage).filter(k => k.includes('supabase')));
よくある修正方法:
- Supabase URL が一致しているか確認します(http と https、末尾のスラッシュ)
- Supabase Auth 設定のサイト URL を確認します
- Cookie がブロックされていないか確認します(Safari、シークレットモード)
- 認証が必要なすべてのコンポーネントが AuthContext でラップされていることを確認します
4. ハイドレーションの不一致
症状:
- 「初期 UI が一致しないため、ハイドレーションに失敗しました」
- ページの読み込み時にコンテンツがちらつく
- サーバーとクライアントでコンテンツが異なる
診断:
// Temporarily add to suspect component
useEffect(() => {
console.log('Client render:', document.body.innerHTML.slice(0, 500));
}, []);
よくある修正方法:
// Use client-only rendering for dynamic content
'use client';
import { useState, useEffect } from 'react';
function DynamicContent() {
const [mounted, setMounted] = useState(false);
useEffect(() => setMounted(true), []);
if (!mounted) return null; // or skeleton
return <div>{/* dynamic content */}</div>;
}
5. Worker がデプロイされない
症状:
- デプロイコマンドは成功するが、変更が反映されない
- 古いコードが引き続き実行される
- 新旧の動作が断続的に切り替わる
診断:
# Check deployment status
npx wrangler deployments list
# View current worker code
npx wrangler deployments view
# Check for multiple environments
npx wrangler whoami
修正方法:
# Force redeploy
npx wrangler deploy --force
# Clear Cloudflare cache
curl -X POST "https://api.cloudflare.com/client/v4/zones/ZONE_ID/purge_cache" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
--data '{"purge_everything":true}'
6. TypeScript のキャッシュが付きまとう
症状:
- 削除または変更したコードを参照するエラーが発生する
- 型が現在のコードと一致しない
- 既存ファイルに対して「モジュールが見つかりません」と表示される
修正方法:
# Nuclear option - clear all caches
rm -rf .next node_modules/.cache tsconfig.tsbuildinfo
npm run build
# Or just TypeScript cache
rm -rf node_modules/.cache/typescript
npx tsc --build --clean
7. 静的エクスポートの問題
症状:
- 「エラー:ページ X を静的にレンダリングできませんでした」
- 静的エクスポートで動的ルートが失敗する
- デプロイ後に API ルートが動作しない
診断:
# Check next.config for output mode
grep -A5 "output:" next.config.ts
# Find dynamic components
grep -r "useSearchParams\|usePathname\|cookies()\|headers()" src/
修正方法:
// For components using dynamic APIs
export const dynamic = 'force-dynamic';
// or wrap in Suspense with fallback
// For generateStaticParams
export async function generateStaticParams() {
return [{ slug: 'page1' }, { slug: 'page2' }];
}
8. レート制限の問題
症状:
- 数回リクエストした後に 429 エラーが発生する
- 最初は動作するが、その後停止する
- IP ごとに動作が異なる
診断:
# Check rate limit headers
curl -i https://your-worker.workers.dev/api/endpoint 2>&1 | grep -i ratelimit
# Check KV for rate limit keys
npx wrangler kv:key list --namespace-id=RATE_LIMIT_KV_ID | grep rate
修正方法:
# Clear rate limit for an IP
npx wrangler kv:key delete --namespace-id=RATE_LIMIT_KV_ID "rate:192.168.1.1"
# Adjust limits in wrangler.toml
RATE_LIMIT_REQUESTS = "100"
RATE_LIMIT_WINDOW = "3600"
9. ミーティング/場所のデータに関する問題
症状:
- 特定の地域でミーティングが見つからない
- ミーティングのデータが古い
- キャッシュに誤ったデータが表示される
診断:
# Check cache status for a location
curl -s -D - -o /dev/null \
-H "Origin: https://yoursite.com" \
"https://your-proxy.workers.dev/api/all?lat=45.52&lng=-122.68&radius=25" \
| grep -iE "(x-cache|x-geohash|x-source)"
# Force cache refresh
curl -H "Origin: https://yoursite.com" \
"https://your-proxy.workers.dev/warm"
# Check Supabase for meeting count
node -e "
const { createClient } = require('@supabase/supabase-js');
const supabase = createClient('URL', 'KEY');
supabase.from('meetings').select('*', { count: 'exact', head: true })
.then(({count}) => console.log('Total meetings:', count));
"
10. Cloudflare Pages でビルドが失敗する
症状:
- ローカルでは動作するが、デプロイ時に失敗する
- 「モジュールが見つかりません」というエラーが発生する
- メモリ上限を超過する
診断:
# Check build output locally
NODE_ENV=production npm run build 2>&1 | tee build.log
# Check for conditional imports
grep -r "require(" src/ --include="*.ts" --include="*.tsx"
# Check bundle size
npx next-bundle-analyzer
修正方法:
// next.config.ts - increase memory
module.exports = {
experimental: {
memoryBasedWorkersCount: true,
},
// Reduce bundle size
webpack: (config) => {
config.externals = [...(config.externals || []), 'sharp'];
return config;
}
};
デバッグスクリプト
scripts/diagnose.sh
#!/bin/bash
# Run all diagnostics
echo "=== Environment ==="
node -v && npm -v
echo "=== Dependencies ==="
npm ls --depth=0 2>&1 | grep -E "(UNMET|missing)"
echo "=== TypeScript ==="
npx tsc --noEmit 2>&1 | head -30
echo "=== Build ==="
npm run build 2>&1 | tail -30
echo "=== Workers ==="
for worker in workers/*/; do
echo "Worker: $worker"
(cd "$worker" && npx wrangler whoami 2>/dev/null)
done
echo "=== Supabase ==="
npx supabase status 2>/dev/null || echo "Supabase CLI not configured"
scripts/check-rls.js
// Check RLS policies are working correctly
const { createClient } = require('@supabase/supabase-js');
const supabase = createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY
);
async function checkTable(table) {
console.log(`\n=== Checking ${table} ===`);
const { data, error, count } = await supabase
.from(table)
.select('*', { count: 'exact' })
.limit(1);
if (error) {
console.log(`ERROR: ${error.message}`);
} else {
console.log(`OK: ${count} rows accessible`);
}
}
// Check critical tables
['profiles', 'meetings', 'forum_posts', 'journal_entries'].forEach(checkTable);
検証チェックリスト
[ ] Can reproduce the issue consistently
[ ] Identified which layer is failing (client/Next/Worker/Supabase/API)
[ ] Checked browser console for errors
[ ] Checked network tab for failed requests
[ ] Checked worker logs (wrangler tail)
[ ] Verified RLS policies allow access
[ ] Tested with fresh browser/incognito
[ ] Cleared all caches (browser, React Query, KV, TS)
[ ] Checked environment variables match production
[ ] Verified CORS headers are correct
[ ] Tested on production URL (not just localhost)
[ ] Created minimal reproduction case
出力
デバッグ時は、必ず次の内容を提示してください。
- 根本原因 - 具体的に何が問題だったか
- 証拠 - 問題を裏付けるログ、エラー、クエリ
- 修正 - 解決に必要な最小限のコード変更
- 検証 - 修正を確認する方法
- 予防 - 今後同じ問題を避ける方法
利用可能なツール
Read、Write、Edit- ファイル操作Bash- コマンド、curl、wrangler の実行Grep、Glob- コードベースの検索WebFetch- エンドポイントのテストmcp__supabase__*- Supabase の直接操作mcp__playwright__*- UI テスト用のブラウザー自動化
コメント
Markdown 対応