Skip to content

[Bug]addAttendance allows duplicate attendance entries for the same student, inflating attendance counts #110

Description

@OmanshiRaj

Description

addAttendance(lectureId, studentId) in src/utils/storage.js (line 203) unconditionally pushes a new { studentId, timestamp } entry into the session's attendance array every time it's called — there is no check for whether that studentId has already been recorded for the lecture. It's called from StudentFeedback.jsx inside the "join lecture" button handler (line 314), with no guard against being triggered more than once for the same student (e.g. double-click, page refresh and re-join, or browser back/forward into the join screen again).

Steps to Reproduce

  1. Go to: a student feedback link for an active lecture (/feedback/:code or similar).
  2. Enter a name/roll/studentId and click the join/continue button that triggers addAttendance.
  3. Navigate back (browser back button) to the join screen, or refresh and re-join with the same generated studentId (persisted via getOrCreateStudentId in localStorage).
  4. Click join again.
  5. Check the lecture's attendance count on the Dashboard/Analytics page.

Expected Outcome

A student is counted once in attendance for a given lecture, regardless of how many times they pass through the join flow.

Actual Outcome

Each join click appends a new attendance record for the same studentId, so the same student is counted multiple times, inflating attendance totals and skewing any analytics built on top of getAttendance().

Expected Behavior

addAttendance should check whether studentId is already present in the lecture's attendance array and skip the push (or update the existing entry's timestamp) if so — mirroring the existing duplicate-prevention pattern already used for feedback via hasStudentSubmitted.

Actual Behavior

No deduplication exists; every call is an unconditional push.

Screenshots

N/A — this is a data-integrity bug, not a visual one. Reproducible by inspecting lecturePulse_sessions in DevTools → Application → Local Storage before and after a repeat join.

Environment

  • Browser: Any (Chrome 125, Firefox 127, Safari)
  • OS: Cross-platform
  • Node.js version: 20.x

Affected Page / Component

  • Landing
  • Login
  • Dashboard
  • Student Feedback
  • Analytics (attendance counts derived from this data)
  • Other: src/utils/storage.jsaddAttendance()

Additional Context

Suggested fix, mirroring the existing hasStudentSubmitted pattern:
```js
export const addAttendance = (lectureId, studentId) => {
try {
const allSessions = JSON.parse(localStorage.getItem("lecturePulse_sessions") || "[]");
const updatedSessions = allSessions.map(s => {
if (s.id === lectureId) {
const attendance = s.attendance ? [...s.attendance] : [];
const alreadyPresent = attendance.some(a => a.studentId === studentId);
if (!alreadyPresent) {
attendance.push({ studentId, timestamp: new Date().toISOString() });
}
return { ...s, attendance };
}
return s;
});
localStorage.setItem("lecturePulse_sessions", JSON.stringify(updatedSessions));
} catch (error) {
console.error("Error adding attendance", error);
}
};
```
Note: studentId can be null for fully anonymous joins (entry.studentId: attendeeStudentId.trim() || null in StudentFeedback.jsx), so the fix should also decide whether multiple null/anonymous entries are intentional (likely yes) versus named/roll-identified students (should be deduplicated).

/assign

Metadata

Metadata

Assignees

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions