26 lines
1.2 KiB
SQL
26 lines
1.2 KiB
SQL
-- 030_cv_bank_matches.sql
|
|
-- Tier-1 ranking of banked CVs against a job post.
|
|
--
|
|
-- Computed by the cvbank.rank_for_job task when a job opens, not on read: the
|
|
-- point is to notify a recruiter that the bank already holds candidates, and a
|
|
-- notification needs a result that exists before anyone opens the screen.
|
|
--
|
|
-- rank_score is deterministic keyword overlap (matching/ranking.py), NOT an ATS
|
|
-- score. Cheap enough to recompute for the whole bank on every job opening.
|
|
-- Applied at startup by alembic_setup.run_manual_sql().
|
|
|
|
CREATE TABLE IF NOT EXISTS app.cv_bank_matches (
|
|
id UUID PRIMARY KEY,
|
|
manual_upload_candidate_id UUID NOT NULL
|
|
REFERENCES app.manual_upload_candidate (id) ON DELETE CASCADE,
|
|
job_post_id UUID NOT NULL
|
|
REFERENCES app.job_posts (id) ON DELETE CASCADE,
|
|
rank_score INTEGER NOT NULL DEFAULT 0,
|
|
computed_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
|
CONSTRAINT uq_cv_bank_matches_pair UNIQUE (manual_upload_candidate_id, job_post_id)
|
|
);
|
|
|
|
-- The read is always "best candidates for THIS job", so the job leads.
|
|
CREATE INDEX IF NOT EXISTS ix_cv_bank_matches_job_rank
|
|
ON app.cv_bank_matches (job_post_id, rank_score DESC);
|