# dev-task-flow — reference

## Scope
- 适用于日常功能开发与接口实现，不替代「提交代码 / 部署测试环境」流程（**deploy-test-env**）。
- 本技能默认包含：技术文档、代码实现、自测、自测报告检查、开发报告。
- 若用户明确要求跳过某阶段，按用户要求执行并在结果中注明风险。

## Hard Rules
- 按顺序执行，失败即停：前置阶段未完成，不进入下一阶段。
- 不使用破坏性 git 命令；不改动与当前需求无关的文件。
- 启动服务前先检查已有终端，避免重复拉起进程。
- 每个实现步骤都要有可验证结果（日志、响应、数据库查询结果等）。
- 不提交敏感文件（如 `.env`、`*.pem`、`*.key`、`credentials.json`）。
- Request 结构强约束：所有 HTTP 接口请求结构必须继承 `BaseHttpRequest`（查询类可在其上扩展 `BaseHttpListRequest` 能力），禁止手写散乱字段解析。
- 查询接口强约束：凡是 Query/List 类接口，必须严格按「1.1 查询类接口实现模板」编码，不得跳步或替换实现范式。
- 禁止绕开模板：不允许「手工解析 filter + 直接查库 + 手工拼装返回」替代统一查询模板，除非用户明确批准偏离模板。
- 若发现历史代码未按模板实现：本次改动范围内需优先重构到模板形态，再继续新增需求。
- 文件拆分强约束：新增独立功能域（如 license、billing、audit）时，必须新建独立 service 文件（如 `license_service.go`），禁止继续堆叠到已有大文件（如 `tenant_service.go`），除非用户明确要求复用原文件。
- 路由注解同步强约束：新建 service 文件后，必须同步更新注解收集逻辑（如 `go:embed` + `ExtractRouteAnnotationsFromString`）确保新增接口被自动注册；未完成注册校验不得进入下一阶段。
- 文档策略：默认按用户诉求执行，**非明确要求不强制产出文档文件**；当任务或用户要求文档时，需在仓库中落盘并给出路径。
- 完成态闸门：默认以「需求梳理 + 代码实现 + 编译检查」为完成条件；若任务包含文档交付，再将文档作为强制项。

## Preflight Checklist（执行前自检）
- 是否已在内部记录当前技能（可选 `[SKILL:dev-task-flow]` 标记）：是/否。
- 是否匹配「开发/实现/完善接口或模块」任务：是/否。
- 是否按 Workflow 顺序执行：是/否。
- 若包含 Query/List 接口：是否满足「1.1 模板强约束」（参数处理、SQL查询、数据渲染三段完整且可验证）：是/否。

## Workflow（详细）

### 1）梳理需求（按需输出技术方案）
- 将需求拆成：输入、处理、输出、边界条件、错误场景。
- 当任务明确要求文档时，技术文档分两部分：
  - **设计文档**：设计思路、数据库设计、流程图。
  - **接口文档**：接口路径/方法、请求参数、响应结构、错误码、示例。
- 文档落地要求（按需）：
- 按当前项目规划选择实现模板（见下文 1.1 / 1.2 / 1.3）。

#### 1.1 查询类接口实现模板
- 参考项目：`code/host/sdmgrvirus`（按项目现有结构对齐）。
- 固定步骤：
  1. 参数处理（必填校验、类型转换、默认值、分页排序）。
  2. SQL 编写查询（过滤条件、分页、排序、总数统计）。
  3. 返回数据渲染（字段映射、脱敏/格式化、统一响应结构）。
- Request 模板（强制）：
  1. 定义请求结构时必须以 `BaseHttpRequest` 为基类。
  2. Query/List 请求必须具备统一过滤能力（`filter/search/date`、分页、排序），不得绕过基类能力。
  3. 业务字段只允许作为基类扩展字段追加，不允许替代基类字段。
- 代码模板（可直接复用）：
```go
type QueryXXXRequest struct {
	query.BaseHttpListRequest
	// 业务扩展字段（按需）
	Pcid string `json:"pcid" form:"pcid"`
}

// @route GET /module/xxx/query
func (s XxxService) QueryXXX(req *QueryXXXRequest) (any, error) {
	if req == nil {
		return []map[string]any{}, nil
	}
	if strings.TrimSpace(req.Pcid) == "" {
		return common.Response{Errno: 1, Errmsg: "pcid不能为空", Timestamp: time.Now().Unix()}, nil
	}

	req.SetDbType(query.DB_TYPE_MYSQL)
	req.BaseFilter("tid", query.EQFilter("tid"))
	req.BaseFilter("tids", query.INFilter("tid"))
	req.Operator(query.EQUAL, "saas", "model_name")

	rows, err := req.Query("select tid,data from settings", "")
	if err != nil {
		return nil, err
	}
	return rows, nil
}
```
- 严格落地要求：
  1. 过滤条件必须优先接入项目统一过滤器机制（如 `BaseHttpListRequest`、`BaseFilter`、`INFilter`、`EQFilter`）。
  2. 查询执行与渲染加工必须解耦：先得到标准查询结果，再做字段映射/补充。
  3. 默认要求可分页且可统计总数；若业务明确不需要总数，需在实现说明中写明理由。
  4. 返回格式与错误处理必须复用项目统一响应风格，禁止自定义散乱结构。
- 反例（禁止）：
  - 仅通过 `json.Unmarshal(req.Filter)` 手工取 `tids` 后直接 `db.Table(...).Find(...)`，且未接入统一过滤器。
  - 在单个方法中混合参数解析、过滤组装、SQL 执行、复杂渲染且无模板分层。

#### 1.2 POST 表单提交类接口实现模板
- 固定步骤：
  1. 参数绑定与校验（必填、长度、枚举、格式）。
  2. 业务处理（去重/幂等、状态流转、事务边界）。
  3. 数据写入（MySQL/ClickHouse 或其他存储）。
  4. 返回提交结果（成功标识、主键/业务 ID、失败原因）。
- Request 模板（强制）：
  1. POST 请求结构必须继承 `BaseHttpRequest`。
  2. 参数校验必须在 Service 入口统一进行，不允许在多处重复解析 `map[string]any`。
  3. 校验失败统一走项目响应结构，不允许返回非标准错误体。
- 代码模板（可直接复用）：
```go
type SubmitXXXRequest struct {
	query.BaseHttpRequest
	Tid                string `json:"tid" form:"tid"`
	Pcid               string `json:"pcid" form:"pcid"`
	AuthorizeTimestamp int64  `json:"authorize_timestamp" form:"authorize_timestamp"`
}

// @route POST /module/xxx/submit
func (s XxxService) SubmitXXX(req *SubmitXXXRequest) (any, error) {
	tid := strings.TrimSpace(req.Tid)
	pcid := strings.TrimSpace(req.Pcid)
	if tid == "" {
		return common.Response{Errno: 1, Errmsg: "tid不能为空", Timestamp: time.Now().Unix()}, nil
	}
	if pcid == "" {
		return common.Response{Errno: 1, Errmsg: "pcid不能为空", Timestamp: time.Now().Unix()}, nil
	}
	if req.AuthorizeTimestamp <= 0 {
		return common.Response{Errno: 1, Errmsg: "authorize_timestamp不能为空", Timestamp: time.Now().Unix()}, nil
	}

	// 业务处理 + 落库
	return common.SuccessResponse("success", nil), nil
}
```

#### 1.3 客户端上报类 workflow 实现模板
- 固定步骤：
  1. 定义上报消息结构与校验规则。
  2. 接入上报入口（通常 NSQ/消息队列）并消费处理。
  3. 数据清洗与标准化（时间、字段、枚举映射）。
  4. 落库（常见为 ClickHouse，也可按现有链路写入 MySQL/CH）。
  5. 提供查询/校验路径（HTTP 查询接口或 DB 校验语句）。

### 2）开始编写代码和检查
- 按第 1 步确定的模板编码，优先复用项目现有模式与公共组件。
- 对新增功能域先做文件边界决策：优先新建独立 service 文件并控制单文件复杂度，避免无边界扩展历史文件。
- 编码后至少完成编译检查（保证改动范围可编译）。
- 对关键分支补充必要的错误处理与日志，保证问题可定位。
- 检查点：参数校验完整、SQL 条件正确、返回字段与接口文档一致。

### 3）检查编译错误和review代码
- go build ./...。
- Lint检查。

## Output Contract
- 每个阶段输出 `PASS` 或 `FAIL`。
- 若 `FAIL`，必须包含：
  - 失败步骤
  - 关键错误现象
  - 已确认原因/待确认点
  - 下一步动作
- 全部成功时，至少输出：
  - 实现模板类型（查询类 / POST / 客户端上报）
  - 已完成文档列表（如本次任务要求：设计文档、接口文档、测试文档、开发报告）
  - 自测结论摘要
- 交付清单强制项（缺一不可）：
  - 代码改动文件路径
  - 编译/测试结果
  - 若任务要求文档：对应文档文件路径
