Gradebook: classes, weighted grading, assignments, grades, student role

- Migration: student role, students.user_id, grade_categories/grade_scale
  (school defaults + per-class override), assignments, grades + RLS
- Classes area (nav): list/create classes, class page with Gradebook / Roster /
  Grading setup tabs; teachers see their classes, admins all
- Weighted-category grade calc -> letter scale (shared helper)
- Roster assignment (admin), assignment + grade entry (teacher/admin)
- Student profile: view-only Grades tab (parents/students)
- Portal access: create parent OR student logins linked to the student

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-07-19 16:57:27 -04:00
co-authored by Claude Opus 4.8
parent 73a4e70f0b
commit 8fe6ad00f4
12 changed files with 901 additions and 20 deletions
+6 -1
View File
@@ -1,7 +1,7 @@
import { createServerFn } from "@tanstack/react-start";
import { requireSupabaseAuth } from "@/integrations/supabase/auth-middleware";
type Role = "admin" | "teacher" | "parent";
type Role = "admin" | "teacher" | "parent" | "student";
// Admin-only: create a user account (service-role, server-side), set its role,
// and optionally link it to a student (for parent hand-off).
@@ -42,6 +42,11 @@ export const createUserFn = createServerFn({ method: "POST" })
.from("parent_students").upsert({ parent_id: uid, student_id: data.linkStudentId }, { onConflict: "parent_id,student_id" });
if (lErr) throw new Error(lErr.message);
}
if (data.linkStudentId && data.role === "student") {
const { error: sErr } = await supabaseAdmin
.from("students").update({ user_id: uid }).eq("id", data.linkStudentId);
if (sErr) throw new Error(sErr.message);
}
return { id: uid, email };
});