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,220 @@
package model
import (
"time"
)
// ==================== M-013: 凭证暴露事件详情 ====================
// CredentialExposureDetail M-013: 凭证暴露事件专用
type CredentialExposureDetail struct {
EventID string `json:"event_id"` // 事件ID关联audit_events
ExposureType string `json:"exposure_type"` // exposed_in_response/exposed_in_log/exposed_in_export
ExposureLocation string `json:"exposure_location"` // response_body/response_header/log_file/export_file
ExposurePattern string `json:"exposure_pattern"` // 匹配到的正则模式
ExposedFragment string `json:"exposed_fragment"` // 暴露的片段(已脱敏)
ScanRuleID string `json:"scan_rule_id"` // 触发扫描规则ID
Resolved bool `json:"resolved"` // 是否已解决
ResolvedAt *time.Time `json:"resolved_at"` // 解决时间
ResolvedBy *int64 `json:"resolved_by"` // 解决人
ResolutionNotes string `json:"resolution_notes"` // 解决备注
}
// NewCredentialExposureDetail 创建凭证暴露详情
func NewCredentialExposureDetail(
exposureType string,
exposureLocation string,
exposurePattern string,
exposedFragment string,
scanRuleID string,
) *CredentialExposureDetail {
return &CredentialExposureDetail{
ExposureType: exposureType,
ExposureLocation: exposureLocation,
ExposurePattern: exposurePattern,
ExposedFragment: exposedFragment,
ScanRuleID: scanRuleID,
Resolved: false,
}
}
// Resolve 标记为已解决
func (d *CredentialExposureDetail) Resolve(resolvedBy int64, notes string) {
now := time.Now()
d.Resolved = true
d.ResolvedAt = &now
d.ResolvedBy = &resolvedBy
d.ResolutionNotes = notes
}
// ==================== M-014: 凭证入站事件详情 ====================
// CredentialIngressDetail M-014: 凭证入站类型专用
type CredentialIngressDetail struct {
EventID string `json:"event_id"` // 事件ID
RequestCredentialType string `json:"request_credential_type"` // 请求中的凭证类型
ExpectedCredentialType string `json:"expected_credential_type"` // 期望的凭证类型
CoverageCompliant bool `json:"coverage_compliant"` // 是否合规
PlatformTokenPresent bool `json:"platform_token_present"` // 平台Token是否存在
UpstreamKeyPresent bool `json:"upstream_key_present"` // 上游Key是否存在
Reviewed bool `json:"reviewed"` // 是否已审核
ReviewedAt *time.Time `json:"reviewed_at"` // 审核时间
ReviewedBy *int64 `json:"reviewed_by"` // 审核人
}
// NewCredentialIngressDetail 创建凭证入站详情
func NewCredentialIngressDetail(
requestCredentialType string,
expectedCredentialType string,
coverageCompliant bool,
platformTokenPresent bool,
upstreamKeyPresent bool,
) *CredentialIngressDetail {
return &CredentialIngressDetail{
RequestCredentialType: requestCredentialType,
ExpectedCredentialType: expectedCredentialType,
CoverageCompliant: coverageCompliant,
PlatformTokenPresent: platformTokenPresent,
UpstreamKeyPresent: upstreamKeyPresent,
Reviewed: false,
}
}
// Review 标记为已审核
func (d *CredentialIngressDetail) Review(reviewedBy int64) {
now := time.Now()
d.Reviewed = true
d.ReviewedAt = &now
d.ReviewedBy = &reviewedBy
}
// ==================== M-015: 直连绕过事件详情 ====================
// DirectCallDetail M-015: 直连绕过专用
type DirectCallDetail struct {
EventID string `json:"event_id"` // 事件ID
ConsumerID int64 `json:"consumer_id"` // 消费者ID
SupplierID int64 `json:"supplier_id"` // 供应商ID
DirectEndpoint string `json:"direct_endpoint"` // 直连端点
ViaPlatform bool `json:"via_platform"` // 是否通过平台
BypassType string `json:"bypass_type"` // ip_bypass/proxy_bypass/config_bypass/dns_bypass
DetectionMethod string `json:"detection_method"` // 检测方法
Blocked bool `json:"blocked"` // 是否被阻断
BlockedAt *time.Time `json:"blocked_at"` // 阻断时间
BlockReason string `json:"block_reason"` // 阻断原因
}
// NewDirectCallDetail 创建直连详情
func NewDirectCallDetail(
consumerID int64,
supplierID int64,
directEndpoint string,
viaPlatform bool,
bypassType string,
detectionMethod string,
) *DirectCallDetail {
return &DirectCallDetail{
ConsumerID: consumerID,
SupplierID: supplierID,
DirectEndpoint: directEndpoint,
ViaPlatform: viaPlatform,
BypassType: bypassType,
DetectionMethod: detectionMethod,
Blocked: false,
}
}
// Block 标记为已阻断
func (d *DirectCallDetail) Block(reason string) {
now := time.Now()
d.Blocked = true
d.BlockedAt = &now
d.BlockReason = reason
}
// ==================== M-016: Query Key 拒绝事件详情 ====================
// QueryKeyRejectDetail M-016: query key 拒绝专用
type QueryKeyRejectDetail struct {
EventID string `json:"event_id"` // 事件ID
QueryKeyID string `json:"query_key_id"` // Query Key ID
RequestedEndpoint string `json:"requested_endpoint"` // 请求端点
RejectReason string `json:"reject_reason"` // not_allowed/expired/malformed/revoked/rate_limited
RejectCode string `json:"reject_code"` // 拒绝码
FirstOccurrence bool `json:"first_occurrence"` // 是否首次发生
OccurrenceCount int `json:"occurrence_count"` // 发生次数
}
// NewQueryKeyRejectDetail 创建Query Key拒绝详情
func NewQueryKeyRejectDetail(
queryKeyID string,
requestedEndpoint string,
rejectReason string,
rejectCode string,
) *QueryKeyRejectDetail {
return &QueryKeyRejectDetail{
QueryKeyID: queryKeyID,
RequestedEndpoint: requestedEndpoint,
RejectReason: rejectReason,
RejectCode: rejectCode,
FirstOccurrence: true,
OccurrenceCount: 1,
}
}
// RecordOccurrence 记录再次发生
func (d *QueryKeyRejectDetail) RecordOccurrence(firstOccurrence bool) {
d.FirstOccurrence = firstOccurrence
d.OccurrenceCount++
}
// ==================== 指标常量 ====================
// M-013 暴露类型常量
const (
ExposureTypeResponse = "exposed_in_response"
ExposureTypeLog = "exposed_in_log"
ExposureTypeExport = "exposed_in_export"
)
// M-013 暴露位置常量
const (
ExposureLocationResponseBody = "response_body"
ExposureLocationResponseHeader = "response_header"
ExposureLocationLogFile = "log_file"
ExposureLocationExportFile = "export_file"
)
// M-015 绕过类型常量
const (
BypassTypeIPBypass = "ip_bypass"
BypassTypeProxyBypass = "proxy_bypass"
BypassTypeConfigBypass = "config_bypass"
BypassTypeDNSBypass = "dns_bypass"
)
// M-015 检测方法常量
const (
DetectionMethodUpstreamAPIPattern = "upstream_api_pattern_match"
DetectionMethodDNSResolution = "dns_resolution_check"
DetectionMethodConnectionSource = "connection_source_check"
DetectionMethodIPWhitelist = "ip_whitelist_check"
)
// M-016 拒绝原因常量
const (
RejectReasonNotAllowed = "not_allowed"
RejectReasonExpired = "expired"
RejectReasonMalformed = "malformed"
RejectReasonRevoked = "revoked"
RejectReasonRateLimited = "rate_limited"
)
// M-016 拒绝码常量
const (
RejectCodeNotAllowed = "QUERY_KEY_NOT_ALLOWED"
RejectCodeExpired = "QUERY_KEY_EXPIRED"
RejectCodeMalformed = "QUERY_KEY_MALFORMED"
RejectCodeRevoked = "QUERY_KEY_REVOKED"
RejectCodeRateLimited = "QUERY_KEY_RATE_LIMITED"
)