[Epic] Playground uniformity & lesson content layers (C / C++ / JavaScript / Python / C#) #323

Closed
opened 2026-07-02 00:49:40 +00:00 by spikerj · 5 comments
Owner

Goal

Identical learning chrome across the five core language playgrounds — C, C++, JavaScript, Python, C# — so students transition concept-to-concept and language-to-language without relearning the UI, plus three new lesson content layers (books, SpikerSoft text, videos) that every playground inherits at once through the shared shell.

Current state (verified in code)

  • The rich "subheader" shell is already shared. C#, C, C++, and Python all render LanguagePlaygroundShellComponent (libraries/platform/clang-runtime/src/lib/language-playground-shell.component.html): File/View/Mode/Options/Lessons/Help menus, lesson/sandbox toggle, beginner/advanced sandbox toggle, status chips (connection, local/server/offline, standard, runtime, running, submission, execution time), guided tour, curriculum pane with lesson sidebar, resizable/swappable panes, and right-pane tabs (Concepts / Submissions / Results).
  • JavaScript is the outlier: libraries/features/dev-tools-javascript-runner/src/lib/javascript-runner.ts wraps the older app-language-runner directly, with its own debugger toolbar and a separate submission-history pane — no shell, no concept pane, no lessons menu chrome.
  • Books / text / videos do not exist in the lesson model. TutorialPanel (libraries/shared/lesson-platform/src/lib/lesson-types.ts) carries only heading/body/code; backend SpikerSoft.Data/Mongos/Lesson.cs has no reading/media fields. These are new content layers, not parity gaps — landing them in the shared shell gives them to all five languages simultaneously.

Phases

Phase Scope
P1 Migrate JavaScript playground onto the shared shell
P2 Shell parity audit: C / C++ / Python vs C# small-gap sweep
P3 Books layer — curated external book links per subject/section
P4 Text layer — SpikerSoft's own authored prose per section
P5 Videos layer — official per-lesson + student-submitted/staff-approved per lesson block
Spike Completion-ratio anonymous unlocks (contribute → see more; account → everything)
Spike Duolingo-style optional progression visualization (menu-launched, sounds, younger audience)

Sub-issues are linked in a comment below as they are filed.

## Goal Identical learning chrome across the five core language playgrounds — C, C++, JavaScript, Python, C# — so students transition concept-to-concept and language-to-language without relearning the UI, plus three new lesson content layers (books, SpikerSoft text, videos) that every playground inherits at once through the shared shell. ## Current state (verified in code) - **The rich "subheader" shell is already shared.** C#, C, C++, and Python all render `LanguagePlaygroundShellComponent` (`libraries/platform/clang-runtime/src/lib/language-playground-shell.component.html`): File/View/Mode/Options/Lessons/Help menus, lesson/sandbox toggle, beginner/advanced sandbox toggle, status chips (connection, local/server/offline, standard, runtime, running, submission, execution time), guided tour, curriculum pane with lesson sidebar, resizable/swappable panes, and right-pane tabs (Concepts / Submissions / Results). - **JavaScript is the outlier**: `libraries/features/dev-tools-javascript-runner/src/lib/javascript-runner.ts` wraps the older `app-language-runner` directly, with its own debugger toolbar and a separate submission-history pane — no shell, no concept pane, no lessons menu chrome. - **Books / text / videos do not exist in the lesson model.** `TutorialPanel` (`libraries/shared/lesson-platform/src/lib/lesson-types.ts`) carries only heading/body/code; backend `SpikerSoft.Data/Mongos/Lesson.cs` has no reading/media fields. These are new content layers, not parity gaps — landing them in the shared shell gives them to all five languages simultaneously. ## Phases | Phase | Scope | |---|---| | P1 | Migrate JavaScript playground onto the shared shell | | P2 | Shell parity audit: C / C++ / Python vs C# small-gap sweep | | P3 | Books layer — curated external book links per subject/section | | P4 | Text layer — SpikerSoft's own authored prose per section | | P5 | Videos layer — official per-lesson + student-submitted/staff-approved per lesson block | | Spike | Completion-ratio anonymous unlocks (contribute → see more; account → everything) | | Spike | Duolingo-style optional progression visualization (menu-launched, sounds, younger audience) | Sub-issues are linked in a comment below as they are filed.
spikerj added the enhancement label 2026-07-02 00:49:40 +00:00
Author
Owner

Sub-issues + status

Phase Issue Status
P1 JavaScript → shared shell #324 Not started
P2 C/C++/Python parity audit vs C# #325 Not started
P3 Books layer #326 Not started
P4 Text layer (SpikerSoft's own book) #327 Not started
P5 Videos layer (official + community/approved) #328 Not started (largest — may split)
Spike: completion-ratio anonymous unlocks #329 Not started
Spike: Duolingo-style progression visualization #330 Not started

Suggested order

  1. P1 (#324) first — everything after it lands in the shared shell, so JS must be on the shell before the content layers ship or JS students miss them.
  2. P2 (#325) in parallel or immediately after — small-gap sweep, low risk.
  3. P3 (#326) → P4 (#327) share the shell's new Reading surface; design it once in P3.
  4. P5 (#328) after the moderation/media-pipeline decisions; expect sub-tickets.
  5. Spikes #329/#330 are independent of each other and can run anytime; #330's design should account for #329's lock states, and #329's recommendation on whether books/text/videos join the ratio feeds back into P3–P5.

Decisions locked in at filing

  • Anonymous unlock currency = lesson/exercise completions (not submissions or engagement signals).
  • Account creation = everything unlocked; the ratio is an on-ramp for the anonymous, never a paywall for members.
  • The progression visualization is opt-in from the menu — the default lesson flow is untouched.
## Sub-issues + status | Phase | Issue | Status | |---|---|---| | P1 JavaScript → shared shell | #324 | Not started | | P2 C/C++/Python parity audit vs C# | #325 | Not started | | P3 Books layer | #326 | Not started | | P4 Text layer (SpikerSoft's own book) | #327 | Not started | | P5 Videos layer (official + community/approved) | #328 | Not started (largest — may split) | | Spike: completion-ratio anonymous unlocks | #329 | Not started | | Spike: Duolingo-style progression visualization | #330 | Not started | ## Suggested order 1. **P1 (#324)** first — everything after it lands in the shared shell, so JS must be on the shell before the content layers ship or JS students miss them. 2. **P2 (#325)** in parallel or immediately after — small-gap sweep, low risk. 3. **P3 (#326) → P4 (#327)** share the shell's new Reading surface; design it once in P3. 4. **P5 (#328)** after the moderation/media-pipeline decisions; expect sub-tickets. 5. Spikes **#329**/**#330** are independent of each other and can run anytime; #330's design should account for #329's lock states, and #329's recommendation on whether books/text/videos join the ratio feeds back into P3–P5. ## Decisions locked in at filing - Anonymous unlock currency = **lesson/exercise completions** (not submissions or engagement signals). - Account creation = **everything unlocked**; the ratio is an on-ramp for the anonymous, never a paywall for members. - The progression visualization is **opt-in from the menu** — the default lesson flow is untouched.
Author
Owner

Status refresh (the earlier table was stale)

Actual merged state on master:

Phase Issue Status
P1 JavaScript → shared shell #324 Merged (angular PR #94)
P2 C/C++/Python parity + tour vs C# #325 Merged (angular PR #95)
P3 Books layer #326 Merged (backend PR #53, angular PR #96) — closed
P4 Text layer (our own book) #327 Merged (backend PR #54, angular PR #97) — closed
P5 Videos layer #328 Not started — only remaining phase
Spike: ratio unlocks #329 Delivered → #331 (backend PR #56) + #332 (angular PRs #99/#100) — closed
Spike: My Journey viz #330 Delivered → #333 (angular PR #98) + #334 (backend PR #55) — closed

The shared Reading surface (right-pane tab) shipped with P3 and is reused by P4, so P5 Videos plugs into the same shell surface. P5 (#328) is now the only open phase of this epic.

## Status refresh (the earlier table was stale) Actual merged state on `master`: | Phase | Issue | Status | |---|---|---| | P1 JavaScript → shared shell | #324 | ✅ Merged (angular PR #94) | | P2 C/C++/Python parity + tour vs C# | #325 | ✅ Merged (angular PR #95) | | P3 Books layer | #326 | ✅ Merged (backend PR #53, angular PR #96) — closed | | P4 Text layer (our own book) | #327 | ✅ Merged (backend PR #54, angular PR #97) — closed | | P5 Videos layer | #328 | ⬜ **Not started — only remaining phase** | | Spike: ratio unlocks | #329 | ✅ Delivered → #331 (backend PR #56) + #332 (angular PRs #99/#100) — closed | | Spike: My Journey viz | #330 | ✅ Delivered → #333 (angular PR #98) + #334 (backend PR #55) — closed | The shared **Reading** surface (right-pane tab) shipped with P3 and is reused by P4, so P5 Videos plugs into the same shell surface. **P5 (#328) is now the only open phase of this epic.**
Author
Owner

Status update — P5 Videos (#328)

Three of the four P5 sub-tickets are merged and closed:

  • #336 P5a backend foundation — merged (spikersoft-backend #57)
  • #338 P5c admin moderation queue — merged (spikersoft-angular #101)
  • #339 P5d playground Videos tab + submit — merged (spikersoft-angular #102)

End-to-end today: staff/admins can moderate community videos; all five playgrounds show approved official + community videos grouped by block; logged-in users can submit a video (URL + metadata) that lands Pending for review; anonymous users never see unapproved content.

Remaining: #337 P5b media pipeline (upload → ClamAV scan → ffmpeg transcode to MP4 + poster → move-to-final → static serving), which upgrades the submit flow from URL-based to file-upload. Architecture + storage/format decisions are recorded on #337 (local SERVER fusionio bind-mount, ffmpeg→MP4, mirror BlogMediaProcessor); implementation is the last step to fully close the epic.

### Status update — P5 Videos (#328) Three of the four P5 sub-tickets are merged and closed: - **#336** P5a backend foundation — merged (spikersoft-backend #57) - **#338** P5c admin moderation queue — merged (spikersoft-angular #101) - **#339** P5d playground Videos tab + submit — merged (spikersoft-angular #102) End-to-end today: staff/admins can moderate community videos; all five playgrounds show approved official + community videos grouped by block; logged-in users can submit a video (URL + metadata) that lands Pending for review; anonymous users never see unapproved content. **Remaining:** **#337** P5b media pipeline (upload → ClamAV scan → ffmpeg transcode to MP4 + poster → move-to-final → static serving), which upgrades the submit flow from URL-based to file-upload. Architecture + storage/format decisions are recorded on #337 (local `SERVER` fusionio bind-mount, ffmpeg→MP4, mirror `BlogMediaProcessor`); implementation is the last step to fully close the epic.
Author
Owner

P5 (Videos layer, #328) complete and closed — with it, all five core phases are done:

Phase Status
P1 — JavaScript onto shared shell done
P2 — shell parity audit (C/C++/Python vs C#) done
P3 — Books layer (#326) done
P4 — Text layer (#327) done
P5 — Videos layer (#328: #336/#337/#338/#339) done
Spike — completion-ratio anonymous unlocks (#332) done
Spike — Duolingo-style optional progression viz not started (optional/exploratory)

The uniformity goal and all three new content layers (books, text, videos) now ship to all five playgrounds through the shared shell. The only remaining item is the optional Duolingo-style progression-visualization spike — leaving this epic open to track that; it can be closed if that spike is out of scope.

Optional follow-up carried from P5: swap the playground video-submit flow from URL entry to the in-browser file upload (POST /api/Lessons/{n}/videos/upload) now that the media pipeline exists.

**P5 (Videos layer, #328) complete and closed** — with it, all five core phases are done: | Phase | Status | |---|---| | P1 — JavaScript onto shared shell | ✅ done | | P2 — shell parity audit (C/C++/Python vs C#) | ✅ done | | P3 — Books layer (#326) | ✅ done | | P4 — Text layer (#327) | ✅ done | | P5 — Videos layer (#328: #336/#337/#338/#339) | ✅ done | | Spike — completion-ratio anonymous unlocks (#332) | ✅ done | | Spike — Duolingo-style optional progression viz | ⚪ not started (optional/exploratory) | The uniformity goal and all three new content layers (books, text, videos) now ship to all five playgrounds through the shared shell. The only remaining item is the optional Duolingo-style progression-visualization spike — leaving this epic open to track that; it can be closed if that spike is out of scope. **Optional follow-up carried from P5:** swap the playground video-submit flow from URL entry to the in-browser file upload (`POST /api/Lessons/{n}/videos/upload`) now that the media pipeline exists.
Author
Owner

Epic complete — closing

Correcting the previous comment: the Duolingo-style progression-visualization spike (#330) was not "not started" — it was delivered and closed earlier the same day. The "not started" line was a stale regression that contradicted the 15:07 refresh and the actual master code.

Final, verified state on master:

Phase Issue(s) Status
P1 — JavaScript onto shared shell #324 done (angular #94)
P2 — shell parity audit (C/C++/Python vs C#) #325 done (angular #95)
P3 — Books layer #326 done (backend #53, angular #96)
P4 — Text layer #327 done (backend #54, angular #97)
P5 — Videos layer #328 (#336/#337/#338/#339) done (backend #57/#58, angular #101/#102, infra #4)
Spike — completion-ratio anonymous unlocks #329 → #331/#332 done
Spike — Duolingo-style progression viz #330 → #333/#334 done (angular #98, backend #55)

The Duolingo spike shipped as feature-my-journey: menu-launched Learn ▸ My Journey (/my-journey), a per-language winding trail with completed/current/available/locked-prereq/locked-horizon node states (buildTrail), opt-in synthesized JourneyAudioService (no assets/CDN), and the repo's first reduced-motion pref (JourneyPrefsService), backed by the anonymous-friendly GET /api/Lessons/journey aggregation.

Optional P5 follow-up also landed: the playground video-submit flow now supports in-browser file upload (POST /api/Lessons/{n}/videos/upload) alongside URL entry — angular #103.

The uniformity goal and all three content layers (books, text, videos) ship to all five playgrounds through the shared shell, and both spikes are delivered. Nothing outstanding — closing the epic.

## Epic complete — closing Correcting the previous comment: the **Duolingo-style progression-visualization spike (#330) was not "not started"** — it was delivered and closed earlier the same day. The "not started" line was a stale regression that contradicted the 15:07 refresh and the actual `master` code. Final, verified state on `master`: | Phase | Issue(s) | Status | |---|---|---| | P1 — JavaScript onto shared shell | #324 | ✅ done (angular #94) | | P2 — shell parity audit (C/C++/Python vs C#) | #325 | ✅ done (angular #95) | | P3 — Books layer | #326 | ✅ done (backend #53, angular #96) | | P4 — Text layer | #327 | ✅ done (backend #54, angular #97) | | P5 — Videos layer | #328 (#336/#337/#338/#339) | ✅ done (backend #57/#58, angular #101/#102, infra #4) | | Spike — completion-ratio anonymous unlocks | #329 → #331/#332 | ✅ done | | Spike — Duolingo-style progression viz | #330 → #333/#334 | ✅ done (angular #98, backend #55) | The Duolingo spike shipped as `feature-my-journey`: menu-launched `Learn ▸ My Journey` (`/my-journey`), a per-language winding trail with completed/current/available/locked-prereq/locked-horizon node states (`buildTrail`), opt-in synthesized `JourneyAudioService` (no assets/CDN), and the repo's first reduced-motion pref (`JourneyPrefsService`), backed by the anonymous-friendly `GET /api/Lessons/journey` aggregation. **Optional P5 follow-up also landed:** the playground video-submit flow now supports in-browser file upload (`POST /api/Lessons/{n}/videos/upload`) alongside URL entry — angular #103. The uniformity goal and all three content layers (books, text, videos) ship to all five playgrounds through the shared shell, and both spikes are delivered. Nothing outstanding — closing the epic.
Sign in to join this conversation.