audit-fe-api について
audit-fe-apiは、フロントエンドとバックエンドのAPI契約を調べるスキルです。API呼び出しや本番エラー、キャッシュ改善の機会を確認する開発者向けに、根拠に基づく読み取り専用の監査手順とレポート形式を備えています。
主な機能
- 01フロントエンドとバックエンドのAPIスタック検出
- 02フロントエンドAPI呼び出しの一覧化
- 03ルート、パラメーター、メソッド、型の確認
- 04Sentryデータによる本番問題の調査
- 05キャッシュ、プリフェッチ、重複リクエストの確認
- 06重大度別の監査結果報告
活用シーン
- 01存在しないバックエンドルートへの呼び出し調査
- 02リクエストパラメーターとレスポンス型の不一致確認
- 03本番APIエラーからフロントエンドの呼び出し元を特定
- 04重複リクエストやキャッシュ不足の発見
MCP 対応
Sentry MCPで本番APIエラーを検索し、バックエンドがSupabaseを使う場合はSupabase MCPでデータベーススキーマを確認する手順が記載されています。
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ kensaurus/ skills --skill audit-fe-apiインストール後、Claude Code で/audit-fe-apiを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
references/fix-patterns.mdreport-template.mdresearch-calls.md詳細
フロントエンド API 監査スキル
自由度:混在 — ステップ 0、1、3~6 は [HIGH freedom]、ステップ 2 の
Sentry クエリとスキーマ SQL は [LOW freedom — run exactly] です。
読み取り専用です。調査結果を提示してください。Phase 6 のスニペットは推奨する修正の形であり、このパスで編集するものではありません。
推論の進め方
- 観察 — FE の呼び出し箇所、BE のルート、レスポンス/エラーを引用します
- 解釈 — 契約が一致しているかを確認します(パス、メソッド、パラメーター、型)
- 分類 — ルート欠落/不一致/型指定なし/キャッシュの不足/問題なし
- 重大度 — 本番環境での 404/401/型の不一致は Critical、キャッシュ/プリフェッチは改善の機会です
例
観察:
useUserは/api/users/${id}に GET しますが、app/api/users/[id]/route.tsはありません。 Sentry では 14 日間に 404 が 25 件発生しています。 解釈: FE は BE に登録されていないルートを呼び出しています。 分類: ルート欠落(Critical)。 重大度: Critical — 必ず 404 になります。 指摘事項:hooks/useUser.ts| GET/api/users/:id| Critical | BE のルートなし。
報告前の自己批評 [LOW freedom — do not skip]
- 証拠がある — FE のファイルと BE のルート、または Sentry イベントを示します。「おそらく 500」では不十分です
- 好みではなく契約 — staleTime の提案には鮮度に関する理由が必要です
- 重大度に根拠がある — Critical は本番環境で契約が壊れている場合に限ります
- 担当先が適切 — 稼働中の 4xx/5xx の再現は
debug-fe-be-integration、DB の形状はaudit-db-schemaに割り当てます - 両側を明記 — 不一致にはすべて FE のファイルと BE のパス(または NOT FOUND)を記載します
Step 0:API レイヤーを自動検出する
0a. フロントエンドスタックを検出する
| 依存関係 | テクノロジー |
|---|---|
@tanstack/react-query | TanStack Query(React Query) |
swr | SWR |
@reduxjs/toolkit と createApi | RTK Query |
axios | Axios HTTP クライアント |
ky | Ky HTTP クライアント |
ofetch または $fetch | Nuxt/ofetch |
@trpc/client | tRPC(型安全な RPC) |
graphql-request または @apollo/client | GraphQL |
openapi-fetch または openapi-typescript | OpenAPI 型付きクライアント |
0b. バックエンドスタックを検出する
Glob: **/app/api/**/route.ts → Next.js App Router API routes
Glob: **/pages/api/**/*.ts → Next.js Pages Router API routes
Glob: **/src/routes/**/*.ts → Express/Hono/Fastify routes
Glob: **/server/api/**/*.ts → Nuxt server routes
Glob: **/src/app.py → Flask/Django
Glob: **/main.go → Go backend
0c. API サービスファイルを見つける
Glob: **/services/*api*.ts → API service files
Glob: **/services/*service*.ts → Service files
Glob: **/api/*.ts → API client files
Glob: **/hooks/use*.ts → Custom hooks (may contain API calls)
Glob: **/lib/api*.ts → API client config
Glob: **/features/*/api.* → Feature-specific API files
0d. 開発サーバーのポートを検出する
Grep: "dev" in package.json scripts → extract port (3000, 3001, 5173, 8080, etc.)
Grep: "PORT" in .env or .env.local
0e. 検出結果を記録する
API LAYER DISCOVERY:
- HTTP client: [axios/fetch/ky/ofetch]
- State management: [TanStack Query/SWR/RTK Query/none]
- API style: [REST/GraphQL/tRPC]
- Backend framework: [Next.js API routes/Express/Hono/etc.]
- API service files: [list paths]
- API hooks: [list paths]
- Dev server: http://localhost:[port]
- API docs: [path or URL if detected]
Step 1:API のベストプラクティスを調査する
1a. Context7 — ライブラリのドキュメント
主要な依存関係(@tanstack/react-query、axios、zod)をそれぞれ解決してから、
「staleTime cacheTime retry error handling optimistic updates」についてドキュメントを検索します。呼び出し本文:
references/research-calls.md §Context7。
1b. Firecrawl — 最新の API パターン
<FRAMEWORK> API integration best practices [current year] を検索し(上限 5 件、web ソース)、続いて
以下の各トピックについてクエリを 1 件ずつ実行します。呼び出し本文:references/research-calls.md §Firecrawl。
| トピック | クエリ |
|---|---|
| キャッシュ | <state library> caching strategy staleTime production |
| エラー処理 | <framework> API error handling patterns retry |
| 型安全性 | <framework> type-safe API client OpenAPI Zod |
| パフォーマンス | frontend API request optimization batching deduplication |
Step 2:本番 API エラーを確認する(Sentry)
2a. API 関連の本番エラーを見つける
sentry:search_issues
{
"organizationSlug": "<ORG_SLUG>",
"query": "API errors 4xx 5xx fetch axios network from the last 14 days",
"projectSlugOrId": "<PROJECT_SLUG>",
"regionUrl": "<REGION_URL>",
"limit": 25
}
2b. 最も遅い API 呼び出しを見つける
sentry:search_events
{
"organizationSlug": "<ORG_SLUG>",
"projectSlug": "<PROJECT_SLUG>",
"regionUrl": "<REGION_URL>",
"dataset": "spans",
"query": "span.op:http.client",
"sort": "-span.duration",
"limit": 15
}
2c. フロントエンドコードと相互参照する
各 Sentry エラーについて、エンドポイントを特定し、Grep で FE の呼び出し元を検索して、エラー処理/再試行/型を確認します。
Phase 3:フロントエンドの API 呼び出しを見つける
3a. すべての API 呼び出しを見つける
Grep(bash grep ではありません):
Grep: pattern "fetch\(|axios\.|api\.(get|post|patch|put|delete)" glob "*.{ts,tsx,js,jsx}"
Grep: pattern "useQuery|useMutation|useInfiniteQuery|useSuspenseQuery" glob "*.{ts,tsx}"
Grep: pattern "createApi|injectEndpoints" glob "*.{ts,tsx}"
3b. API 呼び出しの一覧を作成する
| ファイル | 関数/フック | メソッド | エンドポイント | パラメーター | 使用箇所 |
|---|---|---|---|---|---|
services/user.ts | getUsers | GET | /api/users | page、limit | UserList.tsx |
hooks/useUser.ts | useUser | GET | /api/users/:id | id | UserProfile.tsx |
Phase 4:バックエンドと照合する
4a. エンドポイントの存在を確認する
Grep: pattern "<ENDPOINT_PATH>" glob "*.{ts,js,py,go,rb}" — in backend source
App Router:app/api/<path>/route.ts が存在する必要があります。
4b. パラメーターの正確性を確認する
| 確認項目 | 方法 |
|---|---|
| 必須パラメーターが送信されている | FE の呼び出しパラメーターと BE の検証スキーマ(Zod、Yup、Joi)を比較します |
| 命名規則が一致している | FE の camelCase と BE の snake_case を比較し、変換処理があるか確認します |
| 型が一致している | FE は文字列を送信しているのに BE は数値を想定している、またはその逆になっていないか確認します |
| ボディの形状が一致している | FE のリクエストボディと BE が想定するスキーマを比較します |
4c. Supabase MCP でスキーマを確認する
バックエンドが Supabase から読み取る場合は、DB スキーマがフロントエンドの想定と一致しているか確認します。
supabase:execute_sql
{
"query": "SELECT column_name, data_type, is_nullable FROM information_schema.columns WHERE table_name = '<TABLE>' ORDER BY ordinal_position"
}
列と型を FE の TypeScript インターフェースと比較します。
フェーズ 5:問題を特定する
重大な問題
| 問題 | 影響 | 検出方法 |
|---|---|---|
| エンドポイントが存在しない | 404 エラー | バックエンドでルートを grep し、見つからないことを確認します |
| 必須パラメーターが不足している | 500/422 エラー | FE のパラメーターと BE のスキーマを比較します |
| HTTP メソッドが誤っている | 405 エラー | FE が GET を使用し、BE が POST を想定していないか確認します |
| 認証ヘッダーがない | 401 エラー | API クライアントのインターセプターを確認します |
| 型が一致しない | 実行時エラー | FE のインターフェースと BE のレスポンス形状を比較します |
警告
| 問題 | 影響 | 検出方法 |
|---|---|---|
| パラメーター名が一致しない | パラメーターが無視されても気付けない | camelCase と snake_case を比較します |
| 非推奨のエンドポイント | 将来的な不具合 | BE のルートにあるバージョンマーカーを確認します |
| エラーハンドリングがない | UX の低下 | エラー状態を処理せずに useQuery を使用していないか確認します |
| ローディング状態がない | UX の低下 | isLoading/isPending の確認があるか調べます |
最適化の機会
| 問題 | 影響 | 検出方法 |
|---|---|---|
| リクエストが重複している | 帯域幅の浪費 | 複数のコンポーネントで同じ queryKey が使われていないか確認します |
| キャッシュが設定されていない | UX の低下 | staleTime が設定されていない(デフォルトは 0)か確認します |
| リクエストのバッチ処理がない | リクエストが多すぎる | リストに N+1 クエリのパターンがないか確認します |
| プリフェッチがない | ナビゲーションの遅延 | ホバー/フォーカス時に prefetchQuery があるか確認します |
| 楽観的更新がない | ミューテーションが遅い | ミューテーションがサーバーの応答を待っているか確認します |
フェーズ 6:フロントエンドの最適化
6a. キャッシュ戦略
- データの実際の鮮度要件に応じてクエリごとに
staleTimeを設定します(ユーザープロフィールは約 10 分、設定はInfinity)。デフォルトの 0 では、マウントのたびに再フェッチされます。
const { data } = useQuery({
queryKey: ['user', userId],
queryFn: () => getUser(userId),
staleTime: 1000 * 60 * 10, // User data: 10 minutes
});
6b. 楽観的更新
onMutate:進行中のクエリをキャンセルし、getQueryDataでスナップショットを取得し、setQueryDataで新しい値に更新して、スナップショットを返します。onError:スナップショットを復元します。onSettled:キーを無効化します。
6c. プリフェッチ
- 詳細ビューと同じキーと fn を使って
queryClient.prefetchQueryを実行します。リンクのonMouseEnter/フォーカス時に行います。
6d. エラーハンドリング
- 指数関数的な
retryDelayを指定してretry: 3を設定し、上限を 30 s にします。isLoading、isError、空の状態を、この順でレンダリングします。
6e. レスポンスの検証(Zod)
- スキーマを一度だけ定義し、
type User = z.infer<...>として、サービス関数内でUserSchema.parse(response.data)を呼び出します。
6a~6e のコード全文:references/fix-patterns.md。
出力テンプレート
セクションの報告順:ヘッダー(日付、フレームワーク、クライアント、状態管理ライブラリ)→ 本番エラーの 概要(Sentry)→ 重大な問題 → 警告 → 最適化の機会(キャッシュ、プリフェッチ、 バッチ処理)→ API インベントリ(エンドポイント、メソッド、FE ファイル、BE ルート、ステータス)→ 型安全性の状況 → 適用した調査結果 → 次のステップのチェックリスト。
テンプレート全文:references/report-template.md。
関連項目
debug-fe-be-integration— BE ログからライブの 4xx/5xx を再現しますaudit-db-schema— FE の型と DB の列を比較しますdebug-sentry-monitor— 同じエンドポイントにおける本番エラーの発生数を確認します