为什么:原 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 全绿。
5.4 KiB
5.4 KiB
AGENTS.md — cryptoHermes 操作指南
本文件是 AI 编码代理在此仓库工作的最小操作手册。完整项目设计见 docs/dev.md,用户向文档见 README.md。
1. 项目定位(必读,决定可做与不可做)
cryptoHermes 是给上游 Hermes 量化分析引擎用的 Binance Futures 行情网关。
只做:
- 从 Binance USDⓈ-M Futures 公共接口拉行情、衍生品数据
- 落库到 TimescaleDB
- 通过 REST 把聚合后的市场上下文给 Hermes
绝不做(详见 ai/risk-guardrails.md):
- 下单、撤单、查持仓
- 接入 API Key / Secret
- 任何账户级私有接口(签名请求)
- 钱包、托管、转账
- WebSocket 推送(v1 范围外)
2. 当前状态
- v1 MVP 已完成(Milestone 1-5),可启动、可采集、可返回完整
/v1/market/context - Technical 指标计算(Milestone 6)留待 v2
- 详细路线图见
docs/dev.md第 19 章和 README "路线图"段
3. 技术栈
| 类别 | 选型 |
|---|---|
| Go | 1.23(见 go.mod) |
| HTTP | Fiber v2 |
| DB | TimescaleDB on PG 16 |
| DB Driver | pgx v5 (pgxpool) |
| Scheduler | robfig/cron v3 |
| Config | cleanenv(yaml + env) |
| 限流 | golang.org/x/time/rate |
| Migration | golang-migrate CLI |
为什么是这套选型见 ai/adr/0001-architecture-foundations.md。
4. 仓库结构(参见 ai/project-map.md)
cmd/ 二进制入口(app / backfill)
config/ cleanenv 配置加载
internal/ 业务代码(不可被外部 import)
app/ 装配 DI、cron、graceful shutdown
controller/ Fiber 路由层
entity/ 纯业务实体
usecase/ 业务接口与编排(ports.go 是接口边界)
repo/ 外部依赖实现
webapi/binance/ Binance HTTP client
persistent/postgres/ 5 个 repository
worker/ collector 实现
migrations/ SQL(含 hypertable 转换)
pkg/ 项目内可复用基础设施(logger/httpclient/postgres)
docs/ 设计文档
ai/ harness 工程文档(本目录及子目录)
5. 验证命令(必做:改完代码至少跑前两个)
# 编译(最快反馈)
go build ./...
# 静态分析
go vet ./...
# 单包测试
go test ./internal/<pkg>/...
# 全部测试
make test # 等价于 go test ./...
# 启动(需要先 make docker-up && make migrate-up)
make run
触碰 binance/mapper.go 或 entity/kline.go 之后:必须确保对接 Binance K线数组按下标解析 的代码不被破坏(dev.md 第 9.2 节)。
触碰任何 SQL migration 后:本地必须重跑 make migrate-down && make migrate-up 验证 down/up 互逆。
6. Clean Architecture 边界(自动可验证)
# controller 不可直接 import binance/postgres
grep -r "repo/webapi/binance\|repo/persistent" internal/controller # 必须无输出
# usecase 不可直接 import binance/postgres
grep -r "repo/webapi/binance\|repo/persistent" internal/usecase # 必须无输出
# controller 不可直接编排 derivatives 多源查询(G11)
grep -rn "FundingRepo\|OIRepo\|LSRepo\|TakerRepo" internal/controller # 必须无输出
# 全项目不可出现签名 / 私钥相关字段
grep -ri "apikey\|x-mbx-apikey\|hmac\|secret_key\|api_secret" --include="*.go" . # 必须无输出(不算注释/文档里的"不接入"说明)
任何 PR 都应该满足以上四条。
7. 关键技术约束(容易犯错)
- 价格精度:全链路用
string,落库时由 PG 转NUMERIC(36,18)。禁止用float64存储或传递价格、成交量。 - K线未收线丢弃:从 Binance 拉到的最新一根 K 线如果
close_time > now()就不能入库。Repo 的UpsertMany会过滤IsClosed=false,新代码也必须遵守。 - Binance 历史 OI / 多空比官方只保留 30 天:必须依赖 collector 持续落库才能拿到长历史。
- Rate limit:默认 20 req/s(
config.Binance.RPS)。新增 collector 任务前估算 weight 预算(Binance 2400 weight/min IP 上限)。 - 国内网络:
fapi.binance.com直连不稳定,通过HTTPS_PROXY环境变量挂代理。 - Upsert 幂等:5 张表的主键都包含时间维度,所有 repo 的
UpsertMany使用ON CONFLICT DO UPDATE,可安全重复执行。
8. 任务模式
任何非平凡修改,建议先写一份微型任务契约(参见 ai/task-templates.md):
objective: 要做的事,一句话
scope: 会改的文件 / 目录
out-of-scope: 不会动的范围
constraints: 受 ai/risk-guardrails.md 约束的哪几条
validation: 要跑哪些命令证明通过
acceptance: 如何判断完成
对于跨多个 Milestone 或需要新增数据源(CoinGlass、ETF Flow)的任务,必须先写 ai/specs/<task>.md。
9. 提交规范
- 一个 PR 改一类事。Repo 层、Binance 适配、usecase 编排不要混在一个 commit。
- Commit message 用中文或英文都行,但要写"为什么"。
- 不要在没有跑
go build ./...和go vet ./...的情况下提交。 go.mod改动必须配套go.sum(运行make tidy)。
10. 何时升级 harness
- 同一类错误第二次出现 → 写进
ai/risk-guardrails.md - 重大架构决策(换 HTTP 框架、引入消息队列、跨服务通信)→ 写 ADR
- 新增数据源(CoinGlass / ETF / CME)→ 必须有
ai/specs/<source>.md才动手 - 跨多次会话的长任务 → 写
ai/work-status.md