Files
cryptoHermes/ai/task-templates.md
dela f3dc4d0939 refactor: 把 /derivatives 的多源编排从 controller 搬进 usecase
为什么:原 controller handler 在 HTTP 层同时承担了 4 项 usecase 职责
(多源拼装、错误降级策略、limit 硬编码、响应结构组装),违反了
"controller 只做参数解析 + 调用 + 序列化" 的边界。等后续给衍生品加
缓存 / taker volume / 数据质量字段时,HTTP 层会持续变厚。

改动:
- 新增 internal/usecase/market_query.go: MarketQueryUsecase.GetDerivatives()
  并发拉 current funding/OI + 串行查历史 + 错误聚合为 warnings 返回
- /derivatives handler 退化到 4 行;MarketDeps / restapi.Deps 同步收窄
- /klines 保持直查 KlineRepo(thin query,G11 例外)
- 新增 G11 守卫:grep "FundingRepo|OIRepo|LSRepo|TakerRepo" internal/controller

破坏性 API 变更(/derivatives 响应):
- 删除 funding.error / openInterest.error
- 新增顶层 warnings: []string
顶层 symbol / funding / openInterest / longShortRatio / takerBuySellVolume 保持。

harness 同步:
- AGENTS.md §6 加 G11 grep
- ai/project-map.md 加 market_query.go + /derivatives 数据流分支
- ai/task-templates.md T6 加"破坏性变体"分支(本次重构暴露了原假设过严)
- ai/harness-health.md W1 记一次轻量验证 + 守卫数 10→11

验收: go build / go vet / G6 grep / G11 grep 全绿。
2026-05-24 17:51:11 +08:00

210 lines
6.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Task Templates — cryptoHermes
任何非平凡修改(>1 个文件、改边界、引入新依赖、改 migration、新增 collector先写一份微型任务契约。短即可——长度像 commit message但目的是让你自己和后续 agent能在 30 秒内对齐范围。
---
## 通用契约模板
```
objective: 一句话说要做的事
scope: 会改的文件 / 目录(具体路径,不要"相关文件"
out-of-scope: 显式不改的范围(防止 scope creep
constraints: 引用 ai/risk-guardrails.md 的哪几条G1-G10
validation: 要跑哪些命令证明通过(必须可机械执行)
acceptance: 完成判据(行为可观测的描述)
```
**示例**
```
objective: 给 /v1/market/context 加一个 ?intervals=1h,4h 参数,允许 Hermes 只拉部分周期,减少响应体积
scope:
- internal/controller/restapi/v1/market_routes.go
- internal/usecase/market_context.go
- README.mdAPI 段补 query 参数说明)
out-of-scope:
- 不改 entity响应结构不变只是 klines map 的 key 集合可能少几个)
- 不改 collector采集策略不变
constraints:
- G6不能在 controller 里直接调 repo必须通过 usecase 接收 intervals 参数
validation:
- go build ./... && go vet ./...
- curl 'localhost:8080/v1/market/context?symbol=BTCUSDT&intervals=1h,4h' | jq '.klines | keys'
- 期望:只返回 ["1h","4h"]
acceptance:
- 不传 intervals 时行为完全不变(默认全部 5 个周期)
- 传未知 interval 返回 400
- 至少一个 happy-path 单测覆盖
```
---
## 任务类型 → 模板
### T1. 新增 API 路由
```
objective: <做什么>
scope:
- internal/controller/restapi/v1/<file>.go新 handler
- internal/usecase/<file>.go新业务方法或扩展现有
- internal/usecase/ports.go如果需要新 repo 方法)
out-of-scope:
- 不改 entity 结构
- 不改 collector
constraints: G6
validation:
- go build ./... && go vet ./...
- curl 测 happy-path + 错误参数
acceptance:
- 路由响应符合 JSON schema
- 参数校验完整(缺失/非法都返回 400
- README 更新 API 段
```
### T2. 新增数据表 / migration
```
objective: <为什么要存这个>
scope:
- migrations/0000N_<name>.up.sql
- migrations/0000N_<name>.down.sql
- internal/entity/<name>.go
- internal/repo/persistent/postgres/<name>_repo.go
- internal/usecase/ports.go新 Repository 接口)
out-of-scope:
- 不改已发布 migration编号≤当前 max
constraints:
- G2金额必须 string / NUMERIC(36,18)
- G4UpsertMany 必须幂等)
- G7down/up 互逆)
validation:
- make migrate-up
- make migrate-down
- make migrate-up # 再次成功
- go build ./...
acceptance:
- 表是 hypertablepsql 跑 SELECT * FROM timescaledb_information.hypertables 看到
- upsert 跑两次行数不变
- 至少 1 个 repo 单测(连本地 Timescale
```
### T3. 新增数据源CoinGlass / ETF / ...
**必须先写 `ai/specs/<source>.md`**(见 AGENTS.md §8
```
objective: 接入 <source> 提供 <什么数据>
spec: ai/specs/<source>.md
scope:
- internal/repo/webapi/<source>/{client,dto,mapper,...}.go
- internal/usecase/ports.go新 Provider 接口)
- internal/app/app.goDI 装配)
- config/config.go + config.yml新数据源的 base_url / rps / timeout
out-of-scope:
- 不改 Binance client
constraints:
- G1绝不接私钥
- G2金额 string
- G5必须走 pkg/httpclient 限流)
validation:
- go build ./... && go vet ./...
- 临时挂一个 debug 路由验证能拉到真数据
acceptance:
- 新 Provider 实现接口usecase 不直接 import <source> 包
- 速率预算文档化(在 spec 里)
```
### T4. 改 collector / scheduler
```
objective: <调整哪个采集,为什么>
scope:
- internal/worker/collector.go
- internal/app/scheduler.go
out-of-scope:
- 不改 binance client如果要新方法先开 T3 / T1
- 不改表结构(如果要,开 T2
constraints:
- G3未收线丢弃
- G4upsert 幂等)
- G5rate limit 不绕开)
validation:
- go build ./... && go vet ./...
- 本地起服务跑 1 个 cron 周期psql 看新行写入
acceptance:
- 新 cron 表达式合理(不要 0 0 * * * 这种容易和别人撞的高峰)
- 重启服务后 scheduler 能正常注册
- weight 预算在 PR 描述里说明Binance 2400/min IP 上限)
```
### T5. Bug fix
```
objective: 修 <bug 简述>issue 链接或复现命令)
scope: <最小改动范围>
constraints: <相关 G 条>
validation:
- 写一个能复现 bug 的最小测试(先红后绿)
- go build ./... && go vet ./...
acceptance:
- 测试通过
- 不引入新的 lint warning
```
### T6. 重构 / Clean Architecture 修正
```
objective: <消除哪个边界违反 / 抽取哪段重复>
scope: <文件列表>
out-of-scope:
- 行为变化默认API 响应字节级一致 / DB schema 不变)
- 例外:如果重构本身是为了把不该在 controller 的"错误降级 / 响应组装"搬进 usecase
可以一并修响应契约(如 sub-object 的 error 字段聚合为顶层 warnings
必须在 acceptance 显式标 "破坏性",并在 PR 描述列出旧 → 新字段映射。
constraints: G6 + G11如果动 controller
validation:
- go build ./... && go vet ./...
- 全部 grep 边界检查AGENTS.md §6
- make test
acceptance:
- 默认diff 中不含行为变化(只是搬代码 / 重命名 / 抽接口)
- 破坏性变体列出响应字段变化确认上游Hermes消费方已知或不受影响
```
---
## 何时升级到 spec
micro contract 写不下、或者需要跨多个 agent / 多次会话才能完成 → 升级到 `ai/specs/<task>.md`
- 多 milestone 跨越
- 引入新数据源
- 改变响应 schema影响上游 Hermes
- 引入新部署组件(消息队列、新 service
spec 内容objective / non-goals / config 形状 / API 形状 / 错误模式 / 兼容性 / 验收 / 验证计划。
---
## 何时升级到 ADR
contract 涉及"以后类似场景应该都这么做" → 写 ADR`ai/adr/000N-<decision>.md`
- 换核心库
- 改架构层数 / 改 Clean Arch 边界
- 引入新通信协议
- 改部署拓扑
ADR 结构参考 `ai/adr/0001-architecture-foundations.md`
---
## 反模式
- ❌ "顺便把这里也改一下"——顺便的部分单独开一个 contract不要混
- ❌ "测试很难写,先合了"——测试难写说明设计有问题,先调设计
- ❌ "之前 review 过类似的,应该没问题"——每个 PR 独立 validate
- ❌ commit message 写"WIP"——本仓库不允许 WIP commit 进 main