package maximizer import ( "context" "fmt" "github.com/breakpilot/ai-compliance-sdk/internal/ucca" "github.com/google/uuid" ) // Service contains the business logic for the Compliance Maximizer. type Service struct { store *Store evaluator *Evaluator optimizer *Optimizer uccaStore *ucca.Store rules *ConstraintRuleSet } // NewService creates a maximizer service. func NewService(store *Store, uccaStore *ucca.Store, rules *ConstraintRuleSet) *Service { eval := NewEvaluator(rules) opt := NewOptimizer(eval) return &Service{ store: store, evaluator: eval, optimizer: opt, uccaStore: uccaStore, rules: rules, } } // OptimizeInput is the request to optimize a dimension config. type OptimizeInput struct { Config DimensionConfig `json:"config"` Title string `json:"title"` TenantID uuid.UUID `json:"-"` UserID uuid.UUID `json:"-"` } // OptimizeFromIntakeInput wraps a UCCA intake for optimization. type OptimizeFromIntakeInput struct { Intake ucca.UseCaseIntake `json:"intake"` Title string `json:"title"` TenantID uuid.UUID `json:"-"` UserID uuid.UUID `json:"-"` } // Optimize evaluates and optimizes a dimension config. func (s *Service) Optimize(ctx context.Context, in *OptimizeInput) (*Optimization, error) { result := s.optimizer.Optimize(&in.Config) o := &Optimization{ TenantID: in.TenantID, Title: in.Title, InputConfig: in.Config, IsCompliant: result.OriginalCompliant, OriginalEvaluation: *result.OriginalEval, Variants: result.Variants, ZoneMap: result.OriginalEval.ZoneMap, ConstraintVersion: s.rules.Version, CreatedBy: in.UserID, } if result.MaxSafeConfig != nil { o.MaxSafeConfig = result.MaxSafeConfig } if err := s.store.CreateOptimization(ctx, o); err != nil { return nil, fmt.Errorf("optimize: %w", err) } return o, nil } // OptimizeFromIntake maps a UCCA intake to dimensions and optimizes. func (s *Service) OptimizeFromIntake(ctx context.Context, in *OptimizeFromIntakeInput) (*Optimization, error) { config := MapIntakeToDimensions(&in.Intake) return s.Optimize(ctx, &OptimizeInput{ Config: *config, Title: in.Title, TenantID: in.TenantID, UserID: in.UserID, }) } // OptimizeFromAssessment loads an existing UCCA assessment and optimizes it. func (s *Service) OptimizeFromAssessment(ctx context.Context, assessmentID, tenantID, userID uuid.UUID) (*Optimization, error) { assessment, err := s.uccaStore.GetAssessment(ctx, assessmentID) if err != nil { return nil, fmt.Errorf("load assessment %s: %w", assessmentID, err) } config := MapIntakeToDimensions(&assessment.Intake) result := s.optimizer.Optimize(config) o := &Optimization{ TenantID: tenantID, AssessmentID: &assessmentID, Title: assessment.Title, InputConfig: *config, IsCompliant: result.OriginalCompliant, OriginalEvaluation: *result.OriginalEval, Variants: result.Variants, ZoneMap: result.OriginalEval.ZoneMap, ConstraintVersion: s.rules.Version, CreatedBy: userID, } if result.MaxSafeConfig != nil { o.MaxSafeConfig = result.MaxSafeConfig } if err := s.store.CreateOptimization(ctx, o); err != nil { return nil, fmt.Errorf("optimize from assessment: %w", err) } return o, nil } // Evaluate only evaluates without persisting (3-zone analysis). func (s *Service) Evaluate(config *DimensionConfig) *EvaluationResult { return s.evaluator.Evaluate(config) } // GetOptimization retrieves a stored optimization. func (s *Service) GetOptimization(ctx context.Context, id uuid.UUID) (*Optimization, error) { return s.store.GetOptimization(ctx, id) } // ListOptimizations returns optimizations for a tenant. func (s *Service) ListOptimizations(ctx context.Context, tenantID uuid.UUID, f *OptimizationFilters) ([]Optimization, int, error) { return s.store.ListOptimizations(ctx, tenantID, f) } // DeleteOptimization removes an optimization. func (s *Service) DeleteOptimization(ctx context.Context, id uuid.UUID) error { return s.store.DeleteOptimization(ctx, id) } // GetDimensionSchema returns the dimension schema for the frontend. func (s *Service) GetDimensionSchema() map[string][]string { return AllValues } // GetConstraintRules returns the loaded rules for transparency. func (s *Service) GetConstraintRules() *ConstraintRuleSet { return s.rules }