测试一下修复一部分问题
This commit is contained in:
@@ -1,42 +1,42 @@
|
||||
<!--
|
||||
SYNC IMPACT REPORT - Constitution Amendment
|
||||
============================================
|
||||
Version Change: 2.1.1 → 2.2.0
|
||||
Version Change: 2.2.0 → 2.3.0
|
||||
Date: 2025-11-11
|
||||
|
||||
NEW PRINCIPLES ADDED:
|
||||
- VII. Documentation Standards (文档规范) - NEW principle for feature documentation
|
||||
- VIII. Access Logging Standards (访问日志规范) - NEW principle for comprehensive request/response logging
|
||||
|
||||
MODIFIED SECTIONS:
|
||||
- Added new Principle VII with documentation structure and language requirements
|
||||
- Rule: Summary docs MUST be placed in docs/{feature-id}/ mirroring specs/{feature-id}/
|
||||
- Rule: Summary doc filenames MUST use Chinese
|
||||
- Rule: Summary doc content MUST use Chinese
|
||||
- Rule: README.md MUST be updated with brief Chinese summary for each feature
|
||||
- Rule: Summary should be concise enough for first-time contributors to understand quickly
|
||||
- Examples of correct documentation structure and naming
|
||||
- Rationale for centralized Chinese documentation
|
||||
- Added new Principle VIII with mandatory access logging requirements
|
||||
- Rule: ALL requests MUST be logged to access.log without exception
|
||||
- Rule: Request parameters (query + body) MUST be logged (limited to 50KB)
|
||||
- Rule: Response parameters (body) MUST be logged (limited to 50KB)
|
||||
- Rule: Logging MUST happen via centralized Logger middleware
|
||||
- Rule: No middleware can bypass access logging (including auth failures)
|
||||
- Rule: Body truncation MUST indicate "... (truncated)" when over limit
|
||||
- Rationale for comprehensive logging: debugging, audit trails, compliance
|
||||
|
||||
TEMPLATES REQUIRING UPDATES:
|
||||
✅ .specify/templates/plan-template.md - Added documentation structure guidance
|
||||
✅ .specify/templates/spec-template.md - No changes needed
|
||||
✅ .specify/templates/tasks-template.md - Added documentation task template in Polish phase
|
||||
✅ .specify/templates/plan-template.md - Added access logging check in Constitution Check
|
||||
✅ .specify/templates/tasks-template.md - Added access logging verification in Quality Gates
|
||||
|
||||
FOLLOW-UP ACTIONS:
|
||||
- Update plan-template.md with docs/ structure
|
||||
- Update tasks-template.md with documentation tasks in Polish phase
|
||||
- None required - logging implementation already completed
|
||||
|
||||
RATIONALE:
|
||||
MINOR version bump (2.2.0) - New principle added for documentation standards.
|
||||
This is a new governance rule that establishes how feature documentation should be
|
||||
organized, named, and written. The principle addresses:
|
||||
1. Documentation location consistency (docs/ mirrors specs/)
|
||||
2. Language requirements (Chinese for accessibility)
|
||||
3. README.md update requirements (brief summaries)
|
||||
4. Target audience (first-time contributors)
|
||||
MINOR version bump (2.3.0) - New principle added for access logging standards.
|
||||
This establishes a mandatory governance rule that ALL HTTP requests must be logged
|
||||
with complete request and response data, regardless of middleware short-circuiting
|
||||
(auth failures, rate limits, etc.). This ensures:
|
||||
1. Complete audit trail for all API interactions
|
||||
2. Debugging capability for all failure scenarios
|
||||
3. Compliance with logging requirements
|
||||
4. No special cases or exceptions in logging
|
||||
|
||||
This is a MINOR bump (not PATCH) because it adds a new mandatory principle that
|
||||
affects the development workflow, requiring documentation tasks for all features.
|
||||
affects the development workflow and quality gates, requiring verification that
|
||||
all middleware respects the logging standard.
|
||||
-->
|
||||
|
||||
# 君鸿卡管系统 Constitution
|
||||
@@ -933,6 +933,134 @@ README.md # 项目主文档
|
||||
|
||||
---
|
||||
|
||||
### VIII. Access Logging Standards (访问日志规范)
|
||||
|
||||
**规则 (RULES):**
|
||||
|
||||
- **所有** HTTP 请求 **MUST** 被记录到 `access.log`,无例外
|
||||
- 访问日志 **MUST** 记录完整的请求参数(query 参数 + request body)
|
||||
- 访问日志 **MUST** 记录完整的响应参数(response body)
|
||||
- 请求/响应 body **MUST** 限制大小为 50KB,超过部分截断并标注 `... (truncated)`
|
||||
- 访问日志 **MUST** 通过统一的 Logger 中间件(`pkg/logger/Middleware()`)记录
|
||||
- **任何中间件** 的短路返回(认证失败、限流拒绝、参数验证失败等)**MUST NOT** 绕过访问日志
|
||||
- 访问日志 **MUST** 包含以下字段(最低要求):
|
||||
- `method`: HTTP 方法
|
||||
- `path`: 请求路径
|
||||
- `query`: Query 参数字符串
|
||||
- `status`: HTTP 状态码
|
||||
- `duration_ms`: 请求耗时(毫秒)
|
||||
- `request_id`: 请求唯一 ID
|
||||
- `ip`: 客户端 IP
|
||||
- `user_agent`: 用户代理
|
||||
- `user_id`: 用户 ID(认证后有值,否则为空)
|
||||
- `request_body`: 请求体(限制 50KB)
|
||||
- `response_body`: 响应体(限制 50KB)
|
||||
- 访问日志 **SHOULD** 使用 JSON 格式,便于日志分析和监控
|
||||
- 访问日志文件 **MUST** 配置自动轮转(基于大小或时间)
|
||||
|
||||
**正确的访问日志示例:**
|
||||
|
||||
```json
|
||||
{
|
||||
"level": "info",
|
||||
"timestamp": "2025-11-11T17:45:03.186+0800",
|
||||
"message": "",
|
||||
"method": "POST",
|
||||
"path": "/api/v1/users",
|
||||
"query": "page=1&size=10",
|
||||
"status": 400,
|
||||
"duration_ms": 0.035,
|
||||
"request_id": "f1d8b767-dfb3-4588-9fa0-8a97e5337184",
|
||||
"ip": "127.0.0.1",
|
||||
"user_agent": "curl/8.7.1",
|
||||
"user_id": "",
|
||||
"request_body": "{\"username\":\"testuser\",\"email\":\"test@example.com\"}",
|
||||
"response_body": "{\"code\":1001,\"data\":null,\"msg\":\"缺失认证令牌\",\"timestamp\":\"2025-11-11T17:45:03+08:00\"}"
|
||||
}
|
||||
```
|
||||
|
||||
**Logger 中间件实现要求:**
|
||||
|
||||
```go
|
||||
// pkg/logger/middleware.go
|
||||
func Middleware() fiber.Handler {
|
||||
return func(c *fiber.Ctx) error {
|
||||
startTime := time.Now()
|
||||
|
||||
// 在 c.Next() 之前读取请求 body
|
||||
requestBody := truncateBody(c.Body(), MaxBodyLogSize)
|
||||
queryParams := string(c.Request().URI().QueryString())
|
||||
|
||||
// 处理请求(可能被中间件短路返回)
|
||||
err := c.Next()
|
||||
|
||||
// 在 c.Next() 之后读取响应 body(无论是否短路)
|
||||
responseBody := truncateBody(c.Response().Body(), MaxBodyLogSize)
|
||||
|
||||
// 记录完整的访问日志(包含请求和响应参数)
|
||||
accessLogger.Info("",
|
||||
zap.String("method", c.Method()),
|
||||
zap.String("path", c.Path()),
|
||||
zap.String("query", queryParams),
|
||||
zap.Int("status", c.Response().StatusCode()),
|
||||
zap.Float64("duration_ms", time.Since(startTime).Seconds()*1000),
|
||||
zap.String("request_id", getRequestID(c)),
|
||||
zap.String("ip", c.IP()),
|
||||
zap.String("user_agent", c.Get("User-Agent")),
|
||||
zap.String("user_id", getUserID(c)),
|
||||
zap.String("request_body", requestBody),
|
||||
zap.String("response_body", responseBody),
|
||||
)
|
||||
|
||||
return err
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**禁止的做法:**
|
||||
|
||||
```go
|
||||
// ❌ 在中间件中跳过日志记录
|
||||
func AuthMiddleware() fiber.Handler {
|
||||
return func(c *fiber.Ctx) error {
|
||||
if !isAuthenticated(c) {
|
||||
// ❌ 直接返回,没有记录到 access.log
|
||||
return c.Status(401).JSON(fiber.Map{"error": "unauthorized"})
|
||||
}
|
||||
return c.Next()
|
||||
}
|
||||
}
|
||||
|
||||
// ❌ 只在部分路由记录日志
|
||||
app.Use("/api/v1/users", logger.Middleware()) // ❌ 其他路由没有日志
|
||||
|
||||
// ❌ 不记录请求/响应 body
|
||||
accessLogger.Info("",
|
||||
zap.String("method", c.Method()),
|
||||
zap.String("path", c.Path()),
|
||||
zap.Int("status", c.Response().StatusCode()),
|
||||
// ❌ 缺少 request_body 和 response_body
|
||||
)
|
||||
```
|
||||
|
||||
**理由 (RATIONALE):**
|
||||
|
||||
完整的访问日志是系统可观测性的基础,对于以下场景至关重要:
|
||||
|
||||
1. **问题排查**:当用户报告错误时,通过 request_id 可以追溯完整的请求/响应数据,快速定位问题
|
||||
2. **安全审计**:记录所有请求(包括认证失败、参数验证失败等)可以追踪潜在的安全攻击
|
||||
3. **性能分析**:通过 duration_ms 和请求参数可以分析慢查询和性能瓶颈
|
||||
4. **合规要求**:某些行业(金融、医疗等)要求完整的操作审计日志
|
||||
5. **用户行为分析**:通过 user_id 和请求参数可以分析用户行为模式
|
||||
6. **无例外原则**:确保没有请求"逃脱"日志记录,避免日志盲点
|
||||
|
||||
通过强制在 Logger 中间件中统一记录,确保:
|
||||
- 中间件的短路返回(auth 失败、rate limit 等)不会绕过日志
|
||||
- 所有请求的日志格式统一,便于日志分析工具处理
|
||||
- 50KB 限制平衡了日志完整性和存储成本
|
||||
|
||||
---
|
||||
|
||||
## Development Workflow (开发工作流程)
|
||||
|
||||
### 分支管理
|
||||
@@ -964,6 +1092,7 @@ README.md # 项目主文档
|
||||
- 性能影响可接受
|
||||
- 代码通过 `gofmt`、`go vet`、`golangci-lint` 检查
|
||||
- **文档已按规范更新(docs/ 和 README.md)**
|
||||
- **访问日志记录符合规范(所有请求都被记录,包含请求/响应 body)**
|
||||
|
||||
---
|
||||
|
||||
@@ -990,6 +1119,9 @@ README.md # 项目主文档
|
||||
- [ ] **使用 Go 惯用并发模式**(goroutines/channels,无线程池类)
|
||||
- [ ] **功能总结文档已创建**(在 `docs/{feature-id}/` 目录下,中文命名和内容)
|
||||
- [ ] **README.md 已更新**(添加功能简短描述,2-3 句话)
|
||||
- [ ] **访问日志验证通过**(所有请求被记录到 access.log,包含完整请求/响应参数)
|
||||
- [ ] **访问日志格式正确**(包含所有必需字段:method, path, query, status, duration_ms, request_id, ip, user_agent, user_id, request_body, response_body)
|
||||
- [ ] **中间件不绕过日志**(认证失败、限流等短路返回也被记录)
|
||||
|
||||
### 上线前检查
|
||||
|
||||
@@ -998,6 +1130,7 @@ README.md # 项目主文档
|
||||
- [ ] 数据库迁移在 staging 环境验证通过
|
||||
- [ ] 监控和告警配置完成
|
||||
- [ ] 回滚方案已准备
|
||||
- [ ] 访问日志轮转配置正确(防止日志文件过大)
|
||||
|
||||
---
|
||||
|
||||
@@ -1025,12 +1158,17 @@ README.md # 项目主文档
|
||||
- 特别关注 Go 惯用法原则,拒绝 Java 风格的代码
|
||||
- 特别关注常量使用规范,拒绝不必要的硬编码
|
||||
- 特别关注文档规范,确保每个功能都有完整的中文文档
|
||||
- 特别关注访问日志规范,确保所有请求都被完整记录
|
||||
- 任何复杂性增加(新依赖、新架构层)**MUST** 在设计文档中明确说明必要性
|
||||
|
||||
### 运行时开发指导
|
||||
|
||||
开发时参考本宪章确保一致性。如有疑问,优先遵守原则,再讨论例外情况。记住:**写 Go 代码,不是用 Go 语法写 Java**。记住:**定义常量是为了使用,不是为了装饰**。记住:**写文档是为了团队协作,不是为了应付检查**。
|
||||
开发时参考本宪章确保一致性。如有疑问,优先遵守原则,再讨论例外情况。记住:
|
||||
- **写 Go 代码,不是用 Go 语法写 Java**
|
||||
- **定义常量是为了使用,不是为了装饰**
|
||||
- **写文档是为了团队协作,不是为了应付检查**
|
||||
- **记录日志是为了可观测性,不能有例外**
|
||||
|
||||
---
|
||||
|
||||
**Version**: 2.2.0 | **Ratified**: 2025-11-10 | **Last Amended**: 2025-11-11
|
||||
**Version**: 2.3.0 | **Ratified**: 2025-11-10 | **Last Amended**: 2025-11-11
|
||||
|
||||
@@ -108,6 +108,15 @@
|
||||
- [ ] Uses `context.Context` for timeout control
|
||||
- [ ] Uses `sync.Pool` for frequently allocated objects
|
||||
|
||||
**Access Logging Standards** (Constitution Principle VIII):
|
||||
- [ ] ALL HTTP requests logged to access.log without exception
|
||||
- [ ] Request parameters (query + body) logged (limited to 50KB)
|
||||
- [ ] Response parameters (body) logged (limited to 50KB)
|
||||
- [ ] Logging happens via centralized Logger middleware (pkg/logger/Middleware())
|
||||
- [ ] No middleware bypasses access logging (including auth failures, rate limits)
|
||||
- [ ] Body truncation indicates "... (truncated)" when over 50KB limit
|
||||
- [ ] Access log includes all required fields: method, path, query, status, duration_ms, request_id, ip, user_agent, user_id, request_body, response_body
|
||||
|
||||
## Project Structure
|
||||
|
||||
### Documentation (this feature)
|
||||
|
||||
@@ -201,6 +201,12 @@ Foundational tasks for 君鸿卡管系统 tech stack:
|
||||
- [ ] TXXX Quality Gate: Verify feature summary docs created in docs/{feature-id}/ with Chinese filenames
|
||||
- [ ] TXXX Quality Gate: Verify summary doc content uses Chinese
|
||||
- [ ] TXXX Quality Gate: Verify README.md updated with brief feature description (2-3 sentences)
|
||||
- [ ] TXXX Quality Gate: Verify ALL HTTP requests logged to access.log (no exceptions)
|
||||
- [ ] TXXX Quality Gate: Verify access log includes request parameters (query + body, limited to 50KB)
|
||||
- [ ] TXXX Quality Gate: Verify access log includes response parameters (body, limited to 50KB)
|
||||
- [ ] TXXX Quality Gate: Verify logging via centralized Logger middleware (pkg/logger/Middleware())
|
||||
- [ ] TXXX Quality Gate: Verify no middleware bypasses logging (test auth failures, rate limits, etc.)
|
||||
- [ ] TXXX Quality Gate: Verify access log has all required fields (method, path, query, status, duration_ms, request_id, ip, user_agent, user_id, request_body, response_body)
|
||||
|
||||
---
|
||||
|
||||
|
||||
Reference in New Issue
Block a user