デザイナー向けClaude Code: 本番環境で見落とされるポイント
TL;DR
Social Animalは18ヶ月間に30以上のヘッドレスプロジェクトをデプロイしました。最近の受け入れのおよそ3分の1は、デモはシップしたが本番環境で破綻したデザイナー主導のビルドのレスキュー作業です。Michael NervegnaのSubstackの「Claude Code for Designers」ガイドはプロトタイピングとしては正当に優れていますが、Row Level Security、認証トークンのリフレッシュ、データベース抽象化の選択肢、デプロイロールバック、Content Security Policy、および管理者認証の前で止まっています。この記事はこれらのギャップをカバーしています。本番環境にシップしているなら、これらが必要です。
目次
- Claude Codeとは何か、そしてなぜデザイナーはそれを使用しているのか?
- Nervegnaのガイドは何を正しく理解していますか?
- ガイドはどこで不足していますか?
- Claude Codeが見逃すRow Level Securityの落とし穴
- 認証のハンドオフ:プロトタイプから本番への隙間
- Supabase対Prisma:Claude Codeは何を生成すべきか?
- デプロイロールバック:AI生成コードが破綻したときに何が起こるか
- プロキシされたアセットのContent Security Policy
- 実際に管理者認証が必要な時とは?
- 本番環境にプッシュする前に:チェックリスト
- FAQ
Claude Codeとは何か、そしてなぜデザイナーはそれを使用しているのか?
Claude Codeは2025年初頭にローンチしたAnthropicのターミナルベースのコーディングツールです。@anthropic-ai/claude-codeとして実行され、Claude Pro(月$20)またはTeam(ユーザーあたり月$30)とAPIアクセスが必要です。ターミナルで自然言語を通じてコードを書き、編集し、デバッグします。
デザイナーはそれを使用しています。「Figmaで設計した」から「これはWorkingなNext.jsアプリである」というギャップを埋めるからです。v0やBoltとは異なり、Claude Codeはあなたの実際のファイルシステムで動作します。プロジェクト構造を読み取り、ファイルを変更し、開発サーバーを実行し、エラー出力に対して繰り返します。コンポーネント階層を理解していても、TypeScript汎用型を暗記したくないというなら、それは本当に便利です。
Nervegnaはそれをデザイナーが「構文」ではなく「システム」で考えるようにするツールとして位置付けています。我々も同意します。最初のnpm run devが成功した後に何が起こるかで意見が分かれます。
Nervegnaのガイドは何を正しく理解していますか?
NervegnaはAI Codingチュートリアルのほとんどが見落とす3つのことを正しく理解しています。
第一:プロジェクトのコンテキスト。 彼はClaude CodeにCLAUDE.mdファイルをフィードすることを推奨しており、それにはプロジェクト規約、テックスタック、およびデザイントークンが含まれています。Claude CodeがCSSモジュールを使用しているプロジェクトに対してTailwindユーティリティを生成しているのを見てきました。なぜなら誰もそれに規約を伝えなかったからです。コードを書く前にコンテキストを確立することは正しいアプローチです。
第二:反復ループ。 プロンプト、出力をレビュー、軌道修正、繰り返します。彼はClaude Codeを「説明してシップする」ボタンとして扱いません。彼はそれを監視が必要なペアリングパートナーとして扱っています。それは正しいメンタルモデルです。
第三:小さく開始する。 完全なアプリケーションスキャフォルディングを試みる前に、単一のコンポーネントまたはページを構築してください。デザイナーが「auth、billing、およびadminを備えた完全なSaaS dashboardを構築してください」と1つのメッセージでプロンプトしているのを見てきました。結果は常に混乱しています。Nervegnaのインクリメンタルアプローチはこれを避けます。
Nervegnaのガイドがデザイナーに役立つのは0からプロトタイプ段階です。問題はプロトタイプが本番コードになるということで、それはギャップが重要な場所です。
ガイドはどこで不足していますか?
Nervegnaの記事はプロトタイピング段階のために機能します。実際のデータベース、実際のユーザー、および実際のデプロイメントインフラストラクチャを接続するときに緊急になる懸念に対応していません。
何が不足しているか:
- Row Level Security (RLS) -- Claude Codeによって生成されたSupabaseプロジェクトは正しいRLSポリシーをほぼ持たない
- 認証のハンドオフ -- 開発のSupabase Authと、トークンリフレッシュ、セッション管理、およびリダイレクト処理を伴う本番フローの間のギャップ
- データベース抽象化の決定 -- Supabaseクライアントを直接使用する時対Prismaまたはdrizzle ORMを使用する時
- デプロイロールバック戦略 -- Claude Codeコミットが本番環境を破綻させたときに何が起こるか
- Content Security Policy -- 特にプロキシ/外部アセットを備えたNext.js Imageの場合
- 管理者認証 -- シンプルなユーザー認証を超えたロールベースアクセスが必要な時
それぞれを見てみましょう。
Claude Codeが見逃すRow Level Securityの落とし穴
Row Level Securityはリクエストするユーザーが表示することが許可されている行だけをデータベースクエリが返すことを確保するSupabaseのメカニズムです。Supabaseでテーブルを作成するとき、RLSはデフォルトで無効になっています。任意の認証されたユーザー -- または一部の設定では、任意の匿名リクエスト -- はすべての行を読み取ることができます。
Claude Codeがsupabaseプロジェクトをスキャフォルディングするとき、それはテーブルを作成し、クライアント側のクエリを書きます。あなたがそれを尋ねるなら、時々RLSポリシーを追加します。しかしそれが生成するポリシーはしばしば微妙な方法で間違っています。
AI生成コードの一般的なRLSミス
| ミス | 何が起こるか | 修正方法 |
|---|---|---|
| RLSが全く有効化されていない | 任意の認証されたユーザーがすべてのデータを読み取る | ALTER TABLE your_table ENABLE ROW LEVEL SECURITY; |
ポリシーはauth.uid()を使用するが、テーブルにuser_id列がない |
ポリシーはコンパイルされるが、ゼロ行に一致し、すべてのアクセスをブロック | user_id UUID REFERENCES auth.users(id)を追加し、それを入力してください |
| SELECTポリシーは存在するがINSERT/UPDATE/DELETEポリシーはない | ユーザーは読み取ることはできるが、自分のデータを書き込むことはできない | 各操作ごとに個別にポリシーを作成してください |
ポリシーはauth.role() = 'authenticated'のみを使用する |
ログインしている任意のユーザーはすべての行を見ることができ、自分のものだけではない | auth.uid() = user_id条件を追加してください |
| Service role keyがクライアント側のコードで使用されている | RLSは完全にバイパスされる | SUPABASE_SERVICE_ROLE_KEYをクライアントバンドルに決して露出させないでください |
今年、そのラスト -- クライアント側のコードのservice role key -- を3つの別々のデザイナー構築プロジェクトで見ました。Claude Codeは時々service role keyを使用します。なぜなら「機能する」そして権限エラーをスローしないからです。そのキーはすべてのRLSをバイパスします。それはサーバー側のコード(APIルート、server actions、edge関数)にのみ属します。use clientコンポーネントには決してありません。
Nervegnaはこのガイドでは、RLSについてカバーしていません。これは理解できます。しかし、彼のワークフローに従い、Supabaseに接続しているなら、すべてのテーブルを手動で確認してください。Supabase SQLエディタで実行してください:
SELECT schemaname, tablename, rowsecurity
FROM pg_tables
WHERE schemaname = 'public';
ユーザーデータを保持するテーブルについてrowsecurityがfalseなら、デプロイする前に停止して修正してください。
認証のハンドオフ:プロトタイプから本番への隙間
認証はデザイナー主導ビルドで最も一般的な失敗ポイントです。初期セットアップが間違っているからではなく -- Supabase認証は簡単にスキャフォルディングしている -- 本番認証は、ローカル開発中に表面化しないエッジケースを含むからです。
Nervegnaのガイドはローカルで物事を機能させることに焦点を当てています。ここはあなたがデプロイするときに破綻するものです:
トークンリフレッシュの失敗
Supabase認証トークンはデフォルトで3600秒(1時間)の後に期限切れになります。Supabaseクライアントは理論的には自動的にリフレッシュを処理します。実際には、Next.jsミドルウェアまたはserver components既存セッションを渡さずに、すべてのリクエストで新しいSupabaseクライアントを作成すれば、最初の時間後に間欠的な401エラーが発生します。
Next.js App Routerを使用して、@supabase/ssr(2025年2月の時点でバージョン0.5.x)と適切なミドルウェアのcookie処理が必要です。Claude Codeはしばしば古い@supabase/auth-helpers-nextjsパッケージを生成し、それは廃止されています。あなたのpackage.jsonをチェックしてください。
リダイレクトURIのミスマッチ
OAuthプロバイダー(Google、GitHub)は正確なリダイレクトURIを必要とします。Claude Codeはlocalhost:3000のこれらを設定します。VercelまたはNetlifyにデプロイするとき、OAuthプロバイダーのコンソールとSupabaseの認証設定(「Redirect URLs」下)の両方にプロダクションURLと任意のプレビューデプロイメントURLを追加する必要があります。これは5分かかりますが、OAuthログインの100%をブロックしています(あなたがそれを見落とすなら)。
セッション同期の問題
Next.js 14+では、server components、client components、ミドルウェア、APIルート、およびserver actionsがあります -- すべてが潜在的に現在のユーザーセッションを必要とします。Supabaseクライアントは各コンテキストで異なるように作成される必要があります。Claude Codeはしばしば単一のcreateClient()ユーティリティを作成し、どこでもそれを使用します。これにより、ハイドレーションのミスマッチと古いセッションが引き起こされます。
最少で3つのクライアント作成関数が必要です:
- client componentsの
createBrowserClient() - server componentおよびserver actionsの
createServerClient() - ミドルウェアの
createMiddlewareClient()
これはSupabaseのSSRガイドで文書化されていますが、Claude Codeはそれを一貫して正しく生成しません。
Supabase対Prisma:Claude Codeは何を生成すべきか?
Nervegnaはこの決定に対処していませんし、ほとんどのデザイナーが認識しているより多くの重要性があります。
Supabaseクライアント(@supabase/supabase-js) Supabaseの PostgREST APIを通じてデータベースをクエリします。これは便利で、スキーマ定義ファイルを必要とせず、RLSで直接機能します。しかし、それはSupabaseが生成するもの以上のタイプセーフティを与えず、アプリケーションをSupabaseのインフラストラクチャに密に結合します。
Prisma ORM(現在v6.x) PostgreSQLに直接接続します。スキーマファイル(schema.prisma)、生成されたTypeScript型、マイグレーション、およびデータベース非依存クエリが与えられます。しかし、RLSポリシーを尊重しません(特権ユーザーとして接続します)、およびクライアントを生成するビルドステップが必要です。
Drizzle ORM(v0.36.x)はSQL様構文と優れたedge runtime サポートを備えた軽いオルタナティブです。
意思決定マトリックス
| 因子 | Supabaseクライアント | Prisma | Drizzle |
|---|---|---|---|
| RLSサポート | ネイティブ | アプリレイヤーで実装する必要あり | アプリレイヤーで実装する必要あり |
| タイプセーフティ | CLIで生成 | スキーマから生成 | スキーマ-as-code |
| Edge runtime互換性 | はい | 制限あり(Prisma Accelerate必須) | はい |
| デザイナーの学習曲線 | 低い | 中程度 | 中程度 |
| ベンダーロックイン | 高い(Supabase) | 低い | 低い |
| Claude Code生成品質 | 良い | 良い | 一貫性がない |
私たちの推奨:プロトタイプを構築または常にSupabaseで実行する場合、Supabaseクライアントを使用してください。Supabaseから移動するか、厳密なスキーマ駆動開発が必要な場合、Drizzleを使用してください。edge runtime制限によるので、新しいプロジェクトではPrismaから移動しました。Prisma Accelerate(月の最初の60Kクエリについて$0、その後月$49)はこれを改善しました。
あなたのCLAUDE.mdファイルの決定をClaude Codeに明示的に伝えてください。そうしなければ、アプローチを混ぜる -- 時々Supabaseクライアント経由でクエリし、時々ORM経由 -- そして同じプロジェクト内に2つの異なるデータアクセスパターンで終わります。
デプロイロールバック:AI生成コードが破綻したときに何が起こるか
Nervegnaのガイドは機能を反復的に構築することを通じて説きます。Claude Codeコミットがローカルdev通過するが本番環境で破綻するときに何が起こるかに対応していません。
これは予想より頻繁に起こります。Claude Codeは単一のプロンプト応答で15ファイルを変更できます。それを1ユニットとしてコミットしてデプロイするなら、ロールバックはすべて15の変更を戻す -- 13が良くても。
実用的なロールバック戦略
1. Claude Codeセッションごとではなく、各論理的変更の後にコミットしてください。 Claude authが変更された場合、UI、およびデータベーススキーマが1セッションで、3つの別々のコミットを作成してください。
2. Vercelの瞬時ロールバックを使用してください。 Vercelで展開する場合、すべてのデプロイメントは不変です。ダッシュボードから10秒以下でどんなプリアで展開品をロールバックできます。Netlifyも同じものを提供します。
3. Claude Codeから直接データベースマイグレーションを実行しません。 Claude マイグレーションファイルを生成する場合、npx supabase db pushまたはnpx prisma migrate deployを実行する前に手動で確認してください。削除された列は、git revertでロールバックできないものではありません。
4. 既知の良い状態にタグを付けてください。 認証、支払い、またはデータモデルのような重要なパスに触れるClaude Code セッションを開始する前に、gitタグを作成してください:git tag pre-auth-refactor。物事がうまくいかない場合、git reset --hard pre-auth-refactorはあなたを戻します。
5. プレビューデプロイメントは任意ではなく、必須です。 VercelとNetlifyはすべてのPRについてプレビューデプロイメントを作成します。プレビューをクリックせずにmainにマージしないでください。Claude Codeは環境変数の欠落、edge runtime互換性、またはCSP違反によるローカルで機能するが本番環境で失敗するコードを生成できます。
プロキシされたアセットのContent Security Policy
これはニッチですが、デザイナーで構築されたサイトをデプロイするときに強く咬むことになります。
Next.jsの<Image>コンポーネントはデフォルトで/_next/imageを通じて外部の画像をプロキシします。これは最適化に優れています。しかし、コンテンツセキュリティポリシーヘッダーを持っている場合(そしてあなたは持つべきです)、画像が来るドメインを明確に許可する必要があります。
Claude Codeはnext.config.jsをremotePatternsで画像最適化にセットアップしますが、CSPヘッダーは追加しません。Vercelのセキュリティヘッダーの後ろにデプロイするか、ミドルウェアで独自のものを追加する場合、外部の画像は静かに破綻します -- ローカルで加読み込まれます(CSPはしばしば緩い)が、本番環境で失敗します。
ミドルウェアまたはnext.config.jsヘッダーに最小限で必要なものは:
// middleware.ts
const cspHeader = `
default-src 'self';
script-src 'self' 'unsafe-eval' 'unsafe-inline';
style-src 'self' 'unsafe-inline';
img-src 'self' blob: data: https://your-supabase-project.supabase.co https://your-cdn.com;
font-src 'self';
connect-src 'self' https://your-supabase-project.supabase.co;
frame-ancestors 'none';
`;
本番環境の硬化のため、'unsafe-eval'および'unsafe-inline'をnonceに置き換えてください。ポイントは:Claude Codeが Unsplashからの画像を取得する場合、Supabase Storage、またはどんなどんな外部CDNから、そして あなたがそれらのドメインをあなたのCSPimg-srcディレクティブに追加しないなら、開発で標準コンソールエラーがゼロで本番環境で破った画像が得られるでしょう。
実際に管理者認証が必要な時とは?
Nervegnaのガイドは基本的なユーザー認証をカバーしています。多くのデザイナー構築プロジェクトは管理者インターフェース -- サイト所有者またはコンテンツチームがデータベースに触れずにデータを管理する方法 -- を必要とします。
質問は:カスタム管理者認証が単なるSupabaseのダッシュボードの使用とは異なる懸念として必要な場合は?
あなたがカスタム管理者認証を必要としない場合:
- あなたは唯一の人がコンテンツを管理している
- あなたのクライアントはSupabaseのテーブルエディタを使用するのに快適です
- プロジェクトは3つ未満のコンテンツタイプを持っている
- 更新は週に1回未満で起こる
あなたがカスタム管理者認証を必要とする場合:
- 非技術チームメンバーがコンテンツを管理する必要がある
- 承認ワークフローまたはドラフト/公開状態が必要です
- プロジェクトはロールベースアクセス(editor、admin、viewer)を持っている
- あなたはモデレーションを必要とするユーザー生成コンテンツを管理しています
管理者認証が必要な場合、最もシンプルなアプローチは、あなたのprofilesテーブル(auth.usersを鏡像)でrole列を列挙の型で持つことです:'user' | 'editor' | 'admin'。それからこのロールをチェックするRLSポリシーを追加してください:
CREATE POLICY "Admins can do anything"
ON public.posts
FOR ALL
USING (
EXISTS (
SELECT 1 FROM public.profiles
WHERE profiles.id = auth.uid()
AND profiles.role = 'admin'
)
);
Claude Codeはあなたが明確にそれをプロンプトする場合、これを生成できます。プロンプトなしで、それは単純なauth.uid() = user_idポリシーにデフォルトします。これはロールベースアクセスを考慮していません。あなたは他のユーザーのコンテンツを見ることができない管理者で終わります。
Nervegnaのワークフロー(CLAUDE.mdファイルで必要条件を定義する)はこれをキャッチします -- あなたがあなたの必要条件にロールベースアクセスを含めることを考える場合。ビルドを開始する前に、ファイルに追加してください。
本番環境にプッシュする前に:チェックリスト
これは、AI codingツール構築または著しく援助されたプロジェクトをデプロイする前にSocial Animalで使用するものです。
データベース&セキュリティ
- RLSは
publicスキーマのすべてのテーブルで有効になっています - RLSポリシーは各テーブルのSELECT、INSERT、UPDATE、およびDELETEに対して存在します
-
SUPABASE_SERVICE_ROLE_KEYはサーバー側のコードでのみ使用されます(コードベースをgrep:grep -r "SERVICE_ROLE" --include="*.ts" --include="*.tsx") -
'use client'を含むファイルでは、Supabaseクライアントはservice role keyで作成されません - データベースマイグレーションは手動で確認されています
- 外部キー制約は予想された場所に存在します
- WHERE句およびRLSポリシーで使用される列上のインデックスが存在します
認証
-
@supabase/ssrが使用されています(廃止された@supabase/auth-helpers-nextjsではなく) - 個別のクライアント作成関数がブラウザー、サーバー、およびミドルウェアコンテキストに対して存在します
- OAuthリダイレクトURIは本番ドメイン以上のプレビューデプロイメントドメインに対して設定されます
- トークンリフレッシュがテストされています(一時的に短い有効期限を設定して、セッションが生き残るのを確認)
- 保護されたルートはセッションが不在の場合、ログインにリダイレクトします
- ログアウトはすべてのcookieとサーバー側のセッション状態をクリアします
Admin&ロール
- 管理者機能が存在する場合、ロールチェックはRLSレベルで起こります(UI レベルの隠蔽だけではなく)
- 管理者ルートはミドルウェアで保護されています(条件付きレンダリングではなく)
- 新しいユーザーのデフォルトロールは最小特権ロールです
デプロイ&ロールバック
- 環境変数はデプロイメントプラットフォームで設定されています
- 既知の良いgitタグは、最後の主要なAI援助変更の前から存在します
- プレビューデプロイメントはコアフローをクリックして、テストされています
- Vercel/Netlifyの瞬時ロールバックは理解され、チームのためにドキュメント化されています
- データベースのバックアップは有効にされています(Supabase Proプランは月$25で日次バックアップを含みます)
Content Security&アセット
- CSPヘッダーはすべての外部イメージドメインを
img-srcに含みます - CSPヘッダーはSupabaseプロジェクトURLを
connect-srcに含みます -
next.config.jsremotePatternsはCSPimg-srcドメインに一致します - フォントは自己ホスト、またはそれらのCDNは
font-srcにあります - 無いブレンドコンテンツ(HTTPSページ上のHTTPリソース)
コード品質
- TypeScript strict mode は有効にされています(
"strict": trueintsconfig.json) - No
@ts-ignoreoranytypes that Claude Code added to suppress errors -
npm run buildは警告なしにパスします(npm run devだけではなく) - エラー境界はデータを取得するクライアントコンポーネントに対して存在します
- 非同期操作のための loading および error 状態が存在します
パフォーマンス
- 画像はNext.js
<Image>コンポーネントをwidthおよびheightまたはfillで使用します - クライアント側のデータ取得はサーバーコンポーネントで取得される可能性があるデータではありません
- バンドルサイズはチェックされています(
npx next@latest buildはルートサイズを示します) - Lighthouseスコアは本番環境のために90以上です(プレビューデプロイメント上で実行、localhostではなく)
このチェックリストは包括的ではありません。Supabase、Next.js、およびAI生成コードに触れるプロジェクトの最小値です。
FAQ
Claude Codeはデザイナーが本番アプリを構築するに十分良いですか?
Claude Codeはデザイン意図から working codeを生成するために優れています。しかし本番の準備は、ツールが unprompted では提供しないセキュリティ、認証、およびインフラストラクチャの知識を必要とします。チェックリストとバックエンド経験がある誰かのコード レビューで pair してください。
Nervegnaのガイドはプロトタイプを超えたプロジェクトのために機能しますか?
Nervegnaのワークフロー -- context-first prompting、incrementalビルド、反復レビュー -- はwell scalesします。ギャップはRLS、認証edge cases、およびデプロイメント戦略のような本番懸念です。彼のアプローチは健全です;それはユーザーに直面するすべてのもに対して補充を必要とします。
Claude CodeでSupabaseまたはPrismaを使用するべきですか?
RLS execution database levelでRLSが必要で、Supabaseプラットフォームにコミットされている場合、Supabaseのクライアントライブラリを使用してください。データベースの可搬性とedge runtime互換性が必要な場合、Drizzle ORMを使用してください。edge制限のため、新しいプロジェクトではPrismaから移動しました。
Claude Codeがクライアント side のコードでSupabaseの service role key を使用するのを防ぐにはどうすればいいですか?
あなたのCLAUDE.mdファイルに明示的なルールを追加してください:「Never use SUPABASE_SERVICE_ROLE_KEY in client components. Only use it in server actions, API routes, or middleware.」Claude Codeはプロジェクト level instructions がはっきり述べられた時にそれを尊重します。
Claude Code生成された Next.js アプリをデプロイする最も安い方法は何ですか?
Vercelの無料Hobby planは、プロジェクトごとに1つのプロダクション展開をサポートします。Supabaseの無料ティアには2つのプロジェクト、500MBデータベース、および1GBファイルストレージが含まれます。合計コスト:低トラフィックサイトの月$0。Vercel Pro(月$20)およびSupabase Pro(月$25)への移動は、一度実際のユーザーがある場合です。
Claude Codeはどのくらいの頻度でセキュリティ問題を伴うコードを生成しますか?
私たちの経験では、database操作を含むClaude Code セッションのおよそ40%は、少なくとも1つのRLSギャップを伴うコードを生成します。それは悪意があるものではありません -- ツールは「working」コードを最適化し、RLS違反はエラーを生成しません。彼らは静かにデータを露出させます。常に手動で監査してください。