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 }