Spaces:
Sleeping
Sleeping
| -- repair_system_mismatches.sql | |
| -- Run this in Supabase SQL Editor to resolve the "j_emb" error and restore automatic matching. | |
| -- 1. FIX THE MATCHING FUNCTION (The "j_emb" bug fix) | |
| -- This function is used by triggers and the RPC. | |
| -- We ENSURE it uses 'work_experience' for jobs and 'experience' for profiles. | |
| CREATE OR REPLACE FUNCTION public.match_profile_job(p_id uuid, j_id uuid) | |
| RETURNS json | |
| LANGUAGE plpgsql | |
| AS $function$ | |
| DECLARE | |
| p_rec record; | |
| j_rec record; -- Consistency check: Job record MUST use its real columns | |
| s_sim float := 0; t_sim float := 0; exp_sim float := 0; | |
| edu_sim float := 0; cert_sim float := 0; proj_sim float := 0; | |
| s_score int := 0; t_score int := 0; e_score int := 0; | |
| ed_score int := 0; c_score int := 0; p_score int := 0; | |
| BEGIN | |
| -- Fetch Profile Embeddings | |
| SELECT * INTO p_rec FROM public.profile_embeddings WHERE id = p_id; | |
| IF NOT FOUND THEN RETURN json_build_object('error', 'Profile embeddings not found'); END IF; | |
| -- Fetch Job Embeddings | |
| SELECT * INTO j_rec FROM public.job_embeddings WHERE job_id = j_id; | |
| IF NOT FOUND THEN RETURN json_build_object('error', 'Job embeddings not found'); END IF; | |
| -- Similarity with Cosine Distance (<=>) | |
| IF p_rec.skills IS NOT NULL AND j_rec.skills IS NOT NULL THEN | |
| s_sim := coalesce(nullif(1 - (p_rec.skills <=> j_rec.skills), 'NaN'), 0); | |
| END IF; | |
| IF p_rec.technical_skills IS NOT NULL AND j_rec.technical_skills IS NOT NULL THEN | |
| t_sim := coalesce(nullif(1 - (p_rec.technical_skills <=> j_rec.technical_skills), 'NaN'), 0); | |
| END IF; | |
| -- FIX: Profile column is 'experience', Job column is 'work_experience' | |
| IF p_rec.experience IS NOT NULL AND j_rec.work_experience IS NOT NULL THEN | |
| exp_sim := coalesce(nullif(1 - (p_rec.experience <=> j_rec.work_experience), 'NaN'), 0); | |
| END IF; | |
| IF p_rec.education IS NOT NULL AND j_rec.education IS NOT NULL THEN | |
| edu_sim := coalesce(nullif(1 - (p_rec.education <=> j_rec.education), 'NaN'), 0); | |
| END IF; | |
| IF p_rec.certifications IS NOT NULL THEN | |
| cert_sim := coalesce(nullif(1 - (p_rec.certifications <=> coalesce(j_rec.technical_skills, j_rec.skills)), 'NaN'), 0); | |
| END IF; | |
| IF p_rec.projects IS NOT NULL AND j_rec.technical_skills IS NOT NULL THEN | |
| proj_sim := coalesce(nullif(1 - (p_rec.projects <=> j_rec.technical_skills), 'NaN'), 0); | |
| END IF; | |
| -- Scaling to 0-100 | |
| s_score := (greatest(0, least(1, s_sim)) * 100)::int; | |
| t_score := (greatest(0, least(1, t_sim)) * 100)::int; | |
| e_score := (greatest(0, least(1, exp_sim)) * 100)::int; | |
| ed_score := (greatest(0, least(1, edu_sim)) * 100)::int; | |
| c_score := (greatest(0, least(1, cert_sim)) * 100)::int; | |
| p_score := (greatest(0, least(1, proj_sim)) * 100)::int; | |
| RETURN json_build_object( | |
| 'match_score', ((t_score * 0.35) + (e_score * 0.20) + (p_score * 0.15) + (s_score * 0.10) + (ed_score * 0.10) + (c_score * 0.10))::int, | |
| 'skills_match', s_score, | |
| 'technical_skills_match', t_score, | |
| 'work_experience_match', e_score, | |
| 'education_match', ed_score, | |
| 'certifications_match', c_score, | |
| 'project_match', p_score | |
| ); | |
| END; | |
| $function$; | |
| -- 2. CREATE THE JOB RECOMMENDATIONS RPC (Ranked Jobs) | |
| -- We drop it first because changing the return schema requires it in Postgres. | |
| DROP FUNCTION IF EXISTS public.get_job_recommendations(uuid, int); | |
| CREATE OR REPLACE FUNCTION public.get_job_recommendations(p_user_id uuid, p_limit int DEFAULT 10) | |
| RETURNS json | |
| LANGUAGE plpgsql | |
| AS $function$ | |
| DECLARE | |
| results_json JSON; | |
| BEGIN | |
| SELECT json_agg(r) INTO results_json | |
| FROM ( | |
| SELECT | |
| j.id, | |
| j.title, | |
| j.location, | |
| j.job_type, | |
| j.salary_range, | |
| c.name as company_name, | |
| c.logo_url as company_logo, | |
| (match_profile_job(p_user_id, j.id)->>'match_score')::int as match_score | |
| FROM public.jobs j | |
| JOIN public.companies c ON j.company_id = c.id | |
| WHERE j.status = 'Active' | |
| ORDER BY match_score DESC | |
| LIMIT p_limit | |
| ) r; | |
| RETURN coalesce(results_json, '[]'::json); | |
| END; | |
| $function$; | |