# 数据库设计

<cite>
**本文引用的文件**
- [src/lib/db.ts](file://src/lib/db.ts)
- [src/lib/types.ts](file://src/lib/types.ts)
- [src/lib/session-cleanup.ts](file://src/lib/session-cleanup.ts)
- [src/lib/forge-data.ts](file://src/lib/forge-data.ts)
- [src/lib/workspace-fs.ts](file://src/lib/workspace-fs.ts)
- [src/app/api/sessions/route.ts](file://src/app/api/sessions/route.ts)
- [src/app/api/sessions/[id]/route.ts](file://src/app/api/sessions/[id]/route.ts)
- [src/app/api/sessions/[id]/messages/route.ts](file://src/app/api/sessions/[id]/messages/route.ts)
- [src/app/api/workspaces/route.ts](file://src/app/api/workspaces/route.ts)
- [src/app/api/workspaces/[id]/route.ts](file://src/app/api/workspaces/[id]/route.ts)
- [src/app/api/cron-tasks/route.ts](file://src/app/api/cron-tasks/route.ts)
- [src/app/api/task-executions/route.ts](file://src/app/api/task-executions/route.ts)
- [src/lib/cron/executor.ts](file://src/lib/cron/executor.ts)
- [src/lib/im/conversation-engine.ts](file://src/lib/im/conversation-engine.ts)
</cite>

## 目录
1. [简介](#简介)
2. [项目结构](#项目结构)
3. [核心组件](#核心组件)
4. [架构总览](#架构总览)
5. [详细组件分析](#详细组件分析)
6. [依赖分析](#依赖分析)
7. [性能考虑](#性能考虑)
8. [故障排查指南](#故障排查指南)
9. [结论](#结论)
10. [附录](#附录)

## 简介
本文件系统性梳理 Forge 的数据库设计与实现，聚焦 Sessions、Messages、Workspaces、CronTasks 等核心实体，覆盖表结构、字段定义、主外键关系、索引策略、数据验证与业务规则、数据访问模式、缓存与性能考量、数据生命周期与归档策略、迁移路径与版本管理，以及数据安全与隐私访问控制要点。文档同时提供 ER 图与流程图，帮助读者快速理解代码中的真实数据库结构与运行时行为。

## 项目结构
Forge 使用本地嵌入式 SQLite（better-sqlite3）作为应用数据存储，数据库文件位于用户主目录下的数据目录中，并在首次访问时自动初始化与迁移。数据库初始化时会创建所有核心表、索引与默认种子数据；随后通过一系列 API 路由对表进行读写操作。

```mermaid
graph TB
subgraph "应用层"
API_Sessions["会话 API<br/>sessions/route.ts"]
API_Workspaces["工作区 API<br/>workspaces/route.ts"]
API_Cron["定时任务 API<br/>cron-tasks/route.ts"]
API_Exec["执行记录 API<br/>task-executions/route.ts"]
end
subgraph "服务层"
DB["数据库初始化与迁移<br/>src/lib/db.ts"]
Types["类型定义<br/>src/lib/types.ts"]
Cleanup["会话清理<br/>src/lib/session-cleanup.ts"]
IMConv["IM 会话引擎<br/>src/lib/im/conversation-engine.ts"]
end
subgraph "持久化"
FS["文件系统<br/>~/.forge/"]
DBFile["数据库文件<br/>forge.db(+ WAL)"]
end
API_Sessions --> DB
API_Workspaces --> DB
API_Cron --> DB
API_Exec --> DB
DB --> DBFile
DBFile --> FS
Cleanup --> DB
IMConv --> DB
```

图表来源
- [src/lib/db.ts:18-437](file://src/lib/db.ts#L18-L437)
- [src/app/api/sessions/route.ts:1-34](file://src/app/api/sessions/route.ts#L1-L34)
- [src/app/api/workspaces/route.ts:1-60](file://src/app/api/workspaces/route.ts#L1-L60)
- [src/app/api/cron-tasks/route.ts:1-53](file://src/app/api/cron-tasks/route.ts#L1-L53)
- [src/app/api/task-executions/route.ts:1-37](file://src/app/api/task-executions/route.ts#L1-L37)
- [src/lib/session-cleanup.ts:1-40](file://src/lib/session-cleanup.ts#L1-L40)
- [src/lib/forge-data.ts:20-26](file://src/lib/forge-data.ts#L20-L26)

章节来源
- [src/lib/db.ts:18-437](file://src/lib/db.ts#L18-L437)
- [src/lib/forge-data.ts:20-26](file://src/lib/forge-data.ts#L20-L26)

## 核心组件
- Sessions：会话表，保存单次对话的基本信息与状态。
- Messages：消息表，按会话组织用户与助手的消息内容。
- Workspaces：工作区表，记录项目路径与最近打开时间。
- CronTasks：定时任务表，支持按计划执行动作（运行代理、技能或自定义提示），并可关联工作区。
- TaskExecutions：任务执行记录表，记录每次执行的结果与状态。
- Settings：设置表，用于存储运行时配置（如会话保留天数、内存保留天数等）。
- 其他辅助表：Agents、Skills、McpServers、ImChannels、Hooks、MarketplaceTemplates、Channel_* 系列表等。

章节来源
- [src/lib/db.ts:26-188](file://src/lib/db.ts#L26-L188)
- [src/lib/types.ts:6-219](file://src/lib/types.ts#L6-L219)

## 架构总览
下图展示数据库层与应用层之间的交互关系，以及关键实体间的外键约束与典型查询路径。

```mermaid
erDiagram
SESSIONS {
text id PK
text title
text workspace
text model
text status
text created_at
text updated_at
}
MESSAGES {
text id PK
text session_id FK
text role
text content
text created_at
}
WORKSPACES {
text id PK
text path UK
text last_opened_at
text created_at
}
CRON_TASKS {
text id PK
text name
text schedule
text action
text action_type
text agent_name
text skill_name
text workspace_id
int enabled
int is_heartbeat
text config
text last_run_at
text last_run_result
text created_at
text updated_at
}
TASK_EXECUTIONS {
text id PK
text task_id FK
text task_name
text result
text status
text session_id
text executed_at
}
SESSIONS ||--o{ MESSAGES : "拥有"
WORKSPACES ||--o{ SESSIONS : "包含"
CRON_TASKS ||--o{ TASK_EXECUTIONS : "触发"
```

图表来源
- [src/lib/db.ts:26-188](file://src/lib/db.ts#L26-L188)
- [src/lib/types.ts:6-219](file://src/lib/types.ts#L6-L219)

## 详细组件分析

### Sessions 表
- 字段与类型
  - id: 文本主键
  - title: 文本，默认值“New Session”
  - workspace: 文本，默认空字符串
  - model: 文本，默认模型标识
  - status: 文本，CHECK 限制为 'active' 或 'archived'
  - created_at/updated_at: 文本，默认当前时间戳
- 约束与索引
  - 主键：id
  - 状态检查：status ∈ {'active','archived'}
  - 更新时间戳：每次更新自动刷新 updated_at
- 业务规则
  - 会话状态用于归档与清理策略
  - 与 Workspaces 通过 workspace 字段建立逻辑关联（非外键）
- 数据访问模式
  - 创建：POST /api/sessions
  - 列表：GET /api/sessions（仅 active）
  - 查询/更新/删除：GET/PATCH/DELETE /api/sessions/:id
  - 消息读取：GET /api/sessions/:id/messages
- 清理策略
  - 基于设置项 session_retention 的会话自动清理

章节来源
- [src/lib/db.ts:26-34](file://src/lib/db.ts#L26-L34)
- [src/app/api/sessions/route.ts:6-33](file://src/app/api/sessions/route.ts#L6-L33)
- [src/app/api/sessions/[id]/route.ts:5-48](file://src/app/api/sessions/[id]/route.ts#L5-L48)
- [src/app/api/sessions/[id]/messages/route.ts:4-12](file://src/app/api/sessions/[id]/messages/route.ts#L4-L12)
- [src/lib/session-cleanup.ts:10-39](file://src/lib/session-cleanup.ts#L10-L39)

### Messages 表
- 字段与类型
  - id: 文本主键
  - session_id: 文本，外键引用 sessions(id)，级联删除
  - role: 文本，CHECK 限制为 'user' 或 'assistant'
  - content: 文本，存储消息内容（含附件块序列化）
  - created_at: 文本，默认当前时间戳
- 索引
  - 复合索引：(session_id, created_at)
- 业务规则
  - 按时间顺序排序返回消息
  - 与会话强绑定，删除会话时自动删除其消息
- 数据访问模式
  - 读取：GET /api/sessions/:id/messages
  - 写入：IM 引擎在会话中插入用户消息

章节来源
- [src/lib/db.ts:36-43](file://src/lib/db.ts#L36-L43)
- [src/app/api/sessions/[id]/messages/route.ts:4-12](file://src/app/api/sessions/[id]/messages/route.ts#L4-L12)
- [src/lib/im/conversation-engine.ts:95-97](file://src/lib/im/conversation-engine.ts#L95-L97)

### Workspaces 表
- 字段与类型
  - id: 文本主键
  - path: 文本，UNIQUE 约束
  - last_opened_at: 文本，默认当前时间戳
  - created_at: 文本，默认当前时间戳
- 业务规则
  - 通过路径唯一标识工作区
  - 删除工作区时可选择清理关联会话
- 数据访问模式
  - 列表：GET /api/workspaces
  - 新增：POST /api/workspaces（校验目录存在且为目录）
  - 更新最近打开时间：PATCH /api/workspaces/:id
  - 删除：DELETE /api/workspaces/:id（可选清理会话）

章节来源
- [src/lib/db.ts:159-164](file://src/lib/db.ts#L159-L164)
- [src/app/api/workspaces/route.ts:8-59](file://src/app/api/workspaces/route.ts#L8-L59)
- [src/app/api/workspaces/[id]/route.ts:5-32](file://src/app/api/workspaces/[id]/route.ts#L5-L32)

### CronTasks 与 TaskExecutions 表
- CronTasks 字段与类型
  - id/name/schedule/action: 文本
  - action_type: 文本，CHECK 限制为 'run-agent' | 'run-skill' | 'custom-prompt'
  - agent_name/skill_name/workspace_id: 文本
  - enabled/is_heartbeat: 整型（布尔）
  - config: 文本（JSON 字符串）
  - last_run_at/last_run_result: 文本
  - created_at/updated_at: 文本
- TaskExecutions 字段与类型
  - id/task_id/task_name: 文本
  - result: 文本
  - status: 文本，CHECK 限制为 'ok' | 'alert' | 'error'
  - session_id: 文本
  - executed_at: 文本
- 关系与索引
  - CronTasks 与 TaskExecutions：一对多，外键约束级联删除
  - 索引：task_id + executed_at DESC
- 业务规则
  - 支持全局心跳任务（is_heartbeat=1）
  - 可按工作区过滤任务
- 数据访问模式
  - 列表：GET /api/cron-tasks?workspace_id=...
  - 新增：POST /api/cron-tasks
  - 执行记录：GET /api/task-executions?task_id=...&limit=&offset=&type=&status=

章节来源
- [src/lib/db.ts:117-146](file://src/lib/db.ts#L117-L146)
- [src/lib/types.ts:166-211](file://src/lib/types.ts#L166-L211)
- [src/app/api/cron-tasks/route.ts:6-52](file://src/app/api/cron-tasks/route.ts#L6-L52)
- [src/app/api/task-executions/route.ts:5-37](file://src/app/api/task-executions/route.ts#L5-L37)
- [src/lib/cron/executor.ts:26-47](file://src/lib/cron/executor.ts#L26-L47)

### Settings 表与数据验证规则
- Settings
  - key: 文本主键
  - value: 文本
- 验证规则
  - Sessions.status ∈ {'active','archived'}
  - Messages.role ∈ {'user','assistant'}
  - TaskExecutions.status ∈ {'ok','alert','error'}
  - CronTasks.action_type ∈ {'run-agent','run-skill','custom-prompt'}
- 业务规则
  - 会话保留策略：通过 settings.session_retention 控制（天数或 permanent）
  - 内存归档策略：通过 settings.memory_retention_days 控制（默认 7 天）

章节来源
- [src/lib/db.ts:45-48](file://src/lib/db.ts#L45-L48)
- [src/lib/db.ts:31-31](file://src/lib/db.ts#L31-L31)
- [src/lib/db.ts:140-140](file://src/lib/db.ts#L140-L140)
- [src/lib/db.ts:122-122](file://src/lib/db.ts#L122-L122)
- [src/lib/session-cleanup.ts:16-22](file://src/lib/session-cleanup.ts#L16-L22)
- [src/lib/workspace-fs.ts:464-504](file://src/lib/workspace-fs.ts#L464-L504)

### 数据访问模式与缓存策略
- 访问模式
  - 会话与消息：按会话维度读取，使用复合索引提升排序与分页性能
  - 定时任务：按工作区与心跳标志过滤，执行记录按时间倒序分页
  - 工作区：按最近打开时间倒序列出
- 缓存策略
  - 应用层未见显式数据库缓存；SQLite 通过 WAL 模式与连接池提升并发与可靠性
  - 会话清理与内存归档采用节流策略（每小时最多一次）

章节来源
- [src/app/api/sessions/[id]/messages/route.ts:8-L11](file://src/app/api/sessions/[id]/messages/route.ts#L8-L11)
- [src/app/api/task-executions/route.ts:16-37](file://src/app/api/task-executions/route.ts#L16-L37)
- [src/lib/session-cleanup.ts:10-13](file://src/lib/session-cleanup.ts#L10-L13)
- [src/lib/workspace-fs.ts:499-504](file://src/lib/workspace-fs.ts#L499-L504)

### 数据生命周期、保留策略与归档规则
- 会话保留
  - 依据 settings.session_retention（整数天或 'permanent'）
  - 自动清理：每小时最多一次，事务内批量删除消息与会话
- 内存归档
  - 依据 settings.memory_retention_days（默认 7 天）
  - 每小时检查并归档过期记忆文件到 memory/archive.md
- 归档流程

```mermaid
flowchart TD
Start(["开始"]) --> ReadSetting["读取保留天数设置"]
ReadSetting --> CalcCutoff["计算截止日期"]
CalcCutoff --> ListFiles["遍历 memory 目录"]
ListFiles --> CheckDate{"是否早于截止日期？"}
CheckDate --> |否| NextFile["下一个文件"]
CheckDate --> |是| ReadContent["读取文件内容并提取摘要"]
ReadContent --> AppendArchive["追加到 archive.md"]
AppendArchive --> DeleteFile["删除旧文件"]
DeleteFile --> CountInc["计数+1"]
CountInc --> NextFile
NextFile --> |循环| ListFiles
ListFiles --> |完成| Done(["结束"])
```

图表来源
- [src/lib/workspace-fs.ts:464-504](file://src/lib/workspace-fs.ts#L464-L504)
- [src/lib/session-cleanup.ts:16-39](file://src/lib/session-cleanup.ts#L16-L39)

## 依赖分析
- 组件耦合
  - API 路由依赖数据库初始化模块（db.ts）提供的连接与表结构
  - 会话清理模块依赖 Settings 表中的保留策略
  - IM 会话引擎依赖 Messages 表写入用户消息
  - 定时任务执行依赖 CronTasks 与 TaskExecutions 表
- 外部依赖
  - better-sqlite3 提供 SQLite 访问能力
  - 文件系统用于上传与工作区目录管理

```mermaid
graph LR
API_Sessions["sessions/route.ts"] --> DBInit["db.ts"]
API_Workspaces["workspaces/route.ts"] --> DBInit
API_Cron["cron-tasks/route.ts"] --> DBInit
API_Exec["task-executions/route.ts"] --> DBInit
Cleanup["session-cleanup.ts"] --> DBInit
IMConv["im/conversation-engine.ts"] --> DBInit
DBInit --> SQLite["SQLite 数据库"]
```

图表来源
- [src/app/api/sessions/route.ts:1-34](file://src/app/api/sessions/route.ts#L1-L34)
- [src/app/api/workspaces/route.ts:1-60](file://src/app/api/workspaces/route.ts#L1-L60)
- [src/app/api/cron-tasks/route.ts:1-53](file://src/app/api/cron-tasks/route.ts#L1-L53)
- [src/app/api/task-executions/route.ts:1-37](file://src/app/api/task-executions/route.ts#L1-L37)
- [src/lib/session-cleanup.ts:1-40](file://src/lib/session-cleanup.ts#L1-L40)
- [src/lib/im/conversation-engine.ts:95-97](file://src/lib/im/conversation-engine.ts#L95-L97)
- [src/lib/db.ts:18-437](file://src/lib/db.ts#L18-L437)

## 性能考虑
- WAL 模式
  - 启用 WAL 提升并发读写性能与崩溃恢复能力
- 索引优化
  - messages(session_id, created_at)：满足按会话排序与分页
  - task_executions(task_id, executed_at DESC)：满足按任务查询最新执行记录
- 连接与事务
  - 会话清理使用事务批量删除，减少锁竞争与碎片化
- I/O 与归档
  - 内存归档与会话清理均采用节流策略，避免高频 I/O

章节来源
- [src/lib/db.ts:22-23](file://src/lib/db.ts#L22-L23)
- [src/lib/db.ts:50-50](file://src/lib/db.ts#L50-L50)
- [src/lib/db.ts:146-146](file://src/lib/db.ts#L146-L146)
- [src/lib/session-cleanup.ts:30-36](file://src/lib/session-cleanup.ts#L30-L36)

## 故障排查指南
- 数据库初始化失败
  - 检查数据目录权限与磁盘空间
  - 查看迁移日志与错误输出
- 会话清理未生效
  - 确认 settings.session_retention 是否为正整数
  - 检查清理函数是否被节流（每小时最多一次）
- 内存归档异常
  - 检查 memory 目录是否存在与可读写
  - 确认 settings.memory_retention_days 设置
- 定时任务执行记录缺失
  - 确认任务已启用且存在
  - 检查执行记录查询参数（task_id、type、status、limit、offset）

章节来源
- [src/lib/forge-data.ts:52-103](file://src/lib/forge-data.ts#L52-L103)
- [src/lib/session-cleanup.ts:16-22](file://src/lib/session-cleanup.ts#L16-L22)
- [src/lib/workspace-fs.ts:464-504](file://src/lib/workspace-fs.ts#L464-L504)
- [src/app/api/task-executions/route.ts:16-37](file://src/app/api/task-executions/route.ts#L16-L37)

## 结论
Forge 的数据库设计以 SQLite 为核心，围绕 Sessions、Messages、Workspaces、CronTasks 等实体构建了清晰的数据模型与访问路径。通过 WAL 模式、索引与事务优化，兼顾了性能与一致性。结合设置表与节流策略，实现了会话与记忆的生命周期管理。迁移机制确保历史数据平滑演进，API 层提供稳定的 CRUD 与查询接口。

## 附录

### 示例数据
- Sessions
  - id: 唯一标识
  - title: New Session
  - workspace: 工作区 id 或空
  - model: 默认模型标识
  - status: active/archived
  - created_at/updated_at: 时间戳
- Messages
  - id: 唯一标识
  - session_id: 对应会话 id
  - role: user/assistant
  - content: 文本或序列化块
  - created_at: 时间戳
- Workspaces
  - id: 唯一标识
  - path: 唯一路径
  - last_opened_at: 最近打开时间
  - created_at: 创建时间
- CronTasks
  - id/name/schedule/action: 任务元信息
  - action_type: run-agent/run-skill/custom-prompt
  - agent_name/skill_name/workspace_id: 关联信息
  - enabled/is_heartbeat: 状态标记
  - config: JSON 字符串
  - last_run_at/last_run_result: 上次执行信息
  - created_at/updated_at: 时间戳
- TaskExecutions
  - id/task_id/task_name: 关联任务
  - result: 执行结果
  - status: ok/alert/error
  - session_id: 关联会话
  - executed_at: 执行时间

章节来源
- [src/lib/db.ts:26-188](file://src/lib/db.ts#L26-L188)
- [src/lib/types.ts:6-219](file://src/lib/types.ts#L6-L219)