// Copyright 2025 Chris Bunting
// Brief: Context-aware analysis engine for MCP Code Analysis & Quality Server
// Scope: Provides intelligent analysis based on project context, team preferences, and historical data
import { EventEmitter } from 'events';
import {
UnifiedAnalysisResult,
AnalysisContext,
AnalysisIssue,
UnifiedIssue,
SeverityLevel,
PriorityLevel,
IssueCategory,
Location,
ImpactAssessment,
CrossReference,
CorrelationData,
SuggestionData,
PatternData,
TeamContext,
UserPreferences,
HistoricalData,
QualityTrend,
PerformanceData,
TrendDirection,
PatternType,
CorrelationType,
SuggestionType,
ProjectType,
DevelopmentStage,
ExperienceLevel,
CollaborationStyle,
AnalysisDepth,
LoggerInterface,
CacheInterface
} from '@mcp-code-analysis/shared-types';
export interface ContextAnalysisConfig {
enableLearning: boolean;
enablePatternRecognition: boolean;
enableCorrelationAnalysis: boolean;
enableImpactAssessment: boolean;
maxHistoricalData: number;
patternThreshold: number;
correlationThreshold: number;
learningRate: number;
contextWeight: {
projectType: number;
developmentStage: number;
teamExperience: number;
historicalPerformance: number;
userPreferences: number;
};
}
export interface ContextAnalysisRequest {
projectId: string;
analysisResults: UnifiedAnalysisResult[];
context: AnalysisContext;
options: ContextAnalysisOptions;
}
export interface ContextAnalysisOptions {
includePatterns: boolean;
includeCorrelations: boolean;
includeImpactAssessment: boolean;
includeSuggestions: boolean;
depth: AnalysisDepth;
focusAreas: FocusArea[];
}
export interface FocusArea {
type: FocusType;
priority: PriorityLevel;
criteria: FocusCriteria[];
}
export interface FocusCriteria {
field: string;
operator: FilterOperator;
value: any;
}
export interface ContextAnalysisResult {
id: string;
projectId: string;
timestamp: Date;
originalResults: UnifiedAnalysisResult[];
enhancedResults: EnhancedAnalysisResult[];
patterns: ContextPattern[];
correlations: ContextCorrelation[];
impactAssessment: ContextImpactAssessment;
suggestions: ContextSuggestion[];
insights: ContextInsight[];
metadata: AnalysisMetadata;
}
export interface EnhancedAnalysisResult extends UnifiedAnalysisResult {
contextScore: number;
relevanceScore: number;
priorityAdjustment: number;
contextualFactors: ContextualFactor[];
teamConsiderations: TeamConsideration[];
historicalContext: HistoricalContext[];
}
export interface ContextualFactor {
type: FactorType;
description: string;
impact: number;
confidence: number;
evidence: string[];
}
export interface TeamConsideration {
aspect: TeamAspect;
recommendation: string;
priority: PriorityLevel;
effort: number;
expectedOutcome: string;
}
export interface HistoricalContext {
timeframe: Timeframe;
pattern: string;
frequency: number;
trend: TrendDirection;
impact: number;
}
export interface ContextPattern {
id: string;
type: PatternType;
description: string;
confidence: number;
frequency: number;
impact: number;
locations: Location[];
context: PatternContext;
suggestions: string[];
}
export interface PatternContext {
projectType: ProjectType;
developmentStage: DevelopmentStage;
teamExperience: ExperienceLevel;
technologyFactors: string[];
businessFactors: string[];
}
export interface ContextCorrelation {
id: string;
type: CorrelationType;
description: string;
confidence: number;
strength: number;
relatedIssues: string[];
causalFactors: string[];
context: CorrelationContext;
}
export interface CorrelationContext {
temporal: TemporalContext;
spatial: SpatialContext;
technical: TechnicalContext;
team: TeamContext;
}
export interface TemporalContext {
timeframe: Timeframe;
frequency: number;
trend: TrendDirection;
}
export interface SpatialContext {
files: string[];
modules: string[];
components: string[];
}
export interface TechnicalContext {
technologies: string[];
patterns: string[];
dependencies: string[];
}
export interface ContextImpactAssessment {
overallImpact: ImpactAssessment;
categoryImpacts: CategoryImpact[];
teamImpact: TeamImpact;
businessImpact: BusinessImpact;
technicalImpact: TechnicalImpact;
}
export interface CategoryImpact {
category: IssueCategory;
impact: number;
priority: PriorityLevel;
rationale: string;
}
export interface TeamImpact {
productivity: number;
morale: number;
learning: number;
collaboration: number;
}
export interface BusinessImpact {
revenue: number;
cost: number;
risk: number;
opportunity: number;
}
export interface TechnicalImpact {
maintainability: number;
scalability: number;
performance: number;
security: number;
}
export interface ContextSuggestion extends SuggestionData {
contextRelevance: number;
teamAlignment: number;
historicalSuccess: number;
implementationComplexity: number;
expectedROI: number;
contextualFactors: string[];
}
export interface ContextInsight {
id: string;
type: InsightType;
title: string;
description: string;
confidence: number;
impact: ImpactAssessment;
evidence: string[];
recommendations: string[];
context: InsightContext;
}
export interface InsightContext {
projectContext: AnalysisContext;
teamContext: TeamContext;
historicalContext: HistoricalData;
marketContext: MarketContext;
}
export interface MarketContext {
industry: string;
competition: string;
trends: string[];
regulations: string[];
}
export interface AnalysisMetadata {
generatedAt: Date;
generationTime: number;
analysisDepth: AnalysisDepth;
patternsFound: number;
correlationsFound: number;
suggestionsGenerated: number;
insightsGenerated: number;
contextFactors: ContextFactor[];
}
export enum FactorType {
PROJECT_TYPE = 'project-type',
DEVELOPMENT_STAGE = 'development-stage',
TEAM_EXPERIENCE = 'team-experience',
TECHNOLOGY_STACK = 'technology-stack',
BUSINESS_DOMAIN = 'business-domain',
REGULATORY_REQUIREMENTS = 'regulatory-requirements',
PERFORMANCE_REQUIREMENTS = 'performance-requirements',
SECURITY_REQUIREMENTS = 'security-requirements'
}
export enum TeamAspect {
SKILL_LEVEL = 'skill-level',
CODING_STANDARDS = 'coding-standards',
COLLABORATION_STYLE = 'collaboration-style',
PREFERRED_PRACTICES = 'preferred-practices',
LEARNING_APTITUDE = 'learning-aptitude',
COMMUNICATION_PATTERNS = 'communication-patterns'
}
export enum FocusType {
PERFORMANCE = 'performance',
SECURITY = 'security',
MAINTAINABILITY = 'maintainability',
SCALABILITY = 'scalability',
USABILITY = 'usability',
COMPLIANCE = 'compliance'
}
export enum FilterOperator {
EQUALS = 'equals',
NOT_EQUALS = 'not-equals',
GREATER_THAN = 'greater-than',
LESS_THAN = 'less-than',
CONTAINS = 'contains',
IN = 'in',
MATCHES = 'matches'
}
export enum InsightType {
QUALITY_TREND = 'quality-trend',
TEAM_PATTERN = 'team-pattern',
TECHNOLOGY_RISK = 'technology-risk',
BUSINESS_IMPACT = 'business-impact',
PROCESS_IMPROVEMENT = 'process-improvement',
SKILL_DEVELOPMENT = 'skill-development'
}
export class ContextAwareAnalysisEngine extends EventEmitter {
private config: ContextAnalysisConfig;
private cache: CacheInterface;
private logger: LoggerInterface;
private patternDatabase: Map<string, ContextPattern[]> = new Map();
private correlationDatabase: Map<string, ContextCorrelation[]> = new Map();
private learningData: Map<string, LearningData> = new Map();
constructor(config: ContextAnalysisConfig, cache: CacheInterface, logger: LoggerInterface) {
super();
this.config = config;
this.cache = cache;
this.logger = logger;
this.setupEventHandlers();
}
private setupEventHandlers(): void {
this.on('pattern-discovered', this.handlePatternDiscovered.bind(this));
this.on('correlation-found', this.handleCorrelationFound.bind(this));
this.on('insight-generated', this.handleInsightGenerated.bind(this));
this.on('context-updated', this.handleContextUpdated.bind(this));
}
async initialize(): Promise<void> {
this.logger.info('Initializing Context-Aware Analysis Engine');
// Load pattern and correlation databases
await this.loadDatabases();
// Load learning data
await this.loadLearningData();
this.logger.info('Context-Aware Analysis Engine initialized successfully');
}
async analyzeWithContext(request: ContextAnalysisRequest): Promise<ContextAnalysisResult> {
try {
this.logger.info(`Starting context-aware analysis for project: ${request.projectId}`);
const startTime = Date.now();
// Enhance analysis results with context
const enhancedResults = await this.enhanceAnalysisResults(request);
// Discover patterns
const patterns = request.options.includePatterns
? await this.discoverPatterns(request, enhancedResults)
: [];
// Find correlations
const correlations = request.options.includeCorrelations
? await this.findCorrelations(request, enhancedResults)
: [];
// Assess impact
const impactAssessment = request.options.includeImpactAssessment
? await this.assessImpact(request, enhancedResults, patterns, correlations)
: this.createDefaultImpactAssessment();
// Generate suggestions
const suggestions = request.options.includeSuggestions
? await this.generateSuggestions(request, enhancedResults, patterns, correlations, impactAssessment)
: [];
// Generate insights
const insights = await this.generateInsights(request, enhancedResults, patterns, correlations, impactAssessment);
// Create metadata
const metadata = await this.createAnalysisMetadata(request, Date.now() - startTime);
// Assemble final result
const result: ContextAnalysisResult = {
id: this.generateAnalysisId(),
projectId: request.projectId,
timestamp: new Date(),
originalResults: request.analysisResults,
enhancedResults,
patterns,
correlations,
impactAssessment,
suggestions,
insights,
metadata
};
// Update learning data if enabled
if (this.config.enableLearning) {
await this.updateLearningData(request, result);
}
// Emit event
this.emit('analysis-completed', result);
this.logger.info(`Context-aware analysis completed in ${Date.now() - startTime}ms`);
return result;
} catch (error) {
this.logger.error('Failed to perform context-aware analysis:', error);
throw error;
}
}
private async enhanceAnalysisResults(request: ContextAnalysisRequest): Promise<EnhancedAnalysisResult[]> {
const enhancedResults: EnhancedAnalysisResult[] = [];
for (const result of request.analysisResults) {
const enhanced = await this.enhanceSingleResult(result, request.context);
enhancedResults.push(enhanced);
}
return enhancedResults;
}
private async enhanceSingleResult(result: UnifiedAnalysisResult, context: AnalysisContext): Promise<EnhancedAnalysisResult> {
// Calculate context score
const contextScore = await this.calculateContextScore(result, context);
// Calculate relevance score
const relevanceScore = await this.calculateRelevanceScore(result, context);
// Adjust priority based on context
const priorityAdjustment = await this.calculatePriorityAdjustment(result, context);
// Identify contextual factors
const contextualFactors = await this.identifyContextualFactors(result, context);
// Consider team aspects
const teamConsiderations = await this.generateTeamConsiderations(result, context);
// Provide historical context
const historicalContext = await this.generateHistoricalContext(result, context);
return {
...result,
contextScore,
relevanceScore,
priorityAdjustment,
contextualFactors,
teamConsiderations,
historicalContext
};
}
private async calculateContextScore(result: UnifiedAnalysisResult, context: AnalysisContext): Promise<number> {
let score = 0;
const weights = this.config.contextWeight;
// Project type relevance
score += this.getProjectTypeRelevance(result, context.projectType) * weights.projectType;
// Development stage relevance
score += this.getDevelopmentStageRelevance(result, context.developmentStage) * weights.developmentStage;
// Team experience relevance
score += this.getTeamExperienceRelevance(result, context.teamContext.experienceLevel) * weights.teamExperience;
// Historical performance relevance
score += this.getHistoricalPerformanceRelevance(result, context.historicalData) * weights.historicalPerformance;
// User preferences relevance
score += this.getUserPreferencesRelevance(result, context.userPreferences) * weights.userPreferences;
return Math.min(100, Math.max(0, score));
}
private async calculateRelevanceScore(result: UnifiedAnalysisResult, context: AnalysisContext): Promise<number> {
// Calculate relevance based on current focus areas and project priorities
let relevance = 50; // Base relevance
// Adjust based on issue categories and project priorities
const categoryRelevance = this.getCategoryRelevance(result.issues, context);
relevance += categoryRelevance * 0.3;
// Adjust based on severity and project stage
const severityRelevance = this.getSeverityRelevance(result.issues, context.developmentStage);
relevance += severityRelevance * 0.3;
// Adjust based on technology stack alignment
const techRelevance = this.getTechnologyRelevance(result, context.technologyStack);
relevance += techRelevance * 0.2;
// Adjust based on team capabilities
const teamRelevance = this.getTeamRelevance(result, context.teamContext);
relevance += teamRelevance * 0.2;
return Math.min(100, Math.max(0, relevance));
}
private async calculatePriorityAdjustment(result: UnifiedAnalysisResult, context: AnalysisContext): Promise<number> {
let adjustment = 0;
// Adjust based on development stage
switch (context.developmentStage) {
case DevelopmentStage.PLANNING:
adjustment -= 0.2; // Lower priority in planning
break;
case DevelopmentStage.DEVELOPMENT:
adjustment += 0.1; // Higher priority during development
break;
case DevelopmentStage.TESTING:
adjustment += 0.3; // Much higher priority during testing
break;
case DevelopmentStage.DEPLOYMENT:
adjustment += 0.4; // Highest priority during deployment
break;
case DevelopmentStage.MAINTENANCE:
adjustment += 0.2; // Higher priority in maintenance
break;
}
// Adjust based on team experience
switch (context.teamContext.experienceLevel) {
case ExperienceLevel.JUNIOR:
adjustment += 0.2; // Higher priority for junior teams
break;
case ExperienceLevel.EXPERT:
adjustment -= 0.1; // Lower priority for expert teams
break;
}
// Adjust based on business criticality
if (context.projectType === ProjectType.API || context.projectType === ProjectType.MICROSERVICE) {
adjustment += 0.2;
}
return adjustment;
}
private async identifyContextualFactors(result: UnifiedAnalysisResult, context: AnalysisContext): Promise<ContextualFactor[]> {
const factors: ContextualFactor[] = [];
// Project type factors
factors.push({
type: FactorType.PROJECT_TYPE,
description: `Analysis tailored for ${context.projectType} project`,
impact: 0.8,
confidence: 0.9,
evidence: ['Project type classification', 'Technology stack analysis']
});
// Development stage factors
factors.push({
type: FactorType.DEVELOPMENT_STAGE,
description: `Considerations for ${context.developmentStage} stage`,
impact: 0.7,
confidence: 0.85,
evidence: ['Development lifecycle stage', 'Team workflow analysis']
});
// Team experience factors
factors.push({
type: FactorType.TEAM_EXPERIENCE,
description: `Adjusted for ${context.teamContext.experienceLevel} experience level`,
impact: 0.6,
confidence: 0.8,
evidence: ['Team skill assessment', 'Historical performance data']
});
// Technology stack factors
factors.push({
type: FactorType.TECHNOLOGY_STACK,
description: `Analysis considers ${context.technologyStack.join(', ')} technologies`,
impact: 0.75,
confidence: 0.9,
evidence: ['Technology dependency analysis', 'Framework-specific patterns']
});
return factors;
}
private async generateTeamConsiderations(result: UnifiedAnalysisResult, context: AnalysisContext): Promise<TeamConsideration[]> {
const considerations: TeamConsideration[] = [];
// Skill level considerations
if (context.teamContext.experienceLevel === ExperienceLevel.JUNIOR) {
considerations.push({
aspect: TeamAspect.SKILL_LEVEL,
recommendation: 'Provide detailed documentation and pair programming opportunities',
priority: PriorityLevel.HIGH,
effort: 3,
expectedOutcome: 'Improved code quality and faster onboarding'
});
}
// Coding standards considerations
considerations.push({
aspect: TeamAspect.CODING_STANDARDS,
recommendation: 'Ensure adherence to team coding standards and best practices',
priority: PriorityLevel.MEDIUM,
effort: 2,
expectedOutcome: 'Consistent code quality and maintainability'
});
// Collaboration style considerations
if (context.teamContext.collaborationStyle === CollaborationStyle.CODE_REVIEW) {
considerations.push({
aspect: TeamAspect.COLLABORATION_STYLE,
recommendation: 'Leverage code review process for knowledge sharing',
priority: PriorityLevel.MEDIUM,
effort: 2,
expectedOutcome: 'Improved code quality and team knowledge'
});
}
return considerations;
}
private async generateHistoricalContext(result: UnifiedAnalysisResult, context: AnalysisContext): Promise<HistoricalContext[]> {
const historicalContext: HistoricalContext[] = [];
// Analyze historical trends
for (const trend of context.historicalData.qualityTrends) {
historicalContext.push({
timeframe: Timeframe.MONTH,
pattern: trend.metric,
frequency: 1, // Default frequency since we don't have the actual data structure
trend: trend.trend,
impact: this.calculateTrendImpact(trend)
});
}
// Analyze performance history
for (const perf of context.historicalData.performanceHistory) {
historicalContext.push({
timeframe: Timeframe.MONTH,
pattern: perf.metric,
frequency: 1, // Default frequency since we don't have the actual data structure
trend: perf.deviation > 0 ? TrendDirection.DECLINING : TrendDirection.IMPROVING,
impact: Math.abs(perf.deviation)
});
}
return historicalContext;
}
private async discoverPatterns(request: ContextAnalysisRequest, results: EnhancedAnalysisResult[]): Promise<ContextPattern[]> {
const patterns: ContextPattern[] = [];
// Analyze patterns across all results
const allIssues = results.flatMap(r => r.issues);
// Discover recurring issue patterns
const issuePatterns = await this.discoverIssuePatterns(allIssues, request.context);
patterns.push(...issuePatterns);
// Discover technology-specific patterns
const techPatterns = await this.discoverTechnologyPatterns(results, request.context);
patterns.push(...techPatterns);
// Discover team-specific patterns
const teamPatterns = await this.discoverTeamPatterns(results, request.context);
patterns.push(...teamPatterns);
// Filter patterns by threshold
return patterns.filter(p => p.confidence >= this.config.patternThreshold);
}
private async discoverIssuePatterns(issues: UnifiedIssue[], context: AnalysisContext): Promise<ContextPattern[]> {
const patterns: ContextPattern[] = [];
// Group issues by category and analyze patterns
const categoryGroups = this.groupIssuesByCategory(issues);
for (const [category, categoryIssues] of categoryGroups) {
if (categoryIssues.length >= 3) { // Minimum threshold for pattern
const pattern: ContextPattern = {
id: this.generatePatternId(),
type: PatternType.CODE_SMELL,
description: `Recurring ${category} issues detected`,
confidence: this.calculatePatternConfidence(categoryIssues),
frequency: categoryIssues.length,
impact: this.calculatePatternImpact(categoryIssues),
locations: categoryIssues.map(i => i.location),
context: {
projectType: context.projectType,
developmentStage: context.developmentStage,
teamExperience: context.teamContext.experienceLevel,
technologyFactors: context.technologyStack,
businessFactors: []
},
suggestions: [
'Implement code review checkpoints',
'Add automated testing for common issues',
'Provide team training on best practices'
]
};
patterns.push(pattern);
}
}
return patterns;
}
private async discoverTechnologyPatterns(results: EnhancedAnalysisResult[], context: AnalysisContext): Promise<ContextPattern[]> {
const patterns: ContextPattern[] = [];
// Analyze patterns specific to the technology stack
for (const technology of context.technologyStack) {
const techIssues = results.flatMap(r => r.issues).filter(issue =>
this.isTechnologyRelated(issue, technology)
);
if (techIssues.length >= 2) {
const pattern: ContextPattern = {
id: this.generatePatternId(),
type: PatternType.ANTI_PATTERN,
description: `${technology}-specific anti-patterns detected`,
confidence: this.calculatePatternConfidence(techIssues),
frequency: techIssues.length,
impact: this.calculatePatternImpact(techIssues),
locations: techIssues.map(i => i.location),
context: {
projectType: context.projectType,
developmentStage: context.developmentStage,
teamExperience: context.teamContext.experienceLevel,
technologyFactors: [technology],
businessFactors: []
},
suggestions: [
`Review ${technology} best practices`,
`Implement ${technology}-specific linting rules`,
`Consider refactoring problematic areas`
]
};
patterns.push(pattern);
}
}
return patterns;
}
private async discoverTeamPatterns(results: EnhancedAnalysisResult[], context: AnalysisContext): Promise<ContextPattern[]> {
const patterns: ContextPattern[] = [];
// Analyze patterns based on team collaboration style
const collaborationIssues = results.flatMap(r => r.issues).filter(issue =>
this.isCollaborationRelated(issue, context.teamContext.collaborationStyle)
);
if (collaborationIssues.length >= 2) {
const pattern: ContextPattern = {
id: this.generatePatternId(),
type: PatternType.BUG_PATTERN,
description: `Collaboration-related issues in ${context.teamContext.collaborationStyle} style`,
confidence: this.calculatePatternConfidence(collaborationIssues),
frequency: collaborationIssues.length,
impact: this.calculatePatternImpact(collaborationIssues),
locations: collaborationIssues.map(i => i.location),
context: {
projectType: context.projectType,
developmentStage: context.developmentStage,
teamExperience: context.teamContext.experienceLevel,
technologyFactors: context.technologyStack,
businessFactors: []
},
suggestions: [
'Improve communication protocols',
'Establish clear code ownership',
'Implement better documentation practices'
]
};
patterns.push(pattern);
}
return patterns;
}
private async findCorrelations(request: ContextAnalysisRequest, results: EnhancedAnalysisResult[]): Promise<ContextCorrelation[]> {
const correlations: ContextCorrelation[] = [];
// Find temporal correlations
const temporalCorrelations = await this.findTemporalCorrelations(results, request.context);
correlations.push(...temporalCorrelations);
// Find spatial correlations
const spatialCorrelations = await this.findSpatialCorrelations(results, request.context);
correlations.push(...spatialCorrelations);
// Find technical correlations
const technicalCorrelations = await this.findTechnicalCorrelations(results, request.context);
correlations.push(...technicalCorrelations);
// Filter correlations by threshold
return correlations.filter(c => c.confidence >= this.config.correlationThreshold);
}
private async findTemporalCorrelations(results: EnhancedAnalysisResult[], context: AnalysisContext): Promise<ContextCorrelation[]> {
const correlations: ContextCorrelation[] = [];
// Analyze temporal patterns in issues
const allIssues = results.flatMap(r => r.issues);
// Group issues by time patterns
const timeGroups = this.groupIssuesByTimePattern(allIssues);
for (const [pattern, issues] of timeGroups) {
if (issues.length >= 3) {
const correlation: ContextCorrelation = {
id: this.generateCorrelationId(),
type: CorrelationType.TEMPORAL,
description: `Temporal correlation: ${pattern}`,
confidence: this.calculateCorrelationConfidence(issues),
strength: issues.length / allIssues.length,
relatedIssues: issues.map(i => i.id),
causalFactors: ['Development cycle', 'Team workload', 'Deadline pressure'],
context: {
temporal: {
timeframe: Timeframe.WEEK,
frequency: issues.length,
trend: TrendDirection.STABLE
},
spatial: {
files: issues.map(i => i.location.filePath),
modules: [],
components: []
},
technical: {
technologies: context.technologyStack,
patterns: [],
dependencies: []
},
team: context.teamContext
}
};
correlations.push(correlation);
}
}
return correlations;
}
private async findSpatialCorrelations(results: EnhancedAnalysisResult[], context: AnalysisContext): Promise<ContextCorrelation[]> {
const correlations: ContextCorrelation[] = [];
// Analyze spatial patterns in issues
const allIssues = results.flatMap(r => r.issues);
// Group issues by file/module
const fileGroups = this.groupIssuesByFile(allIssues);
for (const [filePath, issues] of fileGroups) {
if (issues.length >= 3) {
const correlation: ContextCorrelation = {
id: this.generateCorrelationId(),
type: CorrelationType.CORRELATED,
description: `Spatial correlation in ${filePath}`,
confidence: this.calculateCorrelationConfidence(issues),
strength: issues.length / allIssues.length,
relatedIssues: issues.map(i => i.id),
causalFactors: ['File complexity', 'Code ownership', 'Module coupling'],
context: {
temporal: {
timeframe: Timeframe.MONTH,
frequency: issues.length,
trend: TrendDirection.STABLE
},
spatial: {
files: [filePath],
modules: this.extractModules(filePath),
components: this.extractComponents(filePath)
},
technical: {
technologies: context.technologyStack,
patterns: [],
dependencies: []
},
team: context.teamContext
}
};
correlations.push(correlation);
}
}
return correlations;
}
private async findTechnicalCorrelations(results: EnhancedAnalysisResult[], context: AnalysisContext): Promise<ContextCorrelation[]> {
const correlations: ContextCorrelation[] = [];
// Analyze technical correlations between issues
const allIssues = results.flatMap(r => r.issues);
// Group issues by technology
const techGroups = this.groupIssuesByTechnology(allIssues, context.technologyStack);
for (const [technology, issues] of techGroups) {
if (issues.length >= 2) {
const correlation: ContextCorrelation = {
id: this.generateCorrelationId(),
type: CorrelationType.CORRELATED,
description: `Technical correlation with ${technology}`,
confidence: this.calculateCorrelationConfidence(issues),
strength: issues.length / allIssues.length,
relatedIssues: issues.map(i => i.id),
causalFactors: ['Technology complexity', 'Framework limitations', 'Integration challenges'],
context: {
temporal: {
timeframe: Timeframe.MONTH,
frequency: issues.length,
trend: TrendDirection.STABLE
},
spatial: {
files: issues.map(i => i.location.filePath),
modules: [],
components: []
},
technical: {
technologies: [technology],
patterns: [],
dependencies: []
},
team: context.teamContext
}
};
correlations.push(correlation);
}
}
return correlations;
}
private async assessImpact(
request: ContextAnalysisRequest,
results: EnhancedAnalysisResult[],
patterns: ContextPattern[],
correlations: ContextCorrelation[]
): Promise<ContextImpactAssessment> {
// Calculate overall impact
const overallImpact = await this.calculateOverallImpact(results, patterns, correlations);
// Calculate category impacts
const categoryImpacts = await this.calculateCategoryImpacts(results);
// Calculate team impact
const teamImpact = await this.calculateTeamImpact(results, request.context);
// Calculate business impact
const businessImpact = await this.calculateBusinessImpact(results, request.context);
// Calculate technical impact
const technicalImpact = await this.calculateTechnicalImpact(results, patterns);
return {
overallImpact,
categoryImpacts,
teamImpact,
businessImpact,
technicalImpact
};
}
private async calculateOverallImpact(
results: EnhancedAnalysisResult[],
patterns: ContextPattern[],
correlations: ContextCorrelation[]
): Promise<ImpactAssessment> {
const totalIssues = results.reduce((sum, r) => sum + r.issues.length, 0);
const criticalIssues = results.reduce((sum, r) =>
sum + r.issues.filter(i => i.severity === SeverityLevel.ERROR).length, 0
);
const patternImpact = patterns.reduce((sum, p) => sum + p.impact, 0) / patterns.length || 0;
const correlationImpact = correlations.reduce((sum, c) => sum + c.strength, 0) / correlations.length || 0;
const businessImpact = (criticalIssues / totalIssues) * 10 + patternImpact * 3 + correlationImpact * 2;
const technicalImpact = (totalIssues / results.length) * 5 + patternImpact * 4 + correlationImpact * 3;
const userImpact = Math.min(businessImpact, technicalImpact) * 0.8;
const priorityScore = (businessImpact + technicalImpact + userImpact) / 3;
return {
businessImpact: Math.min(10, businessImpact),
technicalImpact: Math.min(10, technicalImpact),
userImpact: Math.min(10, userImpact),
priorityScore: Math.min(10, priorityScore),
effortEstimate: Math.ceil(totalIssues * 0.5),
riskLevel: this.calculateRiskLevel(criticalIssues, totalIssues)
};
}
private async calculateCategoryImpacts(results: EnhancedAnalysisResult[]): Promise<CategoryImpact[]> {
const categoryMap = new Map<IssueCategory, { count: number; severitySum: number }>();
// Aggregate issues by category
for (const result of results) {
for (const issue of result.issues) {
const current = categoryMap.get(issue.category) || { count: 0, severitySum: 0 };
current.count++;
current.severitySum += this.severityToWeight(issue.severity);
categoryMap.set(issue.category, current);
}
}
// Calculate impacts for each category
const impacts: CategoryImpact[] = [];
for (const [category, data] of categoryMap) {
const impact = (data.count / results.length) * 10 + (data.severitySum / data.count) * 5;
impacts.push({
category,
impact: Math.min(10, impact),
priority: this.impactToPriority(impact),
rationale: `${data.count} issues with average severity ${data.severitySum / data.count}`
});
}
return impacts;
}
private async calculateTeamImpact(results: EnhancedAnalysisResult[], context: AnalysisContext): Promise<TeamImpact> {
const totalIssues = results.reduce((sum, r) => sum + r.issues.length, 0);
const avgContextScore = results.reduce((sum, r) => sum + r.contextScore, 0) / results.length;
// Calculate impact on productivity
const productivity = Math.max(0, 10 - (totalIssues * 0.1) - (10 - avgContextScore) * 0.05);
// Calculate impact on morale
const morale = Math.max(0, 8 - (totalIssues * 0.05) - (10 - avgContextScore) * 0.1);
// Calculate impact on learning
const learning = Math.min(10, totalIssues * 0.2 + avgContextScore * 0.1);
// Calculate impact on collaboration
const collaboration = Math.max(0, 9 - (totalIssues * 0.08) - (10 - avgContextScore) * 0.07);
return {
productivity,
morale,
learning,
collaboration
};
}
private async calculateBusinessImpact(results: EnhancedAnalysisResult[], context: AnalysisContext): Promise<BusinessImpact> {
const totalIssues = results.reduce((sum, r) => sum + r.issues.length, 0);
const criticalIssues = results.reduce((sum, r) =>
sum + r.issues.filter(i => i.severity === SeverityLevel.ERROR).length, 0
);
// Calculate revenue impact
const revenue = Math.max(0, 10 - (criticalIssues * 0.5) - (totalIssues * 0.1));
// Calculate cost impact
const cost = Math.min(10, totalIssues * 0.3 + criticalIssues * 0.7);
// Calculate risk impact
const risk = Math.min(10, criticalIssues * 0.8 + (totalIssues * 0.2));
// Calculate opportunity impact
const opportunity = Math.max(0, 10 - (totalIssues * 0.15) - (criticalIssues * 0.3));
return {
revenue,
cost,
risk,
opportunity
};
}
private async calculateTechnicalImpact(results: EnhancedAnalysisResult[], patterns: ContextPattern[]): Promise<TechnicalImpact> {
const totalIssues = results.reduce((sum, r) => sum + r.issues.length, 0);
const patternImpact = patterns.reduce((sum, p) => sum + p.impact, 0) / patterns.length || 0;
// Calculate maintainability impact
const maintainability = Math.max(0, 10 - (totalIssues * 0.2) - (patternImpact * 0.3));
// Calculate scalability impact
const scalability = Math.max(0, 9 - (totalIssues * 0.15) - (patternImpact * 0.25));
// Calculate performance impact
const performance = Math.max(0, 8 - (totalIssues * 0.1) - (patternImpact * 0.2));
// Calculate security impact
const securityIssues = results.reduce((sum, r) =>
sum + r.issues.filter(i => i.category === IssueCategory.SECURITY).length, 0
);
const security = Math.max(0, 10 - (securityIssues * 0.8) - (patternImpact * 0.4));
return {
maintainability,
scalability,
performance,
security
};
}
private async generateSuggestions(
request: ContextAnalysisRequest,
results: EnhancedAnalysisResult[],
patterns: ContextPattern[],
correlations: ContextCorrelation[],
impactAssessment: ContextImpactAssessment
): Promise<ContextSuggestion[]> {
const suggestions: ContextSuggestion[] = [];
// Generate suggestions based on patterns
const patternSuggestions = await this.generatePatternSuggestions(patterns, request.context);
suggestions.push(...patternSuggestions);
// Generate suggestions based on correlations
const correlationSuggestions = await this.generateCorrelationSuggestions(correlations, request.context);
suggestions.push(...correlationSuggestions);
// Generate suggestions based on impact assessment
const impactSuggestions = await this.generateImpactSuggestions(impactAssessment, request.context);
suggestions.push(...impactSuggestions);
// Generate suggestions based on team context
const teamSuggestions = await this.generateTeamSuggestions(results, request.context);
suggestions.push(...teamSuggestions);
// Sort by expected ROI
suggestions.sort((a, b) => b.expectedROI - a.expectedROI);
return suggestions.slice(0, 10); // Limit to top 10 suggestions
}
private async generatePatternSuggestions(patterns: ContextPattern[], context: AnalysisContext): Promise<ContextSuggestion[]> {
const suggestions: ContextSuggestion[] = [];
for (const pattern of patterns) {
const suggestion: ContextSuggestion = {
id: this.generateSuggestionId(),
type: SuggestionType.REFACTOR,
description: `Address ${pattern.type} pattern: ${pattern.description}`,
priority: this.impactToPriority(pattern.impact),
impact: {
businessImpact: pattern.impact * 0.8,
technicalImpact: pattern.impact,
userImpact: pattern.impact * 0.6,
priorityScore: pattern.impact * 0.8,
effortEstimate: pattern.frequency * 0.5,
riskLevel: RiskLevel.MEDIUM
},
effort: pattern.frequency * 0.5,
implementation: {
steps: [
{ step: 1, description: 'Analyze affected code areas', verification: 'Code analysis completed' },
{ step: 2, description: 'Implement pattern fixes', verification: 'Pattern resolved' },
{ step: 3, description: 'Add preventive measures', verification: 'Prevention in place' }
],
resources: pattern.suggestions,
risks: ['Regression potential', 'Performance impact'],
benefits: ['Improved code quality', 'Reduced technical debt']
},
alternatives: [
{
id: 'alt-1',
description: 'Gradual refactoring approach',
pros: ['Lower risk', 'Easier to manage'],
cons: ['Takes longer', 'Partial benefits'],
effort: pattern.frequency * 0.3,
impact: {
businessImpact: pattern.impact * 0.6,
technicalImpact: pattern.impact * 0.7,
userImpact: pattern.impact * 0.5,
priorityScore: pattern.impact * 0.6,
effortEstimate: pattern.frequency * 0.3,
riskLevel: RiskLevel.LOW
}
}
],
contextRelevance: 0.9,
teamAlignment: this.calculateTeamAlignment(pattern, context),
historicalSuccess: 0.75,
implementationComplexity: pattern.impact * 0.2,
expectedROI: pattern.impact * 1.5,
contextualFactors: ['Pattern frequency', 'Team experience', 'Project stage']
};
suggestions.push(suggestion);
}
return suggestions;
}
private async generateCorrelationSuggestions(correlations: ContextCorrelation[], context: AnalysisContext): Promise<ContextSuggestion[]> {
const suggestions: ContextSuggestion[] = [];
for (const correlation of correlations) {
const suggestion: ContextSuggestion = {
id: this.generateSuggestionId(),
type: SuggestionType.OPTIMIZE,
description: `Address correlation: ${correlation.description}`,
priority: this.impactToPriority(correlation.strength * 10),
impact: {
businessImpact: correlation.strength * 6,
technicalImpact: correlation.strength * 8,
userImpact: correlation.strength * 5,
priorityScore: correlation.strength * 6.3,
effortEstimate: correlation.relatedIssues.length * 0.3,
riskLevel: RiskLevel.MEDIUM
},
effort: correlation.relatedIssues.length * 0.3,
implementation: {
steps: [
{ step: 1, description: 'Investigate correlation root causes', verification: 'Root cause identified' },
{ step: 2, description: 'Implement systemic fixes', verification: 'System fixed' },
{ step: 3, description: 'Monitor for recurrence', verification: 'Monitoring active' }
],
resources: correlation.causalFactors,
risks: ['System complexity', 'Unintended side effects'],
benefits: ['Reduced issue recurrence', 'Improved system stability']
},
alternatives: [],
contextRelevance: 0.85,
teamAlignment: this.calculateTeamAlignment(correlation, context),
historicalSuccess: 0.7,
implementationComplexity: correlation.strength * 3,
expectedROI: correlation.strength * 12,
contextualFactors: ['Correlation strength', 'Causal factors', 'System complexity']
};
suggestions.push(suggestion);
}
return suggestions;
}
private async generateImpactSuggestions(impactAssessment: ContextImpactAssessment, context: AnalysisContext): Promise<ContextSuggestion[]> {
const suggestions: ContextSuggestion[] = [];
// Generate suggestions based on business impact
if (impactAssessment.businessImpact.revenue < 7) {
suggestions.push({
id: this.generateSuggestionId(),
type: SuggestionType.OPTIMIZE,
description: 'Improve revenue-generating features',
priority: PriorityLevel.HIGH,
impact: impactAssessment.overallImpact,
effort: 5,
implementation: {
steps: [
{ step: 1, description: 'Identify revenue-critical code', verification: 'Code identified' },
{ step: 2, description: 'Optimize performance', verification: 'Performance improved' },
{ step: 3, description: 'Enhance user experience', verification: 'UX enhanced' }
],
resources: ['Performance profiling tools', 'User feedback'],
risks: ['Feature disruption', 'Performance regression'],
benefits: ['Increased revenue', 'Better user satisfaction']
},
alternatives: [],
contextRelevance: 0.95,
teamAlignment: 0.8,
historicalSuccess: 0.8,
implementationComplexity: 0.6,
expectedROI: 15,
contextualFactors: ['Revenue impact', 'Business criticality']
});
}
// Generate suggestions based on technical impact
if (impactAssessment.technicalImpact.maintainability < 6) {
suggestions.push({
id: this.generateSuggestionId(),
type: SuggestionType.REFACTOR,
description: 'Improve code maintainability',
priority: PriorityLevel.HIGH,
impact: impactAssessment.overallImpact,
effort: 4,
implementation: {
steps: [
{ step: 1, description: 'Refactor complex code', verification: 'Code simplified' },
{ step: 2, description: 'Improve documentation', verification: 'Documentation updated' },
{ step: 3, description: 'Add unit tests', verification: 'Tests added' }
],
resources: ['Refactoring tools', 'Documentation templates'],
risks: ['Introduction of bugs', 'Time investment'],
benefits: ['Easier maintenance', 'Faster development']
},
alternatives: [],
contextRelevance: 0.9,
teamAlignment: 0.85,
historicalSuccess: 0.75,
implementationComplexity: 0.5,
expectedROI: 12,
contextualFactors: ['Maintainability score', 'Team productivity']
});
}
return suggestions;
}
private async generateTeamSuggestions(results: EnhancedAnalysisResult[], context: AnalysisContext): Promise<ContextSuggestion[]> {
const suggestions: ContextSuggestion[] = [];
// Generate suggestions based on team experience
if (context.teamContext.experienceLevel === ExperienceLevel.JUNIOR) {
suggestions.push({
id: this.generateSuggestionId(),
type: SuggestionType.DOCUMENTATION,
description: 'Improve documentation for junior developers',
priority: PriorityLevel.HIGH,
impact: {
businessImpact: 6,
technicalImpact: 7,
userImpact: 8,
priorityScore: 7,
effortEstimate: 3,
riskLevel: RiskLevel.LOW
},
effort: 3,
implementation: {
steps: [
{ step: 1, description: 'Create comprehensive documentation', verification: 'Documentation created' },
{ step: 2, description: 'Add code examples', verification: 'Examples added' },
{ step: 3, description: 'Conduct training sessions', verification: 'Training completed' }
],
resources: ['Documentation tools', 'Training materials'],
risks: ['Documentation maintenance', 'Time investment'],
benefits: ['Faster onboarding', 'Reduced errors']
},
alternatives: [],
contextRelevance: 0.95,
teamAlignment: 0.9,
historicalSuccess: 0.85,
implementationComplexity: 0.4,
expectedROI: 10,
contextualFactors: ['Team experience level', 'Onboarding efficiency']
});
}
return suggestions;
}
private async generateInsights(
request: ContextAnalysisRequest,
results: EnhancedAnalysisResult[],
patterns: ContextPattern[],
correlations: ContextCorrelation[],
impactAssessment: ContextImpactAssessment
): Promise<ContextInsight[]> {
const insights: ContextInsight[] = [];
// Generate quality trend insights
const qualityInsight = await this.generateQualityTrendInsight(results, request.context);
if (qualityInsight) insights.push(qualityInsight);
// Generate team pattern insights
const teamInsight = await this.generateTeamPatternInsight(results, request.context);
if (teamInsight) insights.push(teamInsight);
// Generate technology risk insights
const techInsight = await this.generateTechnologyRiskInsight(results, patterns, request.context);
if (techInsight) insights.push(techInsight);
// Generate business impact insights
const businessInsight = await this.generateBusinessImpactInsight(impactAssessment, request.context);
if (businessInsight) insights.push(businessInsight);
// Generate process improvement insights
const processInsight = await this.generateProcessImprovementInsight(results, correlations, request.context);
if (processInsight) insights.push(processInsight);
return insights;
}
private async generateQualityTrendInsight(results: EnhancedAnalysisResult[], context: AnalysisContext): Promise<ContextInsight | null> {
const totalIssues = results.reduce((sum, r) => sum + r.issues.length, 0);
const avgContextScore = results.reduce((sum, r) => sum + r.contextScore, 0) / results.length;
if (totalIssues > 10 && avgContextScore < 70) {
return {
id: this.generateInsightId(),
type: InsightType.QUALITY_TREND,
title: 'Declining code quality detected',
description: 'High number of issues with low context scores indicate declining code quality',
confidence: 0.85,
impact: {
businessImpact: 8,
technicalImpact: 9,
userImpact: 7,
priorityScore: 8,
effortEstimate: 4,
riskLevel: RiskLevel.HIGH
},
evidence: [
`${totalIssues} total issues found`,
`Average context score: ${avgContextScore.toFixed(1)}%`,
'Multiple files affected'
],
recommendations: [
'Implement code quality gates',
'Increase automated testing coverage',
'Conduct focused code reviews',
'Provide team training on best practices'
],
context: {
projectContext: context,
teamContext: context.teamContext,
historicalContext: context.historicalData,
marketContext: {
industry: 'Technology',
competition: 'High',
trends: ['Quality focus', 'DevOps adoption'],
regulations: []
}
}
};
}
return null;
}
private async generateTeamPatternInsight(results: EnhancedAnalysisResult[], context: AnalysisContext): Promise<ContextInsight | null> {
const teamIssues = results.flatMap(r => r.issues).filter(issue =>
this.isTeamRelated(issue, context.teamContext)
);
if (teamIssues.length > 5) {
return {
id: this.generateInsightId(),
type: InsightType.TEAM_PATTERN,
title: 'Team collaboration patterns identified',
description: 'Multiple issues related to team collaboration and communication patterns',
confidence: 0.8,
impact: {
businessImpact: 6,
technicalImpact: 7,
userImpact: 8,
priorityScore: 7,
effortEstimate: 3,
riskLevel: RiskLevel.MEDIUM
},
evidence: [
`${teamIssues.length} team-related issues`,
`Collaboration style: ${context.teamContext.collaborationStyle}`,
'Multiple team members affected'
],
recommendations: [
'Improve communication protocols',
'Establish clear code ownership guidelines',
'Implement better documentation practices',
'Consider pair programming for complex areas'
],
context: {
projectContext: context,
teamContext: context.teamContext,
historicalContext: context.historicalData,
marketContext: {
industry: 'Technology',
competition: 'Medium',
trends: ['Agile methodologies', 'Remote work'],
regulations: []
}
}
};
}
return null;
}
private async generateTechnologyRiskInsight(results: EnhancedAnalysisResult[], patterns: ContextPattern[], context: AnalysisContext): Promise<ContextInsight | null> {
const techPatterns = patterns.filter(p =>
p.context.technologyFactors.length > 0 && p.impact > 7
);
if (techPatterns.length > 0) {
return {
id: this.generateInsightId(),
type: InsightType.TECHNOLOGY_RISK,
title: 'Technology-specific risks identified',
description: 'High-impact patterns related to specific technologies in the stack',
confidence: 0.9,
impact: {
businessImpact: 8,
technicalImpact: 9,
userImpact: 7,
priorityScore: 8,
effortEstimate: 5,
riskLevel: RiskLevel.HIGH
},
evidence: [
`${techPatterns.length} high-impact technology patterns`,
`Technologies involved: ${techPatterns.map(p => p.context.technologyFactors.join(', ')).join(', ')}`,
'Multiple system components affected'
],
recommendations: [
'Review technology stack choices',
'Implement technology-specific best practices',
'Consider alternative technologies for high-risk areas',
'Invest in team training for problematic technologies'
],
context: {
projectContext: context,
teamContext: context.teamContext,
historicalContext: context.historicalData,
marketContext: {
industry: 'Technology',
competition: 'High',
trends: ['Technology evolution', 'Cloud migration'],
regulations: []
}
}
};
}
return null;
}
private async generateBusinessImpactInsight(impactAssessment: ContextImpactAssessment, context: AnalysisContext): Promise<ContextInsight | null> {
if (impactAssessment.businessImpact.revenue < 6 || impactAssessment.businessImpact.risk > 7) {
return {
id: this.generateInsightId(),
type: InsightType.BUSINESS_IMPACT,
title: 'Significant business impact identified',
description: 'Current issues pose significant risk to business objectives and revenue',
confidence: 0.85,
impact: impactAssessment.overallImpact,
evidence: [
`Revenue impact score: ${impactAssessment.businessImpact.revenue.toFixed(1)}`,
`Risk level: ${impactAssessment.businessImpact.risk.toFixed(1)}`,
`Cost impact: ${impactAssessment.businessImpact.cost.toFixed(1)}`
],
recommendations: [
'Prioritize revenue-critical fixes',
'Implement risk mitigation strategies',
'Consider business process improvements',
'Align technical debt reduction with business priorities'
],
context: {
projectContext: context,
teamContext: context.teamContext,
historicalContext: context.historicalData,
marketContext: {
industry: 'Technology',
competition: 'High',
trends: ['Digital transformation', 'Customer experience'],
regulations: []
}
}
};
}
return null;
}
private async generateProcessImprovementInsight(results: EnhancedAnalysisResult[], correlations: ContextCorrelation[], context: AnalysisContext): Promise<ContextInsight | null> {
const processCorrelations = correlations.filter(c =>
c.causalFactors.some(factor =>
factor.includes('process') || factor.includes('workflow') || factor.includes('methodology')
)
);
if (processCorrelations.length > 0) {
return {
id: this.generateInsightId(),
type: InsightType.PROCESS_IMPROVEMENT,
title: 'Process improvement opportunities identified',
description: 'Correlations indicate opportunities for development process improvements',
confidence: 0.8,
impact: {
businessImpact: 7,
technicalImpact: 6,
userImpact: 8,
priorityScore: 7,
effortEstimate: 3,
riskLevel: RiskLevel.MEDIUM
},
evidence: [
`${processCorrelations.length} process-related correlations`,
`Causal factors: ${processCorrelations.map(c => c.causalFactors.join(', ')).join(', ')}`,
'Multiple development phases affected'
],
recommendations: [
'Review and optimize development workflows',
'Implement better quality gates',
'Improve communication between team members',
'Consider adopting or refining agile methodologies'
],
context: {
projectContext: context,
teamContext: context.teamContext,
historicalContext: context.historicalData,
marketContext: {
industry: 'Technology',
competition: 'Medium',
trends: ['Agile transformation', 'DevOps adoption'],
regulations: []
}
}
};
}
return null;
}
private async createAnalysisMetadata(request: ContextAnalysisRequest, generationTime: number): Promise<AnalysisMetadata> {
return {
generatedAt: new Date(),
generationTime,
analysisDepth: request.options.depth,
patternsFound: 0, // Will be calculated by caller
correlationsFound: 0, // Will be calculated by caller
suggestionsGenerated: 0, // Will be calculated by caller
insightsGenerated: 0, // Will be calculated by caller
contextFactors: []
};
}
private createDefaultImpactAssessment(): ContextImpactAssessment {
return {
overallImpact: {
businessImpact: 5,
technicalImpact: 5,
userImpact: 5,
priorityScore: 5,
effortEstimate: 5,
riskLevel: RiskLevel.MEDIUM
},
categoryImpacts: [],
teamImpact: {
productivity: 5,
morale: 5,
learning: 5,
collaboration: 5
},
businessImpact: {
revenue: 5,
cost: 5,
risk: 5,
opportunity: 5
},
technicalImpact: {
maintainability: 5,
scalability: 5,
performance: 5,
security: 5
}
};
}
// Helper methods
private getProjectTypeRelevance(result: UnifiedAnalysisResult, projectType: ProjectType): number {
const relevanceMap = {
[ProjectType.WEB_APP]: { [IssueCategory.PERFORMANCE]: 0.9, [IssueCategory.SECURITY]: 0.8 },
[ProjectType.MOBILE_APP]: { [IssueCategory.PERFORMANCE]: 0.95, [IssueCategory.ACCESSIBILITY]: 0.9 },
[ProjectType.API]: { [IssueCategory.SECURITY]: 0.95, [IssueCategory.PERFORMANCE]: 0.85 },
[ProjectType.LIBRARY]: { [IssueCategory.MAINTAINABILITY]: 0.9, [IssueCategory.DOCUMENTATION]: 0.85 },
[ProjectType.MICROSERVICE]: { [IssueCategory.SECURITY]: 0.9, [IssueCategory.PERFORMANCE]: 0.85 },
[ProjectType.MONOLITH]: { [IssueCategory.MAINTAINABILITY]: 0.85, [IssueCategory.SCALABILITY]: 0.8 }
};
const typeRelevance = relevanceMap[projectType] || {};
const issues = result.issues;
if (issues.length === 0) return 0.5;
const avgRelevance = issues.reduce((sum, issue) => {
return sum + (typeRelevance[issue.category] || 0.5);
}, 0) / issues.length;
return avgRelevance;
}
private getDevelopmentStageRelevance(result: UnifiedAnalysisResult, stage: DevelopmentStage): number {
const stageMultipliers = {
[DevelopmentStage.PLANNING]: { [SeverityLevel.ERROR]: 1.2, [SeverityLevel.WARNING]: 1.1 },
[DevelopmentStage.DEVELOPMENT]: { [SeverityLevel.ERROR]: 1.0, [SeverityLevel.WARNING]: 1.0 },
[DevelopmentStage.TESTING]: { [SeverityLevel.ERROR]: 1.5, [SeverityLevel.WARNING]: 1.3 },
[DevelopmentStage.DEPLOYMENT]: { [SeverityLevel.ERROR]: 2.0, [SeverityLevel.WARNING]: 1.8 },
[DevelopmentStage.MAINTENANCE]: { [SeverityLevel.ERROR]: 1.3, [SeverityLevel.WARNING]: 1.2 }
};
const multiplier = stageMultipliers[stage] || { [SeverityLevel.ERROR]: 1.0, [SeverityLevel.WARNING]: 1.0 };
const issues = result.issues;
if (issues.length === 0) return 0.5;
const weightedScore = issues.reduce((sum, issue) => {
return sum + (multiplier[issue.severity] || 1.0) * this.severityToWeight(issue.severity);
}, 0) / issues.length;
return Math.min(1.0, weightedScore / 10);
}
private getTeamExperienceRelevance(result: UnifiedAnalysisResult, experience: ExperienceLevel): number {
const experienceMultipliers = {
[ExperienceLevel.JUNIOR]: { [IssueCategory.SYNTAX]: 1.5, [IssueCategory.STYLE]: 1.3 },
[ExperienceLevel.MID]: { [IssueCategory.SYNTAX]: 1.0, [IssueCategory.STYLE]: 1.0 },
[ExperienceLevel.SENIOR]: { [IssueCategory.SYNTAX]: 0.7, [IssueCategory.STYLE]: 0.8 },
[ExperienceLevel.EXPERT]: { [IssueCategory.SYNTAX]: 0.5, [IssueCategory.STYLE]: 0.6 }
};
const multiplier = experienceMultipliers[experience] || { [IssueCategory.SYNTAX]: 1.0, [IssueCategory.STYLE]: 1.0 };
const issues = result.issues;
if (issues.length === 0) return 0.5;
const weightedScore = issues.reduce((sum, issue) => {
return sum + (multiplier[issue.category] || 1.0) * this.severityToWeight(issue.severity);
}, 0) / issues.length;
return Math.min(1.0, weightedScore / 10);
}
private getHistoricalPerformanceRelevance(result: UnifiedAnalysisResult, historicalData: HistoricalData): number {
// This would analyze historical performance data and adjust relevance
// For now, return a default value
return 0.7;
}
private getUserPreferencesRelevance(result: UnifiedAnalysisResult, preferences: UserPreferences): number {
const issues = result.issues;
if (issues.length === 0) return 0.5;
// Check if issues match user's preferred categories
const preferredIssues = issues.filter(issue =>
preferences.preferredCategories.includes(issue.category)
);
const preferredRatio = preferredIssues.length / issues.length;
// Adjust based on severity threshold
const severeIssues = issues.filter(issue =>
this.severityToWeight(issue.severity) >= this.severityToWeight(preferences.severityThreshold)
);
const severeRatio = severeIssues.length / issues.length;
return (preferredRatio * 0.6) + (severeRatio * 0.4);
}
private getCategoryRelevance(issues: UnifiedIssue[], context: AnalysisContext): number {
// Calculate relevance based on project priorities and issue categories
const categoryCounts = new Map<IssueCategory, number>();
for (const issue of issues) {
categoryCounts.set(issue.category, (categoryCounts.get(issue.category) || 0) + 1);
}
// This would be more sophisticated in practice
return Math.random() * 30 + 10; // 10-40 range
}
private getSeverityRelevance(issues: UnifiedIssue[], stage: DevelopmentStage): number {
// Calculate relevance based on severity and development stage
const severityWeights = issues.reduce((sum, issue) => {
return sum + this.severityToWeight(issue.severity);
}, 0);
const avgSeverity = severityWeights / issues.length;
// Adjust based on development stage
const stageMultiplier = {
[DevelopmentStage.PLANNING]: 0.8,
[DevelopmentStage.DEVELOPMENT]: 1.0,
[DevelopmentStage.TESTING]: 1.5,
[DevelopmentStage.DEPLOYMENT]: 2.0,
[DevelopmentStage.MAINTENANCE]: 1.2
};
return avgSeverity * (stageMultiplier[stage] || 1.0) * 5;
}
private getTechnologyRelevance(result: UnifiedAnalysisResult, technologies: string[]): number {
// Calculate relevance based on technology stack alignment
// This would be more sophisticated in practice
return Math.random() * 20 + 15; // 15-35 range
}
private getTeamRelevance(result: UnifiedAnalysisResult, teamContext: TeamContext): number {
// Calculate relevance based on team capabilities and collaboration style
// This would be more sophisticated in practice
return Math.random() * 20 + 15; // 15-35 range
}
private severityToWeight(severity: SeverityLevel): number {
const weights = {
[SeverityLevel.ERROR]: 3,
[SeverityLevel.WARNING]: 2,
[SeverityLevel.INFO]: 1,
[SeverityLevel.HINT]: 0.5
};
return weights[severity] || 1;
}
private impactToPriority(impact: number): PriorityLevel {
if (impact >= 8) return PriorityLevel.CRITICAL;
if (impact >= 6) return PriorityLevel.HIGH;
if (impact >= 4) return PriorityLevel.MEDIUM;
if (impact >= 2) return PriorityLevel.LOW;
return PriorityLevel.INFO;
}
private calculateRiskLevel(criticalIssues: number, totalIssues: number): RiskLevel {
const criticalRatio = criticalIssues / totalIssues;
if (criticalRatio >= 0.3) return RiskLevel.CRITICAL;
if (criticalRatio >= 0.2) return RiskLevel.HIGH;
if (criticalRatio >= 0.1) return RiskLevel.MEDIUM;
return RiskLevel.LOW;
}
private calculateTrendImpact(trend: QualityTrend): number {
const impactMap = {
[TrendDirection.IMPROVING]: -1,
[TrendDirection.STABLE]: 0,
[TrendDirection.DECLINING]: 1
};
return Math.abs(trend.value - trend.baseline) * impactMap[trend.trend];
}
private groupIssuesByCategory(issues: UnifiedIssue[]): Map<IssueCategory, UnifiedIssue[]> {
const groups = new Map<IssueCategory, UnifiedIssue[]>();
for (const issue of issues) {
const categoryIssues = groups.get(issue.category) || [];
categoryIssues.push(issue);
groups.set(issue.category, categoryIssues);
}
return groups;
}
private isTechnologyRelated(issue: UnifiedIssue, technology: string): boolean {
// This would check if an issue is related to a specific technology
// For now, return a random value
return Math.random() > 0.7;
}
private isCollaborationRelated(issue: UnifiedIssue, style: CollaborationStyle): boolean {
// This would check if an issue is related to collaboration style
// For now, return a random value
return Math.random() > 0.6;
}
private isTeamRelated(issue: UnifiedIssue, teamContext: TeamContext): boolean {
// This would check if an issue is related to team factors
// For now, return a random value
return Math.random() > 0.5;
}
private calculatePatternConfidence(issues: UnifiedIssue[]): number {
// Calculate confidence based on pattern consistency and strength
const baseConfidence = Math.min(0.95, 0.5 + (issues.length * 0.1));
// Adjust based on severity consistency
const severities = issues.map(i => i.severity);
const severityVariance = this.calculateVariance(severities.map(s => this.severityToWeight(s)));
const severityConsistency = Math.max(0, 1 - (severityVariance / 4));
return baseConfidence * severityConsistency;
}
private calculatePatternImpact(issues: UnifiedIssue[]): number {
// Calculate impact based on issue severity and frequency
const severitySum = issues.reduce((sum, issue) => sum + this.severityToWeight(issue.severity), 0);
return Math.min(10, severitySum / issues.length * 2);
}
private calculateCorrelationConfidence(issues: UnifiedIssue[]): number {
// Calculate confidence for correlation
const baseConfidence = Math.min(0.9, 0.4 + (issues.length * 0.15));
// Adjust based on spatial/temporal proximity
// This would be more sophisticated in practice
return baseConfidence;
}
private groupIssuesByTimePattern(issues: UnifiedIssue[]): Map<string, UnifiedIssue[]> {
// Group issues by time patterns (e.g., time of day, day of week)
// This would be more sophisticated in practice
const groups = new Map<string, UnifiedIssue[]>();
// Simple grouping by issue category for now
for (const issue of issues) {
const key = issue.category;
const categoryIssues = groups.get(key) || [];
categoryIssues.push(issue);
groups.set(key, categoryIssues);
}
return groups;
}
private groupIssuesByFile(issues: UnifiedIssue[]): Map<string, UnifiedIssue[]> {
const groups = new Map<string, UnifiedIssue[]>();
for (const issue of issues) {
const filePath = issue.location.filePath;
const fileIssues = groups.get(filePath) || [];
fileIssues.push(issue);
groups.set(filePath, fileIssues);
}
return groups;
}
private groupIssuesByTechnology(issues: UnifiedIssue[], technologies: string[]): Map<string, UnifiedIssue[]> {
const groups = new Map<string, UnifiedIssue[]>();
for (const issue of issues) {
// Find matching technology (simplified)
const matchingTech = technologies.find(tech => this.isTechnologyRelated(issue, tech));
if (matchingTech) {
const techIssues = groups.get(matchingTech) || [];
techIssues.push(issue);
groups.set(matchingTech, techIssues);
}
}
return groups;
}
private extractModules(filePath: string): string[] {
// Extract module names from file path
// This would be more sophisticated in practice
return [filePath.split('/')[1] || 'root'];
}
private extractComponents(filePath: string): string[] {
// Extract component names from file path
// This would be more sophisticated in practice
return [filePath.split('/').pop()?.split('.')[0] || 'component'];
}
private calculateVariance(values: number[]): number {
const mean = values.reduce((sum, val) => sum + val, 0) / values.length;
const variance = values.reduce((sum, val) => sum + Math.pow(val - mean, 2), 0) / values.length;
return variance;
}
private calculateTeamAlignment(pattern: ContextPattern | ContextCorrelation, context: AnalysisContext): number {
// Calculate how well the pattern/correlation aligns with team capabilities
const experienceMultiplier = {
[ExperienceLevel.JUNIOR]: 0.7,
[ExperienceLevel.MID]: 0.85,
[ExperienceLevel.SENIOR]: 0.95,
[ExperienceLevel.EXPERT]: 1.0
};
return experienceMultiplier[context.teamContext.experienceLevel] || 0.8;
}
// ID generation methods
private generateAnalysisId(): string {
return `analysis_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
}
private generatePatternId(): string {
return `pattern_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
}
private generateCorrelationId(): string {
return `correlation_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
}
private generateSuggestionId(): string {
return `suggestion_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
}
private generateInsightId(): string {
return `insight_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
}
private async loadDatabases(): Promise<void> {
try {
// Load pattern database
const cachedPatterns = await this.cache.get<Map<string, ContextPattern[]>>('pattern-database');
if (cachedPatterns) {
this.patternDatabase = new Map(Object.entries(cachedPatterns));
}
// Load correlation database
const cachedCorrelations = await this.cache.get<Map<string, ContextCorrelation[]>>('correlation-database');
if (cachedCorrelations) {
this.correlationDatabase = new Map(Object.entries(cachedCorrelations));
}
this.logger.info('Pattern and correlation databases loaded');
} catch (error) {
this.logger.warn('Failed to load databases:', error);
}
}
private async loadLearningData(): Promise<void> {
try {
const cachedLearning = await this.cache.get<Map<string, LearningData>>('learning-data');
if (cachedLearning) {
this.learningData = new Map(Object.entries(cachedLearning));
}
this.logger.info('Learning data loaded');
} catch (error) {
this.logger.warn('Failed to load learning data:', error);
}
}
private async updateLearningData(request: ContextAnalysisRequest, result: ContextAnalysisResult): Promise<void> {
if (!this.config.enableLearning) return;
try {
// Update learning data based on analysis results
const learningData: LearningData = {
projectId: request.projectId,
lastAnalysis: new Date(),
patternsDiscovered: result.patterns.length,
correlationsFound: result.correlations.length,
suggestionsGenerated: result.suggestions.length,
insightsGenerated: result.insights.length,
contextFactors: result.metadata.contextFactors,
effectiveness: this.calculateAnalysisEffectiveness(result)
};
this.learningData.set(request.projectId, learningData);
// Save to cache
await this.cache.set('learning-data', Object.fromEntries(this.learningData), 3600);
this.logger.info('Learning data updated');
} catch (error) {
this.logger.warn('Failed to update learning data:', error);
}
}
private calculateAnalysisEffectiveness(result: ContextAnalysisResult): number {
// Calculate effectiveness based on various factors
const patternEffectiveness = result.patterns.length > 0 ? 0.3 : 0;
const correlationEffectiveness = result.correlations.length > 0 ? 0.3 : 0;
const suggestionEffectiveness = result.suggestions.length > 0 ? 0.2 : 0;
const insightEffectiveness = result.insights.length > 0 ? 0.2 : 0;
return patternEffectiveness + correlationEffectiveness + suggestionEffectiveness + insightEffectiveness;
}
// Event handlers
private handlePatternDiscovered(pattern: ContextPattern): void {
this.logger.debug(`Pattern discovered event handled: ${pattern.description}`);
}
private handleCorrelationFound(correlation: ContextCorrelation): void {
this.logger.debug(`Correlation found event handled: ${correlation.description}`);
}
private handleInsightGenerated(insight: ContextInsight): void {
this.logger.debug(`Insight generated event handled: ${insight.title}`);
}
private handleContextUpdated(context: AnalysisContext): void {
this.logger.debug('Context updated event handled');
}
// Public API methods
async updateConfig(config: Partial<ContextAnalysisConfig>): Promise<void> {
this.config = { ...this.config, ...config };
this.logger.info('Context analysis configuration updated');
}
async getAnalysisStats(): Promise<any> {
return {
totalPatterns: Array.from(this.patternDatabase.values()).reduce((sum, patterns) => sum + patterns.length, 0),
totalCorrelations: Array.from(this.correlationDatabase.values()).reduce((sum, correlations) => sum + correlations.length, 0),
learningEnabled: this.config.enableLearning,
patternThreshold: this.config.patternThreshold,
correlationThreshold: this.config.correlationThreshold,
projectsAnalyzed: this.learningData.size
};
}
async shutdown(): Promise<void> {
this.logger.info('Shutting down Context-Aware Analysis Engine');
// Save databases to cache
try {
await this.cache.set('pattern-database', Object.fromEntries(this.patternDatabase), 3600);
await this.cache.set('correlation-database', Object.fromEntries(this.correlationDatabase), 3600);
await this.cache.set('learning-data', Object.fromEntries(this.learningData), 3600);
} catch (error) {
this.logger.warn('Failed to save databases during shutdown:', error);
}
// Clear event listeners
this.removeAllListeners();
this.logger.info('Context-Aware Analysis Engine shutdown complete');
}
}
interface LearningData {
projectId: string;
lastAnalysis: Date;
patternsDiscovered: number;
correlationsFound: number;
suggestionsGenerated: number;
insightsGenerated: number;
contextFactors: ContextualFactor[];
effectiveness: number;
}