Session log — 23 April 2026

← All sections

Session log — 23 April 2026

Activity funnel for MobiLearn CPD, plus a wifi course on s2l.online · Hasmukh with Claude · long working session.

Late morning

1. Project handover from Kenn

You introduced MobiLearn CPD: a personalised UCT continuing-professional-development platform for South African primary-care doctors. Two sites on the same VPS — cpd.medilearn.africa for the public product, documentation.mobilearn.africa for the internal docs.

The product flow is simple to describe and unusual in execution: a doctor takes a short conversational interview led by Claude, the system extracts a structured profile, and a personalised learning pathway built from the 211-hour UCT lecture library is rendered on the next page.

You asked me toread the documentation, confirm I could reach the server, summarise the platform in five bullets, and propose what to work on first.
Late morning

2. Reading the docs and confirming server access

I read all eight pages on the documentation site and SSH worked first time as root. I gave you a five-bullet summary covering: what is live (homepage, AI interview, personalised pathway, video modal, hand-curated pathways, course viewer); the content engine (300 UCT videos, 211 hours, 28 specialties, all whitelisted); the custom plugins (ep-courses ported from s2l, ep-cpd-brand, ep-cpd-home, ep-cpd-interview); the partnership status (informal, with branding, revenue share, MOU and attribution still open); and the biggest gap (pathway is ephemeral per session, no return visits, no certificates, no monetisation hook).

Late morning

3. Choosing what to work on first

I proposed making the pathway persistent as the highest-leverage move because it unblocks three of the five “Next up” items at once. You picked something else from the same list: the activity dashboard, with a clear constraint — port the pattern from s2l's ep-courses without touching s2l itself.

Midday

4. Surveying the s2l pattern and the CPD starting state

I read the s2l copy of the ep-courses plugin to understand what “the pattern” actually was. Findings:

  • The s2l and CPD copies of ep-courses are byte-identical. So “porting” did not mean copying code — the dashboard renderer was already inside the plugin on CPD too.
  • The plugin already had an Activity tab inside the EP Courses admin, with totals, per-course breakdown, recent events and a date range filter.
  • It read from a pm_ep_events table that existed on CPD with 38 rows, all of them generic landing-page hits. None of the actual CPD product flow — interview, pathway, video plays — was being captured.

So the ep-courses Activity tab existed on CPD but was effectively empty for the parts of the product that mattered. “Porting the pattern” really meant wiring CPD's flow into the events table and surfacing it in a way that told the product story, not the engineering one.

Midday

5. Two-option proposal, fuller version chosen

I gave you a fork:

  1. Minimal port (2–3 hours) — wire CPD's events into the existing Activity tab. Cheapest signal.
  2. Fuller port (half a day) — same events, plus a new “CPD Activity” panel showing the funnel as a stakeholder would want to see it: visits to interviews started to interviews completed to pathway loads to video plays.
You choseOption 2, with reasoning that the interview-to-pathway flow IS the product story, and without a funnel view stakeholders (UCT, funders) have nothing to react to. You added specific requirements: six funnel stages, specialty distribution from completed profiles, top videos by Vimeo ID grouped by specialty, the same date range filter as the existing tab. Match the brand. Document each meaningful decision in /decisions-log/. When done, move the item from Stub to Live on /overview/.
Afternoon

6. The build itself

Event logging

Five event types now flow into pm_ep_events from real CPD traffic:

  • home_view — landing page render
  • interview_start — new interview session created
  • interview_complete — profile extracted from the conversation
  • pathway_view — completed-interview pathway page loaded
  • pathway_video_play — Vimeo modal opened on the pathway page (fired from the browser)

Each is hooked at the trigger point inside the relevant plugin (ep-cpd-home for the landing, ep-cpd-interview for the rest). All event writes are wrapped to fail silently so a logging hiccup can never block a user.

Schema additions

The shared events table got two new columns — session_id for grouping by interview session, and meta for free-form labels (currently used to hold the Vimeo ID on play events). Added via a defensive column-check ALTER, additive only, so it does not affect any other plugin reading the table.

Admin panel

The funnel renders as a new admin group on the EP CPD Interview plugin: a date range pill row at the top, six funnel stages with peak-relative bars and percent-of-previous-stage labels, a specialty distribution panel pulled from the JSON profiles of completed interviews, and a top-watched-videos table joining play events against the inventory taxonomy for titles. Brand-matched: Fraunces for headings, Inter for body, deep-teal bars with coral accent for the specialty list.

Pathway video tracking

The existing pathway.js file was extended to fire a small POST to a public, allow-listed tracking endpoint each time the Vimeo modal opens. The session id is carried via a data attribute on the modal element so plays can be grouped against their originating interview.

Afternoon

7. Deploy and smoke test on cpd.medilearn.africa

Files were staged locally, lint-checked, then deployed via SCP with timestamped backups of every file touched. End-to-end verification on live traffic produced rows for every new event type:

  • Hit the homepage — home_view recorded.
  • Started a real interview — interview_start recorded with session id.
  • Loaded an existing completed-interview pathway — pathway_view recorded.
  • Posted a synthetic video play — pathway_video_play recorded with vimeo id in the meta column.
  • Disallowed event type rejected as expected.
ResultFunnel events flowing on real traffic. Test rows then cleaned up so the live data starts at zero.
Late afternoon

8. Documenting the work

Three new entries added to the top of /decisions-log/ capturing the meaningful design choices:

  • Why a CPD-specific funnel panel rather than reusing the generic ep-courses Activity tab.
  • Why event logging was duplicated inline in the CPD plugins rather than promoting log_event on ep-courses to public — keeps that shared plugin in lock-step with its s2l twin.
  • Why pm_ep_events got two new columns instead of overloading course_slug and lesson_sort with CPD-specific meanings.

The /overview/ page was updated: the activity dashboard line moved from “Next up (Stub)” to “Live and working”, with the panel's actual location and the full feature list.

Evening

9. Reference guide and sidebar update

You asked me to capture the build properly so we could come back to it later. I created a comprehensive page at /activity-funnel/ covering: what the panel measures (each of the six stages, plus the two side panels); every file involved with its full path and purpose; the schema additions and the rationale; each event type, where it fires, what it carries; how the admin panel is wired end-to-end; smoke-test SQL anyone can run to verify events are flowing; three extension recipes (adding a new event type, adding a funnel stage, adding a side metric); full rollback instructions with the actual backup timestamps from the day's deploy; and an endpoints reference table for both the public tracker and the admin data endpoint.

Added an “Activity Funnel” entry to the docs site sidebar so the page is discoverable, sitting between Runbooks and Architecture.

Evening

10. A rule we agreed for future doc additions

You flagged that I had added the new doc page and updated /overview/ for the feature, but had forgotten to mention the new doc page itself on /overview/. From now on: any new page added to documentation.mobilearn.africa must also be reflected on /overview/ in the same session. Saved as a durable rule so future sessions honour it.

To close the loop on the same gap, I added a “Reference guides” subsection to /overview/ linking the new Activity Funnel page.

Late evening

11. Context switch to s2l.online: wifi course built and added to home

With the MobiLearn CPD work documented, you switched contexts to s2l.online and asked for a digital literacy course explaining wifi and the internet at home, aimed at someone brand new to wifi, using video lessons from the Vimeo library.

Picking the videos

I queried your Vimeo account, found roughly twenty candidates, and proposed six that tell a beginner the full story in 18 minutes total:

  1. The Internet (4 min) — what the internet is
  2. FTTH What Is Wi-Fi (3.2 min) — what wifi is
  3. Connecting Your Home To The Internet (4.1 min) — how the internet reaches the home
  4. Where Should You Put Your Wi-Fi Router? (2.4 min) — router placement
  5. How To Connect To WiFi (1 min) — getting a phone or laptop online
  6. Troubleshooting your home WiFi (3.7 min) — when something goes wrong

You confirmed the picks and told me to ship.

The build

  • Course created as “Wifi and the Internet at Home”, free, six lessons in the order above, total 18 minutes.
  • Each video authorised for embedding on s2l.online via the Vimeo API in the same script that did the build.
  • Landing page created at /wifi-and-internet-at-home/ using the existing course-landing shortcode pattern.

Home page card swap

Your s2l home page has a hardcoded set of six course cards. The original six were placeholders without real video content behind them. You asked me to swap one out for the new wifi course. I replaced the “What is the 4th Industrial Revolution?” card (the most abstract of the six) with a “Wifi and the Internet at Home” card linking to the new landing. The original course record was kept in the database in case you want it back later, just hidden from the home page. A timestamped backup of the home page block was kept on the server.

ResultThe new course is the first card on s2l.online and the only home page card that actually plays a video when a learner opens it.