All files / lib/trust calculate.ts

31.37% Statements 16/51
100% Branches 6/6
50% Functions 1/2
31.37% Lines 16/51

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91                                                1x 8x 8x 8x 8x 8x 8x 8x 8x 8x   8x 8x 5x 4x   8x 8x                                                                                                  
/**
 * Shared Trust Score Calculation
 *
 * Extracted from app/api/trust/score/route.ts for reuse
 * in create-order discount logic and other server-side contexts.
 */
 
import { SupabaseClient } from '@supabase/supabase-js';
 
export interface TrustComponents {
  emailVerified: number;
  phoneVerified: number;
  governmentId: number;
  workSamples: number;
  testimonials: number;
  profileComplete: number;
}
 
export interface TrustScoreResult {
  score: number;
  components: TrustComponents;
  confidence: 'low' | 'medium' | 'high' | 'definitive';
}
 
export function calculateSimpleTrustScore(components: TrustComponents): TrustScoreResult {
  const score = Math.min(
    100,
    components.emailVerified +
      components.phoneVerified +
      components.governmentId +
      components.workSamples +
      components.testimonials +
      components.profileComplete
  );
 
  let confidence: 'low' | 'medium' | 'high' | 'definitive' = 'low';
  if (score >= 80) confidence = 'definitive';
  else if (score >= 60) confidence = 'high';
  else if (score >= 30) confidence = 'medium';
 
  return { score, components, confidence };
}
 
/**
 * Fetch and calculate trust score for a user.
 * Accepts a Supabase client (admin or user-scoped) for server-side use.
 */
export async function getUserTrustScore(
  supabase: SupabaseClient,
  userId: string,
  profileId: string,
  profile: {
    display_name: string | null;
    bio: string | null;
    avatar_url: string | null;
    whatsapp: string | null;
  }
): Promise<TrustScoreResult> {
  const [badgesResult, samplesResult, testimonialsResult] = await Promise.all([
    supabase.rpc('get_user_badges', { user_uuid: userId }),
    supabase
      .from('samples')
      .select('id', { count: 'exact', head: true })
      .eq('profile_id', profileId),
    supabase
      .from('testimonials')
      .select('id', { count: 'exact', head: true })
      .eq('profile_id', profileId)
      .eq('status', 'published'),
  ]);
 
  const badgeCodes = new Set(
    (badgesResult.data || []).map((b: { badge_code: string }) => b.badge_code)
  );
 
  const components: TrustComponents = {
    emailVerified: badgeCodes.has('email_verified') || badgeCodes.has('email') ? 10 : 0,
    phoneVerified: badgeCodes.has('phone_verified') || badgeCodes.has('phone') ? 10 : 0,
    governmentId: (badgeCodes.has('aadhaar') ? 15 : 0) + (badgeCodes.has('pan') ? 10 : 0),
    workSamples: Math.min(20, (samplesResult.count || 0) * 4),
    testimonials: Math.min(15, (testimonialsResult.count || 0) * 5),
    profileComplete:
      (profile.display_name ? 5 : 0) +
      (profile.bio ? 5 : 0) +
      (profile.avatar_url ? 5 : 0) +
      (profile.whatsapp ? 5 : 0),
  };
 
  return calculateSimpleTrustScore(components);
}