feat(P1/P2): 完成TDD开发及P1/P2设计文档

## 设计文档
- multi_role_permission_design: 多角色权限设计 (CONDITIONAL GO)
- audit_log_enhancement_design: 审计日志增强 (CONDITIONAL GO)
- routing_strategy_template_design: 路由策略模板 (CONDITIONAL GO)
- sso_saml_technical_research: SSO/SAML调研 (CONDITIONAL GO)
- compliance_capability_package_design: 合规能力包设计 (CONDITIONAL GO)

## TDD开发成果
- IAM模块: supply-api/internal/iam/ (111个测试)
- 审计日志模块: supply-api/internal/audit/ (40+测试)
- 路由策略模块: gateway/internal/router/ (33+测试)
- 合规能力包: gateway/internal/compliance/ + scripts/ci/compliance/

## 规范文档
- parallel_agent_output_quality_standards: 并行Agent产出质量规范
- project_experience_summary: 项目经验总结 (v2)
- 2026-04-02-p1-p2-tdd-execution-plan: TDD执行计划

## 评审报告
- 5个CONDITIONAL GO设计文档评审报告
- fix_verification_report: 修复验证报告
- full_verification_report: 全面质量验证报告
- tdd_module_quality_verification: TDD模块质量验证
- tdd_execution_summary: TDD执行总结

依据: Superpowers执行框架 + TDD规范
This commit is contained in:
Your Name
2026-04-02 23:35:53 +08:00
parent ed0961d486
commit 89104bd0db
94 changed files with 24738 additions and 5 deletions

View File

@@ -0,0 +1,357 @@
package model
import (
"strings"
"time"
"github.com/google/uuid"
)
// 事件类别常量
const (
CategoryCRED = "CRED"
CategoryAUTH = "AUTH"
CategoryDATA = "DATA"
CategoryCONFIG = "CONFIG"
CategorySECURITY = "SECURITY"
)
// 凭证事件子类别
const (
SubCategoryCredExpose = "EXPOSE"
SubCategoryCredIngress = "INGRESS"
SubCategoryCredRotate = "ROTATE"
SubCategoryCredRevoke = "REVOKE"
SubCategoryCredValidate = "VALIDATE"
SubCategoryCredDirect = "DIRECT"
)
// 凭证类型
const (
CredentialTypePlatformToken = "platform_token"
CredentialTypeQueryKey = "query_key"
CredentialTypeUpstreamAPIKey = "upstream_api_key"
CredentialTypeNone = "none"
)
// 操作者类型
const (
OperatorTypeUser = "user"
OperatorTypeSystem = "system"
OperatorTypeAdmin = "admin"
)
// 租户类型
const (
TenantTypeSupplier = "supplier"
TenantTypeConsumer = "consumer"
TenantTypePlatform = "platform"
)
// SecurityFlags 安全标记
type SecurityFlags struct {
HasCredential bool `json:"has_credential"` // 是否包含凭证
CredentialExposed bool `json:"credential_exposed"` // 凭证是否暴露
Desensitized bool `json:"desensitized"` // 是否已脱敏
Scanned bool `json:"scanned"` // 是否已扫描
ScanPassed bool `json:"scan_passed"` // 扫描是否通过
ViolationTypes []string `json:"violation_types"` // 违规类型列表
}
// NewSecurityFlags 创建默认安全标记
func NewSecurityFlags() *SecurityFlags {
return &SecurityFlags{
HasCredential: false,
CredentialExposed: false,
Desensitized: false,
Scanned: false,
ScanPassed: false,
ViolationTypes: []string{},
}
}
// HasViolation 检查是否有违规
func (sf *SecurityFlags) HasViolation() bool {
return len(sf.ViolationTypes) > 0
}
// HasViolationOfType 检查是否有指定类型的违规
func (sf *SecurityFlags) HasViolationOfType(violationType string) bool {
for _, v := range sf.ViolationTypes {
if v == violationType {
return true
}
}
return false
}
// AddViolationType 添加违规类型
func (sf *SecurityFlags) AddViolationType(violationType string) {
sf.ViolationTypes = append(sf.ViolationTypes, violationType)
}
// AuditEvent 统一审计事件
type AuditEvent struct {
// 基础标识
EventID string `json:"event_id"` // 事件唯一ID (UUID)
EventName string `json:"event_name"` // 事件名称 (e.g., "CRED-EXPOSE")
EventCategory string `json:"event_category"` // 事件大类 (e.g., "CRED")
EventSubCategory string `json:"event_sub_category"` // 事件子类
// 时间戳
Timestamp time.Time `json:"timestamp"` // 事件发生时间
TimestampMs int64 `json:"timestamp_ms"` // 毫秒时间戳
// 请求上下文
RequestID string `json:"request_id"` // 请求追踪ID
TraceID string `json:"trace_id"` // 分布式追踪ID
SpanID string `json:"span_id"` // Span ID
// 幂等性
IdempotencyKey string `json:"idempotency_key,omitempty"` // 幂等键
// 操作者信息
OperatorID int64 `json:"operator_id"` // 操作者ID
OperatorType string `json:"operator_type"` // 操作者类型 (user/system/admin)
OperatorRole string `json:"operator_role"` // 操作者角色
// 租户信息
TenantID int64 `json:"tenant_id"` // 租户ID
TenantType string `json:"tenant_type"` // 租户类型 (supplier/consumer/platform)
// 对象信息
ObjectType string `json:"object_type"` // 对象类型 (account/package/settlement)
ObjectID int64 `json:"object_id"` // 对象ID
// 操作信息
Action string `json:"action"` // 操作类型 (create/update/delete)
ActionDetail string `json:"action_detail"` // 操作详情
// 凭证信息 (M-013/M-014/M-015/M-016 关键)
CredentialType string `json:"credential_type"` // 凭证类型 (platform_token/query_key/upstream_api_key/none)
CredentialID string `json:"credential_id,omitempty"` // 凭证标识 (脱敏)
CredentialFingerprint string `json:"credential_fingerprint,omitempty"` // 凭证指纹
// 来源信息
SourceType string `json:"source_type"` // 来源类型 (api/ui/cron/internal)
SourceIP string `json:"source_ip"` // 来源IP
SourceRegion string `json:"source_region"` // 来源区域
UserAgent string `json:"user_agent,omitempty"` // User Agent
// 目标信息 (用于直连检测 M-015)
TargetType string `json:"target_type,omitempty"` // 目标类型
TargetEndpoint string `json:"target_endpoint,omitempty"` // 目标端点
TargetDirect bool `json:"target_direct"` // 是否直连
// 结果信息
ResultCode string `json:"result_code"` // 结果码
ResultMessage string `json:"result_message,omitempty"` // 结果消息
Success bool `json:"success"` // 是否成功
// 状态变更 (用于溯源)
BeforeState map[string]any `json:"before_state,omitempty"` // 操作前状态
AfterState map[string]any `json:"after_state,omitempty"` // 操作后状态
// 安全标记 (M-013 关键)
SecurityFlags SecurityFlags `json:"security_flags"` // 安全标记
RiskScore int `json:"risk_score"` // 风险评分 0-100
// 合规信息
ComplianceTags []string `json:"compliance_tags,omitempty"` // 合规标签 (e.g., ["GDPR", "SOC2"])
InvariantRule string `json:"invariant_rule,omitempty"` // 触发的不变量规则
// 扩展字段
Extensions map[string]any `json:"extensions,omitempty"` // 扩展数据
// 元数据
Version int `json:"version"` // 事件版本
CreatedAt time.Time `json:"created_at"` // 创建时间
}
// NewAuditEvent 创建审计事件
func NewAuditEvent(
eventName string,
eventCategory string,
eventSubCategory string,
metricName string,
requestID string,
traceID string,
operatorID int64,
operatorType string,
operatorRole string,
tenantID int64,
tenantType string,
objectType string,
objectID int64,
action string,
credentialType string,
sourceType string,
sourceIP string,
success bool,
resultCode string,
resultMessage string,
) *AuditEvent {
now := time.Now()
event := &AuditEvent{
EventID: uuid.New().String(),
EventName: eventName,
EventCategory: eventCategory,
EventSubCategory: eventSubCategory,
Timestamp: now,
TimestampMs: now.UnixMilli(),
RequestID: requestID,
TraceID: traceID,
OperatorID: operatorID,
OperatorType: operatorType,
OperatorRole: operatorRole,
TenantID: tenantID,
TenantType: tenantType,
ObjectType: objectType,
ObjectID: objectID,
Action: action,
CredentialType: credentialType,
SourceType: sourceType,
SourceIP: sourceIP,
Success: success,
ResultCode: resultCode,
ResultMessage: resultMessage,
Version: 1,
CreatedAt: now,
SecurityFlags: *NewSecurityFlags(),
ComplianceTags: []string{},
}
// 根据凭证类型设置安全标记
if credentialType != CredentialTypeNone && credentialType != "" {
event.SecurityFlags.HasCredential = true
}
// 根据事件名称设置凭证暴露标记M-013
if IsM013Event(eventName) {
event.SecurityFlags.CredentialExposed = true
}
// 根据事件名称设置指标名称到扩展字段
if metricName != "" {
if event.Extensions == nil {
event.Extensions = make(map[string]any)
}
event.Extensions["metric_name"] = metricName
}
return event
}
// NewAuditEventWithSecurityFlags 创建带完整安全标记的审计事件
func NewAuditEventWithSecurityFlags(
eventName string,
eventCategory string,
eventSubCategory string,
metricName string,
requestID string,
traceID string,
operatorID int64,
operatorType string,
operatorRole string,
tenantID int64,
tenantType string,
objectType string,
objectID int64,
action string,
credentialType string,
sourceType string,
sourceIP string,
success bool,
resultCode string,
resultMessage string,
securityFlags SecurityFlags,
riskScore int,
) *AuditEvent {
event := NewAuditEvent(
eventName,
eventCategory,
eventSubCategory,
metricName,
requestID,
traceID,
operatorID,
operatorType,
operatorRole,
tenantID,
tenantType,
objectType,
objectID,
action,
credentialType,
sourceType,
sourceIP,
success,
resultCode,
resultMessage,
)
event.SecurityFlags = securityFlags
event.RiskScore = riskScore
return event
}
// SetIdempotencyKey 设置幂等键
func (e *AuditEvent) SetIdempotencyKey(key string) {
e.IdempotencyKey = key
}
// SetTarget 设置目标信息用于M-015直连检测
func (e *AuditEvent) SetTarget(targetType, targetEndpoint string, targetDirect bool) {
e.TargetType = targetType
e.TargetEndpoint = targetEndpoint
e.TargetDirect = targetDirect
}
// SetInvariantRule 设置不变量规则用于SECURITY事件
func (e *AuditEvent) SetInvariantRule(rule string) {
e.InvariantRule = rule
// 添加合规标签
e.ComplianceTags = append(e.ComplianceTags, "XR-001")
}
// GetMetricName 获取指标名称
func (e *AuditEvent) GetMetricName() string {
if e.Extensions != nil {
if metricName, ok := e.Extensions["metric_name"].(string); ok {
return metricName
}
}
// 根据事件名称推断指标
switch e.EventName {
case "CRED-EXPOSE-RESPONSE", "CRED-EXPOSE-LOG", "CRED-EXPOSE":
return "supplier_credential_exposure_events"
case "CRED-INGRESS-PLATFORM", "CRED-INGRESS":
return "platform_credential_ingress_coverage_pct"
case "CRED-DIRECT-SUPPLIER", "CRED-DIRECT":
return "direct_supplier_call_by_consumer_events"
case "AUTH-QUERY-KEY", "AUTH-QUERY-REJECT", "AUTH-QUERY":
return "query_key_external_reject_rate_pct"
default:
return ""
}
}
// IsM013Event 判断是否为M-013凭证暴露事件
func IsM013Event(eventName string) bool {
return strings.HasPrefix(eventName, "CRED-EXPOSE")
}
// IsM014Event 判断是否为M-014凭证入站事件
func IsM014Event(eventName string) bool {
return strings.HasPrefix(eventName, "CRED-INGRESS")
}
// IsM015Event 判断是否为M-015直连绕过事件
func IsM015Event(eventName string) bool {
return strings.HasPrefix(eventName, "CRED-DIRECT")
}
// IsM016Event 判断是否为M-016 query key拒绝事件
func IsM016Event(eventName string) bool {
return strings.HasPrefix(eventName, "AUTH-QUERY")
}