refactor(go/ucca): split license_policy, models, pdf_export, escalation_store, obligations_registry
Split 5 oversized files (501-583 LOC each) into focused units all under 500 LOC: - license_policy.go → +_types.go (engine logic / type definitions) - models.go → +_intake.go, +_assessment.go (enums+domains / intake structs / output+DB types) - pdf_export.go → +_markdown.go (PDF export / markdown export) - escalation_store.go → +_dsb.go (main escalation ops / DSB pool ops) - obligations_registry.go → +_grouping.go (registry core / grouping methods) All files remain in package ucca. Zero behavior changes. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
123
ai-compliance-sdk/internal/ucca/escalation_store_dsb.go
Normal file
123
ai-compliance-sdk/internal/ucca/escalation_store_dsb.go
Normal file
@@ -0,0 +1,123 @@
|
||||
package ucca
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/google/uuid"
|
||||
)
|
||||
|
||||
// ============================================================================
|
||||
// DSB Pool Operations
|
||||
// ============================================================================
|
||||
|
||||
// AddDSBPoolMember adds a member to the DSB review pool.
|
||||
func (s *EscalationStore) AddDSBPoolMember(ctx context.Context, m *DSBPoolMember) error {
|
||||
query := `
|
||||
INSERT INTO ucca_dsb_pool (
|
||||
id, tenant_id, user_id, user_name, user_email, role,
|
||||
is_active, max_concurrent_reviews, created_at, updated_at
|
||||
) VALUES (
|
||||
$1, $2, $3, $4, $5, $6, $7, $8, NOW(), NOW()
|
||||
)
|
||||
ON CONFLICT (tenant_id, user_id) DO UPDATE
|
||||
SET user_name = $4, user_email = $5, role = $6,
|
||||
is_active = $7, max_concurrent_reviews = $8, updated_at = NOW()
|
||||
`
|
||||
|
||||
if m.ID == uuid.Nil {
|
||||
m.ID = uuid.New()
|
||||
}
|
||||
|
||||
_, err := s.pool.Exec(ctx, query,
|
||||
m.ID, m.TenantID, m.UserID, m.UserName, m.UserEmail, m.Role,
|
||||
m.IsActive, m.MaxConcurrentReviews,
|
||||
)
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
// GetDSBPoolMembers retrieves active DSB pool members for a tenant.
|
||||
func (s *EscalationStore) GetDSBPoolMembers(ctx context.Context, tenantID uuid.UUID, role string) ([]DSBPoolMember, error) {
|
||||
query := `
|
||||
SELECT id, tenant_id, user_id, user_name, user_email, role,
|
||||
is_active, max_concurrent_reviews, current_reviews, created_at, updated_at
|
||||
FROM ucca_dsb_pool
|
||||
WHERE tenant_id = $1 AND is_active = true
|
||||
`
|
||||
args := []interface{}{tenantID}
|
||||
|
||||
if role != "" {
|
||||
query += " AND role = $2"
|
||||
args = append(args, role)
|
||||
}
|
||||
|
||||
query += " ORDER BY current_reviews ASC, user_name ASC"
|
||||
|
||||
rows, err := s.pool.Query(ctx, query, args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
var members []DSBPoolMember
|
||||
for rows.Next() {
|
||||
var m DSBPoolMember
|
||||
err := rows.Scan(
|
||||
&m.ID, &m.TenantID, &m.UserID, &m.UserName, &m.UserEmail, &m.Role,
|
||||
&m.IsActive, &m.MaxConcurrentReviews, &m.CurrentReviews, &m.CreatedAt, &m.UpdatedAt,
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
members = append(members, m)
|
||||
}
|
||||
|
||||
return members, nil
|
||||
}
|
||||
|
||||
// GetNextAvailableReviewer finds the next available reviewer for a role.
|
||||
func (s *EscalationStore) GetNextAvailableReviewer(ctx context.Context, tenantID uuid.UUID, role string) (*DSBPoolMember, error) {
|
||||
query := `
|
||||
SELECT id, tenant_id, user_id, user_name, user_email, role,
|
||||
is_active, max_concurrent_reviews, current_reviews, created_at, updated_at
|
||||
FROM ucca_dsb_pool
|
||||
WHERE tenant_id = $1 AND is_active = true AND role = $2
|
||||
AND current_reviews < max_concurrent_reviews
|
||||
ORDER BY current_reviews ASC
|
||||
LIMIT 1
|
||||
`
|
||||
|
||||
var m DSBPoolMember
|
||||
err := s.pool.QueryRow(ctx, query, tenantID, role).Scan(
|
||||
&m.ID, &m.TenantID, &m.UserID, &m.UserName, &m.UserEmail, &m.Role,
|
||||
&m.IsActive, &m.MaxConcurrentReviews, &m.CurrentReviews, &m.CreatedAt, &m.UpdatedAt,
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &m, nil
|
||||
}
|
||||
|
||||
// IncrementReviewerCount increments the current review count for a DSB member.
|
||||
func (s *EscalationStore) IncrementReviewerCount(ctx context.Context, userID uuid.UUID) error {
|
||||
query := `
|
||||
UPDATE ucca_dsb_pool
|
||||
SET current_reviews = current_reviews + 1, updated_at = NOW()
|
||||
WHERE user_id = $1
|
||||
`
|
||||
_, err := s.pool.Exec(ctx, query, userID)
|
||||
return err
|
||||
}
|
||||
|
||||
// DecrementReviewerCount decrements the current review count for a DSB member.
|
||||
func (s *EscalationStore) DecrementReviewerCount(ctx context.Context, userID uuid.UUID) error {
|
||||
query := `
|
||||
UPDATE ucca_dsb_pool
|
||||
SET current_reviews = GREATEST(0, current_reviews - 1), updated_at = NOW()
|
||||
WHERE user_id = $1
|
||||
`
|
||||
_, err := s.pool.Exec(ctx, query, userID)
|
||||
return err
|
||||
}
|
||||
Reference in New Issue
Block a user