-- Persist session-level evaluator output for learner reviews and teacher/admin views. CREATE TABLE IF NOT EXISTS app.session_evaluation ( session_id UUID PRIMARY KEY REFERENCES app.sessions(id) ON DELETE CASCADE, status TEXT NOT NULL CHECK (status IN ('ready','degraded','error')), source TEXT NOT NULL, scope TEXT NOT NULL, stage TEXT NOT NULL, payload JSONB NOT NULL DEFAULT '{}'::jsonb, error TEXT, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now() ); ALTER TABLE app.session_evaluation ENABLE ROW LEVEL SECURITY; DROP POLICY IF EXISTS p_session_evaluation_select ON app.session_evaluation; DROP POLICY IF EXISTS p_session_evaluation_insert ON app.session_evaluation; DROP POLICY IF EXISTS p_session_evaluation_update ON app.session_evaluation; DROP POLICY IF EXISTS p_session_evaluation_delete ON app.session_evaluation; CREATE POLICY p_session_evaluation_select ON app.session_evaluation FOR SELECT USING ( app.is_ai_context() OR app.current_role_name() IN ('admin','instructor') OR EXISTS ( SELECT 1 FROM app.sessions s WHERE s.id = app.session_evaluation.session_id AND s.learner_id = app.current_uid() ) ); CREATE POLICY p_session_evaluation_insert ON app.session_evaluation FOR INSERT WITH CHECK ( app.is_ai_context() OR app.current_role_name() IN ('admin','instructor') OR EXISTS ( SELECT 1 FROM app.sessions s WHERE s.id = app.session_evaluation.session_id AND s.learner_id = app.current_uid() ) ); CREATE POLICY p_session_evaluation_update ON app.session_evaluation FOR UPDATE USING ( app.is_ai_context() OR app.current_role_name() IN ('admin','instructor') OR EXISTS ( SELECT 1 FROM app.sessions s WHERE s.id = app.session_evaluation.session_id AND s.learner_id = app.current_uid() ) ) WITH CHECK ( app.is_ai_context() OR app.current_role_name() IN ('admin','instructor') OR EXISTS ( SELECT 1 FROM app.sessions s WHERE s.id = app.session_evaluation.session_id AND s.learner_id = app.current_uid() ) ); CREATE POLICY p_session_evaluation_delete ON app.session_evaluation FOR DELETE USING ( app.is_ai_context() OR app.current_role_name() IN ('admin','instructor') OR EXISTS ( SELECT 1 FROM app.sessions s WHERE s.id = app.session_evaluation.session_id AND s.learner_id = app.current_uid() ) ); -- Learner-edited case formulation worksheet for session review. CREATE TABLE IF NOT EXISTS app.case_worksheet ( session_id UUID PRIMARY KEY REFERENCES app.sessions(id) ON DELETE CASCADE, payload JSONB NOT NULL DEFAULT '{}'::jsonb, created_at TIMESTAMPTZ NOT NULL DEFAULT now(), updated_at TIMESTAMPTZ NOT NULL DEFAULT now() ); ALTER TABLE app.case_worksheet ENABLE ROW LEVEL SECURITY; DROP POLICY IF EXISTS p_case_worksheet_select ON app.case_worksheet; DROP POLICY IF EXISTS p_case_worksheet_insert ON app.case_worksheet; DROP POLICY IF EXISTS p_case_worksheet_update ON app.case_worksheet; DROP POLICY IF EXISTS p_case_worksheet_delete ON app.case_worksheet; CREATE POLICY p_case_worksheet_select ON app.case_worksheet FOR SELECT USING ( app.current_role_name() IN ('admin','instructor') OR EXISTS ( SELECT 1 FROM app.sessions s WHERE s.id = app.case_worksheet.session_id AND s.learner_id = app.current_uid() ) ); CREATE POLICY p_case_worksheet_insert ON app.case_worksheet FOR INSERT WITH CHECK ( EXISTS ( SELECT 1 FROM app.sessions s WHERE s.id = app.case_worksheet.session_id AND s.learner_id = app.current_uid() ) ); CREATE POLICY p_case_worksheet_update ON app.case_worksheet FOR UPDATE USING ( EXISTS ( SELECT 1 FROM app.sessions s WHERE s.id = app.case_worksheet.session_id AND s.learner_id = app.current_uid() ) ) WITH CHECK ( EXISTS ( SELECT 1 FROM app.sessions s WHERE s.id = app.case_worksheet.session_id AND s.learner_id = app.current_uid() ) ); CREATE POLICY p_case_worksheet_delete ON app.case_worksheet FOR DELETE USING ( EXISTS ( SELECT 1 FROM app.sessions s WHERE s.id = app.case_worksheet.session_id AND s.learner_id = app.current_uid() ) );