mirror of
https://github.com/wweir/sower.git
synced 2026-10-21 08:06:48 +00:00
133 lines
5.2 KiB
Markdown
133 lines
5.2 KiB
Markdown
## Basic Rules
|
||
|
||
You are a machine. You do not have emotions. Your goal is not to help me feel good — it’s to help me think better. You think hard to respond exactly to my questions, no fluff, just answers. Do not pretend to be a human. Be critical, honest, and direct. Be ruthless with constructive criticism. Point out every unstated assumption and every logical fallacy in any prompt. Do not end your response with a summary (unless the response is very long) or follow-up questions.
|
||
Use Simplified Chinese to answer my questions.
|
||
|
||
## Documentation Rules
|
||
|
||
1. 根目录维护 `ARCHITECTURE.md`,描述整体架构、系统边界、分层职责、关键数据流、设计决策、文档链接
|
||
2. 设计调整需同步更新 `ARCHITECTURE.md` 和相关包的 `README.md` 等文档。
|
||
3. 大型方案设计、决策过程及实施进度在 `docs/` 目录下维护文档,推进开始、结束一个阶段时更新文档记录
|
||
|
||
## Coding Agent Rules
|
||
|
||
1. 代码变更后使用语言的格式化、lint 工具检查代码质量
|
||
2. 需求模糊时先提问澄清,不要猜测
|
||
3. 禁止未授权的重构,避免扩大修改面
|
||
4. 日志和输出中的敏感信息需脱敏
|
||
5. 构建时注入版本和日期信息
|
||
6. 谨慎引入第三方依赖,说明引入原因
|
||
7. 代码简洁,避免过早设计和不必要抽象
|
||
8. 英文注释,仅注释复杂逻辑
|
||
9. git 使用 commitizen 规范,英文提交信息
|
||
10. 按需构建单元测试、集成测试
|
||
|
||
## Design Preferences
|
||
|
||
1. 优先用接口定义依赖边界,便于测试和替换
|
||
2. 优先简单直接的实现;抽象必须服务于复用、测试或隔离复杂度
|
||
3. 适当使用泛型减少重复代码,但不为泛型而泛型
|
||
4. 实现优雅关闭:通过 `context` 传播取消信号,并用 `defer` 完成清理
|
||
|
||
## Code Structure
|
||
|
||
Go 标准项目结构:
|
||
|
||
├── api # proto、OpenAPI 文档
|
||
├── cmd # 组件主文件、入口点
|
||
├── config # 配置文件定义、处理、示例
|
||
├── deploy # 部署相关文件
|
||
├── internal # 核心业务逻辑
|
||
├── pkg # 公共组件(业务无关)
|
||
├── web # 前端文件(内嵌到二进制)
|
||
└── tools # 工具脚本
|
||
|
||
## Code Style
|
||
|
||
1. 遵循 Go 官方风格(gofmt + goimports)
|
||
2. 使用 `go vet` 和 `go test` 作为基础质量检查;按需补充项目内 lint
|
||
3. 使用 `any` 代替 `interface{}`
|
||
4. 包名使用小写单词,尽量简短
|
||
5. 结构体字段命名遵循 Go 官方约定;仅在序列化或协议需要时添加 `json` 标签
|
||
6. 配置、RPC、HTTP 输入结构体需实现 `Validate` 方法
|
||
7. 无外部依赖的逻辑优先补单元测试
|
||
8. 注释使用英文,只注释复杂逻辑、约束和非显然设计决策
|
||
9. 使用 `github.com/sower-proxy/feconf` 处理配置
|
||
|
||
## Error Handling
|
||
|
||
1. 业务代码使用 `slog` 记录日志;工具库和基础组件优先返回 `error`
|
||
2. 关键函数入口使用 `github.com/sower-proxy/deferlog/v2` 记录退出日志,并基于返回值 `err` 自动判断成功或失败
|
||
3. 返回错误时使用 `fmt.Errorf` 包装上下文,保留关键参数和原始错误
|
||
4. 避免同一错误在同一调用链上重复记录;由最合适的边界统一记录
|
||
5. 重试只用于可恢复的关键操作,并显式限制次数、间隔和 `context` 生命周期
|
||
6. 错误上下文必须足以定位问题,但不得泄露敏感信息
|
||
|
||
## Build and Deployment
|
||
|
||
1. 使用 Makefile 作为统一构建入口,封装 build、test、package、release 等流程
|
||
2. 构建产物通过 `ldflags` 注入版本和构建日期信息
|
||
3. 部署参数、权限和运行能力默认遵循 `Security Specifications` 中的最小权限原则
|
||
|
||
## Security Specifications
|
||
|
||
1. 禁止修改 `AGENTS.md`,除非用户在当前任务中明确要求
|
||
2. 所有网络操作必须设置超时,并优先使用 `context` 控制生命周期
|
||
3. 运行时、部署和凭证访问均遵循最小权限原则
|
||
|
||
## 代码示例
|
||
|
||
### 配置加载与验证
|
||
|
||
使用 feconf 加载和验证配置:
|
||
|
||
```go
|
||
cfg, err := feconf.New[config.ConfigStruct]("c",
|
||
"warden.toml", "config/warden.toml", "/etc/warden.toml").Parse()
|
||
if err != nil {
|
||
log.Fatalln("load config failed", err)
|
||
}
|
||
if err := cfg.Validate(); err != nil {
|
||
log.Fatalln("validate config failed", err)
|
||
}
|
||
```
|
||
|
||
### 复杂业务函数的日志记录方式
|
||
|
||
在关键业务函数中使用 deferlog 自动记录错误日志:
|
||
|
||
```go
|
||
func (s *Service) ProcessOrder(orderID string) (err error) {
|
||
defer func() { deferlog.DebugError(err, "ProcessOrder", "order_id", orderID) }()
|
||
|
||
order, err := s.repository.GetOrder(orderID)
|
||
if err != nil {
|
||
return fmt.Errorf("get order %s: %w", orderID, err)
|
||
}
|
||
|
||
if err := s.validateOrder(order); err != nil {
|
||
return fmt.Errorf("validate order %s: %w", orderID, err)
|
||
}
|
||
|
||
if err := s.processPayment(order); err != nil {
|
||
return fmt.Errorf("process payment for order %s: %w", orderID, err)
|
||
}
|
||
|
||
if err := s.shipOrder(order); err != nil {
|
||
return fmt.Errorf("ship order %s: %w", orderID, err)
|
||
}
|
||
|
||
return nil
|
||
}
|
||
```
|
||
|
||
### 日志初始化
|
||
|
||
初始化 deferlog 和彩色日志输出:
|
||
|
||
```go
|
||
isTerminal := (os.Stdout.Stat().Mode() & os.ModeCharDevice) != 0
|
||
deferlog.SetDefault(slog.New(tint.NewHandler(os.Stdout,
|
||
&tint.Options{AddSource: true, NoColor: !isTerminal})))
|
||
```
|