Imported from nakamori-naoya/go-convention-plugins (
plugins/go-convention/skills/develop-repository/SKILL.md). Install upstream withnpx skills add nakamori-naoya/go-convention-plugins --skill develop-repository. Copyright stays with the author.
develop-repository
工程順序の定義を最初に読み、同じagentが`steps`を宣言順に実行する。YAMLは工程順序を決め、各工程の判断内容と根拠はこの本文と、skill: 工程が指す入口の本文を実読して評価する。失敗時は成功扱いせず停止して、完了工程、根拠、未決を残し、再開時は最初の未完了工程から続ける。
これは、永続化層の 1 単位を「テストを書く → 赤を確かめる → 実装する → 緑を確かめる → 整える」の順で完成させる合成の入口である。1 単位は、集約 1 つの Repository interface の実装(通常型またはイベント型)か、usecase 側が所有する読み取り契約 1 つの query service 実装である。どちらかは単位を固定する工程で決め、実装の工程はその種類に対応する規約だけを呼ぶ。テスト file(*_test.go)と実装 file は分かれたままで、この入口は両者を交互に書く順序と、その間の判断だけを持つ。
これは、テストの書き方や実装の形を新たに決めるものではない。実 DB で何をどう突き合わせるかは永続化層のテストの規約が、marshaller・sqlc・tx の乗り方はリポジトリの実装の規約が、SQL と DTO の写し方は query service の実装の規約が、言語レベルの形は言語規約が、DB が拒んだ事実の翻訳先(sentinel)はエラーの規約が持つ。それぞれは playbook.yml の skill: 工程が指し、この入口はそれらを変えない。集約の判断、usecase の tx 境界、RPC の入口は別の単位の入口が扱う。
前提: Go 1.27・PostgreSQL・pgx/v5・sqlc・dockertest・testify・Docker daemon。ドメインの実装(集約・VO・Repository interface・sentinel)と、データモデル資料が確定している。
入力
- データモデル資料(テーブル定義・「シナリオと記録の対応」・BDD の Before/After)の絶対pathと、この単位で完成させる対象(集約 1 つのリポジトリ、または読み取り契約 1 つの query service)。
- ドメインの実装のpath。query service なら usecase 側の読み取り契約(ポート・読み取りモデル・Page・sentinel)のpath。既存のcodeとテスト、
rdbtestがあればそのpath。 references: 追加で従う資料の絶対path配列。任意。手順の最初に読み、以降の判断でこの規約と併せて従う。
プロジェクト固有の規約(置き場、命名、追加で従う資料)は、対象repositoryのAGENTS.md / CLAUDE.mdとreferencesで渡される。この入口は既定値を持たず、指示文へ展開もしない。
判断基準(TDD の 1 単位)
| 観察対象 | 述語 |
|---|---|
| 単位の種類 | fix-unit で、対象が Repository interface の実装(kind: repository)か読み取り契約の実装(kind: query_service)かが 1 つに決まり、実装の工程はその種類の規約だけを呼ぶ |
| 赤の理由 | run-red で対象のテスト関数が失敗し、その理由が「実装の型・メソッドがまだ無い(コンパイルエラー)」か「保存後の行・読み取った DTO が資料の After と一致しない(assert の失敗)」のどちらかに分類できる。Docker が無い、DDL が無い、rdbtest の Seed* / Read* が無い、無関係なテストの失敗は赤ではない |
| 実装中のテスト | implement-as-* の間、*_test.go と rdbtest を編集していない。テスト支援の不足に気付いたら実装を止め、write-failing-test へ戻って足し、赤を確かめ直してから実装へ進む |
| 緑の範囲 | run-green で、対象のテスト関数と同じ package の全テストが通り、永続化層のテストの規約が求める機械検査(go vet・単独実行・BDD 網羅・テストの形)も通る |
| 整える前後 | refactor の前後で同じテストが緑で、テストの id / name / description・seed* / want* を変えていない |
| テストの範囲 | テストのケースは、資料の BDD の Before/After と、永続化層のテストの規約が定める派生(楽観ロック競合・復元・NotFound・DB 制約違反の翻訳・同時実行)だけ。資料に無いテーブル・列・操作を、テストから先に作らない |
| 単位の大きさ | 1 サイクルで完成させるのは 1 集約のリポジトリ、または 1 契約の query service。別の集約・別の契約に手を伸ばす必要が出たら、この単位を緑で閉じてから次の単位を始める |
手順
- 単位を固定する(
fix-unit)。referencesがあれば先に読む。対象がリポジトリか query service かを決め、リポジトリならRepositoryinterface のメソッドと資料のテーブル一覧・BDD、query service なら読み取り契約のフィールドと資料のテーブルを列挙する。テスト file と実装 file の名前を決め、既存なら現在のgo testの結果を記録する。完了条件: 種類 1 つ、対象のメソッドまたは契約とコンストラクタ名、資料の BDD の ID 一覧(リポジトリのとき)、テスト file と実装 file のpath、開始時のテスト結果が 1 行ずつ言える - テストを書く(
write-failing-test)。 永続化層のテストの規約に、データモデル資料と単位(種類、interface または読み取り契約のメソッド、コンストラクタ名)を渡し、テストが先の場面として適用する。その規約が返すのは、rdbtestとテスト支援、資料の BDD(または読み取り契約の正常・空結果・境界)を写したテスト file、対象未実装による赤の記録である。完了条件: この単位の BDD がid:か末尾コメントに現れ、テスト file が保存され、rdbtestに資料の全テーブル分のSeed*/Read*があり、go testの失敗理由が記録されている - 赤を確かめる(
run-red)。 Docker が動く環境でgo test -count=1 -run '<テスト関数>' ./<package>/...を実行し、失敗の理由を上の表で分類する。完了条件: 失敗の理由が「対象未実装」または「資料の After と一致しない」で、それ以外の失敗が無いgo test -count=1 -run 'TestReservationRepository_ApplyHeld' ./rdb/... # 対象のテスト関数だけ - 実装する(
implement-as-repository/implement-as-query-service。単位の種類に対応する一方だけ)。 リポジトリならリポジトリの実装の規約で marshaller・sqlc の query・Apply*またはCreate/Update・翻訳を書き、query service なら query service の実装の規約で SQL と DTO の写しを書く。テストが緑になる最小の実装で、*_test.goとrdbtestは触らない。完了条件: interface(または読み取り契約)のメソッドが 1:1 で実装され、テストのwant*に現れる行・DTO・sentinel が実装から到達できる - 緑を確かめる(
run-green)。 対象のテスト関数、同じ package の全テスト、永続化層のテストの規約の機械検査をすべて通す。完了条件: 次が全部通る
続けて、永続化層のテストの規約が持つ機械検査(リポジトリのときの BDD 網羅・ケース識別)を同じディレクトリに対して通すgo vet ./... go test -count=1 ./<package>/... go test -count=1 -run '<テスト関数>/<id>_' ./<package>/... # 足したケースを 1 つずつ単独で - 整える(
refactor)。 言語規約で関数の形・型と interface・名前・標準ライブラリを揃える。振る舞いは変えず、テストは触らない。完了条件: 言語規約の機械検査が通り、手順 5 と同じテストが緑 - エラーを揃える(
align-errors。この単位で DB 制約違反・NotFound・楽観ロック競合の翻訳先を足した・変えたときだけ)。 エラーの規約で、翻訳先の sentinel と包み方(層境界で 1 回だけの%w)を揃える。完了条件: 翻訳が 1 か所で、テストが緑 - 報告する(
report)。 下の「報告」の項目
停止条件
止まるのは、資料または規約の契約に反する要求、正式な定義に無い決定が要る、利用者の許可が要る、toolが失敗した、のどれかに当たるときで、それ以外の判断の揺れでは止まらない。
run-redで対象のテストが最初から緑 → 対象が実装済みか、テストが資料を写していない。実装へ進まず、どちらかを確かめてテストの工程へ戻るrun-redの失敗理由が対象未実装以外(Docker が無い、DDL が資料と違う、rdbtestの不足、無関係なテストの失敗)→ 実装へ進まない。理由を返して止まる(rdbtestの不足はテストの工程へ戻る)run-greenで緑にならず、原因がテストの誤り → 実装を止め、write-failing-testへ戻って直し、run-redからやり直す(これは停止ではなく戻り)run-greenで緑にならず、原因が資料と DDL の食い違い、またはRepositoryinterface と資料の型(通常型/イベント型)の不一致 → 止まり、資料・DDL・interface のどれを直すかを返す- 各
skill:工程が持つ停止条件に当たった → その工程の報告に従って止まる
止まるときは、書いた範囲(テスト file・実装 file・rdbtest)と書かなかった範囲を分け、どの工程で止まったか、返す先(資料、規約、利用者)と必要な決定を報告に示す。
判断の揺れでは、その時点の根拠から最も筋の良い形を仮説として採り、仮説であることと採らなかった形を報告に明示して進む。
- リポジトリと、それを使う一覧の query service の両方が要る: リポジトリを先に単独の単位として閉じ、query service を次の単位にする形を採り、報告に示す。
報告
- 単位(種類、対象、BDD の ID 一覧、テスト file と実装 file)
- 赤の理由と、緑になった時点の機械検査の結果
- 整えた点(言語規約・エラーの規約で変えたもの)と、振る舞いを変えていないことの根拠(同じテストの緑)
- 各
skill:工程の報告 - 停止条件に当たって返した論点、次の単位の候補