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,152 @@
package model
import (
"time"
)
// RoleScopeMapping 角色-Scope关联模型
// 对应数据库 iam_role_scopes 表
type RoleScopeMapping struct {
ID int64 // 主键ID
RoleID int64 // 角色ID (FK -> iam_roles.id)
ScopeID int64 // ScopeID (FK -> iam_scopes.id)
IsActive bool // 是否激活
// 审计字段
RequestID string // 请求追踪ID
CreatedIP string // 创建者IP
Version int // 乐观锁版本号
// 时间戳
CreatedAt *time.Time // 创建时间
}
// NewRoleScopeMapping 创建新的角色-Scope映射
func NewRoleScopeMapping(roleID, scopeID int64) *RoleScopeMapping {
now := time.Now()
return &RoleScopeMapping{
RoleID: roleID,
ScopeID: scopeID,
IsActive: true,
RequestID: generateRequestID(),
Version: 1,
CreatedAt: &now,
}
}
// NewRoleScopeMappingWithAudit 创建带审计信息的角色-Scope映射
func NewRoleScopeMappingWithAudit(roleID, scopeID int64, requestID, createdIP string) *RoleScopeMapping {
now := time.Now()
return &RoleScopeMapping{
RoleID: roleID,
ScopeID: scopeID,
IsActive: true,
RequestID: requestID,
CreatedIP: createdIP,
Version: 1,
CreatedAt: &now,
}
}
// Revoke 撤销角色-Scope映射
func (m *RoleScopeMapping) Revoke() {
m.IsActive = false
}
// Grant 授予角色-Scope映射
func (m *RoleScopeMapping) Grant() {
m.IsActive = true
}
// IncrementVersion 递增版本号
func (m *RoleScopeMapping) IncrementVersion() {
m.Version++
}
// GrantScopeList 批量授予Scope
func GrantScopeList(roleID int64, scopeIDs []int64) []*RoleScopeMapping {
mappings := make([]*RoleScopeMapping, 0, len(scopeIDs))
for _, scopeID := range scopeIDs {
mapping := NewRoleScopeMapping(roleID, scopeID)
mappings = append(mappings, mapping)
}
return mappings
}
// RevokeAll 撤销所有映射
func RevokeAll(mappings []*RoleScopeMapping) {
for _, mapping := range mappings {
mapping.Revoke()
}
}
// GetActiveScopeIDs 从映射列表中获取活跃的Scope ID列表
func GetActiveScopeIDs(mappings []*RoleScopeMapping) []int64 {
activeIDs := make([]int64, 0, len(mappings))
for _, mapping := range mappings {
if mapping.IsActive {
activeIDs = append(activeIDs, mapping.ScopeID)
}
}
return activeIDs
}
// GetInactiveScopeIDs 从映射列表中获取非活跃的Scope ID列表
func GetInactiveScopeIDs(mappings []*RoleScopeMapping) []int64 {
inactiveIDs := make([]int64, 0, len(mappings))
for _, mapping := range mappings {
if !mapping.IsActive {
inactiveIDs = append(inactiveIDs, mapping.ScopeID)
}
}
return inactiveIDs
}
// FilterActiveMappings 过滤出活跃的映射
func FilterActiveMappings(mappings []*RoleScopeMapping) []*RoleScopeMapping {
active := make([]*RoleScopeMapping, 0, len(mappings))
for _, mapping := range mappings {
if mapping.IsActive {
active = append(active, mapping)
}
}
return active
}
// FilterMappingsByRole 过滤出指定角色的映射
func FilterMappingsByRole(mappings []*RoleScopeMapping, roleID int64) []*RoleScopeMapping {
filtered := make([]*RoleScopeMapping, 0, len(mappings))
for _, mapping := range mappings {
if mapping.RoleID == roleID {
filtered = append(filtered, mapping)
}
}
return filtered
}
// FilterMappingsByScope 过滤出指定Scope的映射
func FilterMappingsByScope(mappings []*RoleScopeMapping, scopeID int64) []*RoleScopeMapping {
filtered := make([]*RoleScopeMapping, 0, len(mappings))
for _, mapping := range mappings {
if mapping.ScopeID == scopeID {
filtered = append(filtered, mapping)
}
}
return filtered
}
// RoleScopeMappingInfo 角色-Scope映射信息用于API响应
type RoleScopeMappingInfo struct {
RoleID int64 `json:"role_id"`
ScopeID int64 `json:"scope_id"`
IsActive bool `json:"is_active"`
}
// ToInfo 转换为映射信息
func (m *RoleScopeMapping) ToInfo() *RoleScopeMappingInfo {
return &RoleScopeMappingInfo{
RoleID: m.RoleID,
ScopeID: m.ScopeID,
IsActive: m.IsActive,
}
}