Case study · Qingban youth STEM platform
Fifty-nine lessons, and a record of who finished
Qingban is a free STEM platform for left-behind children and the children of migrant workers: four course tracks, 59 recorded lessons, no fee, and no account needed just to watch. The videos were not the slow part. Making the word finished mean something a parent, a teacher or a funder could check was the slow part.
01A video goes up, then what
For a child in a county town with no coding class and no one at home who writes code, a recorded lesson is already a real improvement. The gap this platform is aimed at is not enthusiasm. It is the next question, which arrives immediately: is anyone actually getting through the material, or are the videos being opened and closed?
A view count cannot answer that. Autoplay counts. Dragging the scrubber to the end counts. Opening a lesson and closing it ten seconds later counts. On its own, the number tells an operator that the page works, and it tells a parent nothing.
02What I did not build
- No app. A URL works on a phone browser, and asking a family to install something is a step where people drop out. The site is responsive from 320px up.
- No framework of my own. This runs as secondary development on PbootCMS 3.2.16, and the reason is administrative rather than technical: the people who publish courses need to add a column, swap a cover and post an activity notice without calling me.
- No recommendations and no leaderboard. What a thirteen-year-old studies next should not be decided by a model trained on other people’s children, and a public ranking mostly tells the kids with the least support where they stand.
- No payment entry of any kind. Once a charity site accepts money, it also owes an audit trail, and that is a different project with a different team.
03Defining "finished"
Progress is recorded from the video element itself, not from a button the student presses. While a lesson plays, the player reports its current position every ten seconds; the last position is kept so that reopening the page resumes where the student stopped. This runs on a separate table rather than the CMS content tables, because progress writes are frequent and the content tables are read on every page.
p = 0 or no row → not started
0 < p < 95 → in progress
p ≥ 95 → completed
The 95% line is a compromise, not a measurement of learning. Five percent is left at the end so that a student who stops during the credits is not stuck one second short of a certificate. The certificate number encodes what happened rather than who deserves it: CERT, the completion date, the four-digit course id, the six-digit user id. Printed from the browser with a stylesheet that drops the navigation, it fits on one sheet of A4.
What the rule actually proves: the playhead reached 95% of the video. It does not prove the student understood the lesson, and there is no quiz on this platform that would.
04Two languages means two column trees
Chinese and English are not a translation layer here. Each language owns its own columns and its own entries: 40 columns in total, 20 per language, holding 152 entries at 76 each. Switching language swaps the labels through a cookie plus a CSS class, and fifteen templates carry both wordings. The hreflang tags point Chinese, English and a default at the same page so a search engine indexes them as alternates.
05The constraints were the project
Most of what shaped this build came from the hosting arrangement rather than from the design. One server, no cluster, and a CMS whose URL mode could not be changed without breaking links that had already been shared.
- Compatibility URL mode. The CMS runs with url_rule_type=3, and in that mode the web server will not pass a POST to a dynamic URL. Every progress report, therefore, is a GET with its parameters in the query string.
- An empty language field breaks the menu. If the language code on a column is blanked, the navigation disappears in whole blocks. That column has to keep its value even when the site is being reorganised.
- Caches can be emptied but not removed. Compiled templates and cached pages live in two directories that must keep existing; deleting the directories themselves takes the site down until they are recreated by hand.
- Backups need a file extension the web server refuses to serve. Database dumps and archives carry a download-only suffix, because the server is configured to block direct requests for .sql and .tar.gz.
- File permissions were off limits. Permissions on existing files and directories could not be changed, which rules out several of the usual shortcuts and means any new code has to fit the layout that was already there.
06What it runs on
Nginx in front, PHP 8.2 behind it, MySQL on the same machine. The firewall opens four ports and nothing else. Intrusion blocking bans an address for half an hour after five failed logins. The database listens on loopback only and the application connects with its own user, so a leaked credential does not open the whole server. Certificates renew themselves, and a monitoring check warns when renewal is within thirty days of failing.
07What this does not show
- There is no learning-outcome data. Completion rate is the only measure the platform has, and completion is where the playhead stopped.
- No load test has been run. One server serves the whole thing, and video bandwidth will be the first limit to arrive, well before CPU is.
- The certificate records attendance, not understanding. Anyone reading it as a qualification is reading it wrong, and the page that issues it does not claim otherwise.
- Next: move the videos to object storage behind a CDN, encode a lower-resolution version for weak connections, and add referrer checks so the lessons cannot be hotlinked into someone else’s site.
A view count is for the operator. A completion record is for the child and the family. Keeping those two numbers apart is what made the rest of the design decisions easy.
The platform is not trying to be clever. It is trying to be checkable, and checkable turns out to cost more code than publishing does: a table, a timer, a state rule, a certificate number, and a print stylesheet. That is the part I would defend in a review.