Claude Codeに丸投げしてみた – Q&Aページ実装編

React

こんにちは、白々さじきです。

飲み会の日程調整ツールをCloudflare Workers + Hono + D1で作るこの検証プロジェクト。今回は「データの削除タイミングが分からない」という問題に対応するため、Q&Aページの作成をClaude Codeに丸投げしました。

なぜQ&Aページが必要になったか

このツールには認証機能がなく、URLを知っていれば誰でもイベントに回答できます。当然「自分のデータはいつ消えるの?」という疑問が出てきます。

前回の記事でGitHub Actionsによる月次自動削除を実装しましたが、その仕様がアプリ内でどこにも書かれていませんでした。コードには書いてあるが、ユーザーには見えない。これを解消するのが今回の目的です。

渡したプロンプト

今回もGitHubイシューのURLを渡す形で依頼しました。

下記のIssueを実施するために実行計画を立ててください。この時Q&Aに記載しておいたほうがいい内容も提案してください。

Q&Aページを作成する · Issue #7 · sirajirasajiki/guided-scheduler
やること Q&Aページを作成する。 詳細・背景 guided-schedulerが、データを削除するタイミングがわからない。 なので、現在作成しているgithub actionを元にどの程度の頻度で削除するのかを明確にユーザーがわかるように...

前回との変更点が2つあります。「実行計画を立ててください」と「Q&Aに記載しておいたほうがいい内容も提案してください」を追加しました。

PLAN機能で実装前に計画を出させる

Claude CodeにはPLANモードという機能があります。「実行計画を立ててください」と指示すると、コードを書く前に「何をどう変えるか」の計画を出してくれます。人間がレビューしてOKを出してから実装が始まります。

実際に出てきた計画はこうです。

  • 新規作成:src/client/pages/faq.tsx(Q&Aページ本体)
  • 変更:src/client/App.tsx/faq ルートを追加)
  • 変更:src/client/components/footer.tsx(「よくある質問」リンクを追加)

変更ファイルが3つ、いずれもフロントのみで、DBやAPIへの変更なし。計画を見ればスコープが一目で分かります。

大きな変更を実装させる前に計画を出してもらうと、「思ってたのと違う」を実装後ではなく計画段階で潰せます。今回のような「ページ新設+ルート追加+フッターリンク」程度の規模でも、PLANを挟む習慣をつけておくと安心できます。

Q&A内容もClaudeに提案させた

今回のイシューは「Q&Aページを作る」という指示だけで、具体的な質問・回答の内容は決めていませんでした。「Q&Aに記載しておいたほうがいい内容も提案してください」とお願いすると、7件の候補を出してくれました。

# 質問 提案の根拠
1 データはいつ削除されますか? イシューの主目的
2 回答を修正・上書きできますか? 同名上書き仕様がコードに存在
3 イベントや参加者データを手動で削除できますか? 削除機能が未実装なため
4 管理用URLを紛失した場合は? 再発行機能が未実装なため
5 確定日を変更できますか? 確定後変更不可の仕様
6 何人まで参加できますか? 上限なし(よくある疑問)
7 このサービスは無料ですか? 利用規約に記載があるため

提案の質が高かったのは、Claudeがコードを読んで「この仕様はQ&Aにした方がいい」と判断していたからです。例えば「回答の上書き」はコードを読まないと分からない仕様ですが、それをQ&A候補として挙げてきました。

特に1番の「データはいつ削除されますか?」の回答は、GitHub Actionsのワークフローファイルを直接読んで生成しています。

毎月1日 18:00 UTC(日本時間では毎月2日 3:00)に、最新の候補日から30日以上経過したイベントのデータが自動的に削除されます。

cron式 0 18 1 * * からUTC→JST変換まで含めて正確な記述が出てきました。「自動削除があることは分かっているが、ユーザー向けの日本語説明が書けない」という状況をそのままClaudeに解消してもらえた形です。

教訓:「何を書くか」も丸投げできる。ただし前提としてコードの仕様をClaudeが読めている必要がある。仕様が複雑になるほど提案精度が上がる。

実装内容

変更は3ファイルだけです。

Q&Aページ本体

src/client/pages/faq.tsx はこういう構造にしました。

const faqs: { q: string; a: string }[] = [
  { q: "データはいつ削除されますか?", a: "毎月1日 18:00 UTC..." },
  { q: "回答を修正・上書きできますか?", a: "はい。同じ名前で..." },
  // ...
];

export default function Faq() {
  return (
    // ...
    {faqs.map((faq, index) => (
      <section key={index}>
        <h2>Q. {faq.q}</h2>
        <p>A. {faq.a}</p>
      </section>
    ))}
  );
}

Q&Aの内容は配列 faqs に集約されているため、追加するときは配列に1オブジェクト足すだけです。コンポーネント側は触らなくていい設計になっています。

ルートとフッター

App.tsx/faq ルートを追加し、フッターに「よくある質問」リンクを追加しました。既存の「利用規約」「プライバシーポリシー」リンクは <a target="_blank"> だったので、新規リンクは react-router-domLink を使ってSPA内遷移にしています。

つまずいたこと

① ローカルD1のマイグレーション未適用

実装後に動作確認をしたところ、イベント作成時にこんなエラーが出ました。

D1_ERROR: no such table: events: SQLITE_ERROR

原因はシンプルです。ローカルのD1にマイグレーションを適用していなかった。開発DBはリモートD1を使っているため、ローカルで pnpm dev を起動したときのDB(ローカルSQLite)にはテーブルが存在しない状態でした。

ローカルにマイグレーションを適用するコマンドはこうです。

pnpm exec wrangler d1 migrations apply guided-scheduler-dev --local --env dev

注意点が2つあります。

wrangler単体では動かない。 wrangler はdevDependenciesに入っているローカルインストールです。グローバルにインストールしていないため、直接 wrangler と叩くと command not found になります。pnpm exec wrangler と書くことでローカルインストール版が使えます。

--env dev を忘れずに。 wrangler.toml でD1バインディングを定義しているのは [env.dev] 配下のみです。トップレベルにはD1の定義がないため、--env dev を付けないとデータベースが見つかりません。

教訓:pnpm管理のプロジェクトでwranglerを叩くときは pnpm exec wranglerwrangler.toml の構成に合わせて --env フラグも忘れずに。

② この記事を書かせたらClaudeがファイルを作り忘れた

実はこの記事自体もClaude Codeに書かせています。「WordPressにはるHTMLを作成してください」と依頼したところ、drafts/weekly/2026-05-02/wordpress/faq-page-wp.html は作成しましたが、Markdownファイルを作らなかった

気づいたのは私が「あれ、.mdは?」と聞いたときです。

このプロジェクトの drafts/weekly/ 配下は、記事ごとに .mdwordpress/*.html のセットで管理しています。Claude Codeはその慣習を把握していたはずですが、「WordPressにはるHTMLを作成してください」という指示の文言に引っ張られ、HTMLのみで完了と判断してしまいました。

Claude Codeは明示された指示には忠実に従うが、コードベースから読み取れる暗黙の慣習は見落とすことがある。 今回のように「セットで作るファイルがある」という規則は、指示に明示しないと片方だけ作られるリスクがあります。

教訓:ファイルのセット管理など暗黙の慣習は、プロンプトに明記するか CLAUDE.md に書いておく。「いつも通りに」は通じない。

学びと全体の感想

今回はQ&Aの内容まで含めてほぼすべてをClaude Codeに任せられました。

よかった点は「何を書くか」の提案もできることです。コードの仕様を読んだうえで「これはQ&Aにすべき」と判断して候補を出してくれる。人間がゼロから考えるより、提案を受けてチェック・修正する方が圧倒的に速いです。

一方で暗黙の慣習には弱いという面も確認できました。「WordPressのHTMLを作って」という指示でMarkdownも作るべきかどうか、Claudeは指示の文言で判断します。人間なら過去の作業パターンを見て「あ、セットで作るやつだ」と気づきますが、Claudeは明示されていない規則には気づきにくい。

暗黙にしないための対策は2つあります。

① CLAUDE.mdに成果物ルールを明記する。 今回で言えば「ブログ記事の下書きは .mdwordpress/*.html の両方を作成すること」と書いておけば、次回から指示しなくても守られます。一度書けば永続します。

② プロンプトに成果物リストを書く。 「以下のファイルを作成してください: ① faq-page.md ② wordpress/faq-page-wp.html」のように出力物を列挙する形式にすると、慣習をCLAUDE.mdに書くまでの間でも効きます。

発注スキルとして言うなら、「いつも通りに」という前提は捨てて、慣習はCLAUDE.mdに書く。そうしないとチェックコストが上がります。

次にやること

  • 「トップに戻る」リンクの改善:現在すべてのページで「← トップに戻る」がイベント作成ページ(/)に固定で遷移する。管理ページや参加者ページから来た場合は元のページに戻るようにしたい
  • CLAUDE.mdにブログ下書きの成果物ルールを追記する:.mdwordpress/*.html のセット作成を明文化し、次回から指示なしで守られるようにする

サポートのお願い

下記リンクからお買い物いただけると、ブログ運営のための費用が増え、有料サービスを利用した記事作成が可能になります。ご協力よろしくお願いします!



コメント

タイトルとURLをコピーしました