💭

開発AIエージェントを一歩便利にするプロンプトテンプレート

に公開
## 基本方針

- 不要な抽象化を入れずシンプルに実装する
- 謙虚に思考し、行動する。
- 解決不可能な問題にぶつかった際は雑に対応するのではなく、本質的対応を行う。
- ファイル数は少なくしなさい。新しくファイルを作る際は慎重に考えなさい。
- 不要な関数は作らない
- ソースコードの行数は可能な限り少なくしなさい
- 開発サーバーは起動済みの前提
- シンプルに実装することは重要だが、実質的動作は変わらないように気をつけなさい。
- サービス層を絶対に作らない。シンプルに実装しなさい。ユースケース層は作成して良いが、zenstack などの基本機能を使い可能な限り実装する。
- エラーが起きないことだけを目標に雑な実装は絶対にしない。必要な値が入っていないなら ValueError を throw し、雑にデフォルト値を入れて対応はしない。
- 常識的に考えて、セッションが必要なリクエストを curl で動作確認しない。セッションが必要な場合はきちんとブラウザで動作確認しなさい。
- 厳しい上司のコードレビューで常識的に弾かれるような実装はしない。

## ナレッジ管理について

以下ようにナレッジ管理を行う。存在しない場合はユーザーに確認するなどして構築しなさい。また、ユーザーの指示などで更新する必要があると判断した場合は適切に最新状態に更新しなさい。

- .knowledge/usecase.md: ユースケース
- .knowledge/domain.md: ドメイン制約

## 処理の共通化について

- 複数箇所で使われることが確定するまで共通化は行わない

## 問題の解決に詰まった際の対応

1. 同様の実装で問題なく動いている部分が無いか探し、必要なら参考にしなさい。
2. tyr catch でエラー握りつぶしていないかをチェック
3. 数回修正や確認してもうまく動作しない場合はネット検索し解決策が無いかをチェックする。複数の解決策を探し、俯瞰的に判断しなさい。大きくアーキテクチャを変更をしたり、別のライブラリを使う選択は最終手段であり、ユーザーに必ず確認しなさい。

## エラー処理について

- try catch 文は基本的に使わない。Error が throw されて 500 エラーが変えることは基本的に問題ない。しかし、エラー時に別の特別な処理を続行したい場合や、ループ処理を終了させたくないなど特殊な場合は try catch 文を使って良い
- try catch でエラーを握りつぶすのは最低の実装である。エラーが発生しストップすることは問題を認識するために非常に重要

## 型について

- any は基本的に使わない。しかし、api などの外部からの入力を受け取る場合でやむを得ない場合は使って良いがその場合でもできるだけ unknown を使う。
- できるだけ型は新しく作らない。どうしても作る必要がある場合は既存の型(Prisma の型など)を拡張する。ユースケース層では基本的に既存の型(Prisma の型)を利用する。
- プロパティが nullable な型は作らない
- 型変換のための関数は本来不要なはず。
- as は使わない
- グローバルな型ファイル app.d.ts や、next.d.ts でモジュールの型を絶対に定義しない。ユースケースでしか使わない型ならそのユースケースのファイルに定義、hook でしか使わない型ならその hook のファイルに定義する。
- API の unknown なレスポンスは zod を使って型変換を行う。

## ファイル構成、設計について

- src/lib ディレクトリが存在する場合はこのディレクトリを起点にする。
- 起点のディレクトリに user、todo、auth など各モジュールを作成する。このようにモジュールを作ることで、モジュール内のファイルはモジュール内で完結するようにする。このモジュール以下に components、hooks、utils などのディレクトリを作成することを許可する。
- utils は特殊なファイル、ディレクトリであり、モデル観点ではない様々な箇所で利用される機能を実装する。cache のための関数など
- 起点直下には 自動生成で作成されたものを除き、components、hooks などのディレクトリは作らない。
- {起点}/{モジュール}/hooks/ディレクトリには共通で利用する hook を作成する。useTodo.ts など可能な限りまとめる。
- hook は zenstack の自動生成 hook では実現できないユースケースがある場合のみ作成する。そのパターン以外は作成しない。
- 基本的に zenstack の allow で実現できるようにし、それで実現できない場合は {起点}/{モジュール}/usecase にユースケースを作成する。ここで作成したユースケースに依存した API を作成する。そして、この API を叩く hook を{起点}/{モジュール}/hooks に作成する。
- api を叩く hook は tanstack query を利用する。

## 実装について

- デフォルトが None な引数を受け取る関数は作らない
- 実装にテストを通すために特殊な処理を入れない。
- 環境変数が存在しない場合に throw したり、必須引数の undifined チェックは不要。シンプルに実装しなさい
- テストのモック化は行わないが、日時に関わるもののみ可能。
- テストは必要最小限にする。エラーの確認は基本的にしない。
- HappyPath テストのシナリオと assert を充実させることで正常動作を確認する
- エラーを回復するために、処理を削除する際は本当に問題ないかを慎重に検討する。必要な機能を削除しているだけでないかを確認する。
- プロパティのアクセス時に `|| ""` などのデフォルト値を設定しない。この実装は重大な問題を握りつぶす可能性がある。
- 変数、引数の型はデフォルト値を設定せず、明示的に型を設定する。
- ダミー実行、モック実装は明確な指示が無い限りは絶対に実装しない
- 不安定な入力がされる可能性があるのはバックエンド実装上は API のみである。ここでは unknown を使って対応することもあるはずだが、それ以外の部分では unknown を使う必要は無いはずである。API 以外では unknown を使っている場合はそもそもの実装を見直すことも必要。

## 報告、質問について

- 日本語で行う
- タスクの報告は完了、失敗、質問の 3 つのみであり、報告は先頭にどの状態であるかを明記する。
- 自力での対応が不可能と判断した場合は失敗とするが、質問すれば対応完了できそうなら質問する。
- タスクを完了するには未対応のファイルが残っていない状態にする必要があります。
- 完了報告前に、不要なファイルや不要なコードは削除しておくこと。特に、動作確認のために追加したコードの消し忘れに注意しなさい。
- lint が実行可能なら実行し、将来的に動作に問題を起こす可能性が高いエラーは修正してから完了報告を行いなさい。
- 完了報告前にはいったんファイルとコードを俯瞰して、関連部分のリファクタリングを行いなさい。無駄なコードや非合理なストラクチャを整理し、適切な粒度で整理し、メンテナンス性を向上させなさい。しかし複雑度を上げることは許しません。必要最小限の記述量かつ、必要最小限のファイル数は維持しなさい。
- 環境変数が足りない可能性があったり、自力での解決が不可能な可能性が高い場合は無理せず謙虚に行動しユーザーに報告する。無意味な自信で強引な実装はしない。

## UI を操作する動作確認と修正を指示された場合について

- playwright でブラウザを起動して動作確認する
- ソースコード、ナレッジを確認し、モデル、モジュール、テーブル、ページなどの適切な単位で以下の手順で確認を行い、問題があれば修正を行う。修正後は問題ないかをもう一度確認する。
  - 新規追加が行えるなら新規追加を行い、DB の状態を確認して問題なく反映されているかを確認する。
  - DB の状態を確認し、表示されるべき情報が UI に表示されているかを確認
  - 編集機能があれば編集を UI から行った後に DB の状態を確認し、正しく反映されているかを確認

## ブラウザ操作について

- playwright mcp を利用してブラウザ操作を行う


Discussion