-- 020_requisitions.sql -- Employee Requisition (Annexure A) as its own table, separate from -- candidate_forms (Interview Analysis / Cultural Fit). Nested request objects -- flatten onto columns: position.title → position_title, replacement_for.title -- → recruitment_title, refferal_by → employee_name / employee_department. -- employment type is a CHECK over EmploymentType values, not a native PG enum -- (point releases of the Python enum should not require a type ALTER). -- -- "date" and "type" are quoted: both are PostgreSQL keywords. -- -- Idempotent, applied automatically at startup by alembic_setup.run_manual_sql() -- and recorded in manual_migrations. Matches Requisition in -- backend/candidate_forms/models.py (needed here because prod boots with -- DB_AUTOGENERATE=false and never autogenerates new tables). CREATE TABLE IF NOT EXISTS app.requisitions ( id uuid PRIMARY KEY, department varchar, position_title varchar, "date" date, date_needed date, "type" varchar CHECK ("type" IS NULL OR "type" IN ( 'permanent', 'contract', 'temporary', 'internee' )), job_description text, employee_name varchar, employee_department varchar, to_replace varchar, grade varchar, recruitment_title varchar, date_separated date, justification text, budget varchar, recommended_grade varchar, initiated_by varchar, initiated_date date, recommended_by varchar, recommended_date date, approved_by_hr boolean, approved_by_date_hr date, approved_by_vp boolean, approved_by_date_vp date, approved_by_svp boolean, approved_by_date_svp date, created_by uuid REFERENCES app.users(id), created_at timestamptz NOT NULL DEFAULT NOW(), updated_at timestamptz NOT NULL DEFAULT NOW(), is_deleted boolean NOT NULL DEFAULT false ); CREATE INDEX IF NOT EXISTS ix_requisitions_created_by ON app.requisitions (created_by); CREATE INDEX IF NOT EXISTS ix_requisitions_is_deleted ON app.requisitions (is_deleted);