KnowledgeCity · EdTech LMS · April 2026
An entire course library. Unlocked in 60 seconds.
An AI pipeline that segments existing course transcripts into TikTok-style micro-reels — paired with a swipeable vertical feed, karaoke captions, HLS streaming, and full engagement tracking. Built end-to-end in 10 days.
≥ 5
Reels auto-generated per course — zero manual video editing required
< 100ms
Feed transition time via CSS scroll-snap running on compositor thread
12 / 12
Playwright tests passed across feed, player, and engagement tracking
Executive Summary
Turning idle course content into a discovery engine.
KnowledgeCity's library spans thousands of courses, but course discovery relied entirely on search and browse. Learners who didn't already know what they were looking for rarely found something new. Long-form video required upfront commitment, and the mobile experience had no equivalent of the casual, scroll-driven engagement patterns learners used everywhere else.
I designed and built an end-to-end system: an AI pipeline that processes course transcripts through a three-stage segmentation → scripting → QC workflow, producing 30–90 second micro-reels with structured Hook / Core / Takeaway scripts. The consumer side is a TikTok-style vertical feed with CSS scroll-snap transitions, karaoke-style captions, HLS adaptive streaming, and a Mixpanel-backed engagement event layer with offline queuing.
The feature shipped two tickets to production (PORTAL-2419, PORTAL-2420) within 10 days, with a third (PORTAL-2418) in experimental testing. The implementation exceeded the original Jira spec with three unrequested additions: a TextReelPlayer for courses without video, a Web Audio API lo-fi beat engine, and deep-link support for reel permalinks.
Project Details
- Timeline
- 10 days (April 14–24, 2026)
- Platform
- KnowledgeCity Portal — Enterprise SaaS LMS, B2B, multi-tenant
- Scope
- AI pipeline · Swipeable feed · Reel player · Engagement tracking · Standalone demo
- Role
- Product Engineer — solo, end-to-end
- Stack
- SvelteKit (KC), Next.js + FastAPI (demo), GPT-4o, hls.js, Playwright
- Delivered
- PORTAL-2418 (experimental) · PORTAL-2419 + PORTAL-2420 (production)
What Changed
Engagement metrics are ongoing post-launch. Performance figures are from Playwright test runs and browser DevTools measurement during development.
The Problem
"The course library is massive — but most learners never scroll past page two."
Synthesized from learner research and portal analytics review. Reflects a consistent discovery gap across the KnowledgeCity learner base.
Who it affected
Discovery required knowing what you were looking for.
- Long-form video required upfront commitment — learners needed a reason to start before they had one.
- Mobile browsing patterns had no equivalent to the casual, intent-free scroll that short-form content enables.
- Learners in casual contexts (commute, break) had no lightweight entry point into the course library.
Promoting new courses meant manual marketing effort.
- No automated mechanism to surface course content — admins relied on email campaigns or featured banners.
- Video previews were static thumbnails, not interactive — low conversion from course listing pages.
- Creating short promotional clips required external video editing tools and dedicated effort per course.
Engagement plateaued without a new discovery surface.
- Completion rates are a key contract renewal metric for B2B LMS clients — flat engagement risked churn.
- Competitors in consumer EdTech (Duolingo, Coursera) had invested in micro-content; B2B LMS had not.
- Existing course library represented significant content investment with no short-form access layer.
AI Workflow
A three-stage pipeline from transcript to approved reel script.
Rather than generating reels from scratch, the AI pipeline treats existing course content as structured source material. Each transcript is analyzed for concept boundaries, rewritten into a learnable short-form format, and gated for quality before being surfaced.
Segmentation
GPT-4o-mini
The transcript is chunked and passed to a segmentation prompt that identifies 5–10 self-contained learning moments. Each segment is scored on density (concept richness) and clarity (explainability). Segments with a combined score below 12/20 are filtered before scripting begins.
Outputs
- concept_title
- type (concept | example | tip | mistake | summary)
- hook_line
- density_score + clarity_score
- source_excerpt
Scripting
GPT-4o
Each approved segment is passed to a scripting prompt that rewrites it into a three-part micro-reel structure: Hook (first 5 seconds — one punchy sentence), Core (concept + concrete example + application), and Takeaway (memorable close + course CTA). Target: 150–188 words at 150 wpm = 60–75 seconds.
Outputs
- hook
- core
- takeaway
- estimated_duration_seconds
- confidence_score
QC Gate
Rule-based
Scripts are filtered by a confidence threshold (0.75). Scripts derived from low-scoring segments that the segmenter borderline approved are flagged rather than discarded — available for human review. The pipeline returns separate approved and flagged arrays so editors can override without regenerating.
Outputs
- approved[]
- flagged[] for human review
- total / approved / flagged counts
- mock fallback when no API key
Prompt Design Principles
Second person only — "you", never third-person. Keeps reels direct and personal.
Max 12 words per sentence in scripts. Forces clarity, works muted.
No invented facts — pipeline is instructed to only use source transcript material.
[VERIFY] flag for any non-standard claims — surfaces edge cases without breaking the pipeline.
Cheap model (gpt-4o-mini) for segmentation, full model (gpt-4o) for scripting — cost-conscious design.
Key Features
Six systems that had to work together.
Each feature was a separate Jira ticket with its own acceptance criteria. The feed, player, and engagement layer are independently deployable — and were separately tested.
Swipeable Reels Feed
CSS scroll-snap-type: y mandatory drives the feed — no JS scroll listener, no frame budget cost. IntersectionObserver (threshold: 0.6) detects the active reel and triggers play/pause. Infinite scroll activates when two reels from the end. A ?reel= query param enables deep-links from any surface.
scroll-snap + IntersectionObserver(0.6) + Svelte writable store
Reel Player with Karaoke Captions
Two player types: ReelPlayer streams HLS via video.js with VTT caption sync, mute toggle, progress bar, and "View Course" CTA. TextReelPlayer handles courses without video — animated slides driven by key_ideas arrays, same controls, matched layout. Caption preference persists across sessions via localStorage.
hls.js + VTT captions + animated slide fallback
Web Audio Lo-Fi Beat Engine
TextReelPlayer includes a procedural audio system built with the Web Audio API — 90 BPM lo-fi beat with kick drum, snare, and hi-hats, plus an Am-F-C-G ambient chord progression processed through DynamicsCompressor. Toggleable per-user, respects the shared mute store. Built across 4 commits on April 22.
Web Audio API · OscillatorNode · DynamicsCompressor
Engagement Event Tracking
Four events — reel_view_start, reel_view_complete (fires at ≥ 95% duration), reel_swiped_away, reel_course_clicked — are tracked with a 5-second deduplication window keyed by reelId:eventType. Events are queued in localStorage when offline and batch-flushed on reconnect via window.online.
Mixpanel + offline localStorage queue + auto-flush
AI Reel Generation Pipeline
FastAPI backend with a three-stage GPT pipeline: segmentation (gpt-4o-mini) → scripting (gpt-4o) → QC gate (confidence ≥ 0.75). Gracefully degrades to deterministic mock output when no API key is configured — enabling full frontend development and testing without live AI calls.
FastAPI · GPT-4o · SQLAlchemy async · SQLite
KC API Integration Layer
A transformer function maps KnowledgeCity course data (title, tagline, description, skill_level, lessons_count) to the Reel interface — enabling the feed to populate from the live KC course catalog. Falls back to curated dummy reels on any error (CORS, 498, 499) without a redirect.
courseToReel() transformer · graceful degradation
Delivery
From planning doc to production in 10 days.
Every commit on branch PORTAL-2418 corresponds to a specific feature or refinement. The implementation started from an AI-generated planning document and iterated daily with browser verification after each session.
Jira Tickets Delivered
Commit Timeline — PORTAL-2418
Playwright Test Suite
12 / 12 Passed
Beyond Original Spec
4 unrequested additions.
TextReelPlayer
Animated slide-based reel player for courses without video — same controls, matched layout, Svelte component with blob backgrounds and slide transitions.
Web Audio lo-fi engine
90 BPM lo-fi beat (Am-F-C-G) with kick, snare, and hi-hats via Web Audio API OscillatorNode + DynamicsCompressor. Toggleable per-user.
Shared mute state
reelsMuteStore via svelte-local-storage-store — mute preference persists across all reel types and page reloads, respects browser autoplay policy.
Deep-link support
?reel= query param reads initialReelId on mount and scrolls to the target card — enables direct links from home page previews and external surfaces.