# RMDC API开发规范提示词

---

## 设计原则

### 1. 使用POST + RequestBody

> **核心规范**: 所有API优先使用POST方法，参数通过RequestBody传递

```go
// ✅ 推荐方式
POST /api/jenkins/builds/list
{
    "organization_folder": "Backend",
    "repository_name": "cmii-fly-center",
    "branch_name": "master",
    "page": 1,
    "page_size": 10
}

// ❌ 避免使用
GET /api/jenkins/organizations/{org}/repositories/{repo}/branches/{branch}/builds?page=1&page_size=10
```

### 2. 避免PathVariables

```go
// ❌ 不推荐
GET /api/projects/{project_id}
GET /api/builds/{build_id}/console

// ✅ 推荐
POST /api/projects/detail
{
    "project_id": "namespace_abc12345"
}

POST /api/builds/console
{
    "organization_folder": "Backend",
    "repository_name": "cmii-fly-center",
    "branch_name": "master",
    "build_number": 123
}
```

### 3. 避免RequestParams

```go
// ❌ 不推荐
GET /api/users/list?role=admin&status=active&page=1

// ✅ 推荐
POST /api/users/list
{
    "role": "admin",
    "status": "active",
    "page": 1,
    "page_size": 20
}
```

---

## 统一响应格式

### 成功响应

```json
{
    "code": 0,
    "message": "success",
    "data": {
        // 业务数据
    }
}
```

### 分页响应

```json
{
    "code": 0,
    "message": "success",
    "data": {
        "list": [...],
        "total": 100,
        "page": 1,
        "page_size": 20
    }
}
```

### 错误响应

```json
{
    "code": 1001,
    "message": "参数错误: organization_folder不能为空",
    "data": null
}
```

---

## 请求结构规范

### 通用分页请求

```go
type PageRequest struct {
    Page     int `json:"page" binding:"required,min=1"`
    PageSize int `json:"page_size" binding:"required,min=1,max=100"`
}
```

### 通用筛选请求

```go
type ListRequest struct {
    PageRequest
    Keyword   string `json:"keyword,omitempty"`   // 搜索关键词
    Status    string `json:"status,omitempty"`    // 状态筛选
    SortBy    string `json:"sort_by,omitempty"`   // 排序字段
    SortOrder string `json:"sort_order,omitempty"` // asc/desc
}
```

---

## API命名规范

### 操作类型后缀

| 操作 | 后缀 | 示例 |
|------|------|------|
| 列表查询 | `/list` | `/api/projects/list` |
| 详情查询 | `/detail` | `/api/projects/detail` |
| 创建 | `/create` | `/api/projects/create` |
| 更新 | `/update` | `/api/projects/update` |
| 删除 | `/delete` | `/api/projects/delete` |
| 同步 | `/sync` | `/api/jenkins/organizations/sync` |
| 触发 | `/trigger` | `/api/builds/trigger` |
| 导出 | `/export` | `/api/projects/export` |

### 模块前缀

| 模块 | 前缀 |
|------|------|
| Jenkins | `/api/jenkins/` |
| 项目管理 | `/api/projects/` |
| 用户 | `/api/users/` |
| 权限 | `/api/permissions/` |
| 审计 | `/api/audit/` |
| Exchange-Hub | `/api/exchange-hub/` |
| DCU | `/api/dcu/` |

---

## Handler实现模板

```go
// ListBuilds 获取构建列表
// @Summary 获取构建列表
// @Tags 构建管理
// @Accept json
// @Produce json
// @Param request body dto.ListBuildsRequest true "请求参数"
// @Success 200 {object} response.Response{data=dto.ListBuildsResponse}
// @Router /api/jenkins/builds/list [post]
func (h *BuildHandler) ListBuilds(c *gin.Context) {
    var req dto.ListBuildsRequest
    if err := c.ShouldBindJSON(&req); err != nil {
        response.ParamError(c, err)
        return
    }
    
    resp, err := h.buildService.ListBuilds(c.Request.Context(), &req)
    if err != nil {
        response.Error(c, err)
        return
    }
    
    response.Success(c, resp)
}
```

---

## DTO设计规范

### 请求DTO命名

```go
// 列表请求: List{资源}Request
type ListBuildsRequest struct {
    PageRequest
    OrganizationFolder string `json:"organization_folder" binding:"required"`
    RepositoryName     string `json:"repository_name" binding:"required"`
    BranchName         string `json:"branch_name,omitempty"`
}

// 详情请求: Get{资源}Request 或 {资源}DetailRequest
type GetBuildRequest struct {
    OrganizationFolder string `json:"organization_folder" binding:"required"`
    RepositoryName     string `json:"repository_name" binding:"required"`
    BranchName         string `json:"branch_name" binding:"required"`
    BuildNumber        int    `json:"build_number" binding:"required"`
}

// 创建请求: Create{资源}Request
type CreateProjectRequest struct {
    Name      string `json:"name" binding:"required"`
    Namespace string `json:"namespace" binding:"required"`
    Province  string `json:"province" binding:"required"`
    City      string `json:"city" binding:"required"`
}

// 更新请求: Update{资源}Request
type UpdateProjectRequest struct {
    ProjectID string `json:"project_id" binding:"required"`
    Name      string `json:"name,omitempty"`
    Province  string `json:"province,omitempty"`
    City      string `json:"city,omitempty"`
}

// 删除请求: Delete{资源}Request
type DeleteProjectRequest struct {
    ProjectID string `json:"project_id" binding:"required"`
}
```

### 响应DTO命名

```go
// 列表响应: List{资源}Response
type ListBuildsResponse struct {
    List     []*BuildDTO `json:"list"`
    Total    int64       `json:"total"`
    Page     int         `json:"page"`
    PageSize int         `json:"page_size"`
}

// 详情响应: {资源}DetailResponse 或直接使用 {资源}DTO
type BuildDetailResponse struct {
    *BuildDTO
    ConsoleOutput string `json:"console_output,omitempty"`
}
```

---

## 错误码规范

### 错误码范围

| 范围 | 模块 |
|------|------|
| 1000-1999 | 通用错误 |
| 2000-2999 | 用户/权限 |
| 3000-3999 | Jenkins模块 |
| 4000-4999 | 项目管理 |
| 5000-5999 | Exchange-Hub |
| 6000-6999 | Watchdog |

### 通用错误码

| 错误码 | 说明 |
|--------|------|
| 0 | 成功 |
| 1001 | 参数错误 |
| 1002 | 未授权 |
| 1003 | 禁止访问 |
| 1004 | 资源不存在 |
| 1005 | 内部错误 |

---

## 前端调用示例

```typescript
// api/modules/jenkins.ts
export const jenkinsApi = {
    // 获取构建列表
    listBuilds: (data: ListBuildsRequest) => 
        request.post<ListBuildsResponse>('/api/jenkins/builds/list', data),
    
    // 触发构建
    triggerBuild: (data: TriggerBuildRequest) => 
        request.post<TriggerBuildResponse>('/api/jenkins/builds/trigger', data),
    
    // 获取构建详情
    getBuildDetail: (data: GetBuildRequest) => 
        request.post<BuildDetailResponse>('/api/jenkins/builds/detail', data),
};
```

---

## 安全规范

### 1. 敏感字段不出现在URL

```go
// ❌ 敏感信息泄露到URL
GET /api/auth/login?username=admin&password=123456

// ✅ 使用RequestBody
POST /api/auth/login
{
    "username": "admin",
    "password": "123456"
}
```

### 2. 必须验证请求体

```go
func (h *Handler) CreateProject(c *gin.Context) {
    var req dto.CreateProjectRequest
    if err := c.ShouldBindJSON(&req); err != nil {
        response.ParamError(c, err)
        return
    }
    // 后续处理...
}
```

### 3. 审计敏感操作

所有写操作需通过审计中间件记录。
