Online exam systems almost always face two main enemies:
- Creative cheating behavior from test-takers
- Unreliable network conditions
Therefore, the exam system backend must be designed with a paranoid by design mindset:
- Never trust data from the client
- Assume the connection can drop at any time
- Ensure the system remains consistent even if partial failures occur
In this chapter, we will discuss the Academic Suite strategy in maintaining exam data integrity whilst minimizing opportunities for cheating.
6.1 Async Logging for Performance and Scalability
Most anti-cheating mechanisms are observational, such as detecting tab switching or loss of browser focus.
Every time a student switches tabs (e.g. using Alt + Tab), the frontend sends a FOCUS_LOST event to the backend.
The problem is, these events can occur massively and simultaneously.
Imagine:
- 1,000 students
- 1 exam
- Alt-tabbing at nearly the same time
If the backend processes this logging synchronously, the database can become a bottleneck and slow down main requests.
Solution: Asynchronous Logging with Goroutines
Academic Suite uses goroutines to record events in a fire-and-forget manner.
Implementation in handlers/log.go:
func LogEvent(eventType string, ...) {
go func() {
database.DB.Create(&log)
}()
}
With this approach:
- HTTP requests can be completed immediately
- Logging does not hinder main system performance
- The system remains responsive even if there is a surge in events
This approach is highly effective for non-critical data that serves as an audit trail.
6.2 Answer Integrity (Autosave & Idempotency)
A question that almost always arises from students is:
"If the internet goes down, will my answers be lost?"
Academic Suite addresses this concern with two main mechanisms.
Autosave per Question
Every time a student selects or changes an answer:
- The frontend sends a request to the backend immediately
- The
/api/attempts/:id/answersendpoint saves the change
In this way, every answer is saved almost in real-time.
Idempotency
Slow or unstable connections can cause:
- Requests to be sent repeatedly
- Buttons to be clicked multiple times
The backend must ensure that this condition does not cause data duplication.
Idempotency implementation is done with an upsert pattern:
// handlers/attempt.go
if err := database.DB
.Where("attempt_id = ? AND question_id = ?", ...)
.First(&existing); err == nil {
existing.SelectedOptionID = newValue
database.DB.Save(&existing)
}
With this approach:
- Only the latest answer is saved
- Data remains consistent even if requests are sent repeatedly
6.3 Force Submit as Fail-Safe Mechanism
The worst-case scenario in an online exam is:
- Exam time runs out
- Student's browser crashes or closes
- Submit request is never sent
Without additional mechanisms, the student's attempt can remain stuck in Active status forever.
Solution: Force Submit
Academic Suite provides a special endpoint for teachers:
POST /api/attempts/:id/force-submit
This endpoint will:
- Retrieve all saved answers
- Calculate the score based on that data
- Change the attempt status to
Submitted
Thus:
- No attempt is stuck in an invalid status
- Teachers have full control over exam completion
- The system remains consistent even if client-side failure occurs
6.4 Client Action Restrictions (Disable Right Click & Copy)
As an additional anti-cheating layer, Academic Suite also restricts several client-side actions during the exam, such as:
- Right Click
- Copy text (Ctrl+C / Cmd+C)
- Select text in the question area
The goal is not for absolute security, but to:
- Reduce casual cheating
- Increase friction for participants intending to copy questions
- Support behavior-based monitoring
Frontend Implementation
This restriction is applied only when exam status is active, and is automatically removed after the exam finishes.
Example implementation in React:
useEffect(() => {
const prevent = (e: Event) => e.preventDefault()
document.addEventListener('contextmenu', prevent)
document.addEventListener('copy', prevent)
return () => {
document.removeEventListener('contextmenu', prevent)
document.removeEventListener('copy', prevent)
}
}, [])
Important Note
- These restrictions are easy to bypass by experienced users
- Therefore, this feature does not stand alone
-
Its main value is as an additional layer (defense in depth) combined with:
- Behavior logging
- Server-side authority
- Post-exam analysis
This approach aligns with modern exam system principles: make cheating difficult, don't claim it's impossible.
Chapter Summary
In this chapter, we close the entire discussion of the Academic Suite backend with a focus on system resilience.
We discussed:
- Asynchronous logging for performance
- Autosave and idempotency for answer integrity
- Fail-safe mechanisms through force submit
With this approach, the exam system becomes:
- Secure
- Resilient to network disruptions
- Difficult to manipulate
In the next section, we will switch to frontend implementation and start building the user interface.
Part 3 begins with Chapter 7: React Application Architecture.
Top comments (0)