mirror of
https://github.com/SamyRai/turash.git
synced 2025-12-26 23:01:33 +00:00
415 lines
13 KiB
Go
415 lines
13 KiB
Go
package repository
|
|
|
|
import (
|
|
"bugulma/backend/internal/domain"
|
|
"context"
|
|
"math"
|
|
"time"
|
|
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
// TrustMetricsRepository implements domain.TrustMetricsRepository with GORM
|
|
type TrustMetricsRepository struct {
|
|
*BaseRepository[domain.TrustMetrics]
|
|
}
|
|
|
|
// NewTrustMetricsRepository creates a new GORM-based trust metrics repository
|
|
func NewTrustMetricsRepository(db *gorm.DB) domain.TrustMetricsRepository {
|
|
return &TrustMetricsRepository{
|
|
BaseRepository: NewBaseRepository[domain.TrustMetrics](db),
|
|
}
|
|
}
|
|
|
|
// GetByOrganization retrieves all trust metrics for an organization
|
|
func (r *TrustMetricsRepository) GetByOrganization(ctx context.Context, orgID string) ([]*domain.TrustMetrics, error) {
|
|
return r.FindWhereWithContext(ctx, "organization_id = ?", orgID)
|
|
}
|
|
|
|
// GetByType retrieves trust metrics of a specific type for an organization
|
|
func (r *TrustMetricsRepository) GetByType(ctx context.Context, orgID, metricType string) ([]*domain.TrustMetrics, error) {
|
|
return r.FindWhereWithContext(ctx, "organization_id = ? AND metric_type = ?", orgID, metricType)
|
|
}
|
|
|
|
// GetLatestProfile retrieves the latest comprehensive quality profile for an organization
|
|
func (r *TrustMetricsRepository) GetLatestProfile(ctx context.Context, orgID string) (*domain.DataQualityProfile, error) {
|
|
// Get all metrics for the organization
|
|
metrics, err := r.GetByOrganization(ctx, orgID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Convert []*domain.TrustMetrics to []domain.TrustMetrics
|
|
metricsSlice := make([]domain.TrustMetrics, len(metrics))
|
|
for i, metric := range metrics {
|
|
metricsSlice[i] = *metric
|
|
}
|
|
|
|
// Calculate profile scores
|
|
profile := &domain.DataQualityProfile{
|
|
OrganizationID: orgID,
|
|
LastAssessed: time.Now(),
|
|
AssessmentPeriod: 30 * 24 * time.Hour, // 30 days
|
|
Metrics: metricsSlice,
|
|
}
|
|
|
|
// Calculate completeness score
|
|
completeness := r.calculateCompletenessScore(metrics)
|
|
profile.Completeness = completeness
|
|
|
|
// Calculate accuracy score
|
|
accuracy := r.calculateAccuracyScore(metrics)
|
|
profile.Accuracy = accuracy
|
|
|
|
// Calculate overall score (weighted average)
|
|
profile.OverallScore = (completeness*0.4 + accuracy*0.4 + profile.Timeliness*0.1 + profile.Consistency*0.1)
|
|
|
|
// Generate recommendations
|
|
profile.Recommendations = r.generateRecommendations(profile)
|
|
|
|
return profile, nil
|
|
}
|
|
|
|
// calculateCompletenessScore calculates how complete the organization's data is
|
|
func (r *TrustMetricsRepository) calculateCompletenessScore(metrics []*domain.TrustMetrics) float64 {
|
|
if len(metrics) == 0 {
|
|
return 0.0
|
|
}
|
|
|
|
// Look for completeness metrics
|
|
for _, metric := range metrics {
|
|
if metric.MetricName == "data_completeness" && metric.MetricType == "organization" {
|
|
return metric.Value
|
|
}
|
|
}
|
|
|
|
// Default calculation based on number of metrics
|
|
score := float64(len(metrics)) / 10.0 // Assume 10 key metrics
|
|
if score > 1.0 {
|
|
score = 1.0
|
|
}
|
|
return score
|
|
}
|
|
|
|
// calculateAccuracyScore calculates data accuracy based on metrics
|
|
func (r *TrustMetricsRepository) calculateAccuracyScore(metrics []*domain.TrustMetrics) float64 {
|
|
accuracyMetrics := 0
|
|
totalScore := 0.0
|
|
|
|
for _, metric := range metrics {
|
|
if metric.MetricName == "data_accuracy" || metric.MetricName == "verification_score" {
|
|
accuracyMetrics++
|
|
totalScore += metric.Value
|
|
}
|
|
}
|
|
|
|
if accuracyMetrics == 0 {
|
|
return 0.5 // Default neutral score
|
|
}
|
|
|
|
return totalScore / float64(accuracyMetrics)
|
|
}
|
|
|
|
// generateRecommendations generates improvement recommendations
|
|
func (r *TrustMetricsRepository) generateRecommendations(profile *domain.DataQualityProfile) []string {
|
|
var recommendations []string
|
|
|
|
if profile.Completeness < 0.7 {
|
|
recommendations = append(recommendations, "Complete missing profile information to improve trust scores")
|
|
}
|
|
|
|
if profile.Accuracy < 0.8 {
|
|
recommendations = append(recommendations, "Verify and update outdated information")
|
|
}
|
|
|
|
if profile.OverallScore < 0.6 {
|
|
recommendations = append(recommendations, "Consider third-party verification to build credibility")
|
|
}
|
|
|
|
if len(recommendations) == 0 {
|
|
recommendations = append(recommendations, "Profile quality is good - continue maintaining data accuracy")
|
|
}
|
|
|
|
return recommendations
|
|
}
|
|
|
|
// VerifiedDataRepository implements operations for verified data
|
|
type VerifiedDataRepository struct {
|
|
*BaseRepository[domain.VerifiedData]
|
|
}
|
|
|
|
// NewVerifiedDataRepository creates a new verified data repository
|
|
func NewVerifiedDataRepository(db *gorm.DB) *VerifiedDataRepository {
|
|
return &VerifiedDataRepository{
|
|
BaseRepository: NewBaseRepository[domain.VerifiedData](db),
|
|
}
|
|
}
|
|
|
|
// GetByOrganization retrieves verified data for an organization
|
|
func (r *VerifiedDataRepository) GetByOrganization(ctx context.Context, orgID string) ([]*domain.VerifiedData, error) {
|
|
return r.FindWhereWithContext(ctx, "organization_id = ?", orgID)
|
|
}
|
|
|
|
// GetByStatus retrieves verified data by status
|
|
func (r *VerifiedDataRepository) GetByStatus(ctx context.Context, status domain.VerificationStatus) ([]*domain.VerifiedData, error) {
|
|
return r.FindWhereWithContext(ctx, "status = ?", status)
|
|
}
|
|
|
|
// HistoricalSuccessRepository implements operations for historical success metrics
|
|
type HistoricalSuccessRepository struct {
|
|
*BaseRepository[domain.HistoricalSuccess]
|
|
}
|
|
|
|
// NewHistoricalSuccessRepository creates a new historical success repository
|
|
func NewHistoricalSuccessRepository(db *gorm.DB) *HistoricalSuccessRepository {
|
|
return &HistoricalSuccessRepository{
|
|
BaseRepository: NewBaseRepository[domain.HistoricalSuccess](db),
|
|
}
|
|
}
|
|
|
|
// GetByOrganization retrieves historical success metrics for an organization
|
|
func (r *HistoricalSuccessRepository) GetByOrganization(ctx context.Context, orgID string) ([]*domain.HistoricalSuccess, error) {
|
|
return r.FindWhereWithContext(ctx, "organization_id = ?", orgID)
|
|
}
|
|
|
|
// GetByMetricType retrieves metrics of a specific type
|
|
func (r *HistoricalSuccessRepository) GetByMetricType(ctx context.Context, orgID, metricType string) ([]*domain.HistoricalSuccess, error) {
|
|
return r.FindWhereWithContext(ctx, "organization_id = ? AND metric_type = ?", orgID, metricType)
|
|
}
|
|
|
|
// CalculateTrustScore calculates overall trust score for an organization
|
|
func (r *HistoricalSuccessRepository) CalculateTrustScore(ctx context.Context, orgID string) (*domain.TrustScore, error) {
|
|
// Get trust metrics
|
|
trustRepo := NewTrustMetricsRepository(r.DB())
|
|
metrics, err := trustRepo.GetByOrganization(ctx, orgID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Get historical success metrics
|
|
historical, err := r.GetByOrganization(ctx, orgID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Calculate component scores
|
|
trustScore := &domain.TrustScore{
|
|
OrganizationID: orgID,
|
|
LastCalculated: time.Now(),
|
|
ScoreBreakdown: make(map[string]float64),
|
|
}
|
|
|
|
// Data quality score
|
|
dataQualityScore := calculateDataQualityScore(metrics)
|
|
trustScore.DataQualityScore = dataQualityScore
|
|
trustScore.ScoreBreakdown["data_quality"] = dataQualityScore
|
|
|
|
// Verification score
|
|
verificationScore := calculateVerificationScore(metrics)
|
|
trustScore.VerificationScore = verificationScore
|
|
trustScore.ScoreBreakdown["verification"] = verificationScore
|
|
|
|
// Historical score
|
|
historicalScore := calculateHistoricalScore(historical)
|
|
trustScore.HistoricalScore = historicalScore
|
|
trustScore.ScoreBreakdown["historical"] = historicalScore
|
|
|
|
// Peer review score - calculated from historical success metrics
|
|
// Organizations with successful matches and high completion rates have better peer review scores
|
|
peerReviewScore := calculatePeerReviewScore(historical, metrics)
|
|
trustScore.PeerReviewScore = peerReviewScore
|
|
trustScore.ScoreBreakdown["peer_review"] = peerReviewScore
|
|
|
|
// Overall score (weighted average)
|
|
trustScore.OverallScore = (dataQualityScore*0.3 + verificationScore*0.3 + historicalScore*0.3 + trustScore.PeerReviewScore*0.1)
|
|
|
|
// Confidence level based on data availability
|
|
trustScore.ConfidenceLevel = calculateConfidenceLevel(metrics, historical)
|
|
|
|
// Risk factors and recommendations
|
|
trustScore.RiskFactors = identifyRiskFactors(trustScore)
|
|
trustScore.Recommendations = generateTrustRecommendations(trustScore)
|
|
|
|
return trustScore, nil
|
|
}
|
|
|
|
// Helper functions for trust score calculation
|
|
func calculateDataQualityScore(metrics []*domain.TrustMetrics) float64 {
|
|
if len(metrics) == 0 {
|
|
return 0.3 // Low default
|
|
}
|
|
|
|
totalScore := 0.0
|
|
count := 0
|
|
|
|
for _, metric := range metrics {
|
|
if metric.MetricType == "organization" || metric.MetricType == "resource_flow" {
|
|
totalScore += metric.Value
|
|
count++
|
|
}
|
|
}
|
|
|
|
if count == 0 {
|
|
return 0.3
|
|
}
|
|
|
|
return totalScore / float64(count)
|
|
}
|
|
|
|
func calculateVerificationScore(metrics []*domain.TrustMetrics) float64 {
|
|
for _, metric := range metrics {
|
|
if metric.MetricName == "verification_score" {
|
|
return metric.Value
|
|
}
|
|
}
|
|
return 0.0 // No verification data
|
|
}
|
|
|
|
func calculateHistoricalScore(historical []*domain.HistoricalSuccess) float64 {
|
|
if len(historical) == 0 {
|
|
return 0.4 // Neutral default for new organizations
|
|
}
|
|
|
|
totalScore := 0.0
|
|
count := 0
|
|
|
|
for _, h := range historical {
|
|
if h.MetricType == "completion_rate" {
|
|
totalScore += h.Value
|
|
count++
|
|
}
|
|
}
|
|
|
|
if count == 0 {
|
|
return 0.4
|
|
}
|
|
|
|
return totalScore / float64(count)
|
|
}
|
|
|
|
func calculateConfidenceLevel(metrics []*domain.TrustMetrics, historical []*domain.HistoricalSuccess) float64 {
|
|
dataPoints := len(metrics) + len(historical)
|
|
|
|
// Confidence increases with more data points
|
|
if dataPoints < 5 {
|
|
return 0.3
|
|
} else if dataPoints < 15 {
|
|
return 0.6
|
|
} else {
|
|
return 0.9
|
|
}
|
|
}
|
|
|
|
func identifyRiskFactors(trustScore *domain.TrustScore) []domain.RiskFactor {
|
|
var risks []domain.RiskFactor
|
|
|
|
if trustScore.DataQualityScore < 0.5 {
|
|
risks = append(risks, domain.RiskFactor{
|
|
Type: "data_quality",
|
|
Description: "Low data quality score indicates incomplete or inaccurate information",
|
|
Severity: 0.7,
|
|
Impact: "high",
|
|
Mitigation: "Complete profile information and verify data accuracy",
|
|
})
|
|
}
|
|
|
|
if trustScore.VerificationScore < 0.3 {
|
|
risks = append(risks, domain.RiskFactor{
|
|
Type: "verification",
|
|
Description: "Limited verification reduces trustworthiness",
|
|
Severity: 0.6,
|
|
Impact: "medium",
|
|
Mitigation: "Pursue third-party verification or certification",
|
|
})
|
|
}
|
|
|
|
if trustScore.HistoricalScore < 0.4 {
|
|
risks = append(risks, domain.RiskFactor{
|
|
Type: "historical",
|
|
Description: "Limited historical performance data",
|
|
Severity: 0.4,
|
|
Impact: "low",
|
|
Mitigation: "Build track record through successful partnerships",
|
|
})
|
|
}
|
|
|
|
return risks
|
|
}
|
|
|
|
func generateTrustRecommendations(trustScore *domain.TrustScore) []string {
|
|
var recommendations []string
|
|
|
|
if trustScore.OverallScore < 0.5 {
|
|
recommendations = append(recommendations, "Focus on improving data quality and verification to build trust")
|
|
recommendations = append(recommendations, "Consider obtaining industry certifications or third-party verification")
|
|
}
|
|
|
|
if trustScore.DataQualityScore < 0.7 {
|
|
recommendations = append(recommendations, "Complete all profile information and keep data current")
|
|
}
|
|
|
|
if trustScore.VerificationScore < 0.5 {
|
|
recommendations = append(recommendations, "Pursue verification for key data elements")
|
|
}
|
|
|
|
if trustScore.ConfidenceLevel < 0.6 {
|
|
recommendations = append(recommendations, "Build more comprehensive data profile to increase confidence")
|
|
}
|
|
|
|
if len(recommendations) == 0 {
|
|
recommendations = append(recommendations, "Trust profile is strong - maintain current standards")
|
|
}
|
|
|
|
return recommendations
|
|
}
|
|
|
|
// calculatePeerReviewScore calculates peer review score based on historical performance
|
|
// This uses historical success metrics to infer peer satisfaction
|
|
func calculatePeerReviewScore(historical []*domain.HistoricalSuccess, metrics []*domain.TrustMetrics) float64 {
|
|
if len(historical) == 0 {
|
|
return 0.4 // Neutral default for new organizations
|
|
}
|
|
|
|
// Calculate average completion rate (indicates successful partnerships)
|
|
totalCompletion := 0.0
|
|
completionCount := 0
|
|
|
|
// Calculate average satisfaction if available
|
|
totalSatisfaction := 0.0
|
|
satisfactionCount := 0
|
|
|
|
for _, h := range historical {
|
|
if h.MetricType == "completion_rate" {
|
|
totalCompletion += h.Value
|
|
completionCount++
|
|
} else if h.MetricType == "satisfaction" {
|
|
totalSatisfaction += h.Value
|
|
satisfactionCount++
|
|
}
|
|
}
|
|
|
|
// Base score from completion rate (0.6 weight)
|
|
completionScore := 0.4
|
|
if completionCount > 0 {
|
|
avgCompletion := totalCompletion / float64(completionCount)
|
|
completionScore = avgCompletion * 0.6
|
|
}
|
|
|
|
// Satisfaction score (0.4 weight)
|
|
satisfactionScore := 0.3
|
|
if satisfactionCount > 0 {
|
|
avgSatisfaction := totalSatisfaction / float64(satisfactionCount)
|
|
satisfactionScore = avgSatisfaction * 0.4
|
|
}
|
|
|
|
// Combine scores
|
|
peerScore := completionScore + satisfactionScore
|
|
|
|
// Boost score if organization has many successful partnerships
|
|
if len(historical) > 10 {
|
|
peerScore = math.Min(1.0, peerScore*1.1)
|
|
}
|
|
|
|
return math.Max(0.0, math.Min(1.0, peerScore))
|
|
}
|