Online assessment platforms are usually built assuming the browser stays connected. It does not. Home wifi drops, mobile data hands over between towers, a laptop sleeps when a lid is half closed. During a two-hour exam with 400 students, this happens dozens of times.
Answers must be durable before they are complete
The failure that ends careers is a student answering thirty questions and losing them. Every answer change persists immediately — not on navigation, not on submit, not on a thirty-second autosave timer.
Write locally first, sync in the background:
attempt_answers
attempt_id, question_id
value
answered_at -- client clock
synced_at -- server clock
client_sequence -- monotonic per attempt
client_sequence is what resolves conflicts when a queued batch arrives out of order after a reconnect. Last-write-wins on server arrival time will silently restore an older answer.
The clock is server-side, always
Time remaining must never be computed from the client. A student whose machine sleeps for ten minutes has not gained ten minutes; a student who changes their system clock has not gained two hours.
Store started_at on the attempt server-side and derive remaining time from it on every sync. The client displays a countdown for the human, but it is a display, and the server enforces the deadline independently.
Disconnection is a state to be adjudicated
When a connection drops, the honest thing is to record it rather than guess:
attempt_events
attempt_id
kind -- connected | disconnected | tab_hidden
-- | reconnected | submitted
occurred_at
At the end, an invigilator sees a student had a six-minute gap and can decide whether to allow extra time. Silently extending is unfair to everyone else; silently terminating is unfair to the student. Recording it lets a human make the call with evidence.
Submission is idempotent
A student presses submit, the response is lost, they press again. Both requests arrive. Key the submission by attempt id with a unique constraint so the second is a no-op returning the same receipt.
Give them a receipt with a reference and a timestamp. It is the thing they screenshot, and it ends the disputes that otherwise arrive by email a week later.