跳转到内容
天空之翼
选择 · Enter跳转 · Esc关闭 由 Pagefind 提供索引
EN

开发指南

本地环境搭建、测试、代码规范与常见坑点。

先安装以下工具。

工具版本用途
Node.js22 及以上构建工具链的运行时
bun1.3 及以上workers/frontend/ 的包管理器(packageManager: bun@1.3.14)
wrangler4 及以上Cloudflare Workers 命令行工具,用于本地调试 API

如果还没装 bun:

curl -fsSL https://bun.sh/install | bash

项目统一使用 bun,不要混入 npm、pnpm 或 yarn 的锁文件。

准备两个终端。第一个安装 API 依赖,第二个安装前端依赖:

cd workers && bun install
cd ../frontend && bun install

复制示例文件,再改掉本地开发需要的值:

cp workers/.dev.vars.example workers/.dev.vars

至少把 JWT_SECRETENCRYPTION_KEY 换成独立的值。文件里已带好 SMTP、Turnstile、初始管理员等配置的开发默认值。

对本地 D1 数据库执行迁移:

cd workers
bunx wrangler d1 migrations apply picumet-db --local

该命令会按顺序应用 workers/migrations/ 下所有待执行的迁移。新迁移文件按 NNNN_description.sql 命名,保证执行顺序稳定。

workers/ 目录启动 Workers API:

cd workers && bun run dev

API 监听在 http://localhost:8787

在第二个终端进入 frontend/ 启动前端开发服务器:

cd frontend && bun run dev

前端监听在 http://localhost:5173。Vite 会把 /api/*/webdav/* 代理到 http://localhost:8787,本地不需要配置 CORS。

打开下面的地址:

  • 前端:http://localhost:5173
  • API:http://localhost:8787

首次启动时,workers/src/seed.ts 会创建默认管理员、演示用户、默认 R2 Provider 和根挂载点,并生成演示文件夹。种子只在 KV 键 seed:done 未设置时执行一次。

开发种子账号:

角色用户名密码
管理员adminadmin123456
演示用户demodemo123456

开发密码可用 .dev.vars 里的 ADMIN_PASSWORDDEMO_PASSWORD 覆盖。生产环境必须提供强 ADMIN_PASSWORD;没有它时,种子不会创建管理员,业务 API 会一直返回 503,直到初始化完成。

以下命令都在各自包目录下执行。

任务命令目录
后端测试bun run testworkers/
后端类型检查bun run typecheckworkers/
前端测试bun run testfrontend/
前端覆盖率门禁bun run test:coveragefrontend/
前端类型检查bun run typecheckfrontend/
前端构建bun run buildfrontend/

后端测试共 127 个用例,跑在内存版 node:sqlite 模拟的 D1/KV/R2 上(见 tests/helpers.ts),不依赖 workerd。前端有 7 个用例,外加覆盖率门禁,聚焦安全关键模块 src/lib/escape.tssrc/pages/Register.tsx(lines 80%、functions 60%、branches 40%)。

.github/workflows/ci.yml 在推送到 main 或发起 PR 时运行。workers job 执行安装、类型检查和测试;frontend job 在此基础上增加覆盖率门禁和生产构建。CI 只做质量门禁,不自动部署,发布统一手动执行 wrangler deploy

按下面的约定写代码,保持前后一致。

  • 文件:kebab-case
  • React 组件:PascalCase
  • 函数和变量:camelCase
  • 常量:UPPER_SNAKE_CASE
  • 类型和接口:PascalCase

外部库在前,其次是 Cloudflare 绑定,然后是项目内部模块,类型导入放最后。

  • 保持 strict 开启。
  • 尽量避免 any;确需使用时要加注释说明原因。
  • 每个函数都要显式标注返回类型。
  • 改过类型后,在两个包分别跑 bun run typecheck

改动下面这些模块时,必须补上对应的测试。

services/permissions/check.ts 里的权限判定按优先级依次检查:管理员特权、挂载边界、用户根路径、API 密钥权限范围、路径规则、所有者回退、默认拒绝。测试要锁死路径段边界:/users/alice 绝不能匹配 /users/alice2。规则优先级、通配符模式和默认拒绝也要有用例。

上传会话按 pending → uploading → verifying → completed 流转,终态包括 failedexpiredaborted。分片上传还会经过 parts_uploadedcompleting。要覆盖断点续传、中止,以及按分片覆盖度和最终 HEAD 大小做完成校验的逻辑。

配额更新必须原子。测试并发上传不会突破限额,删除和中止路径恰好释放一次预留。用原子的 UPDATE,不要用「读取-修改-写回」的序列。

改过认证、上传或存储后,重跑安全回归套件:自由模式凭据处理、WebDAV 鉴权、SSRF 校验、加密、限流 fail-closed、一次性下载令牌消费。

使用 Conventional Commits:type(scope): subject。正文用多个 -m 参数,每个参数一条要点。

git commit -m "feat(upload): add multipart upload support for large files" \
-m "- 实现分片会话 API 与断点续传契约" \
-m "- 服务端记录分片 ETag 用于完成校验"
git commit -m "fix(permission): 修复规则匹配的路径边界绕过" \
-m "- 用 isPathWithinBoundary 替换 startsWith" \
-m "- 补充 /users/alice 与 /users/alice2 的边界测试"

提交信息用英文或中文都可以。类型与 scope 的取值如下。

类型含义
feat新功能
fix缺陷修复
docs仅文档改动
style格式化,行为不变
refactor重构,行为不变
perf性能优化
test测试增改
chore维护性改动
Scope范围
auth认证与会话
permission权限算法与规则
storage存储 Provider
upload上传与分片流程
download下载网关与令牌
ui前端组件与页面
apiAPI 路由与 schema
db迁移与数据仓库

提交前对照这份清单逐项检查。

  • 功能在真实 UI 或 API 上端到端跑通。
  • 边界条件和错误路径的行为与文档一致。
  • strict 类型检查通过,没有未说明的 any
  • 命名和导入顺序符合上面的约定。
  • 没有死代码、残留的调试输出或注释掉的代码块。
  • 新行为有对应测试,且测试能在可复现的回归上失败。
  • 两个包都通过 bun run testbun run typecheck
  • 权限检查基于规范化后的路径。
  • 对象存储密钥与凭据不落到客户端或日志。
  • fail-closed 路径保持关闭:限流、自由模式、SSRF。
  • 数据库写入用原子语句,配额不做读改写。
  • 热点请求路径避免无谓的分配与拷贝。
  • 新增或改动端点时,同步更新 docs/API.md
  • 规范或结构变化时,更新本文档与 docs/ARCHITECTURE.md

isPathWithinBoundary,别用 startsWith

Section titled “用 isPathWithinBoundary,别用 startsWith”

startsWith 按字符串前缀比较,/users/alice 能匹配到 /users/alice2utils/path.tsisPathWithinBoundary 按路径段比较,不会有这个问题。

先在一个事务里删除数据库元数据,之后异步清理对象存储;清理失败的对象记入 orphan_objects,交给对账任务处理。先删对象再删元数据的话,元数据删除一旦失败,对象就丢了。

不要「读取配额 → 修改 → 写回」,并发场景下会竞态。直接用一条 UPDATE user_quotas SET used_storage = used_storage + ? ...

权限检查前对每个入站路径调用 normalizePath,/users/../admin/secrets 会归一到 /admin/secrets,无法绕过规则。

Workers API 的热重载不可靠。改了 workers/ 源码后重启进程;保险起见删掉 .wrangler 再重跑迁移,从干净状态起步。

代码库按依赖顺序分阶段构建,后一阶段依赖前一阶段,每阶段验收标准全部通过才算完成。

阶段内容依赖
0环境搭建
1认证系统0
2核心权限系统1
3对象存储连接(R2)2
4基础文件管理3
5配额管理4
6移动与重命名5
7密码保护与分享6
8API 密钥与 WebDAV7
9高级 UI8
10外观定制与国际化9
11管理员功能10
12安全加固11
13分片上传12
14扩展存储源(S3/Oracle)13
15自由模式14
16测试与部署15

这条顺序上的关键里程碑:

  • M1(阶段 4):可用的文件管理系统
  • M2(阶段 8):完整的 API 与分享能力
  • M3(阶段 11):多用户生产系统
  • M4(阶段 15):全功能版本
  • M5(阶段 16):正式发布

后续规划新功能时,可以按这张表判断前置依赖。