feat(admin): add instructor learning analytics and assessment management
New /api/admin routes: cohort learning summary (completion by stage, active learners), per-student learning detail (attempts, hint usage, assessment history, capstone state), scenario analytics (completion rate, avg attempts, failure/hint frequency, avg time), and a needs-attention view (repeated failures, hints used but still stuck, inactivity, an expired assessment - deliberately instructional wording, not punitive, with an explicit test asserting that). Assessment definition CRUD (admin/owner only), cohort assignment and session view/cancel (any instructor role, cohort-scoped for a plain instructor via the existing Phase 3A RBAC helpers - no new authorization primitives needed). New Learning and Assessments tabs in the admin portal, visible to every instructor role; definition-authoring controls are shown but the server 403s a create/edit from a non-admin/ owner role, same pattern CohortsView already uses for admin-only controls.
This commit is contained in:
@@ -6,16 +6,22 @@ import StudentsView from './StudentsView'
|
||||
import InstructorsView from './InstructorsView'
|
||||
import AuditView from './AuditView'
|
||||
import AccountView from './AccountView'
|
||||
import LearningView from './LearningView'
|
||||
import AssessmentsView from './AssessmentsView'
|
||||
import styles from './Admin.module.css'
|
||||
|
||||
// Instructor/Admin portal — clearly separate from the student experience (/admin route,
|
||||
// separate rn_instructor session cookie, separate login). A student session cannot reach any
|
||||
// of these views or their underlying /api/admin/* routes. Per-person accounts replace Phase
|
||||
// 2B's single shared ADMIN_PASSWORD — see docs/PHASE3A_IDENTITY_AND_INSTRUCTOR_ACCESS.md.
|
||||
// Learning/Assessments (Phase 3B) are visible to every instructor role — cohort scoping for a
|
||||
// plain 'instructor' happens server-side per route, not by hiding the whole tab.
|
||||
const NAV = [
|
||||
{ key: 'dashboard', label: 'Dashboard' },
|
||||
{ key: 'cohorts', label: 'Cohorts' },
|
||||
{ key: 'students', label: 'Students' },
|
||||
{ key: 'learning', label: 'Learning' },
|
||||
{ key: 'assessments', label: 'Assessments' },
|
||||
{ key: 'instructors', label: 'Instructors', roles: ['owner'] },
|
||||
{ key: 'audit', label: 'Audit', roles: ['owner', 'admin'] },
|
||||
]
|
||||
@@ -53,6 +59,8 @@ export default function AdminPortal() {
|
||||
{view === 'dashboard' && <AdminDashboard />}
|
||||
{view === 'cohorts' && <CohortsView role={instructor.role} />}
|
||||
{view === 'students' && <StudentsView role={instructor.role} />}
|
||||
{view === 'learning' && <LearningView />}
|
||||
{view === 'assessments' && <AssessmentsView role={instructor.role} />}
|
||||
{view === 'instructors' && instructor.role === 'owner' && <InstructorsView currentInstructorId={instructor.instructor_id} />}
|
||||
{view === 'audit' && ['owner', 'admin'].includes(instructor.role) && <AuditView />}
|
||||
{view === 'account' && <AccountView instructor={instructor} />}
|
||||
|
||||
Reference in New Issue
Block a user