File size: 2,681 Bytes
f853e83
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import {
  getEvaluationLogsByUser,
  getEvaluationsForTeacher,
  overrideScores,
} from "../services/evaluationService.js";
import { getMyProfile } from "../services/authService.js";
import { duplicateForViewer } from "../services/duplicateService.js";

/** A student's own submissions. Optionally filtered by subject. */
export const getEvaluationLogs = async (req, res) => {
  try {
    const userUid = req.user?.uid;
    if (!userUid) {
      return res.status(401).json({ error: "Unauthorized", message: "Missing user context" });
    }

    const logs = await getEvaluationLogsByUser({
      userUid,
      limit: Number(req.query.limit || 50),
      subject: req.query.subject || null,
    });

    // A student's own records keep the fact of a duplicate match but not whose work it was.
    const isTeacher = req.user?.role === "teacher";
    const visible = logs.map((log) => ({
      ...log,
      duplicateCheck: duplicateForViewer(log.duplicateCheck, isTeacher),
    }));

    res.json({ logs: visible, count: visible.length });
  } catch (error) {
    res.status(500).json({ error: "Failed to load evaluation logs", message: error.message });
  }
};

/** Teacher view: all students, filterable by subject and department. */
export const getAllEvaluations = async (req, res) => {
  try {
    const { logs, degraded, indexHint } = await getEvaluationsForTeacher({
      limit: Number(req.query.limit || 100),
      subject: req.query.subject || null,
      department: req.query.department || null,
    });

    res.json({
      logs,
      count: logs.length,
      // Signals the results were sorted in memory because a composite index is missing.
      degraded: Boolean(degraded),
      ...(indexHint ? { indexHint } : {}),
    });
  } catch (error) {
    res.status(500).json({ error: "Failed to load evaluations", message: error.message });
  }
};

/** Teacher adjusts the scores on one evaluation. The model's original scores are kept. */
export const updateScores = async (req, res) => {
  try {
    const teacherUid = req.user?.uid;
    const profile = await getMyProfile({ userUid: teacherUid }).catch(() => null);

    const updated = await overrideScores({
      evaluationId: req.params.id,
      scores: req.body?.scores,
      reason: req.body?.reason,
      byUid: teacherUid,
      byName: profile?.fullName || "",
    });

    res.json({ message: "Scores updated", evaluation: updated });
  } catch (error) {
    const code = error.message === "Evaluation not found" ? 404 : 400;
    res.status(code).json({ error: "Failed to update scores", message: error.message });
  }
};