-- Migration: Drop implicit _SubjectToTeacher and replace with explicit TeacherSubject -- 1. Create the new explicit mapping table CREATE TABLE "TeacherSubject" ( "id" SERIAL PRIMARY KEY, "teacherId" TEXT NOT NULL REFERENCES "Teacher"("id") ON DELETE CASCADE, "subjectId" INTEGER NOT NULL REFERENCES "Subject"("id") ON DELETE CASCADE, "isPrimary" BOOLEAN DEFAULT false, "assignedAt" TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); -- 2. Migrate existing data (Optional, but good practice if not resetting) INSERT INTO "TeacherSubject" ("teacherId", "subjectId") SELECT "B", "A" FROM "_SubjectToTeacher"; -- 3. Drop the old implicit mapping table DROP TABLE "_SubjectToTeacher"; -- 4. Enable RLS on the new table ALTER TABLE "TeacherSubject" ENABLE ROW LEVEL SECURITY; -- 5. Define RLS Policies for the new table CREATE POLICY "Admins have full access" ON "TeacherSubject" FOR ALL USING (is_admin()); CREATE POLICY "Anyone can view teacher-subjects" ON "TeacherSubject" FOR SELECT TO authenticated USING (true); -- 6. Update the auth_user_subjects RLS Helper Function to use explicitly named mapping table CREATE OR REPLACE FUNCTION auth_user_subjects() RETURNS SETOF integer LANGUAGE plpgsql SECURITY DEFINER SET search_path = public STABLE AS $$ BEGIN RETURN QUERY SELECT "subjectId" FROM "TeacherSubject" WHERE "teacherId" = requesting_user_id() AND requesting_user_role() = 'teacher' UNION SELECT "subjectId" FROM "Lesson" WHERE "classId" IN ( SELECT "classId" FROM "Student" WHERE id = requesting_user_id() AND requesting_user_role() = 'student' ) UNION SELECT "subjectId" FROM "Lesson" WHERE "classId" IN ( SELECT "classId" FROM "Student" WHERE "parentId" = requesting_user_id() AND requesting_user_role() = 'parent' ); END; $$;