From 11805f12e6365e5be7439b06cedc6727f8bb74ba Mon Sep 17 00:00:00 2001 From: Michael Wu Date: Wed, 4 Mar 2026 17:47:35 +0800 Subject: [PATCH] Fix candidate search ordering --- .../shared/src/five08/candidate_search.py | 19 +++- .../integration/test_candidate_search_e2e.py | 98 +++++++++++++++---- 2 files changed, 97 insertions(+), 20 deletions(-) diff --git a/packages/shared/src/five08/candidate_search.py b/packages/shared/src/five08/candidate_search.py index aea135db..bcfaa82b 100644 --- a/packages/shared/src/five08/candidate_search.py +++ b/packages/shared/src/five08/candidate_search.py @@ -100,7 +100,20 @@ def search_candidates( WITH req AS (SELECT %s::text[] AS skills), pref AS (SELECT %s::text[] AS skills), - rtypes AS (SELECT %s::text[] AS types) + rtypes AS (SELECT %s::text[] AS types), + dm_agg AS ( + SELECT + dm_raw.discord_user_id, + MAX(dm_raw.discord_username) AS discord_username, + MAX(dm_raw.display_name) AS display_name, + COALESCE( + jsonb_agg(DISTINCT role) FILTER (WHERE role IS NOT NULL), + '[]'::jsonb + ) AS roles + FROM discord_members dm_raw + LEFT JOIN LATERAL jsonb_array_elements_text(dm_raw.roles) AS role ON true + GROUP BY dm_raw.discord_user_id + ) SELECT p.crm_contact_id AS crm_contact_id, COALESCE(p.name, dm.display_name, dm.discord_username) AS name, @@ -159,7 +172,7 @@ def search_candidates( ELSE 0 END AS discord_role_matched FROM people p - FULL OUTER JOIN discord_members dm ON dm.discord_user_id = p.discord_user_id + FULL OUTER JOIN dm_agg dm ON dm.discord_user_id = p.discord_user_id CROSS JOIN rtypes WHERE (p.sync_status = 'active' OR p.sync_status IS NULL) -- Must match at least one required skill OR one discord role type @@ -179,7 +192,7 @@ def search_candidates( OR LOWER(COALESCE(p.address_country, '')) = ANY(%s::text[]) ) ORDER BY - p.is_member DESC, + is_member DESC, timezone_matched DESC, required_matched DESC, discord_role_matched DESC, diff --git a/tests/integration/test_candidate_search_e2e.py b/tests/integration/test_candidate_search_e2e.py index 21470ce5..647faa60 100644 --- a/tests/integration/test_candidate_search_e2e.py +++ b/tests/integration/test_candidate_search_e2e.py @@ -25,37 +25,97 @@ _CREATE_PEOPLE_TABLE = """ CREATE TABLE IF NOT EXISTS people ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), - crm_contact_id TEXT NOT NULL UNIQUE, + crm_contact_id TEXT NOT NULL, name TEXT, email TEXT, email_508 TEXT, discord_user_id TEXT, discord_username TEXT, - linkedin TEXT, - latest_resume_id TEXT, - latest_resume_name TEXT, - is_member BOOLEAN NOT NULL DEFAULT false, + discord_roles JSONB NOT NULL DEFAULT '[]'::jsonb, + github_username TEXT, sync_status TEXT NOT NULL DEFAULT 'active', - seniority TEXT, + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + contact_type TEXT, + is_member BOOLEAN NOT NULL DEFAULT false, address_country TEXT, + address_city TEXT, timezone TEXT, - skills TEXT[] NOT NULL DEFAULT '{}', - skill_attrs JSONB NOT NULL DEFAULT '{}', - discord_roles JSONB NOT NULL DEFAULT '[]' + seniority TEXT, + linkedin TEXT, + skills TEXT[] NOT NULL DEFAULT '{}'::text[], + skill_attrs JSONB NOT NULL DEFAULT '{}'::jsonb, + latest_resume_id TEXT, + latest_resume_name TEXT, + CONSTRAINT ck_people_sync_status CHECK ( + sync_status IN ('active', 'missing_in_crm', 'conflict') + ), + CONSTRAINT uq_people_crm_contact_id UNIQUE (crm_contact_id), + CONSTRAINT uq_people_discord_user_id UNIQUE (discord_user_id) ) """ +_CREATE_PEOPLE_INDEXES = [ + "CREATE INDEX IF NOT EXISTS idx_people_email ON people (email)", + "CREATE INDEX IF NOT EXISTS idx_people_email_508 ON people (email_508)", + "CREATE INDEX IF NOT EXISTS idx_people_discord_user_id ON people (discord_user_id)", + "CREATE INDEX IF NOT EXISTS idx_people_skills ON people USING gin (skills)", + "CREATE INDEX IF NOT EXISTS idx_people_is_member ON people (is_member)", + "CREATE INDEX IF NOT EXISTS idx_people_seniority ON people (seniority)", + "CREATE INDEX IF NOT EXISTS idx_people_address_country ON people (address_country)", +] + +_CREATE_PEOPLE_UPDATED_AT_FUNCTION = """ + CREATE OR REPLACE FUNCTION people_set_updated_at_fn() + RETURNS TRIGGER AS $$ + BEGIN + NEW.updated_at = NOW(); + RETURN NEW; + END; + $$ LANGUAGE plpgsql; +""" + +_CREATE_PEOPLE_UPDATED_AT_TRIGGER = """ + CREATE TRIGGER people_set_updated_at_tr + BEFORE UPDATE ON people + FOR EACH ROW + EXECUTE FUNCTION people_set_updated_at_fn(); +""" + _CREATE_DISCORD_MEMBERS_TABLE = """ CREATE TABLE IF NOT EXISTS discord_members ( guild_id TEXT NOT NULL, discord_user_id TEXT NOT NULL, discord_username TEXT, display_name TEXT, - roles JSONB NOT NULL DEFAULT '[]', + roles JSONB NOT NULL DEFAULT '[]'::jsonb, + created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), + updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(), PRIMARY KEY (guild_id, discord_user_id) ) """ +_CREATE_DISCORD_MEMBERS_INDEXES = [ + "CREATE INDEX IF NOT EXISTS idx_discord_members_guild_id ON discord_members (guild_id)" +] + +_CREATE_DISCORD_MEMBERS_UPDATED_AT_FUNCTION = """ + CREATE OR REPLACE FUNCTION discord_members_set_updated_at_fn() + RETURNS TRIGGER AS $$ + BEGIN + NEW.updated_at = NOW(); + RETURN NEW; + END; + $$ LANGUAGE plpgsql; +""" + +_CREATE_DISCORD_MEMBERS_UPDATED_AT_TRIGGER = """ + CREATE TRIGGER discord_members_set_updated_at_tr + BEFORE UPDATE ON discord_members + FOR EACH ROW + EXECUTE FUNCTION discord_members_set_updated_at_fn(); +""" + # --------------------------------------------------------------------------- # Fixtures # --------------------------------------------------------------------------- @@ -74,15 +134,19 @@ def pg_settings() -> SharedSettings: with connect(_POSTGRES_TEST_URL) as conn: conn.execute(_CREATE_PEOPLE_TABLE) + conn.execute(_CREATE_PEOPLE_UPDATED_AT_FUNCTION) + conn.execute("DROP TRIGGER IF EXISTS people_set_updated_at_tr ON people") + conn.execute(_CREATE_PEOPLE_UPDATED_AT_TRIGGER) + for statement in _CREATE_PEOPLE_INDEXES: + conn.execute(statement) + conn.execute(_CREATE_DISCORD_MEMBERS_TABLE) + conn.execute(_CREATE_DISCORD_MEMBERS_UPDATED_AT_FUNCTION) conn.execute( - "ALTER TABLE people " - "ADD COLUMN IF NOT EXISTS discord_roles JSONB NOT NULL DEFAULT '[]'" - ) - conn.execute("ALTER TABLE people ADD COLUMN IF NOT EXISTS discord_user_id TEXT") - conn.execute( - "ALTER TABLE people ADD COLUMN IF NOT EXISTS discord_username TEXT" + "DROP TRIGGER IF EXISTS discord_members_set_updated_at_tr ON discord_members" ) - conn.execute(_CREATE_DISCORD_MEMBERS_TABLE) + conn.execute(_CREATE_DISCORD_MEMBERS_UPDATED_AT_TRIGGER) + for statement in _CREATE_DISCORD_MEMBERS_INDEXES: + conn.execute(statement) settings = SharedSettings(postgres_url=_POSTGRES_TEST_URL, environment="test") yield settings