Claude Code for Designers: 生產前指南遺漏的內容
總結
我們在 Social Animal 過去 18 個月內部署了 30+ 個無頭專案。最近進來的大約三分之一是救援工作,來自設計師主導的構建,這些專案展示了演示但在生產環境中破裂。Michael Nervegna 在 Substack 上的「Claude Code for Designers」指南對原型設計確實很好 -- 但它在行級安全、認證令牌刷新、資料庫抽象選擇、部署回滾、內容安全政策和管理員認證之前就停止了。本文涵蓋了這些缺口。如果你要推送到生產環境,你需要它們。
目錄
- 什麼是 Claude Code 以及為什麼設計師在使用它?
- Nervegna 的指南做對了什麼?
- 指南在哪裡不夠全面?
- Claude 無法發現的行級安全陷阱
- 認證交接:原型和生產之間的差距
- Supabase vs Prisma:Claude Code 應該為哪一個生成代碼?
- 部署回滾:當你的 AI 生成代碼破裂時會發生什麼
- 代理資產的內容安全政策
- 你何時真正需要管理員認證?
- 推送到生產環境之前:檢查清單
- 常見問題
什麼是 Claude Code 以及為什麼設計師在使用它?
Claude Code 是 Anthropic 在 2025 年初推出的基於終端的編碼工具。它以 @anthropic-ai/claude-code 身份運行,需要 Claude Pro($20/月)或 Team($30/座位/月)及 API 訪問。你在終端中通過自然語言編寫、編輯和調試代碼。
設計師正在使用它,因為它縮小了「我在 Figma 中設計了這個」和「這是一個可工作的 Next.js 應用程式」之間的差距。與 v0 或 Bolt 不同,Claude Code 在你的實際文件系統上運行。它讀取你的專案結構、修改文件、運行你的開發伺服器,並根據錯誤輸出進行迭代。對於理解元件層次結構但不想記住 TypeScript 泛型的人來說,這確實很有用。
Nervegna 將其定位為讓設計師「系統思考」而不是「語法思考」的工具。我們同意。我們分歧的地方在於第一個 npm run dev 成功後會發生什麼。
Nervegna 的指南做對了什麼?
Nervegna 做對了大多數 AI 編碼教程會遺漏的三件事。
第一:專案背景。 他建議給 Claude Code 提供一個 CLAUDE.md 文件,其中包含你的專案約定、技術堆棧和設計令牌。我們看過 Claude Code 對使用 CSS Modules 的專案生成 Tailwind 實用程式,因為沒人告訴它約定。在編寫代碼之前建立背景是正確的方法。
第二:迭代循環。 提示、審查輸出、改正方向、重複。他不把 Claude Code 視為「描述並發布」按鈕。他把它視為需要監督的配對夥伴。這是正確的心智模式。
第三:從小開始。 在嘗試完整應用程式架構之前,先構建一個單一的元件或頁面。我們看過設計師在一條訊息中提示「為我構建一個完整的 SaaS 儀表板,包括認證、計費和管理員」。結果總是一團糟。Nervegna 的增量方法避免了這種情況。
Nervegna 指南服務設計師的地方是 0 到原型的階段。問題是原型會變成生產代碼,這就是差距變得重要的地方。
指南在哪裡不夠全面?
Nervegna 的文章為原型設計階段提供了服務。它沒有解決當你連接真實資料庫、真實使用者和真實部署基礎設施時變得緊迫的問題。
缺失的內容:
- 行級安全 (RLS) -- Claude Code 生成的 Supabase 專案幾乎從不具有正確的 RLS 政策
- 認證交接 -- Supabase Auth 開發與生產流程之間的差距,包括令牌刷新、會話管理和重定向處理
- 資料庫抽象決策 -- 何時直接使用 Supabase 用戶端與何時使用 Prisma 或 Drizzle ORM
- 部署回滾策略 -- Claude Code 提交破裂生產環境時會發生什麼
- 內容安全政策 -- 特別是用於代理/外部資產的 Next.js Image
- 管理員認證 -- 何時需要超越簡單使用者認證的基於角色的訪問
讓我們逐一檢查。
Claude 無法發現的行級安全陷阱
行級安全是 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 條件 |
| 在用戶端代碼中使用服務角色金鑰 | RLS 被完全繞過 | 永遠不要在客戶端捆綁包中公開 SUPABASE_SERVICE_ROLE_KEY |
我們看過最後一個 -- 用戶端代碼中的服務角色金鑰 -- 今年在三個獨立的設計師構建的專案中。Claude Code 有時會使用服務角色金鑰,因為它「有效」且不拋出權限錯誤。該金鑰繞過了所有 RLS。它只屬於伺服器端代碼(API 路線、伺服器操作、邊緣函數)。永遠不要在 use client 元件中使用。
Nervegna 在他的指南中沒有涵蓋 RLS,這是可以理解的。但如果你遵循他的工作流程並連接到 Supabase,請手動檢查每個表格。在 Supabase SQL 編輯器中運行以下內容:
SELECT schemaname, tablename, rowsecurity
FROM pg_tables
WHERE schemaname = 'public';
如果任何持有使用者資料的表格的 rowsecurity 是 false,請停止並在部署之前修復它。
認證交接:原型和生產之間的差距
認證是設計師主導的構建中最常見的故障點。不是因為初始設置是錯誤的 -- Supabase Auth 很容易架構 -- 而是因為生產認證涉及在本地開發期間不會出現的邊緣案例。
Nervegna 的指南著重於讓事物在本地運行。以下是當你部署時會破裂的內容:
令牌刷新失敗
Supabase Auth 令牌在預設情況下在 3600 秒(1 小時)後過期。Supabase 用戶端會自動處理刷新 -- 理論上。實際上,如果你的 Next.js 中間件或伺服器元件在每個請求上建立一個新的 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 時,你需要將你的生產 URL 和任何預覽部署 URL 添加到 OAuth 提供者的主控台和 Supabase 的 Auth 設置(在「重定向 URL」下)。這需要 5 分鐘但如果你遺漏了會阻止 100% 的 OAuth 登入。
會話同步問題
在 Next.js 14+ 中,你有伺服器元件、用戶端元件、中間件、API 路線和伺服器操作 -- 所有可能需要當前使用者會話。Supabase 用戶端必須在每個背景中不同地建立。Claude Code 經常建立單一 createClient() 實用程式並在任何地方使用它,這導致水合不匹配和陳舊會話。
你至少需要三個用戶端建立函數:
createBrowserClient()用於用戶端元件createServerClient()用於伺服器元件和伺服器操作createMiddlewareClient()用於中間件
這在 Supabase 的 SSR 指南中有記載,但 Claude Code 並不能始終正確地生成它。
Supabase vs 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 的語法和更好的邊緣執行時支持。
決策矩陣
| 因素 | Supabase 用戶端 | Prisma | Drizzle |
|---|---|---|---|
| RLS 支持 | 原生 | 必須在應用層實現 | 必須在應用層實現 |
| 類型安全 | 通過 CLI 生成 | 從架構生成 | 架構即代碼 |
| 邊緣執行時相容 | 是 | 有限(需要 Prisma Accelerate) | 是 |
| 設計師的學習曲線 | 低 | 中 | 中 |
| 廠商鎖定 | 高(Supabase) | 低 | 低 |
| Claude Code 生成質量 | 好 | 好 | 不一致 |
我們的建議:如果你正在構建原型或將始終在 Supabase 上運行,請使用 Supabase 用戶端。如果你需要移出 Supabase 或想要嚴格的架構驅動開發,請使用 Drizzle。由於邊緣執行時限制,我們已經為新專案停止使用 Prisma,儘管 Prisma Accelerate($0 用於 60K 查詢/月,然後 $49/月)已經改進了這一點。
在你的 CLAUDE.md 文件中明確告訴 Claude Code 你的決策。如果你不這樣做,它將混合方法 -- 有時通過 Supabase 用戶端查詢,有時通過 ORM -- 你最終會在同一專案中使用兩種不同的資料存取模式。
部署回滾:當你的 AI 生成代碼破裂時會發生什麼
Nervegna 的指南介紹了如何迭代地構建功能。它沒有解決當 Claude Code 會話生成通過本地開發但在生產環境中破裂的提交時會發生什麼。
這比你預期的更頻繁發生。Claude Code 可以在單個提示回應中修改 15 個文件。如果你將其作為一個單位提交並部署,回滾意味著恢復所有 15 個更改 -- 即使 13 個是正常的。
實用的回滾策略
1. 在每個邏輯更改後提交,而不是每個 Claude Code 會話。 如果 Claude 在一個會話中修改了認證、UI 和資料庫架構,請進行三個單獨的提交。
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 建立預覽部署。在不點擊預覽的情況下不要合併到主分支。Claude Code 可以生成在本地運行但在生產環境中因缺失環境變數、邊緣執行時不相容或 CSP 違規而失敗的代碼。
代理資產的內容安全政策
這是小眾的,但當你部署設計師構建的網站時會狠狠咬你。
Next.js 的 <Image> 元件預設通過 /_next/image 代理外部映像。這對優化很有好處。但如果你有內容安全政策標頭(你應該有),你需要明確允許你的映像來自的域。
Claude Code 會使用 remotePatterns 設置 next.config.js 以進行映像優化,但不會添加 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';
`;
用你的 Supabase 專案 URL 和 CDN URL 替換 https://your-supabase-project.supabase.co 和 https://your-cdn.com。用 nonces 替換生產強化的 'unsafe-eval' 和 'unsafe-inline'。要點是:如果 Claude Code 從 Unsplash、Supabase Storage 或任何外部 CDN 拉入映像,而你沒有將這些域添加到你的 CSP img-src 指令中,你在生產環境中會看到破裂的映像,開發環境中的控制台中零錯誤。
你何時真正需要管理員認證?
Nervegna 的指南涵蓋了基本的使用者認證。許多設計師構建的專案需要管理員界面 -- 讓網站所有者或內容團隊在不接觸資料庫的情況下管理資料的方法。
問題是:何時你需要管理員認證作為單獨的關注點,與僅使用 Supabase 儀表板相比。
你不需要自訂管理員認證的時候:
- 你是唯一管理內容的人
- 你的客戶樂於使用 Supabase 的表格編輯器
- 該專案有少於 3 個內容類型
- 更新每周發生少於一次
你需要自訂管理員認證的時候:
- 非技術團隊成員需要管理內容
- 你需要批准工作流程或草稿/發布狀態
- 該專案具有基於角色的訪問權限(編輯器與管理員與查看者)
- 你正在管理需要審核的使用者生成的內容
如果你需要管理員認證,最簡單的方法是在你的 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 文件中定義需求的工作流程會捕捉到這個 -- 如果你想到在開始構建前在文件中包含基於角色的訪問。將其添加到文件中。
推送到生產環境之前:檢查清單
這是我們在 Social Animal 部署任何由 AI 編碼工具構建或顯著協助的專案之前使用的內容。
資料庫和安全
- RLS 在
public架構中的每個表格上都已啟用 - RLS 政策對每個表格上的 SELECT、INSERT、UPDATE 和 DELETE 都存在
-
SUPABASE_SERVICE_ROLE_KEY僅在伺服器端代碼中使用(grep 你的程式碼庫:grep -r "SERVICE_ROLE" --include="*.ts" --include="*.tsx") - 沒有 Supabase 用戶端使用服務角色金鑰在任何包含
'use client'的文件中建立 - 資料庫遷移已被手動審查
- 外鍵約束存在於預期的地方
- 索引存在於 WHERE 子句和 RLS 政策中使用的列上
認證
-
@supabase/ssr被使用(不是已棄用的@supabase/auth-helpers-nextjs) - 為瀏覽器、伺服器和中間件背景存在單獨的用戶端建立函數
- OAuth 重定向 URI 為生產域和預覽部署域配置
- 令牌刷新已測試(暫時設置短期限並驗證會話存活)
- 受保護的路線在會話缺失時重定向到登入
- 登出清除所有 cookies 和伺服器端會話狀態
管理員和角色
- 如果管理員功能存在,角色檢查發生在 RLS 層級(不僅是 UI 層級隱藏)
- 管理員路線由中間件保護,而不是條件渲染
- 新使用者的預設角色是最少特權角色
部署和回滾
- 環境變數在部署平台中設置
- 已知良好的 git 標籤存在於最後主要 AI 協助更改之前
- 預覽部署已通過點擊核心流程進行測試
- 理解並記錄了 Vercel/Netlify 即時回滾對團隊
- 資料庫備份已啟用(Supabase Pro 方案包括 $25/月的每日備份)
內容安全和資產
- CSP 標頭在
img-src中包括所有外部映像域 - CSP 標頭在
connect-src中包括 Supabase 專案 URL -
next.config.jsremotePatterns與 CSPimg-src域匹配 - 字體是自託管的或其 CDN 在
font-src中 - 沒有混合內容(HTTPS 頁面上的 HTTP 資源)
代碼質量
- TypeScript 嚴格模式已啟用(
tsconfig.json中的"strict": true) - 沒有 Claude Code 添加的
@ts-ignore或any類型來抑制錯誤 -
npm run build通過沒有警告(不僅是npm run dev) - 錯誤邊界對於提取資料的用戶端元件存在
- 異步操作存在加載和錯誤狀態
性能
- 映像使用 Next.js
<Image>元件,帶有width和height或fill - 沒有用戶端資料提取可以在伺服器元件中提取的資料
- 捆綁大小已檢查(
npx next@latest build顯示路線大小) - Lighthouse 得分對於性能超過 90(在預覽部署上運行,而不是 localhost)
此檢查清單並非詳盡無遺。它是涉及 Supabase、Next.js 和 AI 生成代碼的專案的最低限度。
常見問題
Claude Code 對設計師構建生產應用程式足夠好嗎? Claude Code 對於根據設計意圖生成工作代碼非常出色。但生產準備需要工具未主動提供的安全、認證和基礎設施知識。將其與檢查清單和後端經驗的人的代碼審查配對。
Nervegna 的指南是否適用於超越原型的專案? Nervegna 的工作流程 -- 背景優先提示、增量構建、迭代審查 -- 擴展得很好。差距在於生產問題,如 RLS、認證邊緣案例和部署策略。他的方法是健全的;它需要補充生產環境相關的任何東西。
我應該在 Claude Code 中使用 Supabase 或 Prisma? 如果你想要資料庫級別的 RLS 強制執行,並且你致力於 Supabase 平台,請使用 Supabase 的用戶端庫。如果你想要資料庫可移植性和邊緣執行時相容性,請使用 Drizzle ORM。由於邊緣限制,我們已經為新專案停止使用 Prisma。
我如何防止 Claude Code 在用戶端代碼中使用 Supabase 服務角色金鑰?
將明確的規則添加到你的 CLAUDE.md 文件:「永遠不要在用戶端元件中使用 SUPABASE_SERVICE_ROLE_KEY。僅在伺服器操作、API 路線或中間件中使用它。」當清楚地陳述時,Claude Code 尊重專案層級的指令。
部署 Claude Code 生成的 Next.js 應用程式的最便宜方式是什麼? Vercel 的免費 Hobby 方案支持每個專案一個生產部署。Supabase 的免費層包括 2 個專案,500MB 資料庫和 1GB 文件存儲。總成本:低流量網站 $0/月。當你有真實使用者時,預期移動到 Vercel Pro($20/月)和 Supabase Pro($25/月)。
Claude Code 生成具有安全問題的代碼的頻率如何? 根據我們的經驗,大約 40% 涉及資料庫操作的 Claude Code 會話生成至少一個 RLS 差距的代碼。這不是惡意的 -- 工具優化了「工作」代碼,而 RLS 違規不會產生錯誤。他們只是靜默地公開資料。始終手動審計。