高度なデバッグ用プロンプト
システム全体の見直し(コードベース監査)
- _「1. API 呼び出しをコンポーネントから分離する: _
ProjectListコンポーネントが直接データをフェッチしています。提案: データ取得処理を専用のフックまたはコンテキストに移動し、コンポーネントを純粋な UI に保ちましょう。
- タスク処理ロジックの結合度を下げる: タスク完了トグルが state を更新すると同時に、直接 localStorage に書き込んでいます。これは単一の信頼できる情報源を持つようにリファクタリングすべきです。
- ユーティリティ関数を整理する:
App.tsxにあるユーティリティ関数は、utilsフォルダ(例: 日付フォーマット関数)に置いたほうがよいでしょう。 - …」*
プロンプトはもっと具体的かつ詳細にする
壊れやすい更新に対する安全なアプローチ
パフォーマンス最適化チェック
- 「データ取得:
ProjectListコンポーネントは、レンダーのたびにデータを取得しています。これはキャッシュを使うか、フェッチ処理をより上位のコンテキストに移動することで、不要な繰り返しを防ぐよう改善できます。一度取得したプロジェクトを保持するために、state や context の使用を検討してください。 - 再レンダー:
TaskItemコンポーネントはメモ化されておらず、親の state が変わるたびに再レンダーされます。タスクが多い場合、これがインタラクションを遅くする原因になります。提案: 不要な再レンダーを防ぐために、TaskItemにReact.memoを使用してください。 - アセット: 2MB の画像(ロゴ)が見つかりました。かなり大きいので、圧縮するか、読み込みを速くするために解像度を下げてください。
- バンドルサイズ: すべてのページが 1 つのバンドルに含まれています。初期ロードを高速化するために、大きなモジュールには動的な
import()を使うなど、コード分割を検討してください。 - …」*
永続的なエラーへの対処
- AI に、これまで試したことを確認する。 「Try to Fix」を何度か実行したり、手動でプロンプトを送ったりしたあとだと、何が変更されたのかわからなくなることがあります。次のように聞いてみてください:_“What solutions have we tried so far for this error?”_。AI がこれまでの試行内容を列挙してくれるので、同じ修正を繰り返すのを避けられます。
- AI にエラーをわかりやすい言葉で説明させる。 “Explain in simple terms why this error occurs.” と聞いてみましょう。AI(とあなた)が本当にエラーを理解できているかどうかがわかります。ここで思い違いに気づけることもあります。
- 別のアプローチを検討する。 次のように聞いてみてください:_“Given this error keeps happening, can we try a different approach to achieve the goal?”_。AI が、問題のある箇所を回避できる別の実装戦略を提案してくれるかもしれません。
- 巻き戻してやり直す。 最悪の場合、いくつか前のステップまでロールバックすることもあります。Lovable では、古いバージョンに戻したり、過去のメッセージを編集して別のアプローチを試すことができます。そのうえで、小さな変更を積み重ねていきましょう。
デバッグフローのサンプル
「エラーの無限ループ」にハマったとき
この一連の流れでは、エラー内容を具体的に説明し、AI に理解を確認させています。単に「直す」ボタンを闇雲に連打しているわけではありません。
「機能が正しく動作しない」場合
要するに、「期待していること(メールが届く)」と「実際に起きたこと(何も起きていない+ログのスニペット)」を説明することで、AI が調査の進め方を案内できるようになります。
「UI 要素が消えてしまった」
AI は、そのコンポーネントがまだレンダーされているか、または return 文が抜けていないかを確認するかもしれません。
例えば、リファクタリングで親の JSX から
ProjectList が削除されてしまったことに気づくかもしれません。AI は、それを再インポートして含めるよう提案します。あるいは、親コンポーネント側の state の変更によって、意図せずリストがフィルタリングされてしまっている可能性もあります。AI は「データはまだフェッチされていますか? コンポーネントはそのデータを受け取れていますか? props を受け取れているか確認するために、render 内に console.log を追加してみましょう」といった可能性を順番に検証してくれます。
Dev tools とコンソールログの活用
根本原因分析、ロールバック、プログレッシブ エンハンスメント
根本原因と症状
null ポインタエラーをチェックの追加で直してくれたのは分かりましたが、そもそもなぜ null だったのでしょうか?その原因自体に対処できませんか?
ロールバックを賢く使う:
通知機能を追加する前の状態にプロジェクトを戻しました。もう一度実装しますが、今回はもっと慎重に進めましょう。
段階的な拡張(プログレッシブエンハンスメント):
- 失敗するテストケースを追加する。
- 問題を切り分けて依存関係を分析する。
- 修正を適用する前に、判明した内容を記録する。
作業しながらドキュメント化する:
問題が何だったか、そしてそれをどのように解決したか要約してください。
README やログに保存できます。将来の自分や、プロジェクトの他のメンバーが何が起きたのか理解するのに役立ちます。
人の助けを求めるべきタイミングを見極める:
コミュニティ向けデバッグガイドブック
エラーの修正
エラーの修正
エラーを修正するときは、関連するコードセクションのみに集中し、正常に動作している無関係な部分は変更しないでください。エラーメッセージを分析し、その原因を突き止めます。既存のコードベースとの互換性を保ちながら、特定の問題に対処する的を絞った修正を実装してください。どの解決策についても、確定する前に、元の問題を確実に解消し、新たなバグを生んでいないことを検証します。動作している機能は常に維持し、エラーに直接関係しないコードを書き換えることは避けましょう。
コード変更の方針
コード変更の方針
既存のコードを変更する場合は、要求された機能や修正を実装するために本当に必要な部分だけを変える、外科的なアプローチを取りましょう。コードベースに存在する変数名、コーディングパターン、アーキテクチャ上の設計判断は維持してください。変更を提案する前に依存関係を分析し、修正によって既存の機能が壊れないことを確認しましょう。変更内容は全面的な書き換えではなく、可能な限り最小限の差分として提示してください。即時のタスクを超える改善点を見つけた場合は、自動で実装せず、別途提案として提示してください。
データベース連携
データベース連携
新しいデータベース構造を提案する前に、既存のスキーマを十分に確認し、すでに存在するテーブルやリレーション、フィールドを把握してください。データモデルを重複させるのではなく、可能な限り既存のテーブルを活用しましょう。データベースに変更が必要な場合は、既存のクエリやデータアクセスパターンと互換性があることを必ず確認してください。スキーマ変更に伴っても既存データを保持できるようなマイグレーション戦略も検討してください。変更を提案する前に、常に外部キーやデータ整合性制約を検証してください。
問題の徹底分析
問題の徹底分析
あらゆる問題には、包括的な診断プロセスで取り組みましょう。まずはエラーメッセージ、ログ、システムの挙動を丁寧に確認し、関連する情報をすべて収集します。性急に結論を出すのではなく、考えられる原因について複数の仮説を立てます。各仮説を体系的に検証し、根本原因が特定できるまで続けます。解決策を提案する前に、分析の過程と結果を必ず記録に残します。考えられるエッジケースと、それらがシステムにどのような影響を与えるかも検討しましょう。
ソリューションの検証
ソリューションの検証
どの解決策も確定する前に、必ず厳密な検証プロセスを実施してください。問題を解決できているか確認するために、元の問題に対してその解決策をテストしてください。関連する機能に予期しない副作用がないか確認してください。パフォーマンスが悪化していないことを確認してください。さまざまな環境や設定との互換性を検証してください。エッジケースを一通り試し、堅牢性を確認してください。これらの検証をすべて完了してはじめて、その解決策を確定したものとして提示してください。
コードの一貫性
コードの一貫性
スタイルやパターン、アプローチの面で、既存のコードベースとの一貫性を保ちましょう。コードを分析して、命名規則、フォーマットの傾向、アーキテクチャパターンを把握します。新しい機能や修正を実装する際には、これら確立されたパターンに従ってください。プロジェクト内で使われているものと同じエラーハンドリング戦略、ロギング手法、テスト手法を使用します。そうすることで、開発者の認知負荷を減らしつつ、可読性と保守性を維持できます。
プログレッシブ・エンハンスメント
プログレッシブ・エンハンスメント
新しい機能を追加する際は、まったく新しいパラダイムを導入するのではなく、既存のアーキテクチャをベースに拡張するようにしてください。現在の設計の中から拡張ポイントを特定し、新しい機能のためにそれらを活用しましょう。コードベースで確立されているパターンや原則に沿う形で変更を実装してください。既存の機能が期待どおりに動作し続けるよう、後方互換性を重視しましょう。新しい追加分が既存システムとどのように統合され、どのようにそれを拡張しているのかを文書化してください。
ドキュメントと説明
ドキュメントと説明
すべての変更内容と提案について、明確で簡潔な説明を提供してください。どんな変更を行うのかだけでなく、なぜそれが必要なのか、どのように機能するのかも必ず説明してください。解決策に含まれる前提条件や依存関係は、すべて文書化してください。複雑なロジックや一見して分かりにくい解決策を導入する場合は、コード内にコメントを記載してください。アーキテクチャの変更を提案する際は、その影響を視覚的にイメージしやすくするために、図やハイレベルな説明を併せて提供してください。
技術的負債の認識
技術的負債の認識
解決策が技術的負債(テクニカルデット)を生み出しうる場合を見極め、こうしたトレードオフについて率直に共有してください。時間的な制約から理想的とは言えない解決策を選ばざるを得ないときは、将来的にどの部分をリファクタリングすべきかを明確にしておきましょう。場当たり的な応急処置と本質的な解決策を区別し、状況に応じて適切なアプローチを提案してください。技術的負債が避けられない場合は、将来の改善を進めやすくするために、その内容を明確に文書化しておきましょう。
学習と適応
学習と適応
プロジェクト固有のパターンや好みに継続的に適応していってください。これまでの提案に対するフィードバックに注意を払い、その学びを今後の提案に反映させてください。アプリケーションのアーキテクチャについて、時間の経過とともに精度が高まる頭の中のモデルを構築してください。過去の問題とその解決策を覚えておき、同じ間違いを繰り返さないようにしてください。技術的な判断の背景にある根本的なビジネス要件を積極的に理解するよう努めてください。
コンポーネントの重複作成を防ぐ
コンポーネントの重複作成を防ぐ
新しいページ、コンポーネント、またはフローを作成する前に、まずコードベース内にどんな既存要素があるかを徹底的に棚卸ししましょう。関連するキーワードやファイルパターンを使って、類似する機能を検索します。重複を作成するのではなく、既存のコンポーネントを再利用・拡張できる機会を特定してください。似た機能がすでに存在する場合は、それらを分析し、重複させるのではなく、パラメータ化や調整で対応できるかどうかを見極めましょう。提案している解決策が冗長な要素を生み出してしまわないよう、アプリケーション構造を頭の中でしっかりと把握しておきましょう。類似したページやフローが必要な場合は、異なるデータや設定で再利用できる抽象化されたコンポーネントの作成を検討し、DRY(Don’t Repeat Yourself)の原則を徹底しましょう。
デッドコード除去
デッドコード除去
使われていないコードを放置して蓄積させるのではなく、積極的に特定して削除してください。機能を置き換える場合は、単にコメントアウトしたり新しいコードの横に残したりするのではなく、古い実装はきれいに削除してください。コードを削除する前に、アプリケーション全体でそのコードが使われていないか、インポートや参照を確認して検証してください。利用可能であれば、依存関係解析などのツールを使って、そのコードが本当に未使用であることを確認しましょう。リファクタリング時には、非推奨メソッドを追跡し、参照されなくなったタイミングで確実に削除してください。孤立したコンポーネント、未使用のインポート、コメントアウトされたブロック、到達不能な条件を定期的にスキャンしましょう。コード削除を提案する際は、それが「デッドコード」と見なされる理由を明確に示し、削除前に見落としている依存関係がないかを確認してください。もはや実行されないコードパスの排除を優先することで、コードベースのクリーンさを維持しましょう。
既存の機能を維持する
既存の機能を維持する
動作している機能は、変更するには明示的な許可が必要な「ロックされたシステム」として扱ってください。正常に動作しているコンポーネントに変更を提案する前に、その境界と依存関係を必ず明確に特定します。明確な指示がない限り、現在稼働中の機能を削除したり、大きく変更したりしないでください。ある領域でエラーが発生しても、動いている無関係なコンポーネントに対して、念のための変更(“just in case” な変更)を行うことは避けましょう。アプリケーションのどの部分が安定していて、どの部分が開発中なのかを、常にはっきり把握しておきます。変更は特定の機能セットに限定し、他の機能に影響が漏れ出さないようにする「機能単位」のアプローチを取ってください。複数の機能で利用される共通コンポーネントを変更する場合は、依存するすべての機能が引き続き期待どおり動作することを必ず確認します。影響を与えそうな変更を行う前に、機能をまたいだ依存関係を十分にドキュメント化しておくことで、安全策を講じてください。アプリケーション内の、既に確立され正常に動作している部分に変更を提案する際は、常にその変更の意図を明示的に確認するようにします。
高度な問題解決アプローチ
高度な問題解決アプローチ
複雑なエラーに直面したときは、深く理解しないまま、その場しのぎの修正を加えたい誘惑をぐっとこらえてください。解決策を提案する前に、一歩引いて立ち止まり、複数の視点から問題を検証しましょう。同じ戦略の些細なバリエーションではなく、根本的に異なるアプローチを検討してください。特定のアプローチを推奨する前に、少なくとも 3 つの候補となる解決策を、その長所と短所とともに文書化しましょう。特に標準的な対処法がうまくいかない場合は、エラーの原因に関する当初の前提を疑ってください。環境設定、外部依存関係、一見すると気づきにくいレースコンディションなど、通常とは異なる原因も視野に入れましょう。思考を逆転させてみてください。「なぜこれは動かないのか?」ではなく、「どのような条件であれば、この挙動に実際に納得がいくだろうか?」と自問してみましょう。複雑な問題は、個別に検証できる小さな要素に分解しましょう。エラーの原因が依然として不明なときは、ログ出力、ブレークポイント、状態トレースなど、ピンポイントなデバッグ戦略を実施して、より多くの情報を集めてください。特に原因がつかみにくい問題に取り組む際には、最終的な解決策ではなく学習の機会として、実験的な修正案を提案する姿勢を持ちましょう。
データベースクエリの検証
データベースクエリの検証
データベースのクエリやスキーマの変更を提案する前に、必ずデータベースの現在の状態を確認してください。既存のテーブル、フィールド、リレーション(テーブル間の関係)を調べて、すでに存在している要素の作成を推奨してしまわないようにします。クエリを提案する際は、まずコードベース内に流用できる類似のクエリがないかを確認してください。既存のデータモデル、マイグレーションファイル、スキーマ定義を確認し、データベース構造を正確に把握します。新しいテーブルの作成を提案する場合は、そのテーブルがすでに存在していないことを明示的に確認し、既存テーブルの変更ではなく新しいテーブルが必要となる理由を説明してください。フィールドの追加を提案する際には、同じ目的を別名で果たしている類似フィールドがすでに存在しないかを確認します。提案するクエリがデータベースパフォーマンスに与える影響を考慮し、必要に応じて最適化された代替案を提示してください。クエリの提案は、常に既存のデータベースアーキテクチャの文脈の中で行い、個別の操作として切り離して扱わないようにします。
UI の一貫性とテーマ
UI の一貫性とテーマ
アプリケーション全体を通して、確立されたデザインシステムとカラーパレットを厳密に順守してください。新しい UI コンポーネントを作成する前に、既存のコンポーネントを確認し、ビジュアル言語、余白のパターン、インタラクションモデル、テーマ設定のアプローチを理解しましょう。新しいインターフェースを実装する際は、ビジュアルのバリエーションを増やすのではなく、既存のコンポーネントパターンを再利用してください。新しい値を導入するのではなく、既存のコードベースから色の値、タイポグラフィ、余白、その他のデザイントークンを抽出して使用してください。すべてのコンポーネントにわたって、状態(ホバー、アクティブ、無効、エラーなど)を一貫して扱ってください。新しいレイアウトを実装する際は、確立されているレスポンシブ挙動のパターンに従ってください。UI 改善を提案する場合は、アプリケーション全体のビジュアルな一体感を損なうのではなく、高める方向であることを確認してください。カラーコントラスト比、キーボードナビゲーション、スクリーンリーダー対応など、すべてのコンポーネントでアクセシビリティ標準を継続的に満たしてください。コンポーネントのバリエーションとその適切な利用シーンを文書化し、一貫した適用ができるようにしてください。新しいビジュアル要素を導入する際は、それが既存のデザインシステムとどのように統合され、補完し合うのかを明示し、単独で浮いた存在にならないようにしてください。
体系的なデバッグアプローチ
体系的なデバッグアプローチ
エラーに遭遇したときは、闇雲に変更を加えるのではなく、系統立てたデバッグ手法を取りましょう。まず、再現性のある制御された環境で、まったく同じ問題を再現することから始めます。コンソールログ、ネットワークリクエスト、コンポーネントの状態、エラーメッセージなどを含む網羅的なデータを収集します。考えられる原因について複数の仮説を立て、それぞれを体系的に検証します。影響を受けているコンポーネントを絞り込み、発生条件を特定することで問題を切り分けます。今後の参考のために、デバッグの手順と結果を必ず記録しておきましょう。ブラウザの開発者ツール、React DevTools、コードレベルのデバッグ手法など、適切なデバッグツールを活用します。解決策がアプリケーションの他の箇所に新たな問題やリグレッション(退行バグ)を生むことなく、問題を完全に解消しているか必ず確認してください。
型安全性とデータバリデーション
型安全性とデータバリデーション
機能を実装する前に、まずデータベーススキーマと TypeScript のインターフェースの両方について、型定義を徹底的に確認・分析してください。コードベース全体で厳格な型チェックを維持し、逃げ道としての
any 型の使用は避けましょう。データ変換を行う際は、パイプラインの各ステップで型安全性を検証してください。特に、数値カラムが文字列として渡されるケース、日付のパースが必要なケース、null になり得るフィールドの扱いなど、よくある型の不一致に注意を払ってください。データベースのカラムと TypeScript インターフェースの間で、一貫した命名規則を適用しましょう。複雑な型の関係や特別な取り扱いが必要な点は、必ずドキュメント化しておいてください。実際のデータの形(シェイプ)を使ってテストを行い、特に null / undefined の扱いなどのエッジケースを検証してください。エラーが発生した場合は、データ変換パイプラインをさかのぼり、型がどこで食い違っているかを正確に特定し、型安全性を維持できる修正を検討してください。データフロー管理
データフロー管理
データフローを、データベースから API、ステートを経て UI に至る一連のパイプラインとして捉えましょう。機能を実装するときは、各段階でデータがどのように変換されるかを慎重に追跡してください。適切なクエリのインバリデーションパターンを実装し、UI がデータベースの状態と常に同期した状態を保てるようにします。重要なポイントに戦略的に console.log などのログを追加し、データの遷移を監視しましょう。アクションに応じてデータがいつ、どのように更新されるべきかについて、明確なメンタルモデルを作ってください。キャッシュ戦略と、データの陳腐化(stale data)の問題に細心の注意を払いましょう。フローに問題があるときは、データの流れをソースから最終的な到達点まで、段階的にたどってデバッグします。タイミングの問題、レースコンディション、変換エラーを確認してください。コンポーネントに到達する最終的なデータ構造が、コンポーネントの期待どおりであることを検証しましょう。データフローに障害が発生したときでも UI の安定性を保てるよう、堅牢なエラーバウンダリとローディング状態の管理を実装してください。
パフォーマンスの最適化
パフォーマンスの最適化
アプリケーションのパフォーマンスは、問題が深刻化するのを待つのではなく、あらかじめ積極的に監視しましょう。不要なデータベース呼び出しを最小限に抑えるために、クエリキャッシング戦略を見直します。適切なメモ化や依存関係管理によって、不要なコンポーネントの再レンダーが発生していないか確認し、排除します。データ取得パターンを分析し、潜在的な N+1 クエリ問題、過度なウォーターフォール構造、冗長なリクエストがないか確認します。長いリストには仮想化(virtualization)を導入し、大規模なデータセットにはページネーションを実装します。コード分割や遅延読み込み(lazy loading)によってバンドルサイズを最適化します。画像を含むアセットを圧縮・最適化します。React DevTools、Performance タブ、Network パネル、Memory プロファイラなどの適切なパフォーマンス計測ツールを使用してボトルネックを特定します。読み込み時間、インタラクティブになるまでの時間(time to interactive)、UI の応答性など、ユーザー体験に直接影響する指標に最適化の焦点を当てましょう。闇雲な早期最適化ではなく、狙いを絞ったパフォーマンス改善を実施します。
エラー処理と耐障害性
エラー処理と耐障害性
アプリケーションの安定性を維持しつつ、有益なフィードバックを提供できる包括的なエラー処理戦略を実装してください。問題が発生しそうなコード箇所を中心に、
try/catch ブロックを戦略的に配置します。アプリケーション全体がクラッシュするのではなく、特定のコンポーネント内に障害を閉じ込められるよう、エラーバウンダリの階層構造を作成します。コンポーネントが限定的なデータでも動作を続けられるような、グレースフルデグレーデーションパターンを設計します。問題を専門用語なしで説明する、明確でユーザーフレンドリーなエラーメッセージを提供します。リトライロジック、フォールバック、状態リセットなどを含むリカバリ機構を実装します。プライバシーに配慮しつつ、デバッグに十分なコンテキストを取得できる堅牢なエラーロギングを維持します。エラーシナリオを徹底的にテストし、リカバリ機構が期待どおりに動作することを確認します。解決策を提案する際は、症状を単に抑え込むのではなく根本原因に対処していること、そしてすべての関連する環境とエッジケースで機能することを必ず検証してください。コンポーネントアーキテクチャ
コンポーネントアーキテクチャ
コンポーネントの設計にあたっては、コンポーネントの階層構造と責務を明確に理解しておきましょう。コンポーネントを、適切な親子関係を持つ家系図としてイメージします。必要に応じて
context や状態管理を戦略的に用いることで、props の深い受け渡し(prop drilling)を最小限に抑えます。コンテナ(スマート)コンポーネントとプレゼンテーショナル(ダム)コンポーネントの間に、明確な境界を設けます。親子間や兄弟間のやりとりを含め、コンポーネント間のやりとりパターンを一貫して整えます。コンポーネントの問題をデバッグする際は、コンポーネントツリー全体、props のフロー、状態の所在、イベントハンドラーの接続を分析します。コンポーネントは単一責務と明確なインターフェースを持つように設計します。将来の保守を容易にするために、コンポーネント同士の関係性と依存関係をドキュメント化します。メモ化、遅延読み込み、コード分割などのパフォーマンス最適化を、効果が見込める箇所に導入します。コンポーネントの再利用性と特化度のバランスを保ち、重複と過度な抽象化の両方を避けましょう。API連携とネットワーク管理
API連携とネットワーク管理
API 連携には、リクエスト、レスポンス、エラーハンドリングを包括的に考慮した戦略で取り組んでください。各リクエストごとに、認証ヘッダー、パラメーター、ボディ形式を確認します。すべてのネットワーク処理に対して適切なエラーハンドリングを実装し、エラー種別ごとに個別にハンドリングします。リクエストペイロード、想定されるレスポンス、アプリケーションの状態の間で型が一貫していることを保証します。適切な CORS 設定を行い、すべての環境で正しく動作することを確認します。一時的な失敗に対しては、指数バックオフを用いたインテリジェントなリトライ機構を実装します。レート制限の影響を考慮し、適切なスロットリングを実装します。パフォーマンス向上とサーバー負荷軽減のために、戦略的にリクエストのキャッシュを追加します。リクエストのタイミングやペイロードサイズを含め、ネットワークパフォーマンスを監視します。正常系(ハッピーパス)だけでなく、さまざまな失敗シナリオに対しても API 連携をテストします。将来の開発やデバッグを容易にするために、すべての API エンドポイントについて、その目的、想定パラメーター、レスポンス形式を明確に文書化しておきます。