PRAGMA foreign_keys = ON; CREATE TABLE IF NOT EXISTS "auth_user" ( "id" TEXT PRIMARY KEY, "name" TEXT NOT NULL, "email" TEXT NOT NULL UNIQUE, "email_verified" BOOLEAN NOT NULL DEFAULT 0, "image" TEXT, "role" TEXT NOT NULL DEFAULT 'owner', "type" TEXT NOT NULL DEFAULT 'candidate', "created_at" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, "updated_at" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE IF NOT EXISTS "auth_session" ( "id" TEXT PRIMARY KEY, "expires_at" TIMESTAMP NOT NULL, "token" TEXT NOT NULL UNIQUE, "created_at" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, "updated_at" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, "ip_address" TEXT, "user_agent" TEXT, "user_id" TEXT NOT NULL REFERENCES "auth_user"("id") ON DELETE CASCADE ); CREATE TABLE IF NOT EXISTS "auth_account" ( "id" TEXT PRIMARY KEY, "account_id" TEXT NOT NULL, "provider_id" TEXT NOT NULL, "user_id" TEXT NOT NULL REFERENCES "auth_user"("id") ON DELETE CASCADE, "access_token" TEXT, "refresh_token" TEXT, "id_token" TEXT, "access_token_expires_at" TIMESTAMP, "refresh_token_expires_at" TIMESTAMP, "scope" TEXT, "password" TEXT, "created_at" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, "updated_at" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, UNIQUE ("provider_id", "account_id") ); CREATE TABLE IF NOT EXISTS "auth_verification" ( "id" TEXT PRIMARY KEY, "identifier" TEXT NOT NULL, "value" TEXT NOT NULL, "expires_at" TIMESTAMP NOT NULL, "created_at" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, "updated_at" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE IF NOT EXISTS "countries" ( "iso3" CHAR(3) PRIMARY KEY, "iso2" CHAR(2) NOT NULL, "name" TEXT NOT NULL, "name_br" TEXT, "name_ko" TEXT, "name_pt_br" TEXT, "name_pt" TEXT, "name_nl" TEXT, "name_hr" TEXT, "name_fa" TEXT, "name_de" TEXT, "name_es" TEXT, "name_fr" TEXT, "name_ja" TEXT, "name_it" TEXT, "name_zh_cn" TEXT, "name_tr" TEXT, "name_ru" TEXT, "name_uk" TEXT, "name_pl" TEXT, "created_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP, "updated_at" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE IF NOT EXISTS "user" ( "user_id" TEXT PRIMARY KEY, "email" TEXT NOT NULL UNIQUE, "name" TEXT NOT NULL, "email_verified_at" TIMESTAMP, "created_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP, "last_updated_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP, "role" TEXT NOT NULL, "type" TEXT NOT NULL, "email_verification_token" TEXT ); CREATE TABLE IF NOT EXISTS "user_auth" ( "user_id" TEXT PRIMARY KEY REFERENCES "user"("user_id") ON DELETE CASCADE, "created_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP, "last_updated_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP, "magic_link" TEXT ); CREATE TABLE IF NOT EXISTS "candidate" ( "candidate_id" TEXT PRIMARY KEY, "email" TEXT NOT NULL UNIQUE, "name" TEXT NOT NULL, "state_work_preference" ARRAY, "join_talent_pool" BOOLEAN, "living_in_germany" BOOLEAN, "eu_passport" BOOLEAN, "country_education" TEXT REFERENCES "countries"("iso3"), "license_provided" BOOLEAN, "language_certificate_provided" BOOLEAN, "language_self_assessment_level" TEXT, "submitted_at" TIMESTAMP, "created_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP, "last_updated_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP, "phone" TEXT, "date_of_birth" DATE, "current_residence" TEXT, "qualification_status_home_country" TEXT, "qualification_status_germany" TEXT, "license_mandatory" BOOLEAN, "duration_requirements_met" BOOLEAN, "status" TEXT NOT NULL DEFAULT 'Initial', "incomplete_reminder_sent_at" TIMESTAMP, "recognition_likelihood" TEXT, "professional_recognition_status" TEXT, "nationality" TEXT, "languages_spoken" ARRAY, "status_changed_at" TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP, "lifecycle_notifications" JSON NOT NULL DEFAULT '{}', "analysis_last_run_at" TIMESTAMP, "analysis_input_fingerprint" TEXT, "invalidated_at" TIMESTAMP, "reupload_requested_at" TIMESTAMP, "reuploaded_at" TIMESTAMP, "failed_purged_at" TIMESTAMP ); CREATE TABLE IF NOT EXISTS "candidate_document" ( "document_id" TEXT PRIMARY KEY, "candidate_id" TEXT NOT NULL REFERENCES "candidate"("candidate_id") ON DELETE CASCADE, "category" TEXT NOT NULL, "title" TEXT, "note" TEXT, "file_path" TEXT NOT NULL, "file_name" TEXT NOT NULL, "file_size" INTEGER, "mime_type" TEXT, "uploaded" BOOLEAN DEFAULT 0, "created_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP, "last_updated_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP, "ocr_text" TEXT, "ocr_model" TEXT, "ocr_started_at" TIMESTAMP, "ocr_ended_at" TIMESTAMP, "document_status" TEXT NOT NULL DEFAULT 'Unverified' ); CREATE TABLE IF NOT EXISTS "candidate_education" ( "education_id" TEXT PRIMARY KEY, "candidate_id" TEXT NOT NULL UNIQUE REFERENCES "candidate"("candidate_id") ON DELETE CASCADE, "institution" TEXT, "country" TEXT, "program" TEXT, "completion_date" DATE, "ai_institution" TEXT, "ai_country" TEXT, "ai_program" TEXT, "ai_completion_date" DATE, "ai_extracted_by" TEXT, "ai_extraction_date" TIMESTAMP, "created_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP, "last_updated_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP, "nursing_related_degree" BOOLEAN, "accredited_university" BOOLEAN, "accredited_study_program" BOOLEAN, "ai_nursing_related_degree" BOOLEAN, "ai_accredited_university" BOOLEAN, "ai_accredited_study_program" BOOLEAN, "has_theory" BOOLEAN, "has_practice" BOOLEAN, "duration_hours" INTEGER, "is_nursing_focus" BOOLEAN, "ai_has_theory" BOOLEAN, "ai_has_practice" BOOLEAN, "ai_duration_hours" INTEGER, "ai_is_nursing_focus" BOOLEAN ); CREATE TABLE IF NOT EXISTS "candidate_license" ( "license_id" TEXT PRIMARY KEY, "candidate_id" TEXT NOT NULL UNIQUE REFERENCES "candidate"("candidate_id") ON DELETE CASCADE, "license_number" TEXT, "issuing_authority" TEXT, "issue_date" DATE, "expiry_date" DATE, "status" TEXT, "license_type" TEXT, "ai_license_number" TEXT, "ai_issuing_authority" TEXT, "ai_issue_date" DATE, "ai_expiry_date" DATE, "ai_status" TEXT, "ai_license_type" TEXT, "ai_extracted_by" TEXT, "ai_extraction_date" TIMESTAMP, "created_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP, "last_updated_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE IF NOT EXISTS "candidate_language" ( "language_id" TEXT PRIMARY KEY, "candidate_id" TEXT NOT NULL UNIQUE REFERENCES "candidate"("candidate_id") ON DELETE CASCADE, "level" TEXT, "issuing_body" TEXT, "issue_date" DATE, "certified_skills" ARRAY, "ai_level" TEXT, "ai_issuing_body" TEXT, "ai_issue_date" DATE, "ai_certified_skills" ARRAY, "ai_extracted_by" TEXT, "ai_extraction_date" TIMESTAMP, "created_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP, "last_updated_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE IF NOT EXISTS "candidate_experience" ( "experience_id" TEXT PRIMARY KEY, "candidate_id" TEXT NOT NULL UNIQUE REFERENCES "candidate"("candidate_id") ON DELETE CASCADE, "employer_name" TEXT, "role_title" TEXT, "department" TEXT, "start_date" DATE, "end_date" DATE, "created_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP, "last_updated_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP, "country" TEXT, "city" TEXT, "facility_type" TEXT ); CREATE TABLE IF NOT EXISTS "leads" ( "lead_id" TEXT PRIMARY KEY, "first_name" TEXT NOT NULL, "last_name" TEXT NOT NULL, "email" TEXT NOT NULL, "phone" TEXT, "facility_name" TEXT NOT NULL, "facility_type" TEXT NOT NULL, "nurses_needed_range" TEXT, "message" TEXT, "source" TEXT NOT NULL DEFAULT 'pilot', "created_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP, "last_updated_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE IF NOT EXISTS "country" ( "country_id" TEXT PRIMARY KEY, "iso_code" TEXT NOT NULL, "name_english" TEXT NOT NULL, "name_official" TEXT, "name_short" TEXT, "publicated" BOOLEAN NOT NULL, "hidden" BOOLEAN, "country_group" TEXT NOT NULL, "created_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP, "last_updated_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE IF NOT EXISTS "location" ( "location_id" TEXT PRIMARY KEY, "id_original" TEXT NOT NULL, "country_id" TEXT NOT NULL REFERENCES "country"("country_id") ON DELETE CASCADE, "origin_name" TEXT NOT NULL, "name_short" TEXT, "created_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP, "last_updated_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE IF NOT EXISTS "institution_type" ( "institution_type_id" TEXT PRIMARY KEY, "name_short" TEXT, "status" TEXT, "comment" TEXT, "created_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP, "last_updated_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE IF NOT EXISTS "institution" ( "institution_id" TEXT PRIMARY KEY, "id_original" TEXT NOT NULL, "country_id" TEXT NOT NULL REFERENCES "country"("country_id") ON DELETE CASCADE, "location_id" TEXT REFERENCES "location"("location_id") ON DELETE SET NULL, "institution_type_id" TEXT NOT NULL REFERENCES "institution_type"("institution_type_id") ON DELETE CASCADE, "name_short" TEXT, "abbreviation" TEXT, "homepage" TEXT, "name_german" TEXT, "address_street" TEXT, "address_zip" TEXT, "address_city" TEXT, "created_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP, "last_updated_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE IF NOT EXISTS "degree_type" ( "degree_type_id" TEXT PRIMARY KEY, "id_original" TEXT NOT NULL, "country_id" TEXT NOT NULL REFERENCES "country"("country_id") ON DELETE CASCADE, "name_short" TEXT, "name_german" TEXT, "name_female" TEXT, "name_female_german" TEXT, "comment" TEXT, "hide_requirement" BOOLEAN, "requirement" TEXT, "additional_requirement" TEXT, "hide_studies" BOOLEAN, "studies_min_length" REAL, "studies_max_length" REAL, "explanation_studies_length" TEXT, "studies_description" TEXT, "abbreviation" TEXT, "abbreviation_female" TEXT, "degree_class" TEXT, "created_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP, "last_updated_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE IF NOT EXISTS "degree_type_equivalence" ( "degree_type_equivalence_id" TEXT PRIMARY KEY, "id_original" TEXT NOT NULL, "degree_type_id" TEXT NOT NULL REFERENCES "degree_type"("degree_type_id") ON DELETE CASCADE, "hidden" BOOLEAN, "equivalence_class" TEXT NOT NULL, "comment" TEXT, "admin_comment" TEXT, "internal_comment" TEXT, "created_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP, "last_updated_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE IF NOT EXISTS "degree_field_of_study" ( "degree_field_of_study_id" TEXT PRIMARY KEY, "id_original" TEXT NOT NULL, "country_id" TEXT NOT NULL REFERENCES "country"("country_id") ON DELETE CASCADE, "name_short" TEXT, "name_german" TEXT, "created_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP, "last_updated_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE IF NOT EXISTS "degree" ( "degree_id" TEXT PRIMARY KEY, "id_original" TEXT NOT NULL, "country_id" TEXT NOT NULL REFERENCES "country"("country_id") ON DELETE CASCADE, "degree_type_id" TEXT REFERENCES "degree_type"("degree_type_id") ON DELETE SET NULL, "field_of_study_id" TEXT REFERENCES "degree_field_of_study"("degree_field_of_study_id") ON DELETE SET NULL, "degree_short" TEXT, "name_short" TEXT, "name_german" TEXT, "name_female" TEXT, "name_female_german" TEXT, "comment" TEXT, "created_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP, "last_updated_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE IF NOT EXISTS "alias_name" ( "alias_name_id" TEXT PRIMARY KEY, "type" TEXT NOT NULL, "id_original" TEXT NOT NULL, "name_short" TEXT, "name_german" TEXT, "comment" TEXT, "hidden" BOOLEAN, "deleted" BOOLEAN, "language_id" TEXT, "name_translated" TEXT, "created_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP, "last_updated_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE IF NOT EXISTS "institution_degree" ( "institution_id" TEXT NOT NULL REFERENCES "institution"("institution_id") ON DELETE CASCADE, "degree_id" TEXT NOT NULL REFERENCES "degree"("degree_id") ON DELETE CASCADE, "created_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP, "last_updated_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY ("institution_id", "degree_id") ); CREATE TABLE IF NOT EXISTS "degree_equivalence" ( "degree_id" TEXT NOT NULL REFERENCES "degree"("degree_id") ON DELETE CASCADE, "equivalence_id" TEXT NOT NULL REFERENCES "degree_type_equivalence"("degree_type_equivalence_id") ON DELETE CASCADE, "created_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP, "last_updated_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY ("degree_id", "equivalence_id") ); CREATE TABLE IF NOT EXISTS "degree_type_equivalence_link" ( "degree_type_id" TEXT NOT NULL REFERENCES "degree_type"("degree_type_id") ON DELETE CASCADE, "equivalence_id" TEXT NOT NULL REFERENCES "degree_type_equivalence"("degree_type_equivalence_id") ON DELETE CASCADE, "created_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP, "last_updated_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY ("degree_type_id", "equivalence_id") ); CREATE TABLE IF NOT EXISTS "entity_name_link" ( "entity_type" TEXT NOT NULL, "entity_id" TEXT NOT NULL, "name_id" TEXT NOT NULL REFERENCES "alias_name"("alias_name_id") ON DELETE CASCADE, "name_type" TEXT NOT NULL, "created_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP, "last_updated_at" TIMESTAMP DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY ("entity_type", "entity_id", "name_id") ); CREATE INDEX IF NOT EXISTS "idx_auth_session_user_id" ON "auth_session" ("user_id"); CREATE INDEX IF NOT EXISTS "idx_auth_account_user_id" ON "auth_account" ("user_id"); CREATE INDEX IF NOT EXISTS "idx_auth_verification_identifier" ON "auth_verification" ("identifier"); CREATE INDEX IF NOT EXISTS "idx_candidate_status_changed_at" ON "candidate" ("status", "status_changed_at"); CREATE INDEX IF NOT EXISTS "idx_candidate_reupload_flags" ON "candidate" ("invalidated_at", "reuploaded_at"); CREATE INDEX IF NOT EXISTS "idx_candidate_document_candidate_id" ON "candidate_document" ("candidate_id"); CREATE UNIQUE INDEX IF NOT EXISTS "idx_candidate_document_profile_image_unique" ON "candidate_document" ("candidate_id") WHERE "category" = 'profile_image'; CREATE VIEW IF NOT EXISTS "institution_search" AS SELECT i.institution_id, i.name_short AS main_name_short, i.name_german AS main_name_german, a.name_short AS alias_name_short, a.name_german AS alias_name_german, enl.name_type AS alias_type FROM "institution" i LEFT JOIN "entity_name_link" enl ON enl.entity_type = 'institution' AND enl.entity_id = i.institution_id LEFT JOIN "alias_name" a ON a.alias_name_id = enl.name_id; CREATE VIEW IF NOT EXISTS "degree_search" AS SELECT d.degree_id, d.name_short AS main_name_short, d.name_german AS main_name_german, a.name_short AS alias_name_short, a.name_german AS alias_name_german, enl.name_type AS alias_type FROM "degree" d LEFT JOIN "entity_name_link" enl ON enl.entity_type = 'degree' AND enl.entity_id = d.degree_id LEFT JOIN "alias_name" a ON a.alias_name_id = enl.name_id;