/** * Comprehensive Reputation and Rating System * Manages trust, performance metrics, and social proof for AI agents and users */ import type { Address } from '@solana/addresses'; import type { Rpc, SolanaRpcApi } from '@solana/rpc'; import type { Commitment } from '@solana/rpc-types'; import type { KeyPairSigner } from '@solana/signers'; import { sendAndConfirmTransactionFactory } from '../utils/transaction-helpers.js'; /** * Rating categories for comprehensive evaluation */ export type RatingCategory = | 'overall' // Overall satisfaction | 'technical_skill' // Technical competency | 'communication' // Communication quality | 'reliability' // Meeting deadlines and commitments | 'innovation' // Creative problem solving | 'collaboration' // Teamwork and cooperation | 'cost_effectiveness' // Value for money | 'responsiveness' // Response time and availability | 'quality' // Work quality and attention to detail | 'professionalism'; // Professional conduct /** * Rating source types for verification */ export type RatingSource = | 'direct_client' // Direct client review | 'peer_review' // Other agent review | 'automated_metric' // System-generated metric | 'escrow_completion' // Successful escrow completion | 'community_vote' // Community consensus | 'verified_transaction' // Blockchain-verified transaction | 'third_party_audit'; // External audit /** * Reputation tier levels */ export type ReputationTier = | 'newcomer' // 0-99 points | 'bronze' // 100-499 points | 'silver' // 500-999 points | 'gold' // 1000-2499 points | 'platinum' // 2500-4999 points | 'diamond' // 5000-9999 points | 'legendary'; // 10000+ points /** * Individual rating with comprehensive metadata */ export interface IRating { ratingId: Address; fromAddress: Address; toAddress: Address; transactionId?: Address; // Associated transaction if applicable // Rating details category: RatingCategory; score: number; // 1-5 scale with decimals (e.g., 4.7) comment?: string; // Verification and source source: RatingSource; isVerified: boolean; verificationProof?: string; // Hash or signature proof // Context projectType?: string; projectValue?: bigint; interactionDuration?: number; // milliseconds // Metadata timestamp: number; blockHeight?: number; weight: number; // 0.1 - 1.0 based on rater credibility // Moderation isDisputed: boolean; moderationStatus: 'pending' | 'approved' | 'rejected' | 'under_review'; reportCount: number; } /** * Comprehensive reputation profile */ export interface IReputationProfile { address: Address; // Overall metrics overallScore: number; // 0-5 weighted average totalRatings: number; reputationPoints: number; tier: ReputationTier; // Category breakdown categoryScores: Record; // Performance metrics completionRate: number; // Percentage of successful completions averageResponseTime: number; // milliseconds onTimeDeliveryRate: number; // Percentage disputeRate: number; // Percentage of transactions disputed // Activity and engagement totalTransactions: number; totalVolume: bigint; // Total SOL transacted activeDays: number; // Days active on platform lastActiveDate: number; // Social proof endorsements: Array<{ fromAddress: Address; skill: string; timestamp: number; }>; achievements: Array<{ type: string; title: string; description: string; earnedDate: number; rarity: 'common' | 'uncommon' | 'rare' | 'legendary'; }>; // Risk indicators riskScore: number; // 0-100 (lower is better) flaggedCount: number; suspensionHistory: Array<{ reason: string; startDate: number; endDate: number; }>; // Verification status isVerified: boolean; verificationLevel: 'basic' | 'enhanced' | 'enterprise'; kycCompleted: boolean; // Calculated metrics trendingScore: number; // Recent performance trend recommendationScore: number; // Likelihood to recommend (0-100) trustScore: number; // Overall trustworthiness (0-100) // Historical data scoreHistory: Array<{ date: number; score: number; event: string; }>; } /** * Rating submission interface */ export interface IRatingSubmission { targetAddress: Address; transactionId?: Address; category: RatingCategory; score: number; // 1-5 comment?: string; projectType?: string; projectValue?: bigint; evidence?: string[]; // IPFS hashes or other proof isAnonymous?: boolean; } /** * Reputation analytics and insights */ export interface IReputationAnalytics { // Performance trends performanceTrend: { period: 'week' | 'month' | 'quarter' | 'year'; direction: 'improving' | 'stable' | 'declining'; changePercentage: number; keyDrivers: string[]; }; // Comparative analysis peerComparison: { percentile: number; // Where they rank among peers averagePeerScore: number; strengthAreas: RatingCategory[]; improvementAreas: RatingCategory[]; }; // Market insights marketPosition: { demandLevel: 'low' | 'medium' | 'high' | 'exceptional'; priceMultiplier: number; // How much premium they can charge competitorCount: number; marketShare: number; // Percentage }; // Recommendations actionableInsights: Array<{ priority: 'high' | 'medium' | 'low'; category: string; recommendation: string; potentialImpact: string; estimatedEffort: 'low' | 'medium' | 'high'; }>; // Risk assessment riskAssessment: { currentRiskLevel: 'low' | 'medium' | 'high' | 'critical'; riskFactors: string[]; mitigationSuggestions: string[]; insurabilityScore: number; // 0-100 }; } /** * Reputation search and filtering */ export interface IReputationFilters { // Score ranges minOverallScore?: number; maxOverallScore?: number; minReputationPoints?: number; tiers?: ReputationTier[]; // Category requirements categoryRequirements?: Record; // Performance filters minCompletionRate?: number; maxDisputeRate?: number; maxResponseTime?: number; // Verification filters verificationRequired?: boolean; verificationLevels?: ('basic' | 'enhanced' | 'enterprise')[]; kycRequired?: boolean; // Activity filters minTotalTransactions?: number; minTotalVolume?: bigint; activeWithinDays?: number; // Risk management maxRiskScore?: number; excludeFlagged?: boolean; excludeSuspended?: boolean; // Sorting sortBy?: 'overall_score' | 'reputation_points' | 'total_ratings' | 'completion_rate' | 'recent_activity'; sortOrder?: 'asc' | 'desc'; } /** * Comprehensive Reputation and Rating Service */ export class ReputationService { constructor( private readonly rpc: Rpc, private readonly _programId: Address, private readonly commitment: Commitment = 'confirmed' ) {} /** * Submit a rating for an agent or user */ async submitRating( rater: KeyPairSigner, submission: IRatingSubmission ): Promise<{ ratingId: Address; signature: string; impactOnScore: number; }> { try { console.log(`⭐ Submitting ${submission.category} rating of ${submission.score} for ${submission.targetAddress}`); // Validate rating submission this.validateRatingSubmission(submission); // Generate rating ID const ratingId = `rating_${Date.now()}_${Math.random().toString(36).substr(2, 9)}` as Address; // Calculate the weight of this rating based on rater's credibility const raterCredibility = await this.calculateRaterCredibility(rater.address); const ratingWeight = Math.min(Math.max(raterCredibility / 100, 0.1), 1.0); // In a real implementation, this would call a submitRating smart contract instruction const mockInstruction = { programAddress: this._programId, accounts: [ { address: ratingId, role: 'writable' as const }, { address: submission.targetAddress, role: 'writable' as const }, { address: rater.address, role: 'writable_signer' as const }, ], data: new Uint8Array([1, 2, 3]) // Mock instruction data }; const sendTransactionFactory = sendAndConfirmTransactionFactory('https://api.devnet.solana.com'); const result = await sendTransactionFactory([mockInstruction], [rater]); const signature = result.signature; // Calculate the impact on target's overall score const impactOnScore = await this.calculateScoreImpact(submission.targetAddress, submission.score, ratingWeight); console.log('✅ Rating submitted successfully:', { ratingId, signature, weight: ratingWeight, impact: impactOnScore }); return { ratingId, signature, impactOnScore }; } catch (error) { throw new Error(`Rating submission failed: ${String(error)}`); } } /** * Get comprehensive reputation profile for an address */ async getReputationProfile(address: Address): Promise { try { console.log(`📊 Retrieving reputation profile for: ${address}`); // In a real implementation, this would fetch from blockchain and compute aggregates const profile = await this.generateReputationProfile(address); console.log(`✅ Reputation profile retrieved: ${profile.overallScore}/5 (${profile.tier})`); return profile; } catch (error) { throw new Error(`Failed to get reputation profile: ${String(error)}`); } } /** * Get detailed ratings for an address with filtering */ async getRatings( address: Address, filters: { categories?: RatingCategory[]; sources?: RatingSource[]; minScore?: number; maxScore?: number; limit?: number; offset?: number; } = {} ): Promise<{ ratings: IRating[]; totalCount: number; averageScore: number; distribution: Record; // Score distribution (1-5) }> { try { console.log(`📋 Getting ratings for ${address} with filters:`, filters); // Get all ratings for the address const allRatings = await this.getAllRatings(address); // Apply filters let filteredRatings = this.applyRatingFilters(allRatings, filters); // Apply pagination const limit = filters.limit || 50; const offset = filters.offset || 0; const paginatedRatings = filteredRatings.slice(offset, offset + limit); // Calculate statistics const averageScore = filteredRatings.length > 0 ? filteredRatings.reduce((sum, r) => sum + r.score, 0) / filteredRatings.length : 0; const distribution = this.calculateScoreDistribution(filteredRatings); return { ratings: paginatedRatings, totalCount: filteredRatings.length, averageScore, distribution, }; } catch (error) { throw new Error(`Failed to get ratings: ${String(error)}`); } } /** * Search agents by reputation criteria */ async searchByReputation( filters: IReputationFilters = {}, limit: number = 50 ): Promise<{ profiles: IReputationProfile[]; totalCount: number; searchMetadata: { executionTime: number; qualityScore: number; averageScore: number; }; }> { const startTime = Date.now(); try { console.log('🔍 Searching agents by reputation criteria:', filters); // Get all reputation profiles (in production, this would use efficient indexing) const allProfiles = await this.getAllReputationProfiles(1000); // Apply filters const filteredProfiles = this.applyReputationFilters(allProfiles, filters); // Sort results const sortedProfiles = this.sortReputationResults(filteredProfiles, filters); // Apply limit const limitedProfiles = sortedProfiles.slice(0, limit); const executionTime = Date.now() - startTime; const averageScore = limitedProfiles.length > 0 ? limitedProfiles.reduce((sum, p) => sum + p.overallScore, 0) / limitedProfiles.length : 0; return { profiles: limitedProfiles, totalCount: filteredProfiles.length, searchMetadata: { executionTime, qualityScore: this.calculateSearchQuality(limitedProfiles, filters), averageScore, }, }; } catch (error) { throw new Error(`Reputation search failed: ${String(error)}`); } } /** * Generate comprehensive reputation analytics */ async getReputationAnalytics(address: Address): Promise { try { console.log(`📈 Generating reputation analytics for: ${address}`); const profile = await this.getReputationProfile(address); const recentRatings = await this.getRecentRatings(address, 30); // Last 30 days const peerProfiles = await this.getPeerProfiles(address); // Calculate performance trend const performanceTrend = this.calculatePerformanceTrend(profile, recentRatings); // Peer comparison analysis const peerComparison = this.calculatePeerComparison(profile, peerProfiles); // Market position analysis const marketPosition = this.analyzeMarketPosition(profile, peerProfiles); // Generate actionable insights const actionableInsights = this.generateActionableInsights(profile, recentRatings, peerComparison); // Risk assessment const riskAssessment = this.assessRisks(profile, recentRatings); return { performanceTrend, peerComparison, marketPosition, actionableInsights, riskAssessment, }; } catch (error) { throw new Error(`Analytics generation failed: ${String(error)}`); } } /** * Endorse someone's skills */ async endorseSkill( endorser: KeyPairSigner, targetAddress: Address, skill: string, evidence?: string ): Promise<{ endorsementId: Address; signature: string; }> { try { console.log(`👍 Endorsing ${skill} for ${targetAddress}`); const endorsementId = `endorsement_${Date.now()}_${Math.random().toString(36).substr(2, 9)}` as Address; // In a real implementation, this would call an endorsement smart contract instruction const mockInstruction = { programAddress: this._programId, accounts: [ { address: endorsementId, role: 'writable' as const }, { address: targetAddress, role: 'writable' as const }, { address: endorser.address, role: 'writable_signer' as const }, ], data: new Uint8Array([4, 5, 6]) // Mock instruction data }; const sendTransactionFactory = sendAndConfirmTransactionFactory('https://api.devnet.solana.com'); const result = await sendTransactionFactory([mockInstruction], [endorser]); const signature = result.signature; console.log('✅ Skill endorsed:', { endorsementId, signature }); return { endorsementId, signature }; } catch (error) { throw new Error(`Skill endorsement failed: ${String(error)}`); } } /** * Report inappropriate rating or behavior */ async reportRating( reporter: KeyPairSigner, ratingId: Address, reason: 'spam' | 'fake' | 'inappropriate' | 'malicious' | 'other', details?: string ): Promise<{ reportId: Address; signature: string; }> { try { console.log(`🚨 Reporting rating ${ratingId} for: ${reason}`); const reportId = `report_${Date.now()}_${Math.random().toString(36).substr(2, 9)}` as Address; // In a real implementation, this would call a report smart contract instruction const mockInstruction = { programAddress: this._programId, accounts: [ { address: reportId, role: 'writable' as const }, { address: ratingId, role: 'writable' as const }, { address: reporter.address, role: 'writable_signer' as const }, ], data: new Uint8Array([7, 8, 9]) // Mock instruction data }; const sendTransactionFactory = sendAndConfirmTransactionFactory('https://api.devnet.solana.com'); const result = await sendTransactionFactory([mockInstruction], [reporter]); const signature = result.signature; console.log('✅ Rating reported:', { reportId, signature }); return { reportId, signature }; } catch (error) { throw new Error(`Rating report failed: ${String(error)}`); } } /** * Get leaderboard of top-rated agents */ async getLeaderboard( category: RatingCategory | 'overall' = 'overall', timeframe: 'week' | 'month' | 'quarter' | 'year' | 'all' = 'month', limit: number = 100 ): Promise> { try { console.log(`🏆 Getting ${category} leaderboard for ${timeframe} (top ${limit})`); const allProfiles = await this.getAllReputationProfiles(1000); // Filter by timeframe if applicable const filteredProfiles = this.filterByTimeframe(allProfiles, timeframe); // Sort by specified category const sortedProfiles = filteredProfiles.sort((a, b) => { const scoreA = category === 'overall' ? a.overallScore : a.categoryScores[category]?.score || 0; const scoreB = category === 'overall' ? b.overallScore : b.categoryScores[category]?.score || 0; return scoreB - scoreA; }); // Create leaderboard entries return sortedProfiles.slice(0, limit).map((profile, index) => ({ address: profile.address, score: category === 'overall' ? profile.overallScore : profile.categoryScores[category]?.score || 0, rank: index + 1, tier: profile.tier, totalRatings: profile.totalRatings, trend: this.calculateTrend(profile), })); } catch (error) { throw new Error(`Leaderboard generation failed: ${String(error)}`); } } /** * Private helper methods */ private validateRatingSubmission(submission: IRatingSubmission): void { if (submission.score < 1 || submission.score > 5) { throw new Error('Rating score must be between 1 and 5'); } if (submission.comment && submission.comment.length > 500) { throw new Error('Comment must be 500 characters or less'); } if (submission.projectValue && submission.projectValue < 0n) { throw new Error('Project value cannot be negative'); } } private async calculateRaterCredibility(raterAddress: Address): Promise { // In a real implementation, this would calculate based on rater's own reputation // For now, simulate based on hash of address const hash = raterAddress.split('').reduce((acc, char) => acc + char.charCodeAt(0), 0); return 50 + (hash % 50); // 50-100 credibility score } private async calculateScoreImpact(targetAddress: Address, newScore: number, weight: number): Promise { // Simulate calculating the impact of a new rating on overall score const currentProfile = await this.generateReputationProfile(targetAddress); const totalWeight = currentProfile.totalRatings + weight; const newAverage = (currentProfile.overallScore * currentProfile.totalRatings + newScore * weight) / totalWeight; return newAverage - currentProfile.overallScore; } private async generateReputationProfile(address: Address): Promise { // Generate mock reputation profile const hash = address.split('').reduce((acc, char) => acc + char.charCodeAt(0), 0); const overallScore = 3.0 + (hash % 200) / 100; // 3.0-5.0 range const totalRatings = Math.floor(hash % 100) + 10; const reputationPoints = Math.floor(overallScore * totalRatings * 10); const tier: ReputationTier = reputationPoints >= 10000 ? 'legendary' : reputationPoints >= 5000 ? 'diamond' : reputationPoints >= 2500 ? 'platinum' : reputationPoints >= 1000 ? 'gold' : reputationPoints >= 500 ? 'silver' : reputationPoints >= 100 ? 'bronze' : 'newcomer'; const categoryScores: Record = {} as any; const categories: RatingCategory[] = [ 'overall', 'technical_skill', 'communication', 'reliability', 'innovation', 'collaboration', 'cost_effectiveness', 'responsiveness', 'quality', 'professionalism' ]; categories.forEach(category => { const categoryHash = (hash + category.length) % 100; categoryScores[category] = { score: 3.0 + categoryHash / 50, // 3.0-5.0 range count: Math.floor(categoryHash / 10) + 1, trend: categoryHash % 3 === 0 ? 'improving' : categoryHash % 3 === 1 ? 'stable' : 'declining', }; }); return { address, overallScore, totalRatings, reputationPoints, tier, categoryScores, completionRate: 85 + (hash % 15), // 85-100% averageResponseTime: Math.floor(hash % 3600000), // 0-1 hour onTimeDeliveryRate: 75 + (hash % 25), // 75-100% disputeRate: (hash % 10), // 0-10% totalTransactions: Math.floor(hash % 500) + 10, totalVolume: BigInt(Math.floor(hash % 10000000000)), activeDays: Math.floor(hash % 365) + 30, lastActiveDate: Date.now() - (hash % 86400000), endorsements: [], achievements: [], riskScore: hash % 30, // 0-30 (low risk) flaggedCount: hash % 3, suspensionHistory: [], isVerified: hash % 3 === 0, verificationLevel: hash % 3 === 0 ? 'enhanced' : 'basic', kycCompleted: hash % 2 === 0, trendingScore: 60 + (hash % 40), // 60-100 recommendationScore: 70 + (hash % 30), // 70-100 trustScore: 80 + (hash % 20), // 80-100 scoreHistory: [], }; } private async getAllRatings(address: Address): Promise { // Simulate getting all ratings for an address const ratingCount = Math.floor(Math.random() * 50) + 10; return Array.from({ length: ratingCount }, (_, i) => { const categories: RatingCategory[] = [ 'overall', 'technical_skill', 'communication', 'reliability' ]; const sources: RatingSource[] = [ 'direct_client', 'peer_review', 'escrow_completion', 'verified_transaction' ]; return { ratingId: `rating_${i + 1}_${Date.now()}` as Address, fromAddress: `rater_${i + 1}` as Address, toAddress: address, category: categories[i % categories.length], score: 3 + Math.random() * 2, // 3-5 range source: sources[i % sources.length], isVerified: Math.random() > 0.3, timestamp: Date.now() - Math.random() * 86400000 * 30, // Last 30 days weight: 0.5 + Math.random() * 0.5, // 0.5-1.0 isDisputed: Math.random() > 0.95, moderationStatus: 'approved', reportCount: 0, }; }); } private applyRatingFilters(ratings: IRating[], filters: any): IRating[] { return ratings.filter(rating => { if (filters.categories && !filters.categories.includes(rating.category)) return false; if (filters.sources && !filters.sources.includes(rating.source)) return false; if (filters.minScore && rating.score < filters.minScore) return false; if (filters.maxScore && rating.score > filters.maxScore) return false; return true; }); } private calculateScoreDistribution(ratings: IRating[]): Record { const distribution: Record = { 1: 0, 2: 0, 3: 0, 4: 0, 5: 0 }; ratings.forEach(rating => { const roundedScore = Math.round(rating.score); distribution[roundedScore] = (distribution[roundedScore] || 0) + 1; }); return distribution; } private async getAllReputationProfiles(limit: number): Promise { // Simulate getting all reputation profiles return Array.from({ length: Math.min(limit, 100) }, (_, i) => this.generateReputationProfile(`agent_${i + 1}_${Date.now()}` as Address) ).map(async profile => await profile).reduce(async (acc, profile) => { const profiles = await acc; profiles.push(await profile); return profiles; }, Promise.resolve([] as IReputationProfile[])); } private applyReputationFilters(profiles: IReputationProfile[], filters: IReputationFilters): IReputationProfile[] { return profiles.filter(profile => { // Score filters if (filters.minOverallScore && profile.overallScore < filters.minOverallScore) return false; if (filters.maxOverallScore && profile.overallScore > filters.maxOverallScore) return false; if (filters.minReputationPoints && profile.reputationPoints < filters.minReputationPoints) return false; if (filters.tiers && !filters.tiers.includes(profile.tier)) return false; // Performance filters if (filters.minCompletionRate && profile.completionRate < filters.minCompletionRate) return false; if (filters.maxDisputeRate && profile.disputeRate > filters.maxDisputeRate) return false; if (filters.maxResponseTime && profile.averageResponseTime > filters.maxResponseTime) return false; // Verification filters if (filters.verificationRequired && !profile.isVerified) return false; if (filters.kycRequired && !profile.kycCompleted) return false; // Activity filters if (filters.minTotalTransactions && profile.totalTransactions < filters.minTotalTransactions) return false; if (filters.minTotalVolume && profile.totalVolume < filters.minTotalVolume) return false; if (filters.activeWithinDays) { const daysSinceActive = (Date.now() - profile.lastActiveDate) / (24 * 60 * 60 * 1000); if (daysSinceActive > filters.activeWithinDays) return false; } // Risk filters if (filters.maxRiskScore && profile.riskScore > filters.maxRiskScore) return false; if (filters.excludeFlagged && profile.flaggedCount > 0) return false; if (filters.excludeSuspended && profile.suspensionHistory.length > 0) return false; return true; }); } private sortReputationResults(profiles: IReputationProfile[], filters: IReputationFilters): IReputationProfile[] { const sortedProfiles = [...profiles]; switch (filters.sortBy) { case 'overall_score': sortedProfiles.sort((a, b) => b.overallScore - a.overallScore); break; case 'reputation_points': sortedProfiles.sort((a, b) => b.reputationPoints - a.reputationPoints); break; case 'total_ratings': sortedProfiles.sort((a, b) => b.totalRatings - a.totalRatings); break; case 'completion_rate': sortedProfiles.sort((a, b) => b.completionRate - a.completionRate); break; case 'recent_activity': sortedProfiles.sort((a, b) => b.lastActiveDate - a.lastActiveDate); break; default: sortedProfiles.sort((a, b) => b.overallScore - a.overallScore); } if (filters.sortOrder === 'asc') { sortedProfiles.reverse(); } return sortedProfiles; } private calculateSearchQuality(profiles: IReputationProfile[], filters: IReputationFilters): number { if (profiles.length === 0) return 0; const avgScore = profiles.reduce((sum, p) => sum + p.overallScore, 0) / profiles.length; const diversityBonus = Math.min(profiles.length / 50, 1) * 10; const qualityBonus = avgScore >= 4.0 ? 15 : avgScore >= 3.5 ? 10 : 5; return Math.min(Math.round(avgScore * 20 + diversityBonus + qualityBonus), 100); } private async getRecentRatings(address: Address, days: number): Promise { const allRatings = await this.getAllRatings(address); const cutoffTime = Date.now() - (days * 24 * 60 * 60 * 1000); return allRatings.filter(rating => rating.timestamp >= cutoffTime); } private async getPeerProfiles(address: Address): Promise { // Get similar profiles for comparison const allProfiles = await this.getAllReputationProfiles(50); return allProfiles.filter(profile => profile.address !== address).slice(0, 20); } private calculatePerformanceTrend(profile: IReputationProfile, recentRatings: IRating[]): IReputationAnalytics['performanceTrend'] { const recentAvg = recentRatings.length > 0 ? recentRatings.reduce((sum, r) => sum + r.score, 0) / recentRatings.length : profile.overallScore; const changePercentage = ((recentAvg - profile.overallScore) / profile.overallScore) * 100; return { period: 'month', direction: changePercentage > 5 ? 'improving' : changePercentage < -5 ? 'declining' : 'stable', changePercentage, keyDrivers: ['Recent client feedback', 'Project completion rate', 'Response time improvements'], }; } private calculatePeerComparison(profile: IReputationProfile, peers: IReputationProfile[]): IReputationAnalytics['peerComparison'] { const scores = peers.map(p => p.overallScore).sort((a, b) => a - b); const percentile = (scores.filter(s => s <= profile.overallScore).length / scores.length) * 100; const averagePeerScore = scores.reduce((sum, s) => sum + s, 0) / scores.length; return { percentile, averagePeerScore, strengthAreas: ['technical_skill', 'quality', 'reliability'], improvementAreas: ['communication', 'responsiveness'], }; } private analyzeMarketPosition(profile: IReputationProfile, peers: IReputationProfile[]): IReputationAnalytics['marketPosition'] { const topPerformers = peers.filter(p => p.overallScore >= 4.5).length; const demandLevel = profile.overallScore >= 4.5 ? 'high' : profile.overallScore >= 4.0 ? 'medium' : 'low'; return { demandLevel, priceMultiplier: 1.0 + (profile.overallScore - 3.0) * 0.5, // 1.0x to 2.0x competitorCount: peers.length, marketShare: (profile.totalTransactions / peers.reduce((sum, p) => sum + p.totalTransactions, 0)) * 100, }; } private generateActionableInsights( profile: IReputationProfile, recentRatings: IRating[], peerComparison: any ): IReputationAnalytics['actionableInsights'] { const insights: IReputationAnalytics['actionableInsights'] = []; if (profile.averageResponseTime > 3600000) { // > 1 hour insights.push({ priority: 'high', category: 'responsiveness', recommendation: 'Improve response time to under 1 hour to increase ratings', potentialImpact: '+0.3 to +0.5 points in overall score', estimatedEffort: 'medium', }); } if (profile.completionRate < 90) { insights.push({ priority: 'high', category: 'reliability', recommendation: 'Focus on project completion rate to build trust', potentialImpact: '+0.2 to +0.4 points in reliability score', estimatedEffort: 'high', }); } return insights; } private assessRisks(profile: IReputationProfile, recentRatings: IRating[]): IReputationAnalytics['riskAssessment'] { const recentDisputes = recentRatings.filter(r => r.isDisputed).length; const riskLevel = profile.riskScore > 70 || recentDisputes > 2 ? 'critical' : profile.riskScore > 50 || recentDisputes > 1 ? 'high' : profile.riskScore > 30 ? 'medium' : 'low'; return { currentRiskLevel: riskLevel, riskFactors: profile.riskScore > 50 ? ['High dispute rate', 'Low completion rate'] : ['Minor rating fluctuations'], mitigationSuggestions: ['Improve communication', 'Set clearer expectations', 'Provide regular updates'], insurabilityScore: Math.max(0, 100 - profile.riskScore), }; } private filterByTimeframe(profiles: IReputationProfile[], timeframe: string): IReputationProfile[] { // For mock implementation, return all profiles // In real implementation, would filter based on timeframe return profiles; } private calculateTrend(profile: IReputationProfile): 'up' | 'down' | 'stable' { // Simulate trend calculation return profile.trendingScore > 80 ? 'up' : profile.trendingScore < 60 ? 'down' : 'stable'; } }