-- Add indexes for optimized search on outgoing letters CREATE INDEX IF NOT EXISTS idx_letters_outgoing_letter_number_text ON letters_outgoing USING gin(to_tsvector('simple', letter_number)); CREATE INDEX IF NOT EXISTS idx_letters_outgoing_subject_text ON letters_outgoing USING gin(to_tsvector('simple', subject)); CREATE INDEX IF NOT EXISTS idx_letters_outgoing_description_text ON letters_outgoing USING gin(to_tsvector('simple', COALESCE(description, ''))); CREATE INDEX IF NOT EXISTS idx_letters_outgoing_reference_number_text ON letters_outgoing USING gin(to_tsvector('simple', COALESCE(reference_number, ''))); -- Composite indexes for common query patterns on outgoing letters CREATE INDEX IF NOT EXISTS idx_letters_outgoing_status_created ON letters_outgoing(status, created_at DESC) WHERE deleted_at IS NULL; CREATE INDEX IF NOT EXISTS idx_letters_outgoing_priority_created ON letters_outgoing(priority_id, created_at DESC) WHERE deleted_at IS NULL; CREATE INDEX IF NOT EXISTS idx_letters_outgoing_institution_created ON letters_outgoing(receiver_institution_id, created_at DESC) WHERE deleted_at IS NULL; CREATE INDEX IF NOT EXISTS idx_letters_outgoing_created_by ON letters_outgoing(created_by, created_at DESC) WHERE deleted_at IS NULL; CREATE INDEX IF NOT EXISTS idx_letters_outgoing_issue_date ON letters_outgoing(issue_date DESC) WHERE deleted_at IS NULL; -- Add indexes for optimized search on incoming letters CREATE INDEX IF NOT EXISTS idx_letters_incoming_letter_number_text ON letters_incoming USING gin(to_tsvector('simple', letter_number)); CREATE INDEX IF NOT EXISTS idx_letters_incoming_subject_text ON letters_incoming USING gin(to_tsvector('simple', subject)); CREATE INDEX IF NOT EXISTS idx_letters_incoming_description_text ON letters_incoming USING gin(to_tsvector('simple', COALESCE(description, ''))); CREATE INDEX IF NOT EXISTS idx_letters_incoming_reference_number_text ON letters_incoming USING gin(to_tsvector('simple', COALESCE(reference_number, ''))); -- Composite indexes for common query patterns on incoming letters CREATE INDEX IF NOT EXISTS idx_letters_incoming_status_created ON letters_incoming(status, created_at DESC) WHERE deleted_at IS NULL; CREATE INDEX IF NOT EXISTS idx_letters_incoming_priority_created ON letters_incoming(priority_id, created_at DESC) WHERE deleted_at IS NULL; CREATE INDEX IF NOT EXISTS idx_letters_incoming_institution_created ON letters_incoming(sender_institution_id, created_at DESC) WHERE deleted_at IS NULL; CREATE INDEX IF NOT EXISTS idx_letters_incoming_created_by ON letters_incoming(created_by, created_at DESC) WHERE deleted_at IS NULL; CREATE INDEX IF NOT EXISTS idx_letters_incoming_received_date ON letters_incoming(received_date DESC) WHERE deleted_at IS NULL; -- Indexes for recipient lookups CREATE INDEX IF NOT EXISTS idx_letter_outgoing_recipients_user ON letter_outgoing_recipients(user_id, letter_id); CREATE INDEX IF NOT EXISTS idx_letter_outgoing_recipients_dept ON letter_outgoing_recipients(department_id, letter_id); CREATE INDEX IF NOT EXISTS idx_letter_incoming_recipients_user ON letter_incoming_recipients(recipient_user_id, letter_id); CREATE INDEX IF NOT EXISTS idx_letter_incoming_recipients_dept ON letter_incoming_recipients(recipient_department_id, letter_id); -- Create a function for full-text search on outgoing letters CREATE OR REPLACE FUNCTION search_outgoing_letters(search_query text) RETURNS SETOF letters_outgoing AS $$ BEGIN RETURN QUERY SELECT * FROM letters_outgoing WHERE deleted_at IS NULL AND ( to_tsvector('simple', letter_number) @@ plainto_tsquery('simple', search_query) OR to_tsvector('simple', subject) @@ plainto_tsquery('simple', search_query) OR to_tsvector('simple', COALESCE(description, '')) @@ plainto_tsquery('simple', search_query) OR to_tsvector('simple', COALESCE(reference_number, '')) @@ plainto_tsquery('simple', search_query) ); END; $$ LANGUAGE plpgsql; -- Create a function for full-text search on incoming letters CREATE OR REPLACE FUNCTION search_incoming_letters(search_query text) RETURNS SETOF letters_incoming AS $$ BEGIN RETURN QUERY SELECT * FROM letters_incoming WHERE deleted_at IS NULL AND ( to_tsvector('simple', letter_number) @@ plainto_tsquery('simple', search_query) OR to_tsvector('simple', subject) @@ plainto_tsquery('simple', search_query) OR to_tsvector('simple', COALESCE(description, '')) @@ plainto_tsquery('simple', search_query) OR to_tsvector('simple', COALESCE(reference_number, '')) @@ plainto_tsquery('simple', search_query) ); END; $$ LANGUAGE plpgsql;