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:
152
supply-api/internal/iam/model/role_scope.go
Normal file
152
supply-api/internal/iam/model/role_scope.go
Normal 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,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user