项目开发规范蒸馏:三层架构与完成定义
作者 1233 阅读1 次浏览
本文目录
name: repo-dev-conventions description: 从 Terra-Wiki 蒸馏的通用开发规范:请求链路分层、统一业务错误类型、"完成的定义"与前端主题约束,适用于全栈 Web 项目
项目开发规范蒸馏:三层架构与完成定义
适用时机
- 给全栈 Web 项目立规矩:请求链路怎么走、错误怎么抛、什么算"做完了"。
- 接手一个分层混乱、错误结构散落各处的代码库,需要一份可落地的重构方向。
- 搭新项目骨架时照抄,即可获得一套完整的工程约束。
规范条目
分层与职责
- 请求链路固定三层,职责不许越界:接口层只做「解析参数(schema 校验)→ 调服务层 → 把业务错误映射成 HTTP 响应」;服务层承载业务规则、校验、生成逻辑,只抛业务错误,不感知 HTTP;数据层收拢全部 SQL,业务代码不直接拼查询。
- 业务错误全站只用一个类型(如
DomainError),错误码取受限枚举:not_found / conflict / forbidden / invalid / unauthorized。错误类型一多,接口层的映射就会漏,前端拿到的形状开始漂移。 - HTTP 响应统一形状
{ ok: boolean, message?: string, ...数据 },错误码用真实 HTTP status,不散落自定义错误结构。 - 写接口优先用框架的服务端动作(如 Server Actions);独立 Route Handler 只保留少数必要场景(认证、机器对机器端点、打点)。新增公开 API 前先问:服务端动作够不够用?
- 同一段业务错误文案只定义一处,Web 界面与 API/工具端共同引用。文案写两遍,改一处漏一处,不同入口就会提示不一致。
完成的定义
- 任务"完成"的唯一定义:类型检查与测试全过。测试连独立测试库,不打扰开发库。
- 包管理器锁定一种并写进
package.json的版本字段,禁止混用——锁文件冲突比锁死工具烦得多。 - 仓库没有 linter 就不要在 CI 加 lint(必挂);有 linter 则 lint 必须进 CI。
前端与样式
- 主题变量集中在一个全局 CSS 的 theme 块定义,禁用会把颜色内联进工具类、不输出 CSS 变量的模式(如
@theme inline)——它会让.dark覆盖整个失效,主题切换悄悄坏掉且极难排查。 - 深色模式只写
.dark下的变量覆盖;新颜色必须同时给浅色、深色两套值,组件里只用语义类(text-ink/bg-paper),不写裸色值。 - 深色不是把浅色反色:代码窗格等特殊容器的底色、标题栏、按钮走独立变量组,文字色必须与底色同明暗,不许深字压深底。
- 组件默认服务端组件,
'use client'只给真需要交互的小件;通用原语、页面布局件、文章内件分目录放置。 - 界面文案不写死在组件里,一律走字典文件;服务端用运行时取 locale 的函数,客户端组件引用常量与类型。
- 正文排版集中在一个类(如
.prose)维护,改排版只动全局 CSS,不在组件里散写。
陷阱与例外
- "变量没输出"类样式问题先怀疑 theme 内联模式,再查别的。
- 本地容器端口可能被宿主工具劫持转发,"迁移成功但没建表"时先确认端口实际落在哪个容器。
- 需要自举初始管理员的,用环境变量驱动的启动钩子,不写死账号。
项目特有约定(不可迁移)
- 技术栈 Next.js (App Router) + React 19 + Tailwind v4 + Drizzle + PostgreSQL;MCP 接入、文章路径解析是本项目的领域逻辑。
- 提交 scope 取值列表来自本仓库模块划分,新项目按自己的模块表重定。
验证方式
- typecheck + test 全过即"完成的定义"。
- 切换主题后检查新颜色是否两套模式都有值、代码窗格是否同明暗。