Videofly Docs

架构

了解 VideoFly 的架构和设计决策

项目架构

VideoFly 是一个基于 Next.js 15 的单体应用架构,采用模块化设计,便于维护和扩展。

videofly/
├── src/
│   ├── app/                 # Next.js App Router
│   ├── components/          # React 组件
│   ├── config/              # 配置文件
│   ├── db/                  # 数据库
│   ├── services/            # 业务服务层
│   ├── ai/                  # AI 提供商抽象
│   ├── hooks/               # React Hooks
│   ├── lib/                 # 工具库
│   ├── stores/              # 状态管理
│   └── styles/              # 样式文件
├── public/                  # 静态资源
└── package.json             # 项目依赖

技术栈

核心框架

技术版本用途
Next.js15.5React 全栈框架
React19.2UI 库
TypeScript5.4类型系统

数据层

技术版本用途
PostgreSQL-关系型数据库
Drizzle ORM0.45类型安全的 ORM
Neon-托管数据库(推荐)

身份验证

技术版本用途
Better Auth1.4身份验证解决方案
next-intl4.7国际化

UI 组件

技术版本用途
Tailwind CSS4.0样式框架
shadcn/ui-UI 组件库
Magic UI-动画组件
Animate UI-动画效果
Framer Motion12.2React 动画库
Three.js0.1633D 渲染

状态管理

技术版本用途
Zustand5.0状态管理
TanStack Query5.90数据同步

表单验证

技术版本用途
React Hook Form7.71表单管理
Zod4.2模式验证

支付集成

技术用途
Creem主要支付提供商
Stripe备用支付提供商

存储

技术用途
R2/S3对象存储(兼容)

邮件

技术用途
Resend邮件发送服务

目录结构

应用层 (src/app/)

Next.js App Router 的核心目录,包含所有页面和 API 路由。

src/app/
├── [locale]/            # 国际化路由
│   ├── (auth)/         # 认证页面组
│   ├── (dashboard)/    # 仪表板页面组
│   ├── (editor)/       # 编辑器页面组
│   ├── (marketing)/    # 营销页面组
│   └── (tool)/         # 工具页面组
├── api/                # API 路由
│   ├── auth/           # Better Auth 端点
│   ├── v1/             # REST API v1
│   └── webhooks/       # Webhook 端点
└── layout.tsx          # 根布局

组件层 (src/components/)

所有 React 组件的统一目录。

src/components/
├── animate-ui/         # Animate UI 组件
├── billing/            # 账单组件
├── blog/               # 博客组件
├── creation/           # 创作相关组件
├── credits/            # 积分组件
├── k8s/                # K8s 集群组件
├── landing/            # 落地页组件
├── layout/             # 布局组件
├── magicui/            # Magic UI 组件
├── price/              # 价格组件
├── tool/               # 工具组件
├── ui/                 # shadcn/ui 基础组件
├── user/               # 用户组件
└── video-generator/    # 视频生成器组件

服务层 (src/services/)

业务逻辑的核心层,封装了所有复杂的业务操作。

文件职责
credit.ts积分系统(冻结/结算/释放)
video.ts视频生成服务
customer.ts客户管理
billing.ts账单管理
k8s.tsK8s 集群管理

AI 层 (src/ai/)

AI 提供商的抽象层,统一接口管理多个 AI 服务。

src/ai/
├── providers/
│   ├── evolink.ts      # Evolink.ai 实现
│   └── kie.ts          # Kie.ai 实现
├── types.ts            # 接口定义
└── index.ts            # Provider 工厂

数据层 (src/db/)

数据库 Schema 和连接管理。

// schema.ts - 使用 Drizzle ORM 定义
export const users = pgTable("user", { ... });
export const creditPackages = pgTable("credit_packages", { ... });
export const videos = pgTable("videos", { ... });
// ... 更多表定义

核心模块

1. 积分系统

采用 FIFO(先进先出) 消费模式,确保积分公平过期。

// 积分操作流程
freeze()    // 任务创建时冻结积分

settle()    // 任务成功时结算积分

release()   // 任务失败时释放积分

2. AI 视频生成

统一的 AI 提供商接口,支持多个 AI 服务:

interface AIVideoProvider {
  name: string;
  supportImageToVideo: boolean;
  createTask(params): Promise<VideoTaskResponse>;
  getTaskStatus(taskId): Promise<VideoTaskResponse>;
}

支持流程:

用户请求 → API 验证 → 冻结积分 → 调用 AI 提供商
→ 异步处理 → Webhook 回调 → 下载视频 → 上传 R2
→ 结算积分 → 通知用户

3. 身份验证

由 Better Auth 驱动的完整认证系统:

  • 邮箱/密码登录
  • Google OAuth
  • GitHub OAuth(可选)
  • 魔法链接登录
  • 会话管理

4. 支付集成

支持两种支付提供商:

提供商状态功能
Creem主要订阅、一次性购买
Stripe备用订阅、一次性购买

API 设计

REST API v1

所有业务 API 都在 /api/v1/ 路径下:

端点方法功能
/api/v1/user/meGET获取当前用户
/api/v1/credit/balanceGET获取积分余额
/api/v1/credit/historyGET获取积分历史
/api/v1/video/generatePOST创建视频生成任务
/api/v1/video/listGET获取视频列表
/api/v1/video/[uuid]GET/DELETE获取/删除视频
/api/v1/video/[uuid]/statusGET轮询视频状态
/api/v1/upload/presignPOST获取预签名上传 URL

Auth API

由 Better Auth 自动处理,位于 /api/auth/

数据库 Schema

核心表

表名用途
users用户信息
sessions会话管理
accountsOAuth 账户
credit_packages积分包
credit_holds积分冻结记录
credit_transactions积分交易历史
videos视频生成记录
customers客户信息
creem_subscriptions订阅信息

枚举类型

// 视频状态
enum VideoStatus {
  PENDING,      // 待处理
  GENERATING,   // 生成中
  UPLOADING,    // 上传中
  COMPLETED,    // 已完成
  FAILED        // 失败
}
 
// 积分交易类型
enum CreditTransType {
  NEW_USER,      // 新用户赠送
  ORDER_PAY,     // 订单支付
  SUBSCRIPTION,  // 订阅
  VIDEO_CONSUME, // 视频消费
  REFUND,        // 退款
  EXPIRED,       // 过期
  SYSTEM_ADJUST  // 系统调整
}

状态管理

Zustand Store

// src/stores/user-store.ts
export const useUserStore = create((set) => ({
  user: null,
  setUser: (user) => set({ user }),
}));

TanStack Query

用于服务端状态同步:

// 获取用户积分
const { data: balance } = useQuery({
  queryKey: ['credit-balance'],
  queryFn: () => fetch('/api/v1/credit/balance').then(r => r.json()),
});

国际化

使用 next-intl 实现中英文双语:

src/messages/
├── en.json    # 英文翻译
└── zh.json    # 中文翻译

路由结构:/[locale]/...

设计决策

为什么选择 Drizzle ORM?

类型安全: Drizzle 提供完整的 TypeScript 类型推导,无需手动维护类型定义。

轻量级: 相比 Prisma,Drizzle 的运行时开销更小。

SQL 优先: 不隐藏 SQL,开发者可以完全控制查询。

为什么选择 Better Auth?

现代设计: 专为全栈框架设计,与 Next.js 完美集成。

灵活: 支持多种认证方式,易于扩展。

类型安全: 端到端的类型安全认证体验。

为什么选择单体应用?

简化部署: 无需管理多个应用和复杂的微服务通信。

快速迭代: 所有代码在一个仓库中,开发和部署更简单。

成本更低: 单一部署,基础设施成本更低。

性能优化

1. 静态生成

尽可能使用 generateStaticParams 预生成页面。

2. 数据库索引

在常用查询字段上创建索引:

// 视频表索引
index("videos_user_id_idx").on(table.userId),
index("videos_status_idx").on(table.status),
index("videos_created_at_idx").on(table.createdAt),

3. CDN 加速

静态资源和视频文件都通过 CDN 分发。

4. 缓存策略

使用 TanStack Query 的缓存功能减少重复请求。

安全性

1. 环境变量

敏感信息(API 密钥、数据库凭证)都通过环境变量管理。

2. SQL 注入防护

使用 Drizzle ORM 的参数化查询。

3. XSS 防护

React 自动转义用户输入,配合 zod 验证所有输入。

4. CSRF 保护

Better Auth 内置 CSRF 保护。

下一步