A learner pauses a lesson at 8:42 on their phone. That evening, they open it on a laptop and have to start over. Another learner skips to the credits and gets a completion badge. Both problems can come from treating playback position and lesson completion as the same thing.
If you’re building a course platform in Laravel, give each of those jobs its own field and rule. You can start with a small progress record and make the completion rules stricter only where the course needs them.
Store the bookmark separately from completion
- Resume position: the point where the learner should pick up next. It can move backwards when the learner rewinds.
- Completion: a recorded decision that the learner met the requirement for this lesson. Replaying an earlier section shouldn’t undo it.
- Coverage: the portions of the video played, if the completion rule depends on them. Track this only when the course needs it.
A learner might watch the first eight minutes, then rewind to minute five to review a definition. Saving the furthest point would send them back to minute eight. Save their latest position as the bookmark. If you need watched coverage, record it separately so the rewind doesn’t erase it.

Open spiral notebook and pen on a scratched classroom desk beside an empty chair. Fictional AI-generated editorial image.
Fictional editorial image: an open notebook on a classroom desk.
Treat player events as signals
The HTML media events reference distinguishes updates to playback position, seeking, and reaching the end. With an embedded video player, use that provider’s documented events instead of assuming you can read the internal video element.
Save a checkpoint periodically during playback and when the learner pauses. For example, begin with a checkpoint every 15 seconds and tune it with real usage. If a tab closes before a final request arrives, the last acknowledged checkpoint still gives the learner somewhere useful to resume.
Choose the completion rule with the instructor. For a general lesson, a “Mark complete” button might be enough. If the requirement is to view most of a recording, measure the union of played intervals so replaying the same minute or jumping ahead doesn’t inflate the total. Player events can support that rule, but they don’t prove attention or understanding. If understanding matters, make a short quiz or exercise the deciding step.
Keep one progress record per enrollment and lesson
A useful starting record holds the enrollment ID, lesson ID, resume position in seconds, last accepted checkpoint marker, and a nullable completion timestamp. A compound unique index on enrollment ID and lesson ID keeps repeat saves from creating extra rows. Laravel documents compound indexes in migrations and upserts in Eloquent.
Look up the enrollment on the server using the signed-in learner, verify that the lesson belongs to that enrollment’s course, and validate the position against the known video duration. Keep the write limited to the fields that request should change: a bookmark save should never clear the completion timestamp.
A unique index prevents duplicate rows, but it doesn’t decide which update wins. Imagine a laptop checkpoint sent at 8:42 arrives after a newer phone checkpoint at 10:15. Decide how to handle competing sessions. One practical design gives each active playback session a server-issued marker and numbers checkpoints within that session. When the learner takes over on another device, reject delayed saves from the previous session. Apply the freshness check and update together so simultaneous requests can’t bypass the ordering rule.
Test what happens when people stop and come back
- Pause on one device and resume on another. Confirm the player starts from the last saved point once the video is ready.
- Seek forward and then rewind. Check that the bookmark follows the learner, but skipping ahead doesn’t satisfy a coverage requirement.
- Deliver the same checkpoint twice, then deliver an older one late. Confirm the bookmark and completion timestamp still make sense.
- Finish a lesson, reopen it, and rewatch the beginning. It should stay complete.
- Replace a recording with a shorter edit. Decide whether to clamp the bookmark or reset it for the new version, and what happens to existing completion records.
For an initial release, start with one resume bookmark, one explicit completion rule, and tests across two devices. That’s enough to tell you whether the workflow works before you build detailed playback analytics.
For a related example of a Laravel platform that organizes several workflows under one account, see my Maven Pro intranet project. If you’re building a course portal, I can help turn your completion rules into a progress model that learners and instructors can both understand.



