# ghb-base 开发规范（人工版）

> 给不用 AI 编码的开发者阅读。用 AI 写代码的看 `.claude/` 目录。

## 一、返回格式（不变式）

**所有接口必须用 `Result<T>` 包装：**

```java
// ✅ 正确
return Result.OK(data);
return Result.OK("操作成功", data);
return Result.error("参数错误");

// ❌ 禁止
return data;
return "success";
return Map.of(...);
```

**分页格式：** `{ code, message, data: { records, total, size, current } }`

**日期格式：** 统一 `yyyy-MM-dd HH:mm:ss`

**状态值：** 枚举中文值必须从 `contract/common/status-map.md` 取，不许硬编码前端文案同义替换（"已拒绝"="拒绝"之类）。

## 二、分层规则

```
controller/     — 参数校验 + 调用 service + 返回 Result，不许写业务逻辑
service/        — 业务逻辑，事务管理
mapper/         — SQL（MyBatis XML 或 @Select），不许写业务逻辑
entity/         — 表映射，纯数据对象
```

**禁止：Controller 超过 20 行、Controller 里有 if/else 嵌套、Service 里直接操作 HttpServletRequest**

## 三、命名规则

| 元素   | 规则               | 示例                                  |
| ------ | ------------------ | ------------------------------------- |
| 类名   | 大驼峰，名词       | `TaskController`，❌ `taskController` |
| 方法名 | 小驼峰，动词开头   | `getById()`，❌ `getbyid()`           |
| 变量   | 小驼峰，有意义     | `taskList`，❌ `list` `data`          |
| 包名   | 全小写             | `com.ghb.base.modules.business`       |
| 表名   | 小写，下划线，单数 | `task_apply`，❌ `TaskApply`          |
| 字段名 | 小写，下划线       | `create_time`，❌ `createdAt`         |
| 主键   | 统一 `id`          | ❌ `task_id`                          |
| 外键   | `关联表_id`        | `user_id`，❌ `uid`                   |
| 布尔   | `is_` 前缀         | `is_deleted`，❌ `deleted`            |

**长度控制：** 类名/表名超过 3 个单词或 30 字符必须缩写。缩写必须一眼能认出含义：

| 完整       | 缩写 |
| ---------- | ---- |
| department | dept |
| permission | perm |
| message    | msg  |
| enterprise | ent  |

## 四、字段类型

| 场景 | 类型                                 |
| ---- | ------------------------------------ |
| 金额 | `DECIMAL(15,2)`，❌ `FLOAT` `DOUBLE` |
| 时间 | `DATETIME`，❌ `VARCHAR` `TIMESTAMP` |
| 状态 | `VARCHAR(20)`，存英文枚举值          |
| 文本 | `VARCHAR(N)`（长度写死，不用 TEXT）  |

**必有字段：** 每张表必须包含 `id` `create_by` `create_time` `update_by` `update_time`。每个字段必须有 `COMMENT`。

## 五、索引规则

| 场景           | 索引            |
| -------------- | --------------- |
| 外键           | 必须建索引      |
| WHERE 高频字段 | 必须建索引      |
| 唯一约束       | `uk_表名_字段`  |
| 普通索引       | `idx_表名_字段` |

## 六、Git 规则

**分支：** `dev`（开发）/ `master`（生产）。新功能从 `dev` 拉，合回 `dev`。

**Commit 格式：**

```
<type>: <简短描述>

[AI: 模型名]
```

**Type：** feat / fix / refactor / docs / style / test / chore

**禁止：** `git push --force`、commit 只写 "update"、提交含硬编码密钥

## 七、安全规则

- 所有接口（除登录）必须验证 JWT Token
- 涉及租户数据的 SQL 必须带 `tenant_id` 条件
- 密码/密钥/Token 禁止硬编码、禁止 log 输出、禁止提交到 Git
- 文件上传限制大小（≤10MB）和类型（白名单）
- 用户输入必须做 XSS 过滤
- 日志不输出敏感信息（手机号脱敏 176\*\*\*\*2303）

## 八、编码规则

- 所有源文件：UTF-8 无 BOM
- 禁止 GBK/GB2312
- `ghb-backend/.editorconfig` 和 `ghb-frontend/.editorconfig` 各一个，不要覆盖
- **Windows 终端重定向（`>` `>>`）会按 GBK 写入，不要用**

## 九、测试规则

**必须写测试：**

- 新增 Service 方法 → 单元测试
- 新增 Controller 接口 → 集成测试
- 涉及金额计算 → 单元测试（多组边界值）
- 涉及状态流转 → 单元测试（覆盖所有路径）

**错误码：** 200 成功 / 400 参数错误 / 401 未登录 / 403 无权限 / 500 服务器异常

## 十、前端规则

**样式铁律：**

- 颜色禁硬编码（`color: #333` ❌），走主题变量
- 字号/间距禁硬编码，走全局类或 Less 变量
- 所有文案必须走 i18n，不能写死中文

**命名规则：**

| 元素      | 规则       | 示例                               |
| --------- | ---------- | ---------------------------------- |
| 组件文件  | kebab-case | `task-card.vue`，❌ `TaskCard.vue` |
| 组件 name | PascalCase | `TaskCard`                         |
| CSS 类名  | kebab-case | `.task-card`，❌ `.taskCard`       |
| JS 变量   | 小驼峰     | `taskList`，❌ `task_list`         |

**代码修改痕迹：** 所有新增或修改的代码块必须用 `// update-begin` / `// update-end` 包裹，注明 author/date/原因。

## 十一、提交前检查表

```
□ 接口变更 → contract/ 同步更新
□ 返回格式 → 全部用 Result 包装
□ 手写 SQL → 有 tenant_id 条件
□ 新增表 → create_time / update_time / COMMENT 完整
□ 金额字段 → DECIMAL 类型
□ 无硬编码魔法数字/裸色值
□ Commit 格式正确
□ 测试通过
```
