Skip to content

编码规范

本文档定义 AI 编程时必须遵守的编码规范。

TypeScript / NestJS 规范

类型严格要求

  • tsconfig.json 必须开启 strict: true
  • 禁止使用 any 类型(ESLint: @typescript-eslint/no-explicit-any: error
  • 所有函数必须声明参数类型和返回值类型
  • DTO 必须使用 class-validator 装饰器校验
  • Service 方法返回值必须明确类型,禁止返回 any 或隐式类型
typescript
// ✅ 正确
async createUser(dto: CreateUserDto): Promise<User> {
  return this.prisma.user.create({ data: dto });
}

// ❌ 错误
async createUser(dto: any): Promise<any> {
  return this.prisma.user.create({ data: dto });
}

测试要求

  • 每个 Service 方法 必须 编写对应的单元测试(.spec.ts
  • Controller 必须 有 E2E 测试覆盖核心 CRUD 路径
  • 新建模块时,<module>.service.spec.ts 必须与 Service 同步提交
  • 测试覆盖率目标:Service ≥ 80%,Controller ≥ 60%
typescript
// 每个 PR 必须包含对应的测试文件:
// src/modules/device/device.service.ts       ← 实现
// src/modules/device/device.service.spec.ts  ← 必须存在

命名约定

类型规范示例
文件名kebab-caseuser.service.ts, auth.controller.ts
类名PascalCaseUserService, AuthController
方法/变量camelCasegetUserInfo(), accessToken
常量UPPER_SNAKE_CASEJWT_SECRET, REDIS_KEY_PREFIX
接口PascalCase, I 前缀可选UserInfo, LoginRequest
类型PascalCasePageResult<T>, ApiResponse

模块结构

src/modules/<module-name>/
├── <module>.module.ts      # 模块定义
├── <module>.controller.ts  # 控制器(路由)
├── <module>.service.ts     # 业务逻辑
├── <module>.service.spec.ts # 单元测试
└── dto/                    # 请求/响应 DTO
    ├── create-<entity>.dto.ts
    └── update-<entity>.dto.ts

装饰器使用

typescript
// Controller 示例
@Controller('users')
@ApiTags('用户管理')
@UseGuards(AuthGuard('jwt'), RolesGuard)
@ApiBearerAuth()
export class UserController {
  @Get()
  @ApiOperation({ summary: '获取用户列表' })
  @Roles('admin')
  async findAll(@Query() query: PageQueryDto) {}
}

错误处理

typescript
// 使用 NestJS 内置异常
throw new BadRequestException('参数错误');
throw new UnauthorizedException('未登录');
throw new ForbiddenException('无权限');
throw new NotFoundException('资源不存在');

Vue 3 规范

组件命名

类型规范示例
页面组件kebab-case 目录views/system/user/index.vue
通用组件PascalCaseUserTable.vue, SearchForm.vue
布局组件PascalCaseDefaultLayout.vue

Composition API 风格

vue
<script setup lang="ts">
import { ref, computed, onMounted } from 'vue'

const loading = ref(false)
const dataList = ref([])

const filteredList = computed(() => {
  return dataList.value.filter(item => item.status === 1)
})

onMounted(async () => {
  await fetchData()
})
</script>

Pinia Store 规范

typescript
// Setup Store 风格(推荐)
export const useUserStore = defineStore('user', () => {
  const userInfo = ref<UserInfo>({} as UserInfo)
  const isLoggedIn = computed(() => !!userInfo.value.id)

  async function login(data: LoginRequest) {
    const res = await AuthAPI.login(data)
    setAccessToken(res.data.accessToken)
  }

  return { userInfo, isLoggedIn, login }
})

数据库规范

表命名

  • 表名:snake_case,单数形式
  • Prisma model 名:PascalCase,单数形式
  • 字段名:camelCase,数据库映射为 snake_case
prisma
model User {
  id          String   @id @map("user_id")
  createdTime DateTime @default(now()) @map("created_time")
  @@map("user")
}

C / ESP-IDF 编码规范

命名约定

类型规范示例
组件名snake_casesc8co2, ws2812_led
源文件snake_casesc8co2.c, ws2812_led.h
函数名snake_case,组件前缀sc8co2_init(), ws2812_led_set_color()
宏/常量UPPER_SNAKE_CASE,组件前缀SC8CO2_UART_PORT, LED_GPIO
结构体snake_case,_t 后缀sc8co2_handle_t
全局变量snake_casei2c_bus, led_strip
FreeRTOS 任务snake_case,_task 后缀sensor_task

组件结构

components/<component-name>/
├── CMakeLists.txt           # idf_component_register
├── <component>.c            # 实现
├── include/
│   └── <component>.h        # 公开 API
└── idf_component.yml        # 组件注册表依赖(可选)

日志规范

c
#include "esp_log.h"

static const char *TAG = "COMPONENT";

ESP_LOGI(TAG, "初始化完成");     // 信息
ESP_LOGW(TAG, "响应超时 %dms", timeout);  // 警告
ESP_LOGE(TAG, "I2C 读取失败: %s", esp_err_to_name(ret));  // 错误

错误处理

c
// 函数返回 esp_err_t,调用方检查返回值
esp_err_t ret = aht20_read_data(handle, &temp, &humi);
if (ret != ESP_OK) {
    ESP_LOGE(TAG, "AHT20 读取失败");
    return ret;
}

// 指针参数有效性检查
if (!handle || !co2_value) {
    return ESP_ERR_INVALID_ARG;
}

传感器故障约定

所有传感器数据获取失败时,对应值设为 -999(float)或 -999.0,便于上层统一判断数据有效性。

Git 提交规范

bash
<type>: <简短描述>

# type 可选:
# feat     新功能
# fix      修复
# docs     文档
# refactor 重构
# test     测试
# chore    构建/工具

示例:

feat: 添加设备注册接口
fix: 修复 MQTT 重连问题
docs: 更新 API 接口规范

API 响应格式

typescript
// 成功响应
{ code: '00000', msg: 'Success', data: {...} }

// 分页响应
{ code: '00000', msg: 'Success', data: { list: [...], total: 100 } }

// 错误响应
{ code: 'A0001', msg: '参数错误' }

日志规范

typescript
// 使用 NestJS Logger
private readonly logger = new Logger(UserService.name);

this.logger.log(`用户 ${userId} 登录成功`);
this.logger.warn(`设备 ${deviceId} 离线`);
this.logger.error(`MQTT 连接失败: ${err.message}`, err.stack);
this.logger.debug(`查询参数: ${JSON.stringify(query)}`);