student_id-FK-Migration Stufe 1+2: Name-Joins -> student_sessions.student_id

- student_sessions: neue Spalte student_id (+Index), backfilled aus (class_id,display_name)
- Session::createStudent setzt student_id (per Lookup, falls nicht uebergeben)
- alle Joins students<->student_sessions von display_name auf student_id umgestellt:
  Benchmark.php, live.php (5x), results.php (4x + runs), modules.php, profile.php, progress.php (answers+runs)
- verlustfrei verifiziert (alt-Join == neu-Join, class 99/102)

Robuster gegen Umbenennung/Doppelnamen, indexierbare Joins.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
2026-08-15 19:16:41 +02:00
parent 2984d93e7e
commit fb44ec7afe
7 changed files with 42 additions and 30 deletions
+8 -8
View File
@@ -93,12 +93,12 @@ if ($method === 'GET') {
s.id AS student_id, s.display_name, s.username, s.emoji_avatar, s.avatar_slug
FROM assessments a
JOIN student_sessions ss ON ss.id = a.session_id
JOIN students s ON s.class_id = ? AND s.display_name = ss.display_name
JOIN students s ON s.id = ss.student_id
WHERE a.class_id = ?
AND a.submitted_at >= ?
AND a.submitted_at < ?
ORDER BY s.id, a.sim_id, a.submitted_at ASC",
[$classId, $classId, $date . ' 00:00:00', $date . ' 23:59:59.999']
[$classId, $date . ' 00:00:00', $date . ' 23:59:59.999']
);
// Helper: extrahiere "Lektion-Key" (mission/level/scenario) aus assessments-row
@@ -394,10 +394,10 @@ if ($method === 'GET') {
FROM assessments a
JOIN student_sessions ss ON ss.id = a.session_id
WHERE a.class_id = ? AND a.sim_id = ?
AND ss.display_name = ?
AND ss.student_id = ?
AND a.submitted_at BETWEEN ? AND ?
ORDER BY a.submitted_at DESC',
[$classId, $simId, $student['display_name'], $start, $end]
[$classId, $simId, $studentId, $start, $end]
);
if (!$rows) Response::ok(['results' => null, 'assessmentCount' => 0]);
// Nimm den Row mit dem reichhaltigsten Results-JSON (Heuristik: hat .stars oder .results.totalStars)
@@ -600,7 +600,7 @@ if ($method === 'GET') {
$heuteRows = $db->fetchAll(
"SELECT DISTINCT s.id AS student_id
FROM students s
LEFT JOIN student_sessions ss ON ss.class_id = s.class_id AND ss.display_name = s.display_name
LEFT JOIN student_sessions ss ON ss.student_id = s.id
LEFT JOIN assessments a ON a.session_id = ss.id AND a.submitted_at >= CURDATE()
LEFT JOIN live_sessions ls ON ls.student_id = s.id AND ls.last_seen >= CURDATE()
WHERE s.class_id = ? AND s.deleted_at IS NULL
@@ -616,7 +616,7 @@ if ($method === 'GET') {
MAX(GREATEST(IFNULL(a.submitted_at, '1970-01-01'),
IFNULL(ls.last_seen, '1970-01-01'))) AS last_seen_any
FROM students s
LEFT JOIN student_sessions ss ON ss.class_id = s.class_id AND ss.display_name = s.display_name
LEFT JOIN student_sessions ss ON ss.student_id = s.id
LEFT JOIN assessments a ON a.session_id = ss.id
LEFT JOIN live_sessions ls ON ls.student_id = s.id
WHERE s.class_id = ? AND s.deleted_at IS NULL
@@ -633,7 +633,7 @@ if ($method === 'GET') {
"SELECT s.id AS student_id, a.sim_id, a.results, a.process_log, a.submitted_at
FROM assessments a
JOIN student_sessions ss ON ss.id = a.session_id
JOIN students s ON s.class_id = ss.class_id AND s.display_name = ss.display_name
JOIN students s ON s.id = ss.student_id
WHERE a.class_id = ? AND s.deleted_at IS NULL
ORDER BY s.id, a.sim_id, a.submitted_at DESC",
[$classId]
@@ -729,7 +729,7 @@ if ($method === 'GET') {
SUM(COALESCE(a.duration_ms, 0)) / 1000 AS sec
FROM assessments a
JOIN student_sessions ss ON ss.id = a.session_id
JOIN students s ON s.class_id = ss.class_id AND s.display_name = ss.display_name
JOIN students s ON s.id = ss.student_id
WHERE a.class_id = ? AND $sinceSql AND s.deleted_at IS NULL
GROUP BY bucket, a.sim_id",
[$classId]