# Supabase 全栈部署指南 (Infrastructure + Auth)

本文档涵盖了 Supabase 基础设施的 Docker 部署、密钥配置、Nginx 安全加固以及用户认证系统的数据库初始化。

---

## 第一部分：基础设施部署 (Infrastructure)

### 1. 准备 Docker 环境 (Ubuntu)

Supabase 严重依赖官方目录结构（挂载配置文件），**必须包含完整的 `docker` 目录**。

```bash
# 1. 创建目录
mkdir -p /home/rongye/ProgramFiles/Supabase
cd /home/rongye/ProgramFiles/Supabase

# 2. 获取官方配置
# 克隆仓库并提取 docker 目录
git clone --depth 1 https://github.com/supabase/supabase.git temp_repo
mv temp_repo/docker/* .
rm -rf temp_repo

# 3. 复制环境变量模板
cp .env.example .env
```

### 2. 生成安全密钥

**警告**：官方模板使用的是公开的弱密钥。生产环境必须重新生成。
使用项目提供的脚本自动生成全套强密钥：

```bash
# 在 ViGent2 项目目录下
cd /home/rongye/ProgramFiles/ViGent2/backend
python generate_keys.py
```

将脚本生成的输出（包括 `JWT_SECRET`, `ANON_KEY`, `SERVICE_ROLE_KEY` 等）复制并**覆盖** `/home/rongye/ProgramFiles/Supabase/.env` 中的对应内容。

### 3. 配置端口与冲突解决

编辑 Supabase 的 `.env` 文件，修改以下端口以避免与现有服务（Code-Server, Moodist）冲突：

```ini
# --- Port Configuration ---
# 避免与 Code-Server (8443) 冲突
KONG_HTTPS_PORT=8444

# 自定义 API 端口 (默认 8000)
KONG_HTTP_PORT=8008

# 自定义管理后台端口 (默认 3000)
STUDIO_PORT=3003

# 外部访问 URL (重要：填入你的公网 API 域名/IP)
# 如果配置了 Nginx 反代: https://api.hbyrkj.top
# 如果直连: http://8.148.25.142:8008
API_EXTERNAL_URL=https://api.hbyrkj.top

# Studio 公网 API 地址 (通过公网访问 Studio 时必须配置)
# 用于 Studio 前端调用 API
SUPABASE_PUBLIC_URL=https://api.hbyrkj.top
```

### 4. 启动服务

```bash
docker compose up -d
```

---

## 第二部分：Storage 本地文件结构

### 1. 存储路径

Supabase Storage 使用本地文件系统存储，路径结构如下：

```
/home/rongye/ProgramFiles/Supabase/volumes/storage/stub/stub/
├── materials/                    # 素材桶
│   └── {user_id}/               # 用户目录 (隔离)
│       └── {timestamp}_{filename}/
│           └── {internal_uuid}  # 实际文件 (Supabase 内部 UUID)
└── outputs/                      # 输出桶
    └── {user_id}/
        └── {task_id}_output.mp4/
            └── {internal_uuid}
```

### 2. 用户隔离策略

所有用户数据通过路径前缀实现隔离：

| 资源类型 | 路径格式 | 示例 |
|----------|----------|------|
| 素材 | `{bucket}/{user_id}/{timestamp}_{filename}` | `materials/abc123/1737000001_video.mp4` |
| 输出 | `{bucket}/{user_id}/{task_id}_output.mp4` | `outputs/abc123/uuid-xxx_output.mp4` |
| Cookie | `cookies/{user_id}/{platform}.json` | `cookies/abc123/bilibili.json` |

### 3. 直接访问本地文件

后端可以直接读取本地文件（跳过 HTTP），提升发布等操作的效率：

```python
# storage.py
SUPABASE_STORAGE_LOCAL_PATH = Path("/home/rongye/ProgramFiles/Supabase/volumes/storage/stub/stub")

def get_local_file_path(self, bucket: str, path: str) -> Optional[str]:
    dir_path = SUPABASE_STORAGE_LOCAL_PATH / bucket / path
    files = list(dir_path.iterdir())
    return str(files[0]) if files else None
```

---

## 第三部分：安全访问配置 (Nginx)

建议在阿里云公网网关上配置 Nginx 反向代理，通过 Frp 隧道连接内网服务。

### 1. 域名规划
- **管理后台**: `https://supabase.hbyrkj.top` -> 内网 3003
- **API 接口**: `https://api.hbyrkj.top` -> 内网 8008

### 2. Nginx 配置示例

```nginx
# Studio (需要密码保护，但静态资源和内部API需排除)
server {
    server_name supabase.hbyrkj.top;

    # SSL 配置略...

    # 静态资源不需要认证
    location ~ ^/(favicon|_next|static)/ {
        auth_basic off;
        proxy_pass http://127.0.0.1:3003;
        proxy_set_header Host $host;
        proxy_http_version 1.1;
    }

    # Studio 内部 API 调用不需要认证
    location /api/ {
        auth_basic off;
        proxy_pass http://127.0.0.1:3003;
        proxy_set_header Host $host;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }

    # 其他路径需要 Basic Auth 认证
    location / {
        auth_basic "Restricted Studio";
        auth_basic_user_file /etc/nginx/.htpasswd;
        proxy_pass http://127.0.0.1:3003;

        # WebSocket 支持 (Realtime 必须)
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";
    }
}

# API (公开访问)
server {
    server_name api.hbyrkj.top;

    # SSL 配置略...

    # ⚠️ 重要：解除上传大小限制
    client_max_body_size 0;

    location / {
        proxy_pass http://127.0.0.1:8008;

        # 允许 WebSocket
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        # 大文件上传超时设置
        proxy_read_timeout 600s;
        proxy_send_timeout 600s;
    }
}
```

### 3. 关键配置说明

| 配置项 | 作用 | 必要性 |
|--------|------|--------|
| `client_max_body_size 0` | 解除上传大小限制（默认 1MB） | **必须** |
| `proxy_read_timeout 600s` | 大文件上传/下载超时 | 推荐 |
| `proxy_http_version 1.1` | WebSocket 支持 | Realtime 必须 |
| `auth_basic` | Studio 访问保护 | 推荐 |

---

## 第四部分：数据库与认证配置 (Database & Auth)

### 1. 初始化表结构 (Schema)

访问管理后台 (Studio) 的 **SQL Editor**，执行以下 SQL 来初始化 ViGent2 所需的表结构：

```sql
-- 1. 用户表 (扩展 auth.users 或独立存储)
-- 注意：这里使用独立表设计，与 FastAPI 逻辑解耦
CREATE TABLE IF NOT EXISTS users (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    email TEXT UNIQUE NOT NULL,
    password_hash TEXT NOT NULL,
    username TEXT,
    role TEXT DEFAULT 'pending' CHECK (role IN ('pending', 'user', 'admin')),
    is_active BOOLEAN DEFAULT FALSE,
    expires_at TIMESTAMP WITH TIME ZONE,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- 2. 会话表 (单设备登录控制)
CREATE TABLE IF NOT EXISTS user_sessions (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id UUID REFERENCES users(id) ON DELETE CASCADE UNIQUE,
    session_token TEXT UNIQUE NOT NULL,
    device_info TEXT,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
);

-- 3. 社交媒体账号绑定表
CREATE TABLE IF NOT EXISTS social_accounts (
    id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
    user_id UUID REFERENCES users(id) ON DELETE CASCADE,
    platform TEXT NOT NULL CHECK (platform IN ('bilibili', 'douyin', 'xiaohongshu')),
    logged_in BOOLEAN DEFAULT FALSE,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
    UNIQUE(user_id, platform)
);

-- 4. 性能索引
CREATE INDEX IF NOT EXISTS idx_users_email ON users(email);
CREATE INDEX IF NOT EXISTS idx_sessions_user_id ON user_sessions(user_id);
CREATE INDEX IF NOT EXISTS idx_social_user_platform ON social_accounts(user_id, platform);
```

### 2. 后端集成配置 (FastAPI)

修改 `ViGent2/backend/.env` 以连接到自托管的 Supabase：

```ini
# =============== Supabase 配置 ===============
# 指向 Docker 部署的 API 端口 (内网直连推荐用 Localhost)
SUPABASE_URL=http://localhost:8008

# 使用生成的 SERVICE_ROLE_KEY (后端需要管理员权限)
SUPABASE_KEY=eyJhbGciOiJIUzI1Ni...

# =============== JWT 配置 ===============
# 必须与 Supabase .env 中的 JWT_SECRET 保持一致！
JWT_SECRET_KEY=填入_generate_keys.py_生成的_JWT_SECRET
JWT_ALGORITHM=HS256
JWT_EXPIRE_HOURS=168
```

---

## 第五部分：常用维护命令

**查看服务状态**:
```bash
cd /home/rongye/ProgramFiles/Supabase
docker compose ps
```

**查看密钥**:
```bash
grep -E "ANON|SERVICE|SECRET" .env
```

**重启服务**:
```bash
docker compose restart
```

**完全重置数据库 (慎用)**:
```bash
docker compose down -v
rm -rf volumes/db/data
docker compose up -d
```
