[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fZsBEzTB5e9S5v68eAiTr9qkFhwcy2pMSczgKP4JaZ8A":3},{"item":4,"related":48},{"id":5,"type":6,"title":7,"slug":8,"summary":9,"body":10,"coverUrl":11,"productScreenshots":12,"productLinks":13,"authorName":14,"authorUrl":15,"authorSubject":16,"category":17,"tags":22,"sourceLabel":39,"sourceName":40,"sourceUrl":40,"status":41,"seoTitle":40,"seoDescription":40,"canonicalUrl":40,"isFeatured":42,"sno":43,"sortOrder":44,"publishedAt":45,"updatedAt":46,"createdAt":47},"d0b9da37-b593-4ce4-a055-6a7a3fa7f6d2","article","使用 AI 为项目接入 Supabase 数据库","ai-supabase","本文介绍如何让 AI 编程助手读取现有项目、规划 Supabase 架构、自动修改代码，并完成数据库、认证、存储和权限配置","本指南适用于以下情况：\n\n- 已有 React、Vue、Nuxt、Next.js、Astro 等项目；\n- 希望接入 Supabase 数据库、Auth 或 Storage；\n- 不熟悉 Supabase SDK、RLS 或服务端会话；\n- 希望由 AI 自动分析项目结构并完成大部分代码修改。\n\n推荐使用具备“读取整个项目、修改多个文件、运行命令和查看报错”能力的 AI 编程助手，而不是只在网页聊天框中复制代码。\n\n## 接入前准备\n\n开始前只需要准备：\n\n1. 一个已有项目；\n2. 一个 Supabase 项目；\n3. Supabase Project URL；\n4. Supabase Publishable Key；\n5. 明确需要接入的功能。\n\n常见功能包括：\n\n- 数据库存储；\n- 邮箱或 OAuth 登录；\n- 用户资料；\n- 图片和文件上传；\n- 后台管理；\n- 实时数据；\n- 服务端数据读取。\n\n不要一开始只对 AI 说“帮我接入 Supabase”。应先让 AI 分析项目，再生成实施方案。\n\n## 第一步：让 AI 分析现有项目\n\n先在项目根目录打开 AI 编程助手，并使用以下提示词：\n\n```text\n请完整分析当前项目，但暂时不要修改代码。\n\n你需要识别：\n\n1. 当前使用的框架、版本和路由模式；\n2. 是否使用 TypeScript；\n3. 当前数据来源和状态管理方式；\n4. 是否已有登录系统；\n5. 是否存在服务端 API、Server Actions 或中间件；\n6. 当前环境变量结构；\n7. 哪些页面需要读取或写入数据；\n8. 接入 Supabase 后可能需要修改的文件；\n9. 可能存在的安全风险。\n\n最后输出一份 Supabase 接入方案，按“数据库、认证、存储、权限、前端调用、服务端调用、迁移步骤”分类。\n\n暂时不要执行修改。\n```\n\n这一步的目标不是生成代码，而是让 AI 先理解项目。\n\n如果 AI 无法准确判断业务结构，可以补充：\n\n```text\n本项目的核心业务是：\n\n- 用户可以注册和登录；\n- 用户可以创建、编辑和删除文章；\n- 文章可以上传封面图；\n- 未登录用户可以浏览已发布文章；\n- 用户只能修改自己的文章；\n- 管理员可以管理全部内容。\n```\n\n## 第二步：让 AI 设计数据库\n\n将业务需求交给 AI，让其生成数据库结构和 RLS 策略。\n\n提示词：\n\n```text\n请根据当前项目业务设计 Supabase PostgreSQL 数据库。\n\n要求：\n\n1. 使用 public schema；\n2. 用户身份使用 auth.users；\n3. 为业务表设计主键、外键、创建时间和更新时间；\n4. 用户私有数据必须包含 user_id；\n5. 所有表默认启用 RLS；\n6. 为匿名用户、登录用户和管理员分别设计 Policy；\n7. 避免依赖前端传入用户身份；\n8. 需要提供完整可执行 SQL；\n9. SQL 要支持重复检查，避免明显的执行顺序错误；\n10. 说明每张表和每条 Policy 的作用。\n\n暂时只生成 SQL，不修改项目代码。\n```\n\n对于文章类项目，AI 通常会生成类似：\n\n```sql\ncreate table public.profiles (...);\ncreate table public.posts (...);\ncreate table public.categories (...);\ncreate table public.post_categories (...);\n```\n\n还应包含：\n\n```sql\nalter table public.posts enable row level security;\n```\n\n以及基于：\n\n```sql\nauth.uid()\n```\n\n的读取、创建、修改和删除策略。\n\n执行前，让 AI 再检查一次：\n\n```text\n请对刚才的 SQL 做安全审查。\n\n重点检查：\n\n- 是否存在越权读取；\n- 是否允许用户修改其他用户的数据；\n- insert 的 with check 是否正确；\n- update 是否同时包含 using 和 with check；\n- delete 是否限制所有者；\n- 管理员判断是否安全；\n- 是否有可能通过前端伪造 user_id；\n- 外键和级联删除是否合理。\n\n发现问题后直接输出修正版完整 SQL。\n```\n\n## 第三步：把 Supabase 配置交给 AI\n\n不要把真实密钥直接写进聊天记录或源代码。\n\n先在本地创建环境变量：\n\n```env\nNEXT_PUBLIC_SUPABASE_URL=\nNEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY=\n```\n\n或者根据项目框架使用对应前缀。\n\n然后告诉 AI：\n\n```text\n我已经在本地环境变量中配置：\n\n- NEXT_PUBLIC_SUPABASE_URL\n- NEXT_PUBLIC_SUPABASE_PUBLISHABLE_KEY\n\n请不要读取、打印或硬编码真实值。\n\n请根据当前项目框架：\n\n1. 安装正确的 Supabase SDK；\n2. 创建浏览器端客户端；\n3. 创建服务端客户端；\n4. 如果项目支持 SSR，正确处理 Cookie 会话；\n5. 为缺失环境变量增加错误提示；\n6. 不要在客户端使用 service_role；\n7. 保持现有项目目录风格；\n8. 完成后列出新增和修改的文件。\n```\n\n如果是 Vue、Nuxt、Vite 或 Astro，应让 AI 自动改用对应的环境变量读取方式，而不是照搬 Next.js 写法。\n\n## 第四步：让 AI 自动接入认证\n\n提示词：\n\n```text\n请为当前项目接入 Supabase Auth。\n\n需要实现：\n\n1. 邮箱注册；\n2. 邮箱密码登录；\n3. 退出登录；\n4. 获取当前用户；\n5. 登录状态持久化；\n6. 受保护页面；\n7. 登录后跳转；\n8. 未登录访问受保护页面时跳转到登录页；\n9. 显示认证错误；\n10. 保持当前 UI 风格。\n\n技术要求：\n\n- 使用当前框架推荐的 Supabase Auth 接入方式；\n- SSR 项目必须在服务端正确读取会话；\n- 不要只依赖客户端状态判断权限；\n- 不要在前端保存 service_role；\n- 不要破坏现有路由；\n- 修改完成后运行类型检查和构建。\n```\n\n如果项目已有登录页面，可补充：\n\n```text\n保留现有登录页面的布局和样式，只替换登录逻辑，不要重新设计 UI。\n```\n\n如果需要第三方登录：\n\n```text\n在现有认证基础上增加 GitHub OAuth 登录。\n\n请同时告诉我需要在 Supabase Dashboard 和 GitHub OAuth App 中配置哪些回调地址，但不要假设具体域名。\n```\n\n## 第五步：让 AI 替换原有数据层\n\n如果项目当前使用静态数据、LocalStorage、Mock API 或其他数据库，可以让 AI 自动迁移。\n\n提示词：\n\n```text\n请分析当前项目中所有数据读取和写入逻辑，将需要持久化的部分迁移到 Supabase。\n\n要求：\n\n1. 找出所有 Mock 数据、LocalStorage 和临时数组；\n2. 映射到对应 Supabase 表；\n3. 创建统一的数据访问层；\n4. 页面组件不要到处直接拼接 Supabase 查询；\n5. 所有查询必须处理 error；\n6. 加入 loading、empty 和 error 状态；\n7. 不改变现有页面视觉结构；\n8. 用户只能操作自己的数据；\n9. 服务端可完成的查询优先放在服务端；\n10. 修改后运行测试、类型检查和构建。\n```\n\n建议让 AI 建立统一目录，例如：\n\n```text\nlib\u002Fsupabase\u002F\nservices\u002F\nrepositories\u002F\nserver\u002F\n```\n\n具体目录应由 AI 根据现有项目风格决定。\n\n## 第六步：让 AI 接入文件上传\n\n提示词：\n\n```text\n请为当前项目接入 Supabase Storage，用于上传文章封面图。\n\n要求：\n\n1. 创建合理的 Bucket 使用方案；\n2. 文件路径包含当前用户 ID；\n3. 限制图片类型和大小；\n4. 文件名避免冲突；\n5. 支持替换和删除；\n6. 上传失败时显示明确错误；\n7. 数据库只保存文件路径或 URL；\n8. 私有文件使用 signed URL；\n9. 公共封面图可使用 public URL；\n10. 设计对应 Storage Policy；\n11. 输出需要在 Supabase 中执行的 SQL；\n12. 修改现有上传组件，不重新设计 UI。\n```\n\n让 AI 重点检查 Storage Policy，而不是只生成上传代码：\n\n```text\n请检查当前 Storage Policy 是否允许用户覆盖、读取或删除其他用户的文件。\n\n文件路径规则为：\n\n{user_id}\u002F{resource_id}\u002F{filename}\n\n用户只能管理路径第一段等于自己 auth.uid() 的文件。\n```\n\n## 第七步：让 AI 生成类型\n\nSupabase 数据库结构确定后，可以让 AI 使用生成的数据库类型。\n\n提示词：\n\n```text\n请为当前 Supabase 数据库接入 TypeScript 类型。\n\n要求：\n\n1. 使用 Supabase 数据库生成类型；\n2. 将类型文件放到合适目录；\n3. Supabase Client 使用 Database 泛型；\n4. 数据访问函数返回明确类型；\n5. 删除重复手写类型；\n6. 保留纯 UI 类型；\n7. 修复由数据库字段可空性引起的类型错误；\n8. 不使用 any 临时绕过。\n```\n\n如果 AI 具备终端权限，可以让它执行 Supabase CLI 命令；如果没有，则让它给出需要执行的命令，并在生成类型文件后继续修改代码。\n\n## 第八步：让 AI 自动检查和修复\n\n完成代码修改后，不要直接认为接入成功。\n\n使用以下提示词：\n\n```text\n请对刚完成的 Supabase 接入做一次完整审查。\n\n依次执行：\n\n1. 检查依赖是否安装；\n2. 检查环境变量命名；\n3. 检查客户端和服务端 Supabase Client；\n4. 检查所有数据库查询；\n5. 检查 Auth 会话；\n6. 检查路由保护；\n7. 检查 RLS；\n8. 检查 Storage Policy；\n9. 检查是否泄露高权限密钥；\n10. 检查是否存在未处理的 error；\n11. 运行 lint；\n12. 运行 TypeScript 检查；\n13. 运行测试；\n14. 运行生产构建。\n\n发现问题后直接修复，直到构建通过。\n\n最后输出：\n\n- 修改文件列表；\n- 数据库 SQL；\n- 需要手动完成的 Supabase Dashboard 配置；\n- 尚未解决的问题；\n- 安全注意事项。\n```\n\n## 推荐的完整 AI 提示词\n\n可以直接将下面的提示词交给支持项目级修改的 AI 编程助手：\n\n```text\n请为当前项目完整接入 Supabase。\n\n第一阶段：只分析，不修改\n\n1. 分析框架、版本、路由、数据层、认证、环境变量和部署方式；\n2. 找出所有需要接入数据库、Auth 和 Storage 的页面；\n3. 输出接入计划和风险；\n4. 等完成分析后继续执行，不需要再次询问我。\n\n第二阶段：数据库\n\n1. 根据现有业务设计 PostgreSQL 表；\n2. 使用 auth.users 关联用户；\n3. 所有业务表启用 RLS；\n4. 用户只能管理自己的数据；\n5. 匿名用户只能读取允许公开的数据；\n6. 输出完整 SQL；\n7. 检查 Policy 是否存在越权风险。\n\n第三阶段：代码接入\n\n1. 安装 Supabase SDK；\n2. 创建浏览器端和服务端 Client；\n3. 使用环境变量，不硬编码密钥；\n4. 接入注册、登录、退出和会话；\n5. 替换现有 Mock 数据或 LocalStorage；\n6. 接入文件上传；\n7. 保留现有 UI；\n8. 建立统一数据访问层；\n9. 所有操作处理 loading、empty 和 error。\n\n第四阶段：质量检查\n\n1. 生成或接入数据库 TypeScript 类型；\n2. 不使用 any；\n3. 运行 lint、类型检查、测试和生产构建；\n4. 修复所有由本次接入产生的问题；\n5. 检查 RLS、Storage Policy 和密钥安全。\n\n限制：\n\n- 不要打印真实环境变量；\n- 不要把 service_role 放进客户端；\n- 不要绕过 RLS；\n- 不要重构无关代码；\n- 不要改变现有视觉设计；\n- 不要删除已有功能。\n\n最终输出：\n\n1. 修改文件清单；\n2. 完整 SQL；\n3. Supabase Dashboard 中需要手动配置的内容；\n4. 本地需要补充的环境变量名称；\n5. 测试结果；\n6. 安全审查结果。\n```\n\n## AI 接入时最常见的问题\n\n### AI 只生成代码，没有理解项目\n\n解决方式：\n\n```text\n先停止修改。请重新完整读取项目结构，并说明每个改动与现有代码的关系。\n```\n\n### AI 把 Supabase 查询写满所有组件\n\n解决方式：\n\n```text\n请把 Supabase 查询集中到统一的数据访问层，组件只调用业务函数。\n```\n\n### AI 关闭 RLS 解决报错\n\n这是错误做法。\n\n提示：\n\n```text\n不允许通过关闭 RLS 或使用 service_role 解决前端权限问题。请修复对应 Policy。\n```\n\n### AI 在客户端判断管理员\n\n前端判断只能用于显示界面，不能作为真正权限控制。\n\n提示：\n\n```text\n管理员权限必须由数据库 Policy 或可信服务端验证，不能只根据客户端字段判断。\n```\n\n### AI 忽略 SSR 会话\n\n提示：\n\n```text\n当前项目使用 SSR。请检查 Cookie 会话同步、服务端用户读取和路由保护，不能只使用浏览器端 getSession。\n```\n\n### AI 修改范围过大\n\n提示：\n\n```text\n只修改 Supabase 接入所需文件，恢复所有无关的格式化、命名和 UI 改动。\n```\n\n## 需要人工完成的内容\n\n即使使用 AI，以下内容通常仍需要项目负责人确认：\n\n- 创建 Supabase 项目；\n- 保存真实环境变量；\n- 执行并审核数据库 SQL；\n- 配置 Auth 回调域名；\n- 配置邮件模板；\n- 配置 OAuth Provider；\n- 确认生产域名；\n- 审核 RLS；\n- 审核 Storage Policy；\n- 决定数据保留和删除策略；\n- 在正式环境中进行多账号权限测试。\n\nAI 可以生成和检查方案，但最终权限设计仍需要人工负责。\n\n## 安全检查清单\n\n- AI 没有将真实密钥写入代码。\n- 客户端没有使用 `service_role`。\n- 所有私有业务表已启用 RLS。\n- 用户不能修改其他用户的 `user_id`。\n- UPDATE 同时检查 `using` 和 `with check`。\n- Storage 路径包含用户身份。\n- 私有文件没有使用永久公开 URL。\n- 管理员权限在数据库或可信服务端验证。\n- SSR 页面不是只在客户端判断登录状态。\n- 所有 Supabase 调用都处理了 `error`。\n- 已使用两个不同账号测试越权访问。\n- 已运行生产构建。\n\n## 官方资料\n\n- Supabase Getting Started  \n  https:\u002F\u002Fsupabase.com\u002Fdocs\u002Fguides\u002Fgetting-started\n\n- Supabase AI Prompts  \n  https:\u002F\u002Fsupabase.com\u002Fdocs\u002Fguides\u002Fgetting-started\u002Fai-prompts\n\n- Next.js Quickstart  \n  https:\u002F\u002Fsupabase.com\u002Fdocs\u002Fguides\u002Fgetting-started\u002Fquickstarts\u002Fnextjs\n\n- Auth  \n  https:\u002F\u002Fsupabase.com\u002Fdocs\u002Fguides\u002Fauth\n\n- Row Level Security  \n  https:\u002F\u002Fsupabase.com\u002Fdocs\u002Fguides\u002Fdatabase\u002Fpostgres\u002Frow-level-security\n\n- Storage  \n  https:\u002F\u002Fsupabase.com\u002Fdocs\u002Fguides\u002Fstorage\n\n- JavaScript SDK  \n  https:\u002F\u002Fsupabase.com\u002Fdocs\u002Freference\u002Fjavascript\u002Fintroduction\n\n## 总结\n\n使用 AI 接入 Supabase 的正确方式，不是让 AI 随机生成几段 SDK 代码，而是让它依次完成：\n\n**分析项目 → 设计数据库 → 生成 RLS → 接入 Auth → 替换数据层 → 接入 Storage → 运行测试 → 安全审查。**\n\nAI 可以显著降低接入成本，但 Supabase 的安全边界最终仍由数据库结构、RLS、Storage Policy 和服务端权限控制决定。","https:\u002F\u002Foxqtewbrpuiouqqjrvdv.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Fpublic-media\u002F2026-07-18\u002Ff7e1bd9c-37c2-4198-b313-4243f6482024.jpg",[],[],"Foundit","https:\u002F\u002Ffoundit.cn","f39339b1-aaa6-4e86-b0c2-a6e6a21113b5",{"id":18,"name":19,"slug":20,"description":21},"d6750616-07d9-4350-8485-1834c77be3d2","指南","guide","指导建议，仅供参考",[23,27,31,35],{"id":24,"name":25,"slug":26},"0848beb4-db26-4fb8-b391-f852a11be192","AI编程","ai-coding",{"id":28,"name":29,"slug":30},"d2513b48-43d7-49ba-adac-6d09366f751f","内容由AI生成","gen-by-ai",{"id":32,"name":33,"slug":34},"144abe77-0dc6-4f66-a176-20bddb1c0bfa","编程","coding",{"id":36,"name":37,"slug":38},"a202d639-99a6-488a-a712-4d4c6ffd7e15","开发","dev","资料来源",null,"published",false,51,0,"2026-07-01T00:00:00.000Z","2026-08-16T03:47:06.994Z","2026-07-18T10:20:35.364Z",[49,58,67],{"id":50,"type":6,"title":51,"slug":52,"summary":53,"coverUrl":54,"authorName":55,"sno":56,"publishedAt":45,"createdAt":57},"d55f78f9-5755-434f-9f6f-462a0ff764c7","氛围编程避坑","vibe-coding-reminds","AI能写代码，但不能替你负责","https:\u002F\u002Foxqtewbrpuiouqqjrvdv.supabase.co\u002Fstorage\u002Fv1\u002Fobject\u002Fpublic\u002Fpublic-media\u002F2026-07-17\u002F867d174b-fbb8-4a1c-8bbf-f12a2881e763.jpg","GPT-5.6 Sol",54,"2026-07-17T15:47:16.293Z",{"id":59,"type":6,"title":60,"slug":61,"summary":62,"coverUrl":63,"authorName":14,"sno":64,"publishedAt":65,"createdAt":66},"190a2a0d-4b47-40f7-902a-00ac69ce1b15","AI 编程时代，为什么 Git 和 Pull Request 更重要了","ai-coding-git-pull-request-safety-net","AI 让改动出现得更快，也让变化更难凭记忆追踪。本文解释小提交、Pull Request、自动检查和人工批准如何把 AI 编程变成可比较、可验证、可回滚的协作流程。","\u002Fuploads\u002F2026-09-13\u002F95ac3b51-0915-4200-8130-4ba3195fd935.jpg",40,"2026-09-13T00:00:00.000Z","2026-09-13T11:56:01.900Z",{"id":68,"type":6,"title":69,"slug":70,"summary":71,"coverUrl":72,"authorName":14,"sno":73,"publishedAt":74,"createdAt":75},"54d83c94-d588-400d-9d13-42daa20331e2","CAS：文件的身份可以由内容决定","content-addressable-storage-ai-coding","内容寻址存储 CAS 用内容摘要识别文件和构建产物，解释 AI 编程工具、容器和缓存为什么能复用结果。","\u002Fuploads\u002F2026-09-14\u002F3fab23b3-8bcd-4a3b-bf5a-2ab895ce3a10.jpg",41,"2026-09-14T00:00:00.000Z","2026-09-14T15:01:41.114Z"]