Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 89cc7d9152 | |||
| 6a5006077b | |||
| ea4f4d41c8 | |||
| fb3962accd | |||
| f6f87e0c47 | |||
| 74e796fe61 | |||
| a6ee653388 | |||
| 1f2abc7507 | |||
| 30ec00df9e | |||
| 01049bc24a |
@@ -1,3 +1,126 @@
|
|||||||
# Review Spec
|
# Code Spec
|
||||||
|
|
||||||
该仓库是小管家代码规范仓库,规范是基于 Gitea Flows Review Spec 协议编写。
|
该仓库是小管家代码规范仓库,规范基于 spaceflow [Review Spec](https://lydanne.github.io/spaceflow/reference/review-spec.html) 协议编写。
|
||||||
|
|
||||||
|
|
||||||
|
## 目标
|
||||||
|
|
||||||
|
- 统一 JS/TS、NestJS、Mongoose Model、Vue 的代码风格与结构约束。
|
||||||
|
- 提供可执行、可审查、可扩展的规则定义(含规则 ID、Good/Bad 示例、覆盖关系)。
|
||||||
|
- 为自动化 Review 与人工 Code Review 提供统一判断标准。
|
||||||
|
|
||||||
|
## 目录结构
|
||||||
|
|
||||||
|
```txt
|
||||||
|
.
|
||||||
|
├── README.md
|
||||||
|
└── references/
|
||||||
|
├── js&ts.base.md
|
||||||
|
├── js&ts.file-name.md
|
||||||
|
├── js&ts.nest.md
|
||||||
|
├── js&ts.test-code.md
|
||||||
|
├── js.models.md
|
||||||
|
├── vue.base.md
|
||||||
|
└── vue.file-name.md
|
||||||
|
```
|
||||||
|
|
||||||
|
## 接入步骤(`.spaceflowrc`)
|
||||||
|
|
||||||
|
1. 在业务仓库根目录创建或修改 `.spaceflowrc`。
|
||||||
|
2. 在 `review.references` 中引入本仓库 `references` 地址。
|
||||||
|
3. 根据项目需要配置 `includes`、注释策略和重试策略。
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"review": {
|
||||||
|
"references": ["https://git.bjxgj.com/xgj-pub/code-spec/src/branch/main/references"],
|
||||||
|
"includes": [
|
||||||
|
"**/*.ts",
|
||||||
|
"**/*.js",
|
||||||
|
"!nest-src/errcode.ts",
|
||||||
|
"!nest-src/libs/entity/**",
|
||||||
|
"!**/dist/**",
|
||||||
|
"!**/*.spec.*",
|
||||||
|
"!**/*.config.*"
|
||||||
|
],
|
||||||
|
"generateDescription": true,
|
||||||
|
"lineComments": true,
|
||||||
|
"verifyFixes": true,
|
||||||
|
"autoUpdatePrTitle": true,
|
||||||
|
"analyzeDeletions": false,
|
||||||
|
"deletionAnalysisMode": "open-code",
|
||||||
|
"concurrency": 1,
|
||||||
|
"retries": 3,
|
||||||
|
"retryDelay": 1000
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> 说明:如果你的 `.spaceflowrc` 已有其他配置,请仅合并 `review` 字段,不要覆盖现有配置。
|
||||||
|
|
||||||
|
### MCP 配置(spaceflow)
|
||||||
|
|
||||||
|
如果你需要在支持 MCP 的客户端中接入 spaceflow,可加入以下配置:
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"mcpServers": {
|
||||||
|
"spaceflow": {
|
||||||
|
"args": [
|
||||||
|
"-y",
|
||||||
|
"@spaceflow/cli",
|
||||||
|
"mcp"
|
||||||
|
],
|
||||||
|
"command": "npx",
|
||||||
|
"disabled": false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
然后我们就可以使用这样的提示词让AI去拉规则了.
|
||||||
|
|
||||||
|
```
|
||||||
|
请使用 spaceflow 工具去 review 代码。
|
||||||
|
```
|
||||||
|
|
||||||
|
## 规范索引
|
||||||
|
|
||||||
|
| 规范集 | 规则 ID 前缀 | 作用范围(includes) | 说明 |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| JS/TS 基础规范 | `JsTs.Base` | 通用 JS/TS 文件 | 命名、复杂度、行数、魔法值等基础约束 |
|
||||||
|
| JS/TS 文件命名规范 | `JsTs.FileName` | 通用 JS/TS 文件 | class/interface 与函数文件命名规则 |
|
||||||
|
| NestJS 规范 | `JsTs.Nest` | `*.controller.ts` `*.service.ts` `*.module.ts` `*.dto.ts` `*.pipe.ts` `*.guard.ts` `*.interceptor.ts` `*.filter.ts` `*.exception-filter.ts` `*.proxy.ts` `*.model.ts` | 目录结构、分层职责、文件命名与模块组织 |
|
||||||
|
| 测试代码规范 | `JsTs.TestCode` | 测试文件(`.test.js` `.test.ts` `.spec.ts`) | 测试文件命名与 `describe/it` 结构约束 |
|
||||||
|
| Mongoose Model 规范 | `Js.Model` | `*/models/*.js` | schema 字段、索引、钩子、方法、引用关系等 |
|
||||||
|
| Vue 基础规范 | `Vue.Base` | `*.vue` | 自定义组件命名规范 |
|
||||||
|
| Vue 文件命名规范 | `Vue.FileName` | `*.vue` | 组件文件命名规范 |
|
||||||
|
|
||||||
|
## 规则覆盖关系(override)
|
||||||
|
|
||||||
|
当多个规范同时命中同一文件时,按以下覆盖关系处理冲突:
|
||||||
|
|
||||||
|
1. `JsTs.Nest` 覆盖 `JsTs.FileName`。
|
||||||
|
2. `JsTs.Nest.DtoDefinition` 对 `JsTs.Base.NoMagicStringsAndNumbers` 做规则级覆盖。
|
||||||
|
3. `Js.Model` 覆盖 `JsTs.Base`。
|
||||||
|
4. `Js.Model.FileName` 覆盖 `JsTs.FileName`。
|
||||||
|
|
||||||
|
> 建议:在实现自动化检查时,先按 `includes` 过滤命中文件,再按 `override` 解析最终生效规则。
|
||||||
|
|
||||||
|
## 使用建议
|
||||||
|
|
||||||
|
1. **按文件类型匹配规范集**:先判断文件路径与后缀,再应用对应规则。
|
||||||
|
2. **输出规则 ID**:Review 结果中保留规则 ID(如 `JsTs.Base.FuncLowerCamel`),便于追踪和整改。
|
||||||
|
3. **先基础后专项**:优先接入 `JsTs.Base` 与 `JsTs.FileName`,再逐步接入 Nest / Model / Vue / Test 专项规则。
|
||||||
|
4. **保持示例驱动**:新增规则时提供清晰的 Good/Bad 示例,降低理解成本。
|
||||||
|
|
||||||
|
## 维护约定
|
||||||
|
|
||||||
|
新增或修改规则时建议遵循以下格式:
|
||||||
|
|
||||||
|
- 一级标题:规范名称 + 规则前缀(如 ``[JsTs.Base]``)
|
||||||
|
- 二级标题:单条规则描述 + 完整规则 ID(如 ``[JsTs.Base.ConstUpperCase]``)
|
||||||
|
- 元信息:`includes` / `override` / `severity`(如适用)
|
||||||
|
- 示例:必须包含 `Good` 与 `Bad`
|
||||||
|
|
||||||
|
这样可以保证规则文档在人工阅读和自动化解析两种场景下都保持一致性。
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
---
|
---
|
||||||
name: 代码规范技能
|
name: code-review
|
||||||
description: 当用户要求重构、审查或编写代码时,请参考此规范。
|
description: 当用户要求重构、审查或编写代码时,请参考此规范。
|
||||||
metadata:
|
metadata:
|
||||||
spaceflow: true
|
spaceflow: true
|
||||||
@@ -7,26 +7,26 @@ metadata:
|
|||||||
|
|
||||||
## 功能
|
## 功能
|
||||||
|
|
||||||
- 自动同步最新的代码规范
|
- 检查代码是否符合规范
|
||||||
- 自动检查代码是否符合规范
|
|
||||||
- 自动修复代码
|
|
||||||
|
|
||||||
## 代码规范
|
|
||||||
|
|
||||||
在 references 目录下
|
|
||||||
|
|
||||||
## 命令
|
## 命令
|
||||||
|
|
||||||
### 同步最新代码规范
|
### 同步最新代码规范
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npx spaceflow install
|
pnpm spaceflow install
|
||||||
|
```
|
||||||
|
|
||||||
|
### 审查当前未提交的代码
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pnpm spaceflow review
|
||||||
```
|
```
|
||||||
|
|
||||||
### 审查一个文件
|
### 审查一个文件
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npx spaceflow review -b main --head develop -f $CODE_PATH
|
pnpm spaceflow review -b main --head develop -f $CODE_PATH
|
||||||
```
|
```
|
||||||
|
|
||||||
- `$CODE_PATH`:需要检查的文件路径
|
- `$CODE_PATH`:需要检查的文件路径
|
||||||
@@ -36,7 +36,7 @@ npx spaceflow review -b main --head develop -f $CODE_PATH
|
|||||||
### 审查一个Commit
|
### 审查一个Commit
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npx spaceflow review -b main --head develop --commits $COMMIT_ID
|
pnpm spaceflow review -b main --head develop --commits $COMMIT_ID
|
||||||
```
|
```
|
||||||
|
|
||||||
- `$COMMIT_ID`:需要检查的Commit ID,可以是多个空格隔开
|
- `$COMMIT_ID`:需要检查的Commit ID,可以是多个空格隔开
|
||||||
@@ -46,7 +46,7 @@ npx spaceflow review -b main --head develop --commits $COMMIT_ID
|
|||||||
### 审查两个分支的差异代码
|
### 审查两个分支的差异代码
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
npx spaceflow review -b main --head develop
|
pnpm spaceflow review -b main --head develop
|
||||||
```
|
```
|
||||||
|
|
||||||
- `-b main`:指定基准分支
|
- `-b main`:指定基准分支
|
||||||
@@ -54,6 +54,10 @@ npx spaceflow review -b main --head develop
|
|||||||
|
|
||||||
## 使用场景
|
## 使用场景
|
||||||
|
|
||||||
|
### 当用户要求审查当前代码
|
||||||
|
|
||||||
|
首先需要同步最新的代码规范,然后直接执行上面的命令。
|
||||||
|
|
||||||
### 当用户要求审查代码时
|
### 当用户要求审查代码时
|
||||||
|
|
||||||
首先需要同步最新的代码规范,然后用户有没有指定审查的文件路径,如果有则审查文件,否则审查两个分支的差异代码。
|
首先需要同步最新的代码规范,然后用户有没有指定审查的文件路径,如果有则审查文件,否则审查两个分支的差异代码。
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
## 常量名使用大写加下划线命名(UPPER_CASE),单词间以下划线分隔 `[JsTs.Base.ConstUpperCase]`
|
## 常量名使用大写加下划线命名(UPPER_CASE),单词间以下划线分隔 `[JsTs.Base.ConstUpperCase]`
|
||||||
|
|
||||||
- 不检查 nodejs 的导包定义,比如 `const fs = require("fs")`
|
- 不检查 nodejs 的导包定义,比如 `const fs = require("fs")`
|
||||||
|
- 常量检查只需检查 `const` 声明的静态值,但是不包含对象和函数
|
||||||
|
|
||||||
### Good
|
### Good
|
||||||
|
|
||||||
@@ -20,6 +21,8 @@ const maxCount = 100;
|
|||||||
|
|
||||||
## 函数名使用小驼峰命名 `[JsTs.Base.FuncLowerCamel]`
|
## 函数名使用小驼峰命名 `[JsTs.Base.FuncLowerCamel]`
|
||||||
|
|
||||||
|
> - severity `warn`
|
||||||
|
|
||||||
### Good
|
### Good
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
@@ -38,7 +41,10 @@ function getuserinfo() {
|
|||||||
|
|
||||||
## 禁止使用字面量魔法字符串和魔法数字 `[JsTs.Base.NoMagicStringsAndNumbers]`
|
## 禁止使用字面量魔法字符串和魔法数字 `[JsTs.Base.NoMagicStringsAndNumbers]`
|
||||||
|
|
||||||
- 只检查数字字面量和字符串字面量,不要检查其他(比如 布尔字面量)
|
> - severity `warn`
|
||||||
|
|
||||||
|
- 只检查数字、字符串、正则字面量,不要检查其他(比如 布尔字面量、对象字面量、函数字面量、数组字面量)
|
||||||
|
- 这块只检查含义不明确的字面量,比如 0 1 500 等,像是 'user' 'admin' 'active' 'inactive' 等是合理的
|
||||||
- 无需检查单词是否完整拼写
|
- 无需检查单词是否完整拼写
|
||||||
- throw 的错误信息无需审查
|
- throw 的错误信息无需审查
|
||||||
- new Error 的错误信息无需审查
|
- new Error 的错误信息无需审查
|
||||||
@@ -54,10 +60,6 @@ function getuserinfo() {
|
|||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
const MAX_COUNT = 100;
|
const MAX_COUNT = 100;
|
||||||
const USER_STATUS = {
|
|
||||||
ACTIVE: "active",
|
|
||||||
INACTIVE: "inactive",
|
|
||||||
};
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Bad
|
### Bad
|
||||||
@@ -67,8 +69,30 @@ const maxCount = 100;
|
|||||||
const userStatus = "active";
|
const userStatus = "active";
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## 基于 JsTs.Base.NoMagicStringsAndNumbers 抽离的静态常量需要放在对应文件里 `[JsTs.Base.ConstantsDefinition]`
|
||||||
|
|
||||||
|
> - severity `warn`
|
||||||
|
|
||||||
|
- 需要放在指定模块的 constants 文件里
|
||||||
|
|
||||||
|
### Good
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// user.constants.js
|
||||||
|
const MAX_COUNT = 100; // 这是 user 模块需要的
|
||||||
|
```
|
||||||
|
|
||||||
|
### Bad
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// class.constants.js
|
||||||
|
const MAX_COUNT = 100; // 这是 user 模块需要的
|
||||||
|
```
|
||||||
|
|
||||||
## class 和 interface 命名使用大驼峰命名 `[JsTs.Base.ClassUpperCamel]`
|
## class 和 interface 命名使用大驼峰命名 `[JsTs.Base.ClassUpperCamel]`
|
||||||
|
|
||||||
|
> - severity `warn`
|
||||||
|
|
||||||
### Good
|
### Good
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
@@ -87,6 +111,10 @@ class userinfo {
|
|||||||
|
|
||||||
## 变量名使用小驼峰命名 `[JsTs.Base.VarLowerCamel]`
|
## 变量名使用小驼峰命名 `[JsTs.Base.VarLowerCamel]`
|
||||||
|
|
||||||
|
> - severity `warn`
|
||||||
|
|
||||||
|
- 需要注意的是从 require 导入的变量不受检查
|
||||||
|
|
||||||
### Good
|
### Good
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
@@ -130,3 +158,49 @@ function getUserInfo() {
|
|||||||
// ... 大于 200
|
// ... 大于 200
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## 复杂的逻辑判断要添加注释 `[JsTs.Base.ComplexLogic]`
|
||||||
|
|
||||||
|
> - severity `warn`
|
||||||
|
|
||||||
|
- 逻辑判断的复杂度超过 2 个的要添加注释
|
||||||
|
|
||||||
|
### Good
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// 逻辑判断复杂度超过 2 个
|
||||||
|
if (a && b || c) {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Bad
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
if (a && b && c && d) {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## 复杂的函数要添加注释 `[JsTs.Base.ComplexFunc]`
|
||||||
|
|
||||||
|
> - severity `warn`
|
||||||
|
|
||||||
|
### Good
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
/**
|
||||||
|
* 复杂的算法逻辑
|
||||||
|
*/
|
||||||
|
function complexFunc() {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Bad
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
function complexFunc() {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Nestjs 项目下的规范 `[JsTs.Nest]`
|
# Nestjs 项目下的规范 `[JsTs.Nest]`
|
||||||
|
|
||||||
> - includes `*.controller.ts` `*.service.ts` `*.module.ts` `*.dto.ts` `*.pipe.ts` `*.guard.ts` `*.interceptor.ts` `*.filter.ts` `*.exception-filter.ts` `*.proxy.ts` `*.model.ts`
|
> - includes `*.controller.ts` `*.service.ts` `*.module.ts` `*.dto.ts` `*.pipe.ts` `*.guard.ts` `*.interceptor.ts` `*.filter.ts` `*.exception-filter.ts` `*.proxy.ts` `*.model.ts` `*.constants.ts`
|
||||||
> - override `[JsTs.FileName]`
|
> - override `[JsTs.FileName]`
|
||||||
|
|
||||||
## 目录框架规范 `[JsTs.Nest.DirStructure]`
|
## 目录框架规范 `[JsTs.Nest.DirStructure]`
|
||||||
@@ -61,6 +61,7 @@ src/
|
|||||||
- 该文件不能写业务逻辑,只能写调用 service 的代码
|
- 该文件不能写业务逻辑,只能写调用 service 的代码
|
||||||
- 文件名使用小写加横线命名(如 `user-extends.controller.ts`)
|
- 文件名使用小写加横线命名(如 `user-extends.controller.ts`)
|
||||||
- 文件名必须加 `.controller.ts` 后缀
|
- 文件名必须加 `.controller.ts` 后缀
|
||||||
|
- 注解和装饰器上的静态值无需进行魔法值的提炼 `[JsTs.Base.NoMagicStringsAndNumbers]`
|
||||||
|
|
||||||
### Good
|
### Good
|
||||||
|
|
||||||
@@ -113,6 +114,8 @@ userModule.ts
|
|||||||
|
|
||||||
## Dto 命名规范 `[JsTs.Nest.DtoDefinition]`
|
## Dto 命名规范 `[JsTs.Nest.DtoDefinition]`
|
||||||
|
|
||||||
|
> - override `[JsTs.Base.NoMagicStringsAndNumbers]`
|
||||||
|
|
||||||
- 文件名使用小写加横线命名(如 `user-extends.dto.ts`)
|
- 文件名使用小写加横线命名(如 `user-extends.dto.ts`)
|
||||||
- 文件名必须加 `.dto.ts` 后缀
|
- 文件名必须加 `.dto.ts` 后缀
|
||||||
- dto 目录下必须包含 `dto.ts` 文件
|
- dto 目录下必须包含 `dto.ts` 文件
|
||||||
@@ -178,6 +181,8 @@ export class UserProxy {
|
|||||||
|
|
||||||
## Model 编写规范 `[JsTs.Nest.ModelDefinition]`
|
## Model 编写规范 `[JsTs.Nest.ModelDefinition]`
|
||||||
|
|
||||||
|
> - includes `*.model.ts`
|
||||||
|
|
||||||
- 内部只能写使用 model 数据库调用的逻辑
|
- 内部只能写使用 model 数据库调用的逻辑
|
||||||
- 文件名使用小写加横线命名(如 `user.model.ts`)
|
- 文件名使用小写加横线命名(如 `user.model.ts`)
|
||||||
- 文件名必须加 `.model.ts` 后缀
|
- 文件名必须加 `.model.ts` 后缀
|
||||||
@@ -243,3 +248,24 @@ export class UserProxy {
|
|||||||
```typescript
|
```typescript
|
||||||
// proxy/user.js
|
// proxy/user.js
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## 基于 JsTs.Base.NoMagicStringsAndNumbers 抽离的静态常量需要放在对应文件里 `[JsTs.Nest.ConstantsDefinition]`
|
||||||
|
|
||||||
|
> - severity `warn`
|
||||||
|
> - override `[JsTs.Base.ConstantsDefinition]`
|
||||||
|
|
||||||
|
- 需要放在指定模块的 constants 文件里
|
||||||
|
|
||||||
|
### Good
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// user.constants.ts
|
||||||
|
const MAX_COUNT = 100; // 这是 user 模块需要的
|
||||||
|
```
|
||||||
|
|
||||||
|
### Bad
|
||||||
|
|
||||||
|
```typescript
|
||||||
|
// class.constants.ts
|
||||||
|
const MAX_COUNT = 100; // 这是 user 模块需要的
|
||||||
|
```
|
||||||
|
|||||||
@@ -1,9 +1,12 @@
|
|||||||
# mongoose 数据库模型 JS 规范 `[Js.Model]`
|
# mongoose 数据库模型 JS 规范 `[Js.Model]`
|
||||||
|
|
||||||
> - includes `models/*.js`
|
> - includes `*/models/*.js`
|
||||||
|
> - override `[JsTs.Base]`
|
||||||
|
|
||||||
## 模型文件命名规范 `[Js.Model.FileName]`
|
## 模型文件命名规范 `[Js.Model.FileName]`
|
||||||
|
|
||||||
|
> - override `[JsTs.FileName]`
|
||||||
|
|
||||||
- 文件名使用小写加下划线命名(如 `user_extends.js`),或者使用小写加横线命名(如 `user-extends.js`)
|
- 文件名使用小写加下划线命名(如 `user_extends.js`),或者使用小写加横线命名(如 `user-extends.js`)
|
||||||
- 文件名应与模型名称对应
|
- 文件名应与模型名称对应
|
||||||
|
|
||||||
@@ -61,7 +64,7 @@ const userSchema = new Schema({
|
|||||||
```javascript
|
```javascript
|
||||||
const userSchema = new Schema({
|
const userSchema = new Schema({
|
||||||
user_name: { type: String, required: true },
|
user_name: { type: String, required: true },
|
||||||
email: { type: String, required: true, unique: true },
|
email: { type: String, required: true },
|
||||||
age: { type: Number, default: 0 },
|
age: { type: Number, default: 0 },
|
||||||
status: { type: String, enum: ["active", "inactive"], default: "active" },
|
status: { type: String, enum: ["active", "inactive"], default: "active" },
|
||||||
created_at: { type: Date, default: Date.now },
|
created_at: { type: Date, default: Date.now },
|
||||||
|
|||||||
Reference in New Issue
Block a user