Files
agent/docs/mvp-verification.md

10 KiB
Raw Blame History

森林AI MVP 验证

本文记录 2026-07-21 在 Windows、PowerShell 环境中对当前仓库实际执行的验证。只有获得成功退出码或明确 HTTP 响应的命令列为通过;未满足环境条件的项目单独列出,不视为通过。

环境基线

  • Go 1.26.1 windows/amd64
  • Node.js 24.11.0
  • npm 11.12.1
  • Rust 1.97.1
  • Cargo 1.97.1
  • Docker CLI当前机器不可用
  • DATABASE_URL:当前 shell 未设置

本地 Compose 与 backend/etc/agent.dev.yaml 约定 PostgreSQL 监听 localhost:5432API 监听 localhost:9150Vite 默认监听 localhost:5173。Compose 和开发配置中的固定数据库凭据只供本地开发,生产环境必须替换。

本次结果摘要

验证项 结果 说明
go test ./... 通过 全部 Go 包通过;另以 -count=1 无缓存复核通过。
go run ./cmd/api 未通过 本机现有 PostgreSQL 的账号配置与开发配置不匹配,初始化时认证失败。
go run ./cmd/seed 未通过 与 API 相同,因本机 PostgreSQL 认证失败。
Compose 启动 未验证 当前机器没有可用的 Docker CLI未声称启动成功。
Web 依赖安装 通过 npm ci 成功,审计未发现漏洞。
Web 短时启动 通过 npm run dev 启动因默认端口已有用户进程占用时自动选择可用端口HTTP 根路径返回 200。本次进程随后已停止。
Web 视觉检查 通过 node scripts/visual-check.mjs 退出 0,无未预期 console error。
Web 生产构建 通过 npm run build 退出 0;存在 bundle 大小警告,不影响构建结果。
Web lint 通过 npm run lint 退出 0
Web 结构检查 通过 node scripts/structure-check.mjs 输出 structure ok
桌面端依赖安装 通过 apps/desktopnpm ci 成功。
Tauri 可执行文件构建 通过 冷构建超过单次 240 秒工具等待上限,但已完成 release 编译;同一命令增量重跑 58.3 秒退出 0
Tauri 安装包 未验证 本次未运行 npm run bundle
PostgreSQL 集成测试 未运行 当前 shell 未提供 DATABASE_URL

本地启动检查

PostgreSQL

需要 Docker Desktop。可在任意仓库子目录运行

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

当前机器无法识别 docker 命令,因此这两条命令未验证。不要根据本记录推断 Compose 已成功启动。

演示数据与 API

数据库可用后,在两个独立终端中运行:

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

本次两条命令都真实执行过,但均在连接本机 PostgreSQL 时因开发账号认证失败而退出。排除本机数据库冲突并成功启动后,应检查:

Invoke-RestMethod http://localhost:9150/healthz
Invoke-RestMethod http://localhost:9150/api/v1/status

预期分别返回 status: ok 和 UTC RFC 3339 timestamp/api/v1/status 是登录页使用的公开连接检查;其他业务接口除登录外均要求有效 bearer 会话。

Web 开发服务器

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

本次 npm ci 通过。短时启动时默认端口已被用户原有 Vite 进程占用,本次实例自动选择另一个可用端口;对该实例根路径请求得到 HTTP 200。验证结束后仅停止了本次新建的进程树,用户原有进程未被修改。

自动化验证

后端

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

本次退出 0。为排除 Go 测试缓存影响,还执行了:

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

无缓存复核同样退出 0覆盖配置、HTTP 路由、认证、项目/工作区、任务、标签、资料、Inbox、关键词搜索、AI key 加密、限流与审计等包。

PostgreSQL 集成测试

仅在准备了隔离的实时测试数据库时运行:

$repoRoot = (git rev-parse --show-toplevel).Trim()
Set-Location (Join-Path $repoRoot 'backend')
$env:DATABASE_URL = '<隔离测试库连接串>'
go test -tags integration ./internal/models -run TestPostgresPing -v

连接串必须通过安全的本地或 CI secret 注入,不能提交到仓库。本次 DATABASE_URL 未设置,因此没有运行,也不列为通过。

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
node scripts/structure-check.mjs

四条命令本次均退出 0。视觉检查覆盖桌面和移动登录页、工作台、项目导航、Inbox 确认、AI 会话受控创建、深色模式、无横向溢出和无未预期 console error。

npm run build 生成:

  • apps/web_v1/dist/index.html
  • apps/web_v1/dist/assets/
  • apps/web_v1/dist/senlinai-icon.svg

node scripts/visual-check.mjs 生成的本地证据位于 apps/web_v1/test-results/,包括:

  • login-react-acro.png
  • login-react-acro-mobile.png
  • workbench-react-acro-light.png
  • project-react-acro-light.png
  • project-react-acro-dark.png
  • project-navigation-mobile.png
  • channel-navigation-mobile.png
  • project-inbox-confirmed.png
  • project-inbox-confirmed-mobile.png
  • project-ai-controlled.png

dist/test-results/ 都是本地产物,已被 .gitignore 排除,不应提交。

桌面端

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

本次最终重跑退出 0npm run build 使用 tauri build --no-bundle,并先执行 Web 生产构建。Windows 可执行文件为:

apps/desktop/src-tauri/target/release/senlinai_workbench.exe

本次产物大小为 8,783,360 字节。冷构建需要下载或编译 Rust 依赖,可能耗时数分钟;本次第一次调用因外部等待工具达到 240 秒上限而返回超时,但编译日志已显示 release 完成和产物生成,随后相同命令增量重跑获得退出码 0

安装包是独立验证项:

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

本次没有运行该命令,不记录安装包结果。

API 契约抽查

当前路由注册与 Web API client 均使用 /api/v1

  • 公共:GET /api/v1/statusPOST /api/v1/auth/login
  • 项目与工作区:项目列表/创建/读取/更新,以及项目工作区读取。
  • 任务与标签:任务创建/更新、项目标签列表/创建。
  • 资料与计划任务multipart 文件资料创建、计划任务元数据创建。
  • Inbox收集、生成建议、按服务端建议 ID 确认。
  • 搜索:带 q 参数的关键词搜索,响应为 items 数组。
  • AI 会话:项目会话列表与受控创建,响应为会话 DTO。

抽查结论:创建接口返回 201,读取和当前更新接口返回 200JSON DTO 使用 camelCase对外路径参数使用 UUIDv7错误为 error.codeerror.message 包装结构。API 不直接返回 Gorm 模型或内部自增 ID。

人工 MVP 流程

在 Compose、seed、API 和 Web 均成功启动后,按以下顺序人工验收:

  1. 打开 Web 客户端,在登录页输入服务器 IP 地址或域名。
  2. 使用仅供开发的演示账号登录,并确认生产部署未使用默认凭据。
  3. 创建项目,修改项目设置,再刷新确认数据保留。
  4. 创建项目内标签和任务,验证任务卡显示真实标签与状态。
  5. 上传文件资料,确认返回路径是相对存储路径,且越权项目不能留下文件。
  6. 创建计划任务元数据,确认界面没有暗示自主 Agent 已执行。
  7. 收集一条 Inbox 内容,先分析建议;此时不应出现正式对象。
  8. 选择一条或多条服务端建议并确认,验证生成对象保留来源 Inbox ID。
  9. 用关键词搜索项目、任务和笔记,确认用户只能看到有权访问的结果。
  10. 创建项目 AI 会话,确认缺 key、限流和服务错误有明确提示且不会自动生成正式对象。
  11. 在桌面与移动视口检查项目/频道导航、焦点状态和横向溢出。
  12. 启动桌面可执行文件,逐项检查登录持久化、拖拽上传、通知和全局快捷收集等 MVP 目标;未实际走通的能力不得记为通过。

安全复核清单

  • 生产环境已替换数据库凭据、auth_secret、AI key 加密密钥和所有开发默认值。
  • 未提交数据库连接串、用户 AI key、会话凭据、日志、数据库文件、上传文件或构建产物。
  • 登录凭据由签名且会过期的 bearer session 校验handler 从认证上下文获取用户。
  • 用户 AI key 加密存储AI 操作在 key/provider 选择前占用限流配额,并写 provider、key 类型、action、status 和 error 审计。
  • AI 输出只形成待确认草稿;用户确认前不创建任务、笔记或资料。
  • 项目标签保持项目内范围;任务分享的 note/source 与任务属于同一项目。
  • 被指派人只看到任务和明确分享的关联对象。
  • PostgreSQL 集成测试只使用显式 DATABASE_URL 指向的隔离测试库。

文档一致性检查

已完成以下一致性检查:两份文档中的旧品牌、旧 API 前缀、旧前端目录和旧技术栈关键词扫描无匹配Markdown 相对链接均指向现有文件;命令使用的工作目录、入口和脚本均与仓库实际路径一致。