Spaces:
Running
Running
Download api/v2/_services/publicProfileSystem.ts from Sarvesh213/getcert-backend: direct link, hf CLI and curl.
- Browser
- Download file 9.78 kB
-
https://huggingface.co/spaces/Sarvesh213/getcert-backend/resolve/main/api/v2/_services/publicProfileSystem.ts
- Command line
-
hf download hf://spaces/Sarvesh213/getcert-backend/api/v2/_services/publicProfileSystem.ts
-
curl -L -o publicProfileSystem.ts https://huggingface.co/spaces/Sarvesh213/getcert-backend/resolve/main/api/v2/_services/publicProfileSystem.ts
9.78 kB
| import { getSupabaseAdmin } from '../_shared/supabaseAdmin.js'; | |
| import type { | |
| AggregatedSkillScore, | |
| CertificationTrack, | |
| ProjectEvidence, | |
| PublicProfile, | |
| ValidationSummary, | |
| } from '../_types.js'; | |
| type JsonRecord = Record<string, unknown>; | |
| type UserRow = { | |
| id: string; | |
| username: string; | |
| referral_code: string | null; | |
| }; | |
| type CertificateRow = { | |
| id: string; | |
| topic: string; | |
| project_title: string | null; | |
| issued_at: string; | |
| metadata: JsonRecord | null; | |
| }; | |
| const CANONICAL_PUBLIC_DOMAIN = 'https://getcert.eu.cc'; | |
| function appBaseUrl(): string { | |
| const configured = (process.env.CERTIFICATE_VERIFY_BASE_URL || process.env.APP_ORIGIN || '').trim(); | |
| if ( | |
| !configured || | |
| configured.includes('hf.space') || | |
| configured.includes('huggingface.co') || | |
| configured.includes('vercel.app') || | |
| configured.includes('localhost') | |
| ) { | |
| return CANONICAL_PUBLIC_DOMAIN; | |
| } | |
| return configured.replace(/\/$/, ''); | |
| } | |
| function toStringValue(value: unknown): string | null { | |
| if (typeof value !== 'string') { | |
| return null; | |
| } | |
| const trimmed = value.trim(); | |
| return trimmed.length > 0 ? trimmed : null; | |
| } | |
| function toNumberValue(value: unknown): number | null { | |
| if (typeof value === 'number' && Number.isFinite(value)) { | |
| return value; | |
| } | |
| if (typeof value === 'string' && value.trim()) { | |
| const parsed = Number(value); | |
| if (Number.isFinite(parsed)) { | |
| return parsed; | |
| } | |
| } | |
| return null; | |
| } | |
| function getObject(value: unknown): JsonRecord | null { | |
| if (!value || typeof value !== 'object' || Array.isArray(value)) { | |
| return null; | |
| } | |
| return value as JsonRecord; | |
| } | |
| function parseValidationSummary(metadata: JsonRecord): ValidationSummary | null { | |
| const nested = getObject(metadata.validation_summary); | |
| if (!nested) { | |
| return null; | |
| } | |
| const suspiciousSignals = Array.isArray(nested.suspicious_signals) | |
| ? nested.suspicious_signals.filter((item): item is string => typeof item === 'string') | |
| : []; | |
| return { | |
| overallPassed: Boolean(nested.overall_passed), | |
| commitPassed: Boolean(nested.commit_passed), | |
| readmePassed: Boolean(nested.readme_passed), | |
| proofPassed: Boolean(nested.proof_passed), | |
| commitCount: Math.round(toNumberValue(nested.commit_count) ?? 0), | |
| fileCount: Math.round(toNumberValue(nested.file_count) ?? 0), | |
| meaningfulFileCount: Math.round(toNumberValue(nested.meaningful_file_count) ?? 0), | |
| readmeRichness: Math.round(toNumberValue(nested.readme_richness) ?? 0), | |
| suspiciousSignals, | |
| }; | |
| } | |
| function getDifficultyWeight(projectType: string | null): number { | |
| if (projectType === 'data') { | |
| return 1.3; | |
| } | |
| if (projectType === 'python') { | |
| return 1.15; | |
| } | |
| if (projectType === 'web' || projectType === 'fullstack') { | |
| return 1.2; | |
| } | |
| return 1; | |
| } | |
| function getDifficultyLevel(weight: number): 'beginner' | 'intermediate' | 'advanced' { | |
| if (weight >= 1.26) { | |
| return 'advanced'; | |
| } | |
| if (weight >= 1.16) { | |
| return 'intermediate'; | |
| } | |
| return 'beginner'; | |
| } | |
| function roundValue(value: number): number { | |
| return Math.round(value * 100) / 100; | |
| } | |
| function buildPassConfidence(finalScore: number, summary: ValidationSummary | null): number { | |
| if (!summary) { | |
| return Math.max(0, Math.min(100, Math.round(finalScore * 0.8))); | |
| } | |
| let confidence = finalScore * 0.6; | |
| confidence += summary.overallPassed ? 22 : 10; | |
| confidence += Math.min(10, summary.commitCount * 0.6); | |
| confidence += summary.readmePassed ? 8 : 2; | |
| return Math.max(0, Math.min(100, Math.round(confidence))); | |
| } | |
| export async function getPublicProfile(userId: string): Promise<PublicProfile> { | |
| const supabase = getSupabaseAdmin(); | |
| const base = appBaseUrl(); | |
| const { data: user, error: userError } = await supabase | |
| .from('users') | |
| .select('id, username, referral_code') | |
| .eq('id', userId) | |
| .single(); | |
| if (userError || !user) { | |
| throw new Error('User not found'); | |
| } | |
| const { data: certificates, error: certError } = await supabase | |
| .from('certificates') | |
| .select('id, topic, project_title, issued_at, metadata') | |
| .eq('user_id', userId) | |
| .order('issued_at', { ascending: false }); | |
| const { count: referredUsersCount } = await supabase | |
| .from('users') | |
| .select('id', { count: 'exact', head: true }) | |
| .eq('referred_by', userId); | |
| if (certError) { | |
| throw new Error(`Failed to fetch certificates: ${certError.message}`); | |
| } | |
| const rows = (certificates || []) as CertificateRow[]; | |
| const allProjects: ProjectEvidence[] = rows.map((item) => { | |
| const metadata = item.metadata || {}; | |
| const validationSummary = parseValidationSummary(metadata); | |
| const projectType = toStringValue(metadata.project_type); | |
| const difficultyWeight = getDifficultyWeight(projectType); | |
| const finalScore = Math.round(toNumberValue(metadata.final_score) ?? 0); | |
| const commitCount = Math.round( | |
| toNumberValue(metadata.commit_count) ?? | |
| toNumberValue(validationSummary?.commitCount) ?? | |
| 0 | |
| ); | |
| const fileCount = Math.round(toNumberValue(validationSummary?.fileCount) ?? 0); | |
| const readmeScore = Math.round(toNumberValue(validationSummary?.readmeRichness) ?? 0); | |
| const track = (toStringValue(metadata.certification_track) || 'verifiedcert') as CertificationTrack; | |
| return { | |
| certificateId: toStringValue(metadata.certificate_id), | |
| certificateDbId: item.id, | |
| skill: item.topic, | |
| projectTitle: item.project_title, | |
| projectType, | |
| difficultyLevel: getDifficultyLevel(difficultyWeight), | |
| difficultyWeight, | |
| githubRepoUrl: toStringValue(metadata.github_repo_url) || toStringValue(metadata.github_url), | |
| liveDemoUrl: toStringValue(metadata.live_demo_url) || toStringValue(metadata.proof_url), | |
| finalScore, | |
| commitCount, | |
| fileCount, | |
| validationSummary, | |
| passConfidence: buildPassConfidence(finalScore, validationSummary), | |
| issuedAt: item.issued_at, | |
| track, | |
| trustSignals: { | |
| commitCount, | |
| validationPassed: validationSummary ? validationSummary.overallPassed : finalScore >= 60, | |
| readmeScore, | |
| projectType, | |
| }, | |
| }; | |
| }); | |
| const projects = allProjects.filter((p) => p.track === 'verifiedcert'); | |
| const skillAccumulator = new Map<string, { | |
| totalScore: number; | |
| weightedScore: number; | |
| totalWeight: number; | |
| count: number; | |
| }>(); | |
| for (const project of projects) { | |
| const current = skillAccumulator.get(project.skill) || { | |
| totalScore: 0, | |
| weightedScore: 0, | |
| totalWeight: 0, | |
| count: 0, | |
| }; | |
| current.totalScore += project.finalScore; | |
| current.weightedScore += project.finalScore * project.difficultyWeight; | |
| current.totalWeight += project.difficultyWeight; | |
| current.count += 1; | |
| skillAccumulator.set(project.skill, current); | |
| } | |
| const aggregatedSkills: AggregatedSkillScore[] = Array.from(skillAccumulator.entries()) | |
| .map(([skill, aggregate]) => ({ | |
| skill, | |
| averageScore: roundValue(aggregate.totalScore / Math.max(1, aggregate.count)), | |
| weightedScore: roundValue(aggregate.weightedScore / Math.max(1, aggregate.totalWeight)), | |
| projectCount: aggregate.count, | |
| totalWeight: roundValue(aggregate.totalWeight), | |
| })) | |
| .sort((left, right) => right.weightedScore - left.weightedScore); | |
| const totalCertificates = rows.length; | |
| const verifiedProjects = projects; | |
| const verifiedCount = verifiedProjects.length; | |
| const totalCommitCount = verifiedProjects.reduce((sum, project) => sum + project.commitCount, 0); | |
| const averageFinalScore = verifiedCount | |
| ? roundValue(verifiedProjects.reduce((sum, project) => sum + project.finalScore, 0) / verifiedCount) | |
| : 0; | |
| const averageReadmeScore = verifiedCount | |
| ? roundValue(verifiedProjects.reduce((sum, project) => sum + project.trustSignals.readmeScore, 0) / verifiedCount) | |
| : 0; | |
| const validationPassRate = verifiedCount | |
| ? roundValue( | |
| (verifiedProjects.filter((project) => project.trustSignals.validationPassed).length / verifiedCount) * 100 | |
| ) | |
| : 0; | |
| const certificatesPayload = rows.map((item) => { | |
| const metadata = item.metadata || {}; | |
| const projectType = toStringValue(metadata.project_type); | |
| const track = (toStringValue(metadata.certification_track) || 'verifiedcert') as CertificationTrack; | |
| return { | |
| id: item.id, | |
| skill: item.topic, | |
| projectTitle: item.project_title, | |
| issuedAt: item.issued_at, | |
| githubUrl: toStringValue(metadata.github_repo_url) || toStringValue(metadata.github_url), | |
| proofUrl: toStringValue(metadata.live_demo_url) || toStringValue(metadata.proof_url), | |
| certificateId: toStringValue(metadata.certificate_id), | |
| finalScore: Math.round(toNumberValue(metadata.final_score) ?? 0), | |
| difficultyLevel: getDifficultyLevel(getDifficultyWeight(projectType)), | |
| track, | |
| }; | |
| }); | |
| const quickCertCount = allProjects.filter((p) => p.track === 'quickcert').length; | |
| const verifiedCertCount = verifiedCount; | |
| return { | |
| userId, | |
| username: (user as UserRow).username, | |
| referralCode: (user as UserRow).referral_code, | |
| referredUsersCount: referredUsersCount || 0, | |
| certificates: certificatesPayload, | |
| aggregatedSkills, | |
| projects, | |
| trustMetrics: { | |
| totalCertificates, | |
| averageFinalScore, | |
| totalCommitCount, | |
| validationPassRate, | |
| averageReadmeScore, | |
| topSkill: aggregatedSkills[0]?.skill || null, | |
| quickCertCount, | |
| verifiedCertCount, | |
| }, | |
| shareLinks: { | |
| profile: `${base}/user/${encodeURIComponent(userId)}`, | |
| recruiter: `${base}/recruiter/${encodeURIComponent(userId)}`, | |
| referral: (user as UserRow).referral_code | |
| ? `${base}/?ref=${encodeURIComponent((user as UserRow).referral_code as string)}` | |
| : null, | |
| }, | |
| }; | |
| } | |