森林AI

产品定位

森林AI 是一个以项目为中心、面向私有化部署的工作台 MVP服务于个人知识工作者、团队负责人和可信的内部用户。它把项目、任务、Inbox 收集、Markdown 笔记、文件资料、AI 会话、项目内标签和轻量任务分发组织在同一工作区中。

Web 客户端桌面优先,同时保留移动浏览器可用性;登录页允许输入私有部署服务器的 IP 地址或域名。

MVP 范围

当前版本包含:

  • 项目创建、设置和聚合工作区。
  • 项目内任务、标签、文件资料和计划任务元数据。
  • Inbox 收集、分析建议和用户确认创建对象的流程。
  • 项目、任务和笔记的关键词搜索。
  • 项目内 AI 会话入口、密钥选择、限流与调用审计。
  • React Web 客户端和 Tauri 桌面壳。

当前版本不包含实时即时通讯、项目级成员角色体系、匿名公开分享、自主 Agent 执行、语义或向量搜索、第三方数据源集成、原生移动 App、浏览器扩展、离线编辑或本地优先同步。

技术栈

  • 后端Go 1.26.1、Gin、Gorm、PostgreSQL 16。
  • WebReact 18、TypeScript、Vite 8、Arco Design。
  • 桌面端Tauri 2、Rust stable共用 Web 构建产物。
  • 本地基础设施Docker Compose。

本仓库当前验证环境使用 Node.js 24.11.0、npm 11.12.1、Rust 1.97.1;其他版本应满足各锁文件与工具链要求。

目录结构

.
├── backend/                  # Go API、数据库模型、业务逻辑和演示数据
│   ├── cmd/api/              # API 入口
│   ├── cmd/seed/             # 开发演示数据入口
│   ├── etc/                  # 按模式加载的 YAML 配置
│   └── internal/             # httpx、models 与各业务包
├── apps/web_v1/              # React + TypeScript 主 Web 客户端
├── apps/desktop/             # Tauri 桌面壳
├── infra/docker-compose.yml  # 本地 PostgreSQL 16
└── docs/                     # 规格、计划与 MVP 验证说明

快速开始

1. 准备环境

安装 Go、Node.js/npm 和 Docker Desktop并确保 Docker Desktop 已启动。桌面端构建还需要 Rust stable 与平台编译工具链。

2. 启动 PostgreSQL

在任意仓库子目录运行:

$repoRoot = (git rev-parse --show-toplevel).Trim()
Set-Location $repoRoot
docker compose -f infra/docker-compose.yml up -d

Compose 只用于本地开发,创建 PostgreSQL 16 服务并监听 localhost:5432。其中的默认数据库凭据不得用于生产环境。

3. 初始化演示数据

$repoRoot = (git rev-parse --show-toplevel).Trim()
Set-Location (Join-Path $repoRoot 'backend')
go run ./cmd/seed

默认演示账号为 demo@senlin.ai,默认密码为 password123。它们只用于本地开发;生产部署必须创建正式用户并替换所有默认凭据与密钥。

4. 启动 API

在新的终端中运行:

$repoRoot = (git rev-parse --show-toplevel).Trim()
Set-Location (Join-Path $repoRoot 'backend')
go run ./cmd/api

开发配置默认监听 http://localhost:9150。可用 GET /healthz 检查进程健康状态Web 登录页使用 GET /api/v1/status 检查服务器连接。

5. 启动 Web 客户端

在新的终端中运行:

$repoRoot = (git rev-parse --show-toplevel).Trim()
Set-Location (Join-Path $repoRoot 'apps/web_v1')
npm ci
npm run dev

Vite 默认地址为 http://localhost:5173。登录页的服务器地址默认是 http://localhost:9150;用户可以改为私有部署服务器的 IP 地址或域名,登录及后续 API 请求会使用用户填写的地址。

配置

后端从 backend/etc/agent.<mode>.yaml 读取配置。SENLIN_APP_MODE 未设置时使用 backend/etc/agent.dev.yaml;例如设置 $env:SENLIN_APP_MODE='prod' 时读取 backend/etc/agent.prod.yaml,该生产文件需由部署方安全提供。

字段 用途
env 运行环境标识。
port API 监听端口;开发值为 9150
dsn PostgreSQL 连接串。
storage_dir 服务端文件存储根目录。
max_upload_bytes multipart 请求体大小上限;开发值为 32 MiB。
auth_secret 邀请和登录会话签名密钥。
system_ai_key 可选的系统级 AI provider fallback key。
ai_key_encryption_secret 用户 AI key 的静态加密密钥。
allowed_origins 允许访问 API 的 Web/Tauri 来源列表。

不要提交生产数据库连接串、AI key、会话凭据或真实密钥。开发配置中的固定值和 Compose 数据库账号仅供本地使用,生产环境必须全部替换。修改 Web 来源或端口时,应同步更新 allowed_origins,否则浏览器会拦截跨域请求。

go run ./cmd/seed 还支持 DATABASE_DSNDATABASE_URL 临时覆盖数据库地址,以及 SENLIN_SEED_EMAILSENLIN_SEED_NAMESENLIN_SEED_PASSWORD 覆盖演示用户信息。

API v1 概览

业务接口前缀为 /api/v1JSON 字段使用 camelCase对外 ID 使用 UUIDv7 字符串,时间使用 UTC RFC 3339。除连接状态和登录外接口都要求有效的 Authorization: Bearer 会话凭据。

方法 路径 成功响应
GET /api/v1/status 200,包含 timestamp 的对象;无需登录。
POST /api/v1/auth/login 200,包含签名且会过期的 token 字段;请求体为 emailpassword
GET /api/v1/projects 200,项目 DTO 数组。
POST /api/v1/projects 201,项目 DTO。
GET /api/v1/projects/:projectId 200,项目 DTO。
PATCH /api/v1/projects/:projectId 200,更新后的项目 DTO。
GET /api/v1/projects/:projectId/workspace 200聚合项目、频道、标签、Inbox、任务、AI 会话、笔记资料和计划任务的工作区 DTO。
POST /api/v1/projects/:projectId/tasks 201,任务 DTO。
PATCH /api/v1/projects/:projectId/tasks/:taskId 200,更新后的任务 DTO。
GET /api/v1/projects/:projectId/tags 200,该项目的标签 DTO 数组。
POST /api/v1/projects/:projectId/tags 201,标签 DTO。
POST /api/v1/projects/:projectId/sources 201,文件资料 DTO请求为含 file 和可选 title 的 multipart 表单。
POST /api/v1/projects/:projectId/cron-plans 201,计划任务 DTO只管理元数据不执行自主 Agent。
POST /api/v1/projects/:projectId/inbox 201Inbox 条目 DTO。
POST /api/v1/inbox/:inboxId/analyze 200suggestions 草稿数组,不创建正式对象。
POST /api/v1/inbox/:inboxId/confirm 200,含 createdCount;只确认服务端已保存且由用户选中的建议。
GET /api/v1/search?q=... 200items 数组,当前检索项目、任务和笔记。
GET /api/v1/projects/:projectId/ai-sessions 200AI 会话 DTO 数组。
POST /api/v1/projects/:projectId/ai-sessions 201AI 会话 DTO请求体只接收 titlecontext

错误统一返回 {"error":{"code":"...","message":"..."}}。路径中的项目、任务和 Inbox ID 必须是 UUIDv7数据库自增 ID 不对外暴露。

验证

后端:

$repoRoot = (git rev-parse --show-toplevel).Trim()
Set-Location (Join-Path $repoRoot 'backend')
go test ./...

Web

$repoRoot = (git rev-parse --show-toplevel).Trim()
Set-Location (Join-Path $repoRoot 'apps/web_v1')
node scripts/visual-check.mjs
npm run build
npm run lint

如果设置了指向隔离测试库的 DATABASE_URL,再运行 PostgreSQL 集成检查:

$repoRoot = (git rev-parse --show-toplevel).Trim()
Set-Location (Join-Path $repoRoot 'backend')
go test -tags integration ./internal/models -run TestPostgresPing -v

不得把真实测试数据库凭据写入仓库。当前机器的逐项执行结果与产物路径见 MVP 验证说明

桌面端

先完成 Web 依赖安装,再构建 Tauri 可执行文件:

$repoRoot = (git rev-parse --show-toplevel).Trim()
Set-Location (Join-Path $repoRoot 'apps/desktop')
npm ci
npm run build

npm run build 会先执行 Web 生产构建,再运行 tauri build --no-bundle。Windows 产物位于 apps/desktop/src-tauri/target/release/senlinai_workbench.exe

需要安装包时运行:

$repoRoot = (git rev-parse --show-toplevel).Trim()
Set-Location (Join-Path $repoRoot 'apps/desktop')
npm run bundle

打包需要 Rust stable、平台编译工具链和对应安装器依赖它与无安装包的可执行文件构建是两个独立验证项。

常见问题

数据库连接或认证失败

确认 Docker Desktop 和 Compose 服务正在运行,并用 docker compose -f infra/docker-compose.yml ps 查看状态。若本机已有 PostgreSQL 占用 5432,请停止冲突服务或同步修改 Compose 映射与 backend/etc/agent.dev.yaml 中的 dsn。演示数据和 API 必须连接到同一个数据库。

浏览器提示无法连接或 CORS 错误

先访问 http://localhost:9150/api/v1/status。如果 API 可达但浏览器仍失败,检查登录页的服务器地址、协议和端口,并把实际 Web 来源加入 allowed_origins 后重启 API。

Vite 端口被占用

默认端口是 5173。可以停止占用进程,或让 Vite 选择可用端口;使用其他端口时必须同步配置后端 allowed_origins

演示账号无法登录

先成功运行 go run ./cmd/seed,再使用 seed 命令输出所对应的开发账号。若通过环境变量覆盖过演示用户信息,应使用覆盖后的值。生产环境不得使用默认演示密码。

AI 会话返回缺少密钥或限流错误

创建 AI 会话前会执行每用户、每动作限流并选择加密存储的用户 key 或系统 fallback key。缺少可用 key 时返回服务不可用,超过配额时返回 429;不要在前端或提交记录中粘贴 key。

安全说明

  • 登录会话使用签名且会过期的 bearer token服务端从认证中间件读取当前用户不接受可伪造的用户 ID 字符串。
  • 用户 AI key 加密存储。AI 操作先限流,再选择 provider/key并记录 provider、key 类型、action、status 和 error日志不得记录 key 明文。
  • AI 分析和会话不会自动创建正式任务、笔记或资料。Inbox 只有在用户确认服务端保存的建议后才创建对象,并保留来源 Inbox ID。
  • 项目标签只在项目内有效。任务移动、标签写入和文件上传都校验项目所有权。
  • 任务分享遵循最小可见范围:被指派人只能看到任务以及被显式分享的关联对象;分享的 note/source 必须与任务属于同一项目。
  • 文件存储路径只由文件服务构造,上传在写磁盘前校验所有权和请求体大小。
  • 生产部署必须替换所有开发凭据和密钥、限制 CORS 来源、使用独立数据库与受控存储目录,并通过 HTTPS 暴露服务。
Description
No description provided
Readme 19 MiB
Languages
Go 52.3%
TypeScript 31%
JavaScript 7.7%
CSS 7.3%
HTML 0.7%
Other 1%