304 lines
9.4 KiB
Markdown
304 lines
9.4 KiB
Markdown
以下是**完全适配 design3.0.md(前后端分离 + MinerU + LightRAG 版)的全新阶段 0 重做指南**。
|
||||
|
|
目标:在 1~2 天(AI 助手 < 4 小时)内把你已经跑完旧 stage0 的项目**安全迁移/拆分**成两个干净仓库:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
wolai-frontend ← 只负责 UI + 实时协作 + 轻量调用后端 API
|
|||
|
|
wolai-backend ← FastAPI + Celery Redis LightRAG MinerU 全包
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
最终状态:
|
|||
|
|
- 前端仍然是 Next.js 15 App Router + Supabase Auth/Realtime/Storage
|
|||
|
|
- 所有重量级任务(OCR、向量化、知识图谱构建、RAG 查询)全部后端完成
|
|||
|
|
- 0 客户端卡顿
|
|||
|
|
- 两边共享同一 Supabase 项目(Auth + Postgres + Storage + Realtime)
|
|||
|
|
- 代码结构、环境变量、数据库表 100% 符合 design3.0.md 最新要求
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
### 第一步:备份 & 拆分仓库(必须先做,防止误删)
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# 在你当前项目根目录
|
|||
|
|
mv wolai-clone wolai-clone-old-backup-$(date +%Y%m%d)
|
|||
|
|
|
|||
|
|
# 新建两个干净文件夹
|
|||
|
|
mkdir wolai-frontend wolai-backend
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 第二步:创建全新前端项目(保留必要依赖,卸载已迁移到后端的包
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# 进入前端目录
|
|||
|
|
cd wolai-frontend
|
|||
|
|
|
|||
|
|
npx create-next-app@latest . \
|
|||
|
|
--typescript \
|
|||
|
|
--tailwind \
|
|||
|
|
--eslint \
|
|||
|
|
--app \
|
|||
|
|
--src-dir \
|
|||
|
|
--import-alias "@/*" \
|
|||
|
|
--turbo \
|
|||
|
|
--yes
|
|||
|
|
|
|||
|
|
# 初始化 shadcn(2025-11 最新版默认 darkMode: "class")
|
|||
|
|
npx shadcn@latest init -d
|
|||
|
|
|
|||
|
|
# 安装前端真正需要的依赖(精简版)
|
|||
|
|
pnpm add \
|
|||
|
|
@supabase/supabase-js \
|
|||
|
|
@supabase/auth-helpers-nextjs \
|
|||
|
|
@supabase/auth-helpers-react \
|
|||
|
|
@blocknote/core \
|
|||
|
|
@blocknote/react \
|
|||
|
|
@xyflow/react \
|
|||
|
|
yjs \
|
|||
|
|
y-protocols \
|
|||
|
|
@hocuspocus/provider \
|
|||
|
|
zustand \
|
|||
|
|
@tanstack/react-query \
|
|||
|
|
react-dropzone \
|
|||
|
|
sonner \
|
|||
|
|
uuid \
|
|||
|
|
@hello-pangea/dnd \
|
|||
|
|
lucide-react
|
|||
|
|
|
|||
|
|
# 一次性加常用 shadcn 组件(和以前一样)
|
|||
|
|
npx shadcn@latest add button card dialog toast dropdown-menu avatar separator sheet input label textarea badge command popover scroll-area skeleton tabs toggle drawer
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**需要卸载的旧依赖(因为已移到后端)**
|
|||
|
|
```bash
|
|||
|
|
pnpm remove \
|
|||
|
|
@blocknote/mantine \
|
|||
|
|
tesseract.js \
|
|||
|
|
pdfjs-dist \
|
|||
|
|
langchain \
|
|||
|
|
@langchain/openai \
|
|||
|
|
@langchain/community \
|
|||
|
|
neo4j-driver \
|
|||
|
|
@neo4j/graphql
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 第三步:前端目录结构(AI 接手零摩擦)
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
src/
|
|||
|
|
├── app/
|
|||
|
|
│ ├── (auth)/ # 登录注册页
|
|||
|
|
│ ├── (app)/ # 主体布局
|
|||
|
|
│ │ ├── documents/
|
|||
|
|
│ │ │ ├── [id]/
|
|||
|
|
│ │ │ │ ├── page.tsx # BlockNote + XYFlow 切换
|
|||
|
|
│ │ │ │ └── mindmap/page.tsx
|
|||
|
|
│ │ └── layout.tsx # Sidebar + Breadcrumb + BottomToolbar
|
|||
|
|
│ ├── api/ # 只保留轻量 route handlers(如上传文件到 Storage)
|
|||
|
|
│ ├── globals.css
|
|||
|
|
│ └── layout.tsx
|
|||
|
|
├── components/
|
|||
|
|
│ ├── editor/ # BlockNoteEditor.tsx + 实时协作
|
|||
|
|
│ ├── mindmap/ # ReactFlow 组件
|
|||
|
|
│ ├── sidebar/
|
|||
|
|
│ ├── ui/ # shadcn
|
|||
|
|
│ └── common/
|
|||
|
|
├── lib/
|
|||
|
|
│ └── supabase/ # client.ts + server.ts(保持不变)
|
|||
|
|
├── hooks/
|
|||
|
|
└── store/ # zustand
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 第四步:创建后端 FastAPI 项目(全新仓库)
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
cd ../wolai-backend
|
|||
|
|
python -m venv venv
|
|||
|
|
source venv/bin/activate # Windows 用 venv\Scripts\activate
|
|||
|
|
|
|||
|
|
pip install \
|
|||
|
|
fastapi \
|
|||
|
|
"uvicorn[standard]" \
|
|||
|
|
celery[redis] \
|
|||
|
|
redis \
|
|||
|
|
lightrag[hf] \
|
|||
|
|
mineru \
|
|||
|
|
supabase-py \
|
|||
|
|
python-dotenv \
|
|||
|
|
pgvector \
|
|||
|
|
openai \
|
|||
|
|
python-multipart \
|
|||
|
|
python-jose[cryptography] \
|
|||
|
|
passlib[bcrypt]
|
|||
|
|
|
|||
|
|
# 创建基本结构
|
|||
|
|
mkdir app
|
|||
|
|
touch app/main.py app/celery_app.py app/tasks.py app/lightrag_utils.py app/__init__.py
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**推荐的初始文件(直接复制即可)**
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
# app/main.py
|
|||
|
|
from fastapi import FastAPI, Depends, HTTPException
|
|||
|
|
from fastapi.middleware.cors import CORSMiddleware
|
|||
|
|
from supabase import create_client
|
|||
|
|
import os
|
|||
|
|
from dotenv import load_dotenv
|
|||
|
|
|
|||
|
|
load_dotenv()
|
|||
|
|
|
|||
|
|
app = FastAPI(title="Wolai Backend v3.0")
|
|||
|
|
|
|||
|
|
app.add_middleware(
|
|||
|
|
CORSMiddleware,
|
|||
|
|
allow_origins=["http://localhost:3000", os.getenv("FRONTEND_URL")],
|
|||
|
|
allow_credentials=True,
|
|||
|
|
allow_methods=["*"],
|
|||
|
|
allow_headers=["*"],
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
supabase = create_client(os.getenv("SUPABASE_URL"), os.getenv("SUPABASE_SERVICE_ROLE_KEY"))
|
|||
|
|
|
|||
|
|
@app.get("/health")
|
|||
|
|
async def health():
|
|||
|
|
return {"status": "ok"}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
# app/celery_app.py
|
|||
|
|
from celery import Celery
|
|||
|
|
|
|||
|
|
celery = Celery(
|
|||
|
|
"worker",
|
|||
|
|
broker=os.getenv("REDIS_URL"),
|
|||
|
|
backend=os.getenv("REDIS_URL")
|
|||
|
|
)
|
|||
|
|
celery.conf.task_default_queue = "wolai"
|
|||
|
|
celery.conf.worker_concurrency = 3
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 第五步:Supabase 数据库表(2025-11-17 最新版)直接在 SQL Editor 全部执行
|
|||
|
|
|
|||
|
|
```sql
|
|||
|
|
-- 1. 启用扩展
|
|||
|
|
create extension if not exists "uuid-ossp";
|
|||
|
|
create extension if not exists vector;
|
|||
|
|
|
|||
|
|
-- 2. 文档表(新增字段)
|
|||
|
|
create table if not exists documents (
|
|||
|
|
id uuid primary key default uuid_generate_v4(),
|
|||
|
|
user_id uuid references auth.users not null,
|
|||
|
|
parent_id uuid references documents(id) on delete set null,
|
|||
|
|
title text default '无标题',
|
|||
|
|
content jsonb default '{}'::jsonb,
|
|||
|
|
mindmap_data jsonb,
|
|||
|
|
raw_text text, -- MinerU 提取的纯文本
|
|||
|
|
index_status text default 'pending', -- pending / processing / completed / failed
|
|||
|
|
created_at timestamptz default now(),
|
|||
|
|
updated_at timestamptz default now()
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
-- 3. 后台任务进度表(前端轮询或 Realtime 订阅)
|
|||
|
|
create table if not exists background_tasks (
|
|||
|
|
id uuid primary key default uuid_generate_v4(),
|
|||
|
|
user_id uuid references auth.users not null,
|
|||
|
|
document_id uuid references documents(id),
|
|||
|
|
task_type text check (task_type in ('ocr', 'index')),
|
|||
|
|
status text default 'pending',
|
|||
|
|
progress integer default 0,
|
|||
|
|
message text,
|
|||
|
|
created_at timestamptz default now(),
|
|||
|
|
updated_at timestamptz default now()
|
|||
|
|
);
|
|||
|
|
|
|||
|
|
-- 4. RLS
|
|||
|
|
alter table documents enable row level security;
|
|||
|
|
alter table background_tasks enable row level security;
|
|||
|
|
|
|||
|
|
create policy "own docs" on documents for all using (auth.uid() = user_id);
|
|||
|
|
create policy "own tasks" on background_tasks for all using (auth.uid() = user_id);
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
> LightRAG 会自动在你的 Supabase 里创建自己的表(embeddings、entities、relationships 等),不需要手动建。
|
|||
|
|
|
|||
|
|
### 第六步:环境变量(两个项目都要)
|
|||
|
|
|
|||
|
|
**前端 .env.local**
|
|||
|
|
```env
|
|||
|
|
NEXT_PUBLIC_SUPABASE_URL=https://xxxx.supabase.co
|
|||
|
|
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJ...
|
|||
|
|
NEXT_PUBLIC_BACKEND_URL=http://localhost:8000 # 开发时
|
|||
|
|
# 生产时改成你的 Railway/Fly.io 域名
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**后端 .env**
|
|||
|
|
```env
|
|||
|
|
SUPABASE_URL=https://xxxx.supabase.co
|
|||
|
|
SUPABASE_SERVICE_ROLE_KEY=xxxxxx # 危险!只在后端使用,绝不泄露
|
|||
|
|
REDIS_URL=redis://default:xxxx@redis.upstash.io:6379
|
|||
|
|
OPENAI_API_KEY=sk-...
|
|||
|
|
FRONTEND_URL=https://your-frontend.vercel.app
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 第七步:Git 初始化(推荐两个仓库)
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# 前端
|
|||
|
|
cd wolai-frontend
|
|||
|
|
git init
|
|||
|
|
git add .
|
|||
|
|
git commit -m "chore: phase0 frontend - nextjs15 + supabase + blocknote + xyflow (2025-11-17 v3)"
|
|||
|
|
git tag -a "v0.1.0-phase0-frontend" -m "design v3.0 ready"
|
|||
|
|
|
|||
|
|
# 后端
|
|||
|
|
cd ../wolai-backend
|
|||
|
|
git init
|
|||
|
|
git add .
|
|||
|
|
git commit -m "chore: phase0 backend - fastapi + celery + lightrag + mineru (2025-11-17 v3)"
|
|||
|
|
git tag -a "v0.1.0-phase0-backend" -m "design v3.0 ready"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 第八步:交给 AI 编码助手的“一键 Prompt”(直接复制丢给 Claude/Cursor/Codex)
|
|||
|
|
|
|||
|
|
```text
|
|||
|
|
你现在是一个顶级全栈工程师,需要严格按照 design3.0.md(2025-11-17 最新版)实现 Wolai 克隆,要求前后端完全分离。
|
|||
|
|
|
|||
|
|
仓库状态:
|
|||
|
|
- wolai-frontend:Next.js 15 App Router + TypeScript + Tailwind + shadcn/ui + Supabase 客户端已就绪,依赖已精简
|
|||
|
|
- wolai-backend:FastAPI + Celery + Redis + LightRAG + MinerU 骨架已就绪,Supabase service_role 已配置
|
|||
|
|
|
|||
|
|
请完成以下阶段 1 任务(只做前端 + 后端必要接口):
|
|||
|
|
|
|||
|
|
前端:
|
|||
|
|
1. 实现递归侧边栏(240px,@hello-pangea/dnd 拖拽,无限嵌套,参考 ui_react.md 像素级复刻)
|
|||
|
|
2. /documents/[id]/page.tsx 使用 BlockNote + @hocuspocus/provider + Supabase Realtime 实现多人实时协作
|
|||
|
|
3. 实现面包屑、底部固定 AI 工具栏、移动端 Drawer 侧边栏
|
|||
|
|
4. 文件上传 → Supabase Storage → 调用后端 POST /api/v1/tasks/ocr {document_id, file_url} → 显示 background_tasks 进度(Realtime 订阅)
|
|||
|
|
|
|||
|
|
后端:
|
|||
|
|
1. /api/v1/tasks/ocr 接口(接收 document_id + signed_url,使用 service_role 下载文件 → Celery 任务执行 MinerU → 保存 markdown 到 documents.content + raw_text → LightRAG.index)
|
|||
|
|
2. /api/v1/chat SSE 流式接口(LightRAG.query + OpenAI gpt-4o,带来源引用)
|
|||
|
|
|
|||
|
|
全部使用 Server Components + Server Actions(前端) 和 FastAPI Depends 验证 Supabase JWT(后端)。
|
|||
|
|
代码必须 100% 符合 design3.0.md 表结构与数据流。
|
|||
|
|
请输出完整文件列表与代码。
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
执行完以上所有步骤后,你就拥有了一个**完全符合 2025-11-17 最新 design3.0.md 的干净双仓库**,可以直接丢给 AI 继续阶段 1。
|
|||
|
|
|
|||
|
|
现在只需要运行:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# 前端
|
|||
|
|
cd wolai-frontend && pnpm dev
|
|||
|
|
|
|||
|
|
# 后端
|
|||
|
|
cd wolai-backend
|
|||
|
|
uvicorn app.main:app --reload --port 8000
|
|||
|
|
celery -A app.celery_app worker --loglevel=info
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
两个项目同时启动,就能看到熟悉的 Wolai 界面,上传 PDF 后进度条实时显示,AI 问答秒回。
|
|||
|
|
|
|||
|
|
到此,阶段 0(v3.0 版)完成。接下来直接把第八步的 Prompt 丢给 Claude/Cursor 即可进入高速开发阶段。
|
|||
|
|
|
|||
|
|
祝编码愉快!
|