conventions.md 5.3 KB

conventions — 编码约定与硬性约束

本文件回答:文档与代码的组织规则、文档与代码的主从关系、以及本项目的硬性禁令清单。 依赖:无

本文件是给 opencode + DeepSeek 生成代码时的护栏。每次生成跑偏,就把对应的禁令追加到本文件,不另起新文件。

一、文档归属规则

文档按“约束谁”划分目录,不按“代码在哪”划分:

  • docs/backend/:只约束后端的文档
  • docs/frontend/:只约束前端的文档(含 TUI / Neovim 客户端)
  • docs/ 根:前后端共享的契约,或项目级文档

当前文件归属:

  • docs/overview.md — 项目定位、场景、非目标(项目级)
  • docs/architecture.md — 整体架构、目录结构、部署形态(项目级)
  • docs/conventions.md — 本文件(项目级)
  • docs/api.md — HTTP 接口契约,前后端共享,固定放根目录
  • docs/backend/data-model.md — 数据库 schema
  • docs/backend/auth.md — 鉴权与权限模型
  • docs/backend/audit.md — 审计日志
  • docs/backend/llm-extension.md — LLM 抽象层预留
  • docs/frontend/frontend.md — Web 前端页面与交互
  • docs/frontend/clients.md — TUI 与 Neovim 插件

新增文档时,先判断它约束谁,再决定放哪个目录。

二、文档与代码的主从关系

  1. docs/ 是唯一事实来源。所有代码由 opencode + DeepSeek 依据文档生成,不以代码反推文档。
  2. 代码与文档冲突时,以文档为准。生成结果不符合文档,是代码错,重新生成或修正代码,不修改文档去迁就代码。
  3. 改需求先改文档。任何功能变更、接口变更、数据模型变更,先落文档,再重新生成相关代码。
  4. 文档回答的问题必须唯一。同一个问题只在一个文件里回答;如果发现两处都在回答同一问题,合并到一处,另一处改为引用。
  5. 文档只能由人类修改。opencode / AI 只读取 docs/ 生成代码,不得写入或修改 docs/ 下任何文件。文档的增删改一律由项目维护者手动完成。

每个文档文件开头固定两行:

本文件回答:<一句话,这个问题只有本文件回答> 依赖:<前置文件,没有就写“无”>

三、目录边界

Haven/ ├── docs/ # 唯一事实来源 ├── backend/ # Go 后端,代码只写在这里 ├── frontend/ # Vue 前端,代码只写在这里 ├── deploy/ # 部署脚本(systemd unit、构建脚本等),如需要 └── README.md

  • 后端代码只写在 backend/ 下,前端代码只写在 frontend/ 下,不得交叉。
  • 生成后端代码时,上下文为 docs/ 根下项目级文件 + docs/backend/ + docs/api.md。
  • 生成前端代码时,上下文为 docs/ 根下项目级文件 + docs/frontend/ + docs/api.md。

四、硬性禁令清单

本清单只锁“不做什么”,不锁“具体怎么做”。具体实现方式以 architecture.md 为准。

以下事项本项目明确不做。opencode 生成代码时不得自行添加,发现即视为生成错误。

架构与部署

  • 不使用 Docker / Docker Compose 部署本项目。
  • 不使用 Kubernetes。
  • 原因备注:同机 Gogs 若跑在容器中会导致 SSH 失败;为避免同类问题,Haven 不使用容器。
  • 不引入 PostgreSQL 之外的存储作为真值源;Redis / 对象存储等如后续需要,只作为辅助,不存真值。
  • 不做多租户、不做多用户协作,本项目是单人自用。数据模型保留 user_id 归属字段,是为将来可能的第二个账号预留技术位;不代表本期要实现注册、邀请、账号管理等多人功能。所有接口仍按“当前登录用户”过滤,不提供账号创建入口。

前端

  • 不做 SSR / Nuxt / 预渲染,纯 Vue 3 + Vite SPA。
  • 不为 SEO 做任何专门优化。

后端 / 接口

  • 创建笔记接口不接受 visibility 参数,新建笔记一律为 private;公开走独立的 publish 动作。
  • visibility 的默认值在数据库层固化(DEFAULT 'private' + NOT NULL),不依赖应用层传值。
  • API Token 只做 read / read_write 两档 scope,不做细粒度权限。
  • 所有读接口统一走授权中间件做 visibility 收敛,不在各 handler 里各自判断。

客户端

  • TUI 与 Neovim 插件只覆盖“读写笔记 + 检索”主路径,不做功能对等,其余交给 Web。
  • 次级客户端以服务端为准,不做离线编辑与冲突合并(如后续要做,先改本文档再实现)。

LLM

  • 本期只定义 LLMProvider 接口,不实现任何 LLM 调用。
  • 抽象层不泄漏具体模型 SDK 到业务层。

审计

  • 前期只记录安全与状态事件(登录成功/失败、TOTP 验证、Token 创建/撤销、授信设备添加/撤销、笔记 publish)。
  • 笔记 CRUD 等高频业务事件前期不记录。

五、追加规则

  • 每次 opencode 生成结果出现“文档没写、但代码自作主张”的行为,由项目维护者(人类)判断是否合理:
    • 合理:补进对应文档,作为正式需求;
    • 不合理:追加到本文件第四节禁令清单。
  • 本文件第四节只增不删;确需解除禁令时,写明原因和日期。
  • AI / opencode 不得自行修改 docs/ 下任何文件,也不得自行向禁令清单追加条目。
苏ICP备2026082406号
苏公网安备 待审核