// Copyright 2025 Chris Bunting
// Brief: Team preference learning service for MCP Code Analysis & Quality Server
// Scope: Manages team preference learning, adaptation, and synchronization
import { EventEmitter } from 'events';
import {
AnalysisContext,
UnifiedAnalysisResult,
LoggerInterface,
CacheInterface,
PriorityLevel,
SeverityLevel
} from '@mcp-code-analysis/shared-types';
export interface TeamPreferenceConfig {
enableLearning: boolean;
enableAdaptation: boolean;
enableSynchronization: boolean;
learningRate: number;
adaptationThreshold: number;
conflictResolutionStrategy: ConflictResolutionStrategy;
maxPreferencesPerUser: number;
preferenceRetention: number;
enableTeamBehaviorAnalysis: boolean;
}
export interface UserProfile {
id: string;
name: string;
email: string;
role: TeamRole;
experience: ExperienceLevel;
skills: string[];
preferences: UserPreference[];
behavior: UserBehavior;
history: UserHistory[];
createdAt: Date;
updatedAt: Date;
lastActive: Date;
}
export interface UserPreference {
id: string;
category: PreferenceCategory;
key: string;
value: any;
confidence: number;
source: PreferenceSource;
context: PreferenceContext;
priority: PriorityLevel;
createdAt: Date;
updatedAt: Date;
usageCount: number;
effectiveness: number;
}
export interface UserBehavior {
codingPatterns: CodingPattern[];
collaborationStyle: CollaborationStyle;
communicationPatterns: CommunicationPattern[];
learningStyle: LearningStyle;
productivityMetrics: ProductivityMetrics;
errorPatterns: ErrorPattern[];
successMetrics: SuccessMetrics;
}
export interface UserHistory {
timestamp: Date;
action: UserAction;
context: ActionContext;
outcome: ActionResult;
satisfaction: number;
impact: ImpactAssessment;
}
export interface TeamProfile {
id: string;
name: string;
description: string;
members: string[];
preferences: TeamPreference[];
behavior: TeamBehavior;
dynamics: TeamDynamics;
performance: TeamPerformance;
createdAt: Date;
updatedAt: Date;
}
export interface TeamPreference {
id: string;
category: PreferenceCategory;
key: string;
value: any;
consensus: number;
conflicts: PreferenceConflict[];
source: PreferenceSource;
context: PreferenceContext;
priority: PriorityLevel;
createdAt: Date;
updatedAt: Date;
adaptationHistory: AdaptationRecord[];
}
export interface TeamBehavior {
collaborationPatterns: CollaborationPattern[];
communicationStyle: TeamCommunicationStyle;
decisionMaking: DecisionMakingStyle;
conflictResolution: ConflictResolutionStyle;
learningPatterns: LearningPattern[];
productivityPatterns: ProductivityPattern[];
}
export interface TeamDynamics {
cohesion: number;
communication: number;
collaboration: number;
conflict: number;
satisfaction: number;
performance: number;
adaptation: number;
}
export interface TeamPerformance {
velocity: number;
quality: number;
efficiency: number;
innovation: number;
collaboration: number;
satisfaction: number;
trends: PerformanceTrend[];
}
export interface PreferenceLearningRequest {
userId: string;
teamId: string;
action: UserAction;
context: ActionContext;
outcome: ActionResult;
timestamp: Date;
}
export interface PreferenceAdaptationRequest {
teamId: string;
context: AdaptationContext;
triggers: AdaptationTrigger[];
options: AdaptationOptions;
}
export interface PreferenceSynchronizationRequest {
sourceTeamId: string;
targetTeamId: string;
preferences: string[];
options: SynchronizationOptions;
}
export interface PreferenceConflictResolutionRequest {
teamId: string;
conflicts: PreferenceConflict[];
resolutionStrategy: ConflictResolutionStrategy;
options: ResolutionOptions;
}
export interface CodingPattern {
id: string;
pattern: string;
frequency: number;
context: PatternContext;
effectiveness: number;
lastUsed: Date;
}
export interface CollaborationStyle {
preferredMethods: CollaborationMethod[];
communicationFrequency: CommunicationFrequency;
decisionMaking: DecisionMakingPreference;
feedbackStyle: FeedbackStyle;
conflictHandling: ConflictHandlingStyle;
}
export interface CommunicationPattern {
id: string;
type: CommunicationType;
frequency: number;
effectiveness: number;
context: CommunicationContext;
timestamp: Date;
}
export interface LearningStyle {
preferredMethods: LearningMethod[];
pace: LearningPace;
depth: LearningDepth;
socialPreference: SocialLearningPreference;
}
export interface ProductivityMetrics {
codeOutput: number;
qualityScore: number;
efficiency: number;
focusTime: number;
contextSwitches: number;
taskCompletion: number;
}
export interface ErrorPattern {
id: string;
type: ErrorType;
frequency: number;
context: ErrorContext;
severity: SeverityLevel;
lastOccurred: Date;
resolution: string;
}
export interface SuccessMetrics {
achievements: Achievement[];
recognition: Recognition[];
impact: number;
satisfaction: number;
growth: number;
}
export interface CollaborationPattern {
id: string;
type: CollaborationType;
participants: string[];
frequency: number;
effectiveness: number;
context: CollaborationContext;
lastUsed: Date;
}
export interface TeamCommunicationStyle {
primaryChannels: CommunicationChannel[];
frequency: CommunicationFrequency;
formality: FormalityLevel;
transparency: TransparencyLevel;
documentation: DocumentationPreference;
}
export interface DecisionMakingStyle {
approach: DecisionApproach;
participation: ParticipationLevel;
speed: DecisionSpeed;
criteria: DecisionCriteria[];
}
export interface ConflictResolutionStyle {
approach: ConflictApproach;
mediation: MediationPreference;
compromise: CompromisePreference;
escalation: EscalationPreference;
}
export interface LearningPattern {
id: string;
type: LearningType;
participants: string[];
frequency: number;
effectiveness: number;
context: LearningContext;
lastUsed: Date;
}
export interface ProductivityPattern {
id: string;
type: ProductivityType;
factors: ProductivityFactor[];
effectiveness: number;
context: ProductivityContext;
lastObserved: Date;
}
export interface PerformanceTrend {
metric: string;
timeframe: Timeframe;
trend: TrendDirection;
data: TrendPoint[];
prediction: TrendPrediction;
}
export interface AdaptationRecord {
timestamp: Date;
trigger: AdaptationTrigger;
change: PreferenceChange;
impact: AdaptationImpact;
effectiveness: number;
}
export interface PreferenceConflict {
id: string;
preferenceId: string;
user1Id: string;
user2Id: string;
type: ConflictType;
severity: ConflictSeverity;
context: ConflictContext;
resolution: ConflictResolution | null;
}
export interface PatternContext {
projectType: string;
technology: string[];
complexity: number;
domain: string;
timeframe: Timeframe;
}
export interface CommunicationContext {
channel: CommunicationChannel;
purpose: CommunicationPurpose;
participants: string[];
urgency: UrgencyLevel;
}
export interface ErrorContext {
task: string;
technology: string;
complexity: number;
timePressure: number;
context: string;
}
export interface CollaborationContext {
project: string;
task: string;
participants: string[];
duration: number;
outcome: string;
}
export interface LearningContext {
topic: string;
method: LearningMethod;
participants: string[];
duration: number;
outcome: string;
}
export interface ProductivityContext {
project: string;
task: string;
environment: WorkEnvironment;
timeOfDay: string;
duration: number;
}
export interface AdaptationContext {
project: string;
team: string;
trigger: AdaptationTrigger;
environment: AdaptationEnvironment;
timeframe: Timeframe;
}
export interface ConflictContext {
project: string;
task: string;
users: string[];
context: string;
severity: ConflictSeverity;
}
export interface PreferenceContext {
project: string;
technology: string[];
domain: string;
timeframe: Timeframe;
environment: WorkEnvironment;
}
export interface ActionContext {
project: string;
task: string;
environment: WorkEnvironment;
tools: string[];
collaborators: string[];
timePressure: number;
}
export interface ImpactAssessment {
technicalImpact: number;
businessImpact: number;
userImpact: number;
teamImpact: number;
overallImpact: number;
}
export interface Achievement {
id: string;
type: AchievementType;
description: string;
date: Date;
impact: number;
recognition: string[];
}
export interface Recognition {
id: string;
type: RecognitionType;
source: string;
description: string;
date: Date;
value: number;
}
export interface AdaptationOptions {
maxChanges: number;
confidenceThreshold: number;
impactThreshold: number;
includeReasoning: boolean;
includeAlternatives: boolean;
}
export interface SynchronizationOptions {
overwriteConflicts: boolean;
mergeStrategy: MergeStrategy;
includeReasoning: boolean;
validationLevel: ValidationLevel;
}
export interface ResolutionOptions {
includeReasoning: boolean;
includeAlternatives: boolean;
votingEnabled: boolean;
votingThreshold: number;
}
export interface PreferenceChange {
preferenceId: string;
oldValue: any;
newValue: any;
reason: string;
confidence: number;
}
export interface AdaptationImpact {
userSatisfaction: number;
teamPerformance: number;
qualityImpact: number;
productivityImpact: number;
overallImpact: number;
}
export interface ConflictResolution {
strategy: ConflictResolutionStrategy;
decision: string;
reasoning: string;
satisfaction: number;
effectiveness: number;
}
export interface TrendPoint {
timestamp: Date;
value: number;
baseline: number;
target: number;
}
export interface TrendPrediction {
timeframe: Timeframe;
predictedValue: number;
confidence: number;
factors: string[];
}
export interface ActionResult {
success: boolean;
duration: number;
quality: number;
efficiency: number;
satisfaction: number;
errors: string[];
lessons: string[];
}
export interface UserAction {
type: ActionType;
description: string;
tools: string[];
collaborators: string[];
complexity: number;
}
export enum PreferenceCategory {
CODING_STYLE = 'coding-style',
ARCHITECTURE = 'architecture',
TESTING = 'testing',
DOCUMENTATION = 'documentation',
COLLABORATION = 'collaboration',
COMMUNICATION = 'communication',
LEARNING = 'learning',
PRODUCTIVITY = 'productivity',
QUALITY = 'quality',
SECURITY = 'security',
PERFORMANCE = 'performance'
}
export enum PreferenceSource {
USER_EXPLICIT = 'user-explicit',
LEARNED_BEHAVIOR = 'learned-behavior',
TEAM_CONSENSUS = 'team-consensus',
ORGANIZATIONAL_POLICY = 'organizational-policy',
INDUSTRY_BEST_PRACTICE = 'industry-best-practice',
AUTOMATED_ANALYSIS = 'automated-analysis',
PEER_RECOMMENDATION = 'peer-recommendation'
}
export enum TeamRole {
DEVELOPER = 'developer',
SENIOR_DEVELOPER = 'senior-developer',
LEAD_DEVELOPER = 'lead-developer',
ARCHITECT = 'architect',
QA_ENGINEER = 'qa-engineer',
DEVOPS_ENGINEER = 'devops-engineer',
PRODUCT_MANAGER = 'product-manager',
PROJECT_MANAGER = 'project-manager',
TEAM_LEAD = 'team-lead',
TECHNICAL_LEAD = 'technical-lead'
}
export enum ExperienceLevel {
JUNIOR = 'junior',
MID = 'mid',
SENIOR = 'senior',
EXPERT = 'expert'
}
export enum ConflictResolutionStrategy {
MAJORITY_VOTE = 'majority-vote',
CONSENSUS = 'consensus',
HIERARCHICAL = 'hierarchical',
AUTOMATED = 'automated',
MEDIATION = 'mediation',
COMPROMISE = 'compromise',
PREFERENCE_BASED = 'preference-based'
}
export enum ActionType {
CODE_REVIEW = 'code-review',
TASK_COMPLETION = 'task-completion',
BUG_FIX = 'bug-fix',
FEATURE_DEVELOPMENT = 'feature-development',
REFACTORING = 'refactoring',
TESTING = 'testing',
DOCUMENTATION = 'documentation',
COLLABORATION = 'collaboration',
LEARNING = 'learning',
MENTORING = 'mentoring'
}
export enum ErrorType {
SYNTAX = 'syntax',
LOGIC = 'logic',
PERFORMANCE = 'performance',
SECURITY = 'security',
COMPATIBILITY = 'compatibility',
CONFIGURATION = 'configuration',
DEPENDENCY = 'dependency',
COMMUNICATION = 'communication'
}
export enum CollaborationMethod {
PAIR_PROGRAMMING = 'pair-programming',
CODE_REVIEW = 'code-review',
MOB_PROGRAMMING = 'mob-programming',
SWARM_PROGRAMMING = 'swarm-programming',
DESIGN_SESSION = 'design-session',
STANDUP = 'standup',
RETROSPECTIVE = 'retrospective'
}
export enum CommunicationFrequency {
CONTINUOUS = 'continuous',
FREQUENT = 'frequent',
MODERATE = 'moderate',
OCCASIONAL = 'occasional',
MINIMAL = 'minimal'
}
export enum DecisionMakingPreference {
AUTONOMOUS = 'autonomous',
COLLABORATIVE = 'collaborative',
CONSENSUS_DRIVEN = 'consensus-driven',
HIERARCHICAL = 'hierarchical',
DATA_DRIVEN = 'data-driven'
}
export enum FeedbackStyle {
DIRECT = 'direct',
CONSTRUCTIVE = 'constructive',
SUPPORTIVE = 'supportive',
DETAILED = 'detailed',
CONCISE = 'concise'
}
export enum ConflictHandlingStyle {
CONFRONTING = 'confronting',
COLLABORATING = 'collaborating',
COMPROMISING = 'compromising',
AVOIDING = 'avoiding',
ACCOMMODATING = 'accommodating'
}
export enum CommunicationType {
SYNC_VERBAL = 'sync-verbal',
SYNC_WRITTEN = 'sync-written',
ASYNC_WRITTEN = 'async-written',
FORMAL = 'formal',
INFORMAL = 'informal'
}
export enum LearningMethod {
HANDS_ON = 'hands-on',
VISUAL = 'visual',
AUDITORY = 'auditory',
READING = 'reading',
SOCIAL = 'social',
SELF_PACED = 'self-paced'
}
export enum LearningPace {
FAST = 'fast',
MODERATE = 'moderate',
SLOW = 'slow',
VARIABLE = 'variable'
}
export enum LearningDepth {
SURFACE = 'surface',
MODERATE = 'moderate',
DEEP = 'deep',
EXPERT = 'expert'
}
export enum SocialLearningPreference {
HIGHLY_SOCIAL = 'highly-social',
SOCIAL = 'social',
NEUTRAL = 'neutral',
INDEPENDENT = 'independent',
HIGHLY_INDEPENDENT = 'highly-independent'
}
export enum CollaborationType {
TASK_COLLABORATION = 'task-collaboration',
KNOWLEDGE_SHARING = 'knowledge-sharing',
PROBLEM_SOLVING = 'problem-solving',
MENTORING = 'mentoring',
REVIEW = 'review'
}
export enum CommunicationChannel {
FACE_TO_FACE = 'face-to-face',
VIDEO_CALL = 'video-call',
PHONE = 'phone',
CHAT = 'chat',
EMAIL = 'email',
DOCUMENT = 'document',
CODE_COMMENT = 'code-comment'
}
export enum CommunicationPurpose {
COORDINATION = 'coordination',
INFORMATION_SHARING = 'information-sharing',
DECISION_MAKING = 'decision-making',
PROBLEM_SOLVING = 'problem-solving',
SOCIAL = 'social'
}
export enum UrgencyLevel {
LOW = 'low',
MEDIUM = 'medium',
HIGH = 'high',
CRITICAL = 'critical'
}
export enum FormalityLevel {
INFORMAL = 'informal',
CASUAL = 'casual',
PROFESSIONAL = 'professional',
FORMAL = 'formal'
}
export enum TransparencyLevel {
LOW = 'low',
MEDIUM = 'medium',
HIGH = 'high',
COMPLETE = 'complete'
}
export enum DocumentationPreference {
MINIMAL = 'minimal',
ADEQUATE = 'adequate',
COMPREHENSIVE = 'comprehensive',
EXTENSIVE = 'extensive'
}
export enum DecisionApproach {
INTUITIVE = 'intuitive',
ANALYTICAL = 'analytical',
SYSTEMATIC = 'systematic',
CREATIVE = 'creative'
}
export enum ParticipationLevel {
INDIVIDUAL = 'individual',
CONSULTATIVE = 'consultative',
PARTICIPATIVE = 'participative',
COLLABORATIVE = 'collaborative'
}
export enum DecisionSpeed {
IMMEDIATE = 'immediate',
QUICK = 'quick',
MODERATE = 'moderate',
DELIBERATE = 'deliberate'
}
export enum ConflictApproach {
COMPETING = 'competing',
COLLABORATING = 'collaborating',
COMPROMISING = 'compromising',
AVOIDING = 'avoiding',
ACCOMMODATING = 'accommodating'
}
export enum MediationPreference {
FORMAL = 'formal',
INFORMAL = 'informal',
PEER = 'peer',
MANAGERIAL = 'managerial',
EXTERNAL = 'external'
}
export enum CompromisePreference {
SEEK_WIN_WIN = 'seek-win-win',
PRACTICAL = 'practical',
PRINCIPLED = 'principled',
FLEXIBLE = 'flexible'
}
export enum EscalationPreference {
IMMEDIATE = 'immediate',
STEP_BY_STEP = 'step-by-step',
AS_NEEDED = 'as-needed',
AVOID_ESCALATION = 'avoid-escalation'
}
export enum LearningType {
SKILL_ACQUISITION = 'skill-acquisition',
KNOWLEDGE_SHARING = 'knowledge-sharing',
PROBLEM_SOLVING = 'problem-solving',
BEST_PRACTICE = 'best-practice',
INNOVATION = 'innovation'
}
export enum ProductivityType {
FOCUS_TIME = 'focus-time',
TASK_SWITCHING = 'task-switching',
COLLABORATION = 'collaboration',
LEARNING = 'learning',
TOOL_USAGE = 'tool-usage'
}
export enum ProductivityFactor {
ENVIRONMENT = 'environment',
TIME_OF_DAY = 'time-of-day',
TOOLS = 'tools',
COLLABORATORS = 'collaborators',
TASK_TYPE = 'task-type',
MOTIVATION = 'motivation'
}
export enum Timeframe {
HOUR = 'hour',
DAY = 'day',
WEEK = 'week',
MONTH = 'month',
QUARTER = 'quarter',
YEAR = 'year'
}
export enum TrendDirection {
IMPROVING = 'improving',
STABLE = 'stable',
DECLINING = 'declining'
}
export enum AdaptationTrigger {
PERFORMANCE_DECLINE = 'performance-decline',
CONFLICT_INCREASE = 'conflict-increase',
SATISFACTION_DECREASE = 'satisfaction-decrease',
TEAM_CHANGE = 'team-change',
PROJECT_CHANGE = 'project-change',
FEEDBACK_RECEIVED = 'feedback-received'
}
export enum ConflictType {
VALUE = 'value',
PREFERENCE = 'preference',
APPROACH = 'approach',
PRIORITY = 'priority',
STYLE = 'style'
}
export enum ConflictSeverity {
LOW = 'low',
MEDIUM = 'medium',
HIGH = 'high',
CRITICAL = 'critical'
}
export enum AdaptationEnvironment {
STABLE = 'stable',
CHANGING = 'changing',
DYNAMIC = 'dynamic',
UNCERTAIN = 'uncertain'
}
export enum WorkEnvironment {
OFFICE = 'office',
REMOTE = 'remote',
HYBRID = 'hybrid',
COLLABORATIVE = 'collaborative',
FOCUSED = 'focused'
}
export enum MergeStrategy {
SOURCE_WINS = 'source-wins',
TARGET_WINS = 'target-wins',
MERGE = 'merge',
MANUAL = 'manual'
}
export enum ValidationLevel {
BASIC = 'basic',
STANDARD = 'standard',
THOROUGH = 'thorough'
}
export enum AchievementType {
TECHNICAL = 'technical',
LEADERSHIP = 'leadership',
COLLABORATION = 'collaboration',
INNOVATION = 'innovation',
MENTORING = 'mentoring'
}
export enum RecognitionType {
PEER = 'peer',
MANAGERIAL = 'managerial',
ORGANIZATIONAL = 'organizational',
EXTERNAL = 'external'
}
export class TeamPreferenceLearningService extends EventEmitter {
private config: TeamPreferenceConfig;
private cache: CacheInterface;
private logger: LoggerInterface;
private userProfiles: Map<string, UserProfile> = new Map();
private teamProfiles: Map<string, TeamProfile> = new Map();
private learningAlgorithms: Map<LearningAlgorithmType, LearningAlgorithm> = new Map();
private adaptationAlgorithms: Map<AdaptationAlgorithmType, AdaptationAlgorithm> = new Map();
constructor(config: TeamPreferenceConfig, cache: CacheInterface, logger: LoggerInterface) {
super();
this.config = config;
this.cache = cache;
this.logger = logger;
this.setupEventHandlers();
this.initializeAlgorithms();
}
private setupEventHandlers(): void {
this.on('preference-learned', this.handlePreferenceLearned.bind(this));
this.on('preference-adapted', this.handlePreferenceAdapted.bind(this));
this.on('preference-synchronized', this.handlePreferenceSynchronized.bind(this));
this.on('conflict-resolved', this.handleConflictResolved.bind(this));
}
private initializeAlgorithms(): void {
// Initialize learning algorithms
this.learningAlgorithms.set(LearningAlgorithmType.BEHAVIORAL, new BehavioralLearningAlgorithm());
this.learningAlgorithms.set(LearningAlgorithmType.COLLABORATIVE, new CollaborativeLearningAlgorithm());
this.learningAlgorithms.set(LearningAlgorithmType.ADAPTIVE, new AdaptiveLearningAlgorithm());
// Initialize adaptation algorithms
this.adaptationAlgorithms.set(AdaptationAlgorithmType.PERFORMANCE_BASED, new PerformanceBasedAdaptationAlgorithm());
this.adaptationAlgorithms.set(AdaptationAlgorithmType.CONFLICT_BASED, new ConflictBasedAdaptationAlgorithm());
this.adaptationAlgorithms.set(AdaptationAlgorithmType.SATISFACTION_BASED, new SatisfactionBasedAdaptationAlgorithm());
}
async initialize(): Promise<void> {
this.logger.info('Initializing Team Preference Learning Service');
// Load existing profiles from cache
await this.loadProfiles();
this.logger.info('Team Preference Learning Service initialized successfully');
}
async createUserProfile(userData: Partial<UserProfile>): Promise<UserProfile> {
const profile: UserProfile = {
id: this.generateProfileId(),
name: userData.name || '',
email: userData.email || '',
role: userData.role || TeamRole.DEVELOPER,
experience: userData.experience || ExperienceLevel.MID,
skills: userData.skills || [],
preferences: [],
behavior: userData.behavior || this.createDefaultBehavior(),
history: [],
createdAt: new Date(),
updatedAt: new Date(),
lastActive: new Date()
};
this.userProfiles.set(profile.id, profile);
await this.saveUserProfile(profile.id);
this.emit('user-profile-created', profile);
this.logger.info(`User profile created for: ${profile.name}`);
return profile;
}
async createTeamProfile(teamData: Partial<TeamProfile>): Promise<TeamProfile> {
const profile: TeamProfile = {
id: this.generateTeamId(),
name: teamData.name || '',
description: teamData.description || '',
members: teamData.members || [],
preferences: [],
behavior: teamData.behavior || this.createDefaultTeamBehavior(),
dynamics: teamData.dynamics || this.createDefaultTeamDynamics(),
performance: teamData.performance || this.createDefaultTeamPerformance(),
createdAt: new Date(),
updatedAt: new Date()
};
this.teamProfiles.set(profile.id, profile);
await this.saveTeamProfile(profile.id);
this.emit('team-profile-created', profile);
this.logger.info(`Team profile created for: ${profile.name}`);
return profile;
}
async learnFromUserAction(request: PreferenceLearningRequest): Promise<boolean> {
try {
this.logger.info(`Learning from user action for user: ${request.userId}`);
const user = this.userProfiles.get(request.userId);
if (!user) {
throw new Error(`User profile not found: ${request.userId}`);
}
// Record user action in history
const historyEntry: UserHistory = {
timestamp: request.timestamp,
action: request.action,
context: request.context,
outcome: request.outcome,
satisfaction: this.calculateSatisfaction(request.outcome),
impact: this.calculateImpact(request.outcome)
};
user.history.push(historyEntry);
user.lastActive = new Date();
// Update user behavior patterns
await this.updateUserBehavior(user, request);
// Learn preferences from action
if (this.config.enableLearning) {
await this.learnPreferences(user, request);
}
// Update team profile if user belongs to a team
if (request.teamId) {
const team = this.teamProfiles.get(request.teamId);
if (team) {
await this.updateTeamBehavior(team, user, request);
}
}
// Save updated profiles
await this.saveUserProfile(user.id);
if (request.teamId) {
await this.saveTeamProfile(request.teamId);
}
this.emit('preference-learned', {
userId: request.userId,
teamId: request.teamId,
action: request.action.type
});
this.logger.info(`Successfully learned from user action for user: ${request.userId}`);
return true;
} catch (error) {
this.logger.error('Failed to learn from user action:', error);
return false;
}
}
async adaptTeamPreferences(request: PreferenceAdaptationRequest): Promise<boolean> {
try {
this.logger.info(`Adapting team preferences for team: ${request.teamId}`);
const team = this.teamProfiles.get(request.teamId);
if (!team) {
throw new Error(`Team profile not found: ${request.teamId}`);
}
// Analyze adaptation triggers
const analysis = await this.analyzeAdaptationTriggers(request.triggers, team);
if (analysis.shouldAdapt) {
// Select and apply adaptation algorithm
const algorithm = this.selectAdaptationAlgorithm(analysis.primaryTrigger);
const adaptation = await algorithm.adapt(request, team, analysis);
if (adaptation.success) {
// Apply adaptation changes
for (const change of adaptation.changes) {
await this.applyPreferenceChange(team, change);
}
// Record adaptation
this.recordAdaptation(team, adaptation);
// Update team dynamics
await this.updateTeamDynamics(team, adaptation);
team.updatedAt = new Date();
await this.saveTeamProfile(team.id);
this.emit('preference-adapted', {
teamId: request.teamId,
changes: adaptation.changes.length,
effectiveness: adaptation.effectiveness
});
this.logger.info(`Successfully adapted team preferences for team: ${request.teamId}`);
return true;
}
}
this.logger.info(`No adaptation needed for team: ${request.teamId}`);
return false;
} catch (error) {
this.logger.error('Failed to adapt team preferences:', error);
return false;
}
}
async synchronizePreferences(request: PreferenceSynchronizationRequest): Promise<boolean> {
try {
this.logger.info(`Synchronizing preferences from team ${request.sourceTeamId} to team ${request.targetTeamId}`);
const sourceTeam = this.teamProfiles.get(request.sourceTeamId);
const targetTeam = this.teamProfiles.get(request.targetTeamId);
if (!sourceTeam || !targetTeam) {
throw new Error('Source or target team profile not found');
}
let synchronizedCount = 0;
let conflictCount = 0;
for (const preferenceId of request.preferences) {
const sourcePreference = sourceTeam.preferences.find(p => p.id === preferenceId);
if (sourcePreference) {
const targetPreference = targetTeam.preferences.find(p =>
p.category === sourcePreference.category && p.key === sourcePreference.key
);
if (targetPreference) {
// Handle conflict
if (request.options.overwriteConflicts) {
targetPreference.value = sourcePreference.value;
targetPreference.source = PreferenceSource.TEAM_CONSENSUS;
targetPreference.updatedAt = new Date();
synchronizedCount++;
} else {
conflictCount++;
}
} else {
// Create new preference
const newPreference: TeamPreference = {
...sourcePreference,
id: this.generatePreferenceId(),
consensus: 0.5, // Start with neutral consensus
conflicts: [],
createdAt: new Date(),
updatedAt: new Date(),
adaptationHistory: []
};
targetTeam.preferences.push(newPreference);
synchronizedCount++;
}
}
}
if (synchronizedCount > 0) {
targetTeam.updatedAt = new Date();
await this.saveTeamProfile(targetTeam.id);
this.emit('preference-synchronized', {
sourceTeamId: request.sourceTeamId,
targetTeamId: request.targetTeamId,
synchronizedCount,
conflictCount
});
this.logger.info(`Successfully synchronized ${synchronizedCount} preferences with ${conflictCount} conflicts`);
return true;
}
this.logger.info('No preferences synchronized');
return false;
} catch (error) {
this.logger.error('Failed to synchronize preferences:', error);
return false;
}
}
async resolveConflicts(request: PreferenceConflictResolutionRequest): Promise<boolean> {
try {
this.logger.info(`Resolving preference conflicts for team: ${request.teamId}`);
const team = this.teamProfiles.get(request.teamId);
if (!team) {
throw new Error(`Team profile not found: ${request.teamId}`);
}
let resolvedCount = 0;
for (const conflict of request.conflicts) {
const resolution = await this.resolveSingleConflict(conflict, request.resolutionStrategy, request.options);
if (resolution) {
// Apply resolution
const preference = team.preferences.find(p => p.id === conflict.preferenceId);
if (preference) {
preference.conflicts = preference.conflicts.filter(c => c.id !== conflict.id);
if (resolution.resolution) {
conflict.resolution = resolution.resolution;
}
resolvedCount++;
}
}
}
if (resolvedCount > 0) {
team.updatedAt = new Date();
await this.saveTeamProfile(team.id);
this.emit('conflict-resolved', {
teamId: request.teamId,
resolvedCount,
totalConflicts: request.conflicts.length
});
this.logger.info(`Successfully resolved ${resolvedCount} conflicts for team: ${request.teamId}`);
return true;
}
this.logger.info(`No conflicts resolved for team: ${request.teamId}`);
return false;
} catch (error) {
this.logger.error('Failed to resolve conflicts:', error);
return false;
}
}
async getUserProfile(userId: string): Promise<UserProfile | null> {
return this.userProfiles.get(userId) || null;
}
async getTeamProfile(teamId: string): Promise<TeamProfile | null> {
return this.teamProfiles.get(teamId) || null;
}
async getUserPreferences(userId: string, category?: PreferenceCategory): Promise<UserPreference[]> {
const user = this.userProfiles.get(userId);
if (!user) return [];
if (category) {
return user.preferences.filter(p => p.category === category);
}
return user.preferences;
}
async getTeamPreferences(teamId: string, category?: PreferenceCategory): Promise<TeamPreference[]> {
const team = this.teamProfiles.get(teamId);
if (!team) return [];
if (category) {
return team.preferences.filter(p => p.category === category);
}
return team.preferences;
}
async getTeamDynamics(teamId: string): Promise<TeamDynamics | null> {
const team = this.teamProfiles.get(teamId);
return team ? team.dynamics : null;
}
async getTeamPerformance(teamId: string): Promise<TeamPerformance | null> {
const team = this.teamProfiles.get(teamId);
return team ? team.performance : null;
}
private async updateUserBehavior(user: UserProfile, request: PreferenceLearningRequest): Promise<void> {
// Update coding patterns
if (request.action.type === ActionType.TASK_COMPLETION ||
request.action.type === ActionType.FEATURE_DEVELOPMENT) {
await this.updateCodingPatterns(user.behavior, request);
}
// Update communication patterns
if (request.action.collaborators.length > 0) {
await this.updateCommunicationPatterns(user.behavior, request);
}
// Update productivity metrics
await this.updateProductivityMetrics(user.behavior, request);
// Update error patterns if there were errors
if (request.outcome.errors.length > 0) {
await this.updateErrorPatterns(user.behavior, request);
}
// Update success metrics if successful
if (request.outcome.success) {
await this.updateSuccessMetrics(user.behavior, request);
}
}
private async updateTeamBehavior(team: TeamProfile, user: UserProfile, request: PreferenceLearningRequest): Promise<void> {
// Update collaboration patterns
if (request.action.collaborators.length > 0) {
await this.updateCollaborationPatterns(team.behavior, request);
}
// Update learning patterns
if (request.action.type === ActionType.LEARNING) {
await this.updateLearningPatterns(team.behavior, request);
}
// Update productivity patterns
await this.updateProductivityPatterns(team.behavior, request);
// Update team dynamics
await this.updateTeamDynamicsFromAction(team, user, request);
}
private async learnPreferences(user: UserProfile, request: PreferenceLearningRequest): Promise<void> {
// Use learning algorithms to extract preferences from user actions
for (const [type, algorithm] of this.learningAlgorithms) {
try {
const learnedPreferences = await algorithm.learn(request, user);
for (const learnedPref of learnedPreferences) {
// Check if preference already exists
const existingPref = user.preferences.find(p =>
p.category === learnedPref.category && p.key === learnedPref.key
);
if (existingPref) {
// Update existing preference
existingPref.value = learnedPref.value;
existingPref.confidence = Math.max(existingPref.confidence, learnedPref.confidence);
existingPref.updatedAt = new Date();
existingPref.usageCount++;
} else {
// Create new preference
const newPreference: UserPreference = {
...learnedPref,
id: this.generatePreferenceId(),
createdAt: new Date(),
updatedAt: new Date(),
usageCount: 1,
effectiveness: 0.5 // Start with neutral effectiveness
};
user.preferences.push(newPreference);
}
}
} catch (error) {
this.logger.warn(`Failed to learn preferences with algorithm ${type}:`, error);
}
}
// Limit preferences to max count
if (user.preferences.length > this.config.maxPreferencesPerUser) {
// Sort by effectiveness and usage, keep top preferences
user.preferences.sort((a, b) =>
(b.effectiveness + b.usageCount * 0.1) - (a.effectiveness + a.usageCount * 0.1)
);
user.preferences = user.preferences.slice(0, this.config.maxPreferencesPerUser);
}
}
private async analyzeAdaptationTriggers(triggers: AdaptationTrigger[], team: TeamProfile): Promise<AdaptationAnalysis> {
let shouldAdapt = false;
let primaryTrigger: AdaptationTrigger | null = null;
let maxSeverity = 0;
for (const trigger of triggers) {
const severity = await this.calculateTriggerSeverity(trigger, team);
if (severity >= this.config.adaptationThreshold) {
shouldAdapt = true;
if (severity > maxSeverity) {
maxSeverity = severity;
primaryTrigger = trigger;
}
}
}
return {
shouldAdapt,
primaryTrigger,
severity: maxSeverity,
recommendations: shouldAdapt ? await this.generateAdaptationRecommendations(triggers, team) : []
};
}
private selectAdaptationAlgorithm(trigger: AdaptationTrigger): AdaptationAlgorithm {
switch (trigger) {
case AdaptationTrigger.PERFORMANCE_DECLINE:
return this.adaptationAlgorithms.get(AdaptationAlgorithmType.PERFORMANCE_BASED)!;
case AdaptationTrigger.CONFLICT_INCREASE:
return this.adaptationAlgorithms.get(AdaptationAlgorithmType.CONFLICT_BASED)!;
case AdaptationTrigger.SATISFACTION_DECREASE:
return this.adaptationAlgorithms.get(AdaptationAlgorithmType.SATISFACTION_BASED)!;
default:
return this.adaptationAlgorithms.get(AdaptationAlgorithmType.PERFORMANCE_BASED)!;
}
}
private async applyPreferenceChange(team: TeamProfile, change: PreferenceChange): Promise<void> {
const preference = team.preferences.find(p => p.id === change.preferenceId);
if (preference) {
preference.value = change.newValue;
preference.updatedAt = new Date();
// Record adaptation
const adaptationRecord: AdaptationRecord = {
timestamp: new Date(),
trigger: AdaptationTrigger.PERFORMANCE_DECLINE, // This should be passed in
change,
impact: {
userSatisfaction: 0,
teamPerformance: 0,
qualityImpact: 0,
productivityImpact: 0,
overallImpact: 0
},
effectiveness: change.confidence
};
preference.adaptationHistory.push(adaptationRecord);
}
}
private recordAdaptation(team: TeamProfile, adaptation: AdaptationResult): void {
// Record adaptation in team performance metrics
// This would update performance trends and metrics
}
private async updateTeamDynamics(team: TeamProfile, adaptation: AdaptationResult): Promise<void> {
// Update team dynamics based on adaptation effectiveness
const effectiveness = adaptation.effectiveness;
team.dynamics.adaptation = Math.min(100, team.dynamics.adaptation + effectiveness * 10);
team.dynamics.cohesion = Math.min(100, team.dynamics.cohesion + effectiveness * 5);
team.dynamics.collaboration = Math.min(100, team.dynamics.collaboration + effectiveness * 5);
// Update performance metrics
team.performance.quality = Math.min(100, team.performance.quality + effectiveness * 3);
team.performance.collaboration = Math.min(100, team.performance.collaboration + effectiveness * 4);
}
private async resolveSingleConflict(
conflict: PreferenceConflict,
strategy: ConflictResolutionStrategy,
options: ResolutionOptions
): Promise<ConflictResolution | null> {
// Implement conflict resolution logic based on strategy
switch (strategy) {
case ConflictResolutionStrategy.MAJORITY_VOTE:
return await this.resolveByMajorityVote(conflict, options);
case ConflictResolutionStrategy.CONSENSUS:
return await this.resolveByConsensus(conflict, options);
case ConflictResolutionStrategy.HIERARCHICAL:
return await this.resolveByHierarchy(conflict, options);
default:
return null;
}
}
private async resolveByMajorityVote(conflict: PreferenceConflict, options: ResolutionOptions): Promise<ConflictResolution | null> {
// Simulate majority vote resolution
return {
strategy: ConflictResolutionStrategy.MAJORITY_VOTE,
decision: 'Majority decision',
reasoning: 'Resolved by majority vote among team members',
satisfaction: 0.7,
effectiveness: 0.8
};
}
private async resolveByConsensus(conflict: PreferenceConflict, options: ResolutionOptions): Promise<ConflictResolution | null> {
// Simulate consensus resolution
return {
strategy: ConflictResolutionStrategy.CONSENSUS,
decision: 'Consensus decision',
reasoning: 'Resolved through team consensus building',
satisfaction: 0.9,
effectiveness: 0.9
};
}
private async resolveByHierarchy(conflict: PreferenceConflict, options: ResolutionOptions): Promise<ConflictResolution | null> {
// Simulate hierarchical resolution
return {
strategy: ConflictResolutionStrategy.HIERARCHICAL,
decision: 'Hierarchical decision',
reasoning: 'Resolved by team lead or manager',
satisfaction: 0.6,
effectiveness: 0.7
};
}
private createDefaultBehavior(): UserBehavior {
return {
codingPatterns: [],
collaborationStyle: {
preferredMethods: [CollaborationMethod.CODE_REVIEW],
communicationFrequency: CommunicationFrequency.MODERATE,
decisionMaking: DecisionMakingPreference.COLLABORATIVE,
feedbackStyle: FeedbackStyle.CONSTRUCTIVE,
conflictHandling: ConflictHandlingStyle.COLLABORATING
},
communicationPatterns: [],
learningStyle: {
preferredMethods: [LearningMethod.HANDS_ON],
pace: LearningPace.MODERATE,
depth: LearningDepth.MODERATE,
socialPreference: SocialLearningPreference.NEUTRAL
},
productivityMetrics: {
codeOutput: 0,
qualityScore: 0,
efficiency: 0,
focusTime: 0,
contextSwitches: 0,
taskCompletion: 0
},
errorPatterns: [],
successMetrics: {
achievements: [],
recognition: [],
impact: 0,
satisfaction: 0,
growth: 0
}
};
}
private createDefaultTeamBehavior(): TeamBehavior {
return {
collaborationPatterns: [],
communicationStyle: {
primaryChannels: [CommunicationChannel.CHAT, CommunicationChannel.VIDEO_CALL],
frequency: CommunicationFrequency.MODERATE,
formality: FormalityLevel.PROFESSIONAL,
transparency: TransparencyLevel.HIGH,
documentation: DocumentationPreference.ADEQUATE
},
decisionMaking: {
approach: DecisionApproach.COLLABORATIVE,
participation: ParticipationLevel.PARTICIPATIVE,
speed: DecisionSpeed.MODERATE,
criteria: []
},
conflictResolution: {
approach: ConflictApproach.COLLABORATING,
mediation: MediationPreference.PEER,
compromise: CompromisePreference.SEEK_WIN_WIN,
escalation: EscalationPreference.STEP_BY_STEP
},
learningPatterns: [],
productivityPatterns: []
};
}
private createDefaultTeamDynamics(): TeamDynamics {
return {
cohesion: 70,
communication: 75,
collaboration: 70,
conflict: 20,
satisfaction: 75,
performance: 70,
adaptation: 65
};
}
private createDefaultTeamPerformance(): TeamPerformance {
return {
velocity: 70,
quality: 75,
efficiency: 70,
innovation: 65,
collaboration: 75,
satisfaction: 75,
trends: []
};
}
private calculateSatisfaction(outcome: ActionResult): number {
if (!outcome.success) return 0.3;
const qualityWeight = 0.3;
const efficiencyWeight = 0.3;
const satisfactionWeight = 0.4;
return (
outcome.quality * qualityWeight +
outcome.efficiency * efficiencyWeight +
outcome.satisfaction * satisfactionWeight
) / 100;
}
private calculateImpact(outcome: ActionResult): ImpactAssessment {
const successMultiplier = outcome.success ? 1.0 : 0.3;
const qualityImpact = outcome.quality * successMultiplier;
const efficiencyImpact = outcome.efficiency * successMultiplier;
return {
technicalImpact: qualityImpact * 0.8,
businessImpact: qualityImpact * 0.6,
userImpact: outcome.satisfaction * successMultiplier,
teamImpact: efficiencyImpact * 0.7,
overallImpact: (qualityImpact + efficiencyImpact + outcome.satisfaction) / 3 * successMultiplier
};
}
private async updateCodingPatterns(behavior: UserBehavior, request: PreferenceLearningRequest): Promise<void> {
// Update coding patterns based on action
// This is a simplified implementation
}
private async updateCommunicationPatterns(behavior: UserBehavior, request: PreferenceLearningRequest): Promise<void> {
// Update communication patterns based on collaborators
// This is a simplified implementation
}
private async updateProductivityMetrics(behavior: UserBehavior, request: PreferenceLearningRequest): Promise<void> {
// Update productivity metrics
behavior.productivityMetrics.taskCompletion += request.outcome.success ? 1 : 0;
behavior.productivityMetrics.qualityScore =
(behavior.productivityMetrics.qualityScore + request.outcome.quality) / 2;
behavior.productivityMetrics.efficiency =
(behavior.productivityMetrics.efficiency + request.outcome.efficiency) / 2;
}
private async updateErrorPatterns(behavior: UserBehavior, request: PreferenceLearningRequest): Promise<void> {
// Update error patterns
for (const error of request.outcome.errors) {
const errorPattern: ErrorPattern = {
id: this.generateErrorPatternId(),
type: ErrorType.LOGIC, // Default, should be determined from error
frequency: 1,
context: {
task: request.action.description,
technology: 'unknown', // Should be extracted from context
complexity: request.action.complexity,
timePressure: request.context.timePressure,
context: request.context.project
},
severity: SeverityLevel.WARNING, // Default
lastOccurred: new Date(),
resolution: error
};
behavior.errorPatterns.push(errorPattern);
}
}
private async updateSuccessMetrics(behavior: UserBehavior, request: PreferenceLearningRequest): Promise<void> {
// Update success metrics
behavior.successMetrics.impact =
(behavior.successMetrics.impact + this.calculateImpact(request.outcome).overallImpact) / 2;
behavior.successMetrics.satisfaction =
(behavior.successMetrics.satisfaction + this.calculateSatisfaction(request.outcome)) / 2;
}
private async updateCollaborationPatterns(behavior: TeamBehavior, request: PreferenceLearningRequest): Promise<void> {
// Update collaboration patterns
// This is a simplified implementation
}
private async updateLearningPatterns(behavior: TeamBehavior, request: PreferenceLearningRequest): Promise<void> {
// Update learning patterns
// This is a simplified implementation
}
private async updateProductivityPatterns(behavior: TeamBehavior, request: PreferenceLearningRequest): Promise<void> {
// Update productivity patterns
// This is a simplified implementation
}
private async updateTeamDynamicsFromAction(team: TeamProfile, user: UserProfile, request: PreferenceLearningRequest): Promise<void> {
// Update team dynamics based on user action
const satisfaction = this.calculateSatisfaction(request.outcome);
const impact = this.calculateImpact(request.outcome);
team.dynamics.satisfaction = (team.dynamics.satisfaction + satisfaction) / 2;
team.dynamics.collaboration = (team.dynamics.collaboration + impact.teamImpact) / 2;
// Update performance metrics
team.performance.quality = (team.performance.quality + request.outcome.quality) / 2;
team.performance.collaboration = (team.performance.collaboration + impact.teamImpact) / 2;
}
private async calculateTriggerSeverity(trigger: AdaptationTrigger, team: TeamProfile): Promise<number> {
// Calculate severity based on trigger type and team state
switch (trigger) {
case AdaptationTrigger.PERFORMANCE_DECLINE:
return Math.max(0, 80 - team.performance.quality);
case AdaptationTrigger.CONFLICT_INCREASE:
return Math.min(100, team.dynamics.conflict * 5);
case AdaptationTrigger.SATISFACTION_DECREASE:
return Math.max(0, 80 - team.dynamics.satisfaction);
default:
return 50;
}
}
private async generateAdaptationRecommendations(triggers: AdaptationTrigger[], team: TeamProfile): Promise<string[]> {
const recommendations: string[] = [];
for (const trigger of triggers) {
switch (trigger) {
case AdaptationTrigger.PERFORMANCE_DECLINE:
recommendations.push('Consider adopting performance-focused coding practices');
recommendations.push('Review and optimize team workflow');
break;
case AdaptationTrigger.CONFLICT_INCREASE:
recommendations.push('Implement conflict resolution workshops');
recommendations.push('Improve communication protocols');
break;
case AdaptationTrigger.SATISFACTION_DECREASE:
recommendations.push('Conduct team satisfaction surveys');
recommendations.push('Address team morale and motivation');
break;
}
}
return recommendations;
}
private async loadProfiles(): Promise<void> {
try {
// Load user profiles
const cachedUsers = await this.cache.get<Map<string, any>>('user-profiles');
if (cachedUsers) {
for (const [userId, userData] of Object.entries(cachedUsers)) {
this.userProfiles.set(userId, userData);
}
}
// Load team profiles
const cachedTeams = await this.cache.get<Map<string, any>>('team-profiles');
if (cachedTeams) {
for (const [teamId, teamData] of Object.entries(cachedTeams)) {
this.teamProfiles.set(teamId, teamData);
}
}
this.logger.info(`Loaded ${this.userProfiles.size} user profiles and ${this.teamProfiles.size} team profiles`);
} catch (error) {
this.logger.warn('Failed to load profiles:', error);
}
}
private async saveUserProfile(userId: string): Promise<void> {
try {
const user = this.userProfiles.get(userId);
if (user) {
await this.cache.set(`user-profile-${userId}`, user, 3600);
// Also save to global users index
const usersIndex: Record<string, any> = {};
for (const [uid, u] of this.userProfiles.entries()) {
usersIndex[uid] = u;
}
await this.cache.set('user-profiles', usersIndex, 3600);
}
} catch (error) {
this.logger.warn(`Failed to save user profile for user ${userId}:`, error);
}
}
private async saveTeamProfile(teamId: string): Promise<void> {
try {
const team = this.teamProfiles.get(teamId);
if (team) {
await this.cache.set(`team-profile-${teamId}`, team, 3600);
// Also save to global teams index
const teamsIndex: Record<string, any> = {};
for (const [tid, t] of this.teamProfiles.entries()) {
teamsIndex[tid] = t;
}
await this.cache.set('team-profiles', teamsIndex, 3600);
}
} catch (error) {
this.logger.warn(`Failed to save team profile for team ${teamId}:`, error);
}
}
// ID generation methods
private generateProfileId(): string {
return `user_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
}
private generateTeamId(): string {
return `team_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
}
private generatePreferenceId(): string {
return `pref_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
}
private generateErrorPatternId(): string {
return `error_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
}
// Event handlers
private handlePreferenceLearned(data: any): void {
this.logger.debug(`Preference learned event handled for user: ${data.userId}`);
}
private handlePreferenceAdapted(data: any): void {
this.logger.debug(`Preference adapted event handled for team: ${data.teamId}`);
}
private handlePreferenceSynchronized(data: any): void {
this.logger.debug(`Preference synchronized event handled`);
}
private handleConflictResolved(data: any): void {
this.logger.debug(`Conflict resolved event handled for team: ${data.teamId}`);
}
// Public API methods
async updateConfig(config: Partial<TeamPreferenceConfig>): Promise<void> {
this.config = { ...this.config, ...config };
this.logger.info('Team preference learning configuration updated');
}
async getLearningStats(): Promise<any> {
const totalUsers = this.userProfiles.size;
const totalTeams = this.teamProfiles.size;
const totalPreferences = Array.from(this.userProfiles.values())
.reduce((sum, user) => sum + user.preferences.length, 0) +
Array.from(this.teamProfiles.values())
.reduce((sum, team) => sum + team.preferences.length, 0);
const averageTeamSatisfaction = Array.from(this.teamProfiles.values())
.reduce((sum, team) => sum + team.dynamics.satisfaction, 0) / this.teamProfiles.size || 0;
return {
totalUsers,
totalTeams,
totalPreferences,
averageTeamSatisfaction,
learningEnabled: this.config.enableLearning,
adaptationEnabled: this.config.enableAdaptation,
synchronizationEnabled: this.config.enableSynchronization,
learningAlgorithms: this.learningAlgorithms.size,
adaptationAlgorithms: this.adaptationAlgorithms.size
};
}
async shutdown(): Promise<void> {
this.logger.info('Shutting down Team Preference Learning Service');
// Save all profiles
for (const userId of this.userProfiles.keys()) {
await this.saveUserProfile(userId);
}
for (const teamId of this.teamProfiles.keys()) {
await this.saveTeamProfile(teamId);
}
// Clear event listeners
this.removeAllListeners();
this.logger.info('Team Preference Learning Service shutdown complete');
}
}
// Type definitions for algorithm results
interface AdaptationAnalysis {
shouldAdapt: boolean;
primaryTrigger: AdaptationTrigger | null;
severity: number;
recommendations: string[];
}
interface AdaptationResult {
success: boolean;
changes: PreferenceChange[];
effectiveness: number;
reasoning: string[];
}
// Algorithm type definitions
enum LearningAlgorithmType {
BEHAVIORAL = 'behavioral',
COLLABORATIVE = 'collaborative',
ADAPTIVE = 'adaptive'
}
enum AdaptationAlgorithmType {
PERFORMANCE_BASED = 'performance-based',
CONFLICT_BASED = 'conflict-based',
SATISFACTION_BASED = 'satisfaction-based'
}
// Abstract base classes for algorithms
abstract class LearningAlgorithm {
abstract learn(request: PreferenceLearningRequest, user: UserProfile): Promise<UserPreference[]>;
}
abstract class AdaptationAlgorithm {
abstract adapt(request: PreferenceAdaptationRequest, team: TeamProfile, analysis: AdaptationAnalysis): Promise<AdaptationResult>;
}
// Concrete algorithm implementations (simplified)
class BehavioralLearningAlgorithm extends LearningAlgorithm {
async learn(request: PreferenceLearningRequest, user: UserProfile): Promise<UserPreference[]> {
// Implement behavioral learning logic
return [];
}
}
class CollaborativeLearningAlgorithm extends LearningAlgorithm {
async learn(request: PreferenceLearningRequest, user: UserProfile): Promise<UserPreference[]> {
// Implement collaborative learning logic
return [];
}
}
class AdaptiveLearningAlgorithm extends LearningAlgorithm {
async learn(request: PreferenceLearningRequest, user: UserProfile): Promise<UserPreference[]> {
// Implement adaptive learning logic
return [];
}
}
class PerformanceBasedAdaptationAlgorithm extends AdaptationAlgorithm {
async adapt(request: PreferenceAdaptationRequest, team: TeamProfile, analysis: AdaptationAnalysis): Promise<AdaptationResult> {
// Implement performance-based adaptation logic
return {
success: true,
changes: [],
effectiveness: 0.8,
reasoning: ['Performance-based adaptation applied']
};
}
}
class ConflictBasedAdaptationAlgorithm extends AdaptationAlgorithm {
async adapt(request: PreferenceAdaptationRequest, team: TeamProfile, analysis: AdaptationAnalysis): Promise<AdaptationResult> {
// Implement conflict-based adaptation logic
return {
success: true,
changes: [],
effectiveness: 0.7,
reasoning: ['Conflict-based adaptation applied']
};
}
}
class SatisfactionBasedAdaptationAlgorithm extends AdaptationAlgorithm {
async adapt(request: PreferenceAdaptationRequest, team: TeamProfile, analysis: AdaptationAnalysis): Promise<AdaptationResult> {
// Implement satisfaction-based adaptation logic
return {
success: true,
changes: [],
effectiveness: 0.75,
reasoning: ['Satisfaction-based adaptation applied']
};
}
}