Files
heygermany-e2e-mrg5ct1q/db/postgres/0004-candidate-details.sql
e2e 2c4174b44b
Some checks failed
Main / Setup and Test (push) Has been cancelled
Main / Build Website (push) Has been cancelled
chore: heygermany customer project
2026-07-11 11:13:08 +02:00

323 lines
9.5 KiB
SQL

-- Create enums for OCR models, AI models, and user roles
CREATE TYPE app.ocr_model AS ENUM (
'tesseract',
'azure_cognitive',
'aws_textract',
'google_vision',
'manual_entry'
);
CREATE TYPE app.ai_model AS ENUM (
'gpt-five',
'claude-three-opus',
'claude-three-sonnet',
'claude-three-haiku',
'gemini-pro'
);
CREATE TYPE app.user_role AS ENUM (
'admin',
'recruiter',
'candidate'
);
CREATE TYPE app.nurse_recognition AS ENUM (
'nurse',
'assistant_nurse',
'nursing_helper'
);
-- Update User Table
ALTER TABLE app.user
ADD COLUMN role app.user_role DEFAULT 'candidate';
-- Update Candidate Document Table
ALTER TABLE app.candidate_document
ADD COLUMN ocr_text TEXT,
ADD COLUMN ocr_model app.ocr_model,
ADD COLUMN ocr_started_at TIMESTAMPTZ,
ADD COLUMN ocr_ended_at TIMESTAMPTZ;
-- Update Candidate Table (user-provided data only)
ALTER TABLE app.candidate
ADD COLUMN phone VARCHAR,
ADD COLUMN date_of_birth DATE,
ADD COLUMN current_residence VARCHAR,
ADD COLUMN recognition_status app.nurse_recognition;
-- Create Education Table
CREATE TABLE app.candidate_education (
education_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
candidate_id UUID NOT NULL REFERENCES app.candidate(candidate_id),
source_document_id UUID REFERENCES app.candidate_document(document_id),
-- Admin-confirmed data
institution VARCHAR,
country VARCHAR,
program VARCHAR,
duration_years INTEGER,
completion_date DATE,
is_accredited BOOLEAN,
-- AI-extracted data
ai_institution VARCHAR,
ai_country VARCHAR,
ai_program VARCHAR,
ai_duration_years INTEGER,
ai_completion_date DATE,
ai_is_accredited BOOLEAN,
-- Metadata
ai_extracted_by app.ai_model,
ai_extraction_date TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
last_updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
-- Constraint: AI data requires source document
CONSTRAINT ai_data_requires_document CHECK (
(source_document_id IS NOT NULL) OR
(ai_institution IS NULL AND
ai_country IS NULL AND
ai_program IS NULL AND
ai_duration_years IS NULL AND
ai_completion_date IS NULL AND
ai_is_accredited IS NULL AND
ai_extracted_by IS NULL AND
ai_extraction_date IS NULL)
)
);
-- Create Transcript Table
CREATE TABLE app.candidate_transcript (
transcript_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
candidate_id UUID NOT NULL REFERENCES app.candidate(candidate_id),
source_document_id UUID REFERENCES app.candidate_document(document_id),
education_id UUID REFERENCES app.candidate_education(education_id),
-- Admin-confirmed data
total_theory_hours INTEGER,
total_practical_hours INTEGER,
-- AI-extracted data
ai_total_theory_hours INTEGER,
ai_total_practical_hours INTEGER,
-- Metadata
ai_extracted_by app.ai_model,
ai_extraction_date TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
last_updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
-- Constraint
CONSTRAINT ai_data_requires_document CHECK (
(source_document_id IS NOT NULL) OR
(ai_total_theory_hours IS NULL AND
ai_total_practical_hours IS NULL AND
ai_extracted_by IS NULL AND
ai_extraction_date IS NULL)
)
);
-- Create Transcript Course Table
CREATE TABLE app.candidate_transcript_course (
course_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
transcript_id UUID NOT NULL REFERENCES app.candidate_transcript(transcript_id),
-- Admin-confirmed data
course_name VARCHAR,
hours INTEGER,
grade VARCHAR,
-- AI-extracted data
ai_course_name VARCHAR,
ai_hours INTEGER,
ai_grade VARCHAR,
-- Metadata
ai_extracted_by app.ai_model
);
-- Create Clinical Placement Table
CREATE TABLE app.candidate_clinical_placement (
placement_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
transcript_id UUID NOT NULL REFERENCES app.candidate_transcript(transcript_id),
-- Admin-confirmed data
institution VARCHAR,
department VARCHAR,
duration_hours INTEGER,
duration_weeks INTEGER,
-- AI-extracted data
ai_institution VARCHAR,
ai_department VARCHAR,
ai_duration_hours INTEGER,
ai_duration_weeks INTEGER,
-- Metadata
ai_extracted_by app.ai_model
);
-- Create License Table
CREATE TABLE app.candidate_license (
license_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
candidate_id UUID NOT NULL REFERENCES app.candidate(candidate_id),
source_document_id UUID REFERENCES app.candidate_document(document_id),
-- Admin-confirmed data
license_number VARCHAR,
issuing_authority VARCHAR,
issue_date DATE,
expiry_date DATE,
status VARCHAR,
license_type VARCHAR,
-- AI-extracted data
ai_license_number VARCHAR,
ai_issuing_authority VARCHAR,
ai_issue_date DATE,
ai_expiry_date DATE,
ai_status VARCHAR,
ai_license_type VARCHAR,
-- Metadata
ai_extracted_by app.ai_model,
ai_extraction_date TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
last_updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
-- Constraint
CONSTRAINT ai_data_requires_document CHECK (
(source_document_id IS NOT NULL) OR
(ai_license_number IS NULL AND
ai_issuing_authority IS NULL AND
ai_issue_date IS NULL AND
ai_expiry_date IS NULL AND
ai_status IS NULL AND
ai_license_type IS NULL AND
ai_extracted_by IS NULL AND
ai_extraction_date IS NULL)
)
);
-- Create Language Certificate Table
CREATE TABLE app.candidate_language (
language_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
candidate_id UUID NOT NULL REFERENCES app.candidate(candidate_id),
source_document_id UUID REFERENCES app.candidate_document(document_id),
-- Admin-confirmed data
language VARCHAR DEFAULT 'German',
level app.language_level,
issuing_body VARCHAR,
issue_date DATE,
certified_skills TEXT[],
-- AI-extracted data
ai_language VARCHAR DEFAULT 'German',
ai_level app.language_level,
ai_issuing_body VARCHAR,
ai_issue_date DATE,
ai_certified_skills TEXT[],
-- Metadata
ai_extracted_by app.ai_model,
ai_extraction_date TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
last_updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
-- Constraint
CONSTRAINT ai_data_requires_document CHECK (
(source_document_id IS NOT NULL) OR
(ai_language IS NULL AND
ai_level IS NULL AND
ai_issuing_body IS NULL AND
ai_issue_date IS NULL AND
ai_certified_skills IS NULL AND
ai_extracted_by IS NULL AND
ai_extraction_date IS NULL)
)
);
-- Create Work Experience Table
CREATE TABLE app.candidate_experience (
experience_id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
candidate_id UUID NOT NULL REFERENCES app.candidate(candidate_id),
source_document_id UUID REFERENCES app.candidate_document(document_id),
-- Admin-confirmed data
employer VARCHAR,
position VARCHAR,
department VARCHAR,
start_date DATE,
end_date DATE,
duration_months INTEGER,
is_full_time BOOLEAN,
duties TEXT[],
-- AI-extracted data
ai_employer VARCHAR,
ai_position VARCHAR,
ai_department VARCHAR,
ai_start_date DATE,
ai_end_date DATE,
ai_duration_months INTEGER,
ai_is_full_time BOOLEAN,
ai_duties TEXT[],
-- Metadata
ai_extracted_by app.ai_model,
ai_extraction_date TIMESTAMPTZ,
created_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
last_updated_at TIMESTAMPTZ DEFAULT CURRENT_TIMESTAMP,
-- Constraint
CONSTRAINT ai_data_requires_document CHECK (
(source_document_id IS NOT NULL) OR
(ai_employer IS NULL AND
ai_position IS NULL AND
ai_department IS NULL AND
ai_start_date IS NULL AND
ai_end_date IS NULL AND
ai_duration_months IS NULL AND
ai_is_full_time IS NULL AND
ai_duties IS NULL AND
ai_extracted_by IS NULL AND
ai_extraction_date IS NULL)
)
);
-- Add Indexes
CREATE INDEX idx_education_candidate ON app.candidate_education(candidate_id);
CREATE INDEX idx_transcript_candidate ON app.candidate_transcript(candidate_id);
CREATE INDEX idx_license_candidate ON app.candidate_license(candidate_id);
CREATE INDEX idx_language_candidate ON app.candidate_language(candidate_id);
CREATE INDEX idx_experience_candidate ON app.candidate_experience(candidate_id);
CREATE INDEX idx_user_role ON app.user(role);
CREATE INDEX idx_document_ocr_status ON app.candidate_document(ocr_started_at, ocr_ended_at);
-- Add Update Triggers
CREATE TRIGGER update_candidate_education_timestamp
BEFORE UPDATE ON app.candidate_education
FOR EACH ROW EXECUTE PROCEDURE app.update_lastupdated_timestamp();
CREATE TRIGGER update_candidate_transcript_timestamp
BEFORE UPDATE ON app.candidate_transcript
FOR EACH ROW EXECUTE PROCEDURE app.update_lastupdated_timestamp();
CREATE TRIGGER update_candidate_license_timestamp
BEFORE UPDATE ON app.candidate_license
FOR EACH ROW EXECUTE PROCEDURE app.update_lastupdated_timestamp();
CREATE TRIGGER update_candidate_language_timestamp
BEFORE UPDATE ON app.candidate_language
FOR EACH ROW EXECUTE PROCEDURE app.update_lastupdated_timestamp();
CREATE TRIGGER update_candidate_experience_timestamp
BEFORE UPDATE ON app.candidate_experience
FOR EACH ROW EXECUTE PROCEDURE app.update_lastupdated_timestamp();