Phase P3 of epic #323. First of three new lesson content layers (books → text #TBD → videos #TBD); landing it in the shared shell gives it to all five core playgrounds at once.
What: curated links to books on the subject of the current lesson/section, surfaced in the playground so students always have a deeper-reading path.
Model (backend):
Add a Books collection to the lesson/section model — SpikerSoft.Data/Mongos/Lesson.cs (per lesson) with optional category/section-level defaults so one recommendation can cover a lesson range without duplication
Expose via the existing catalog endpoints (GET /api/Lessons, GET /api/Lessons/{id} in LessonsController — both already anonymous-readable)
Seed data for the C# curriculum first (most complete), then the other four
Model (frontend):
Extend LessonCatalogEntry/lesson detail DTOs in libraries/shared/lesson-platform/src/lib/lesson-types.ts
Render as a section of a new Reading tab/pane in LanguagePlaygroundShellComponent (design should anticipate P4's text layer sharing this surface)
External links open in a new tab with appropriate rel attributes; i18n for all chrome labels (Transloco, es review queue)
Acceptance: a lesson with book recommendations shows them in the shell in all five playgrounds; lessons without them render no empty chrome.
Phase P3 of epic #323. First of three new lesson content layers (books → text #TBD → videos #TBD); landing it in the shared shell gives it to all five core playgrounds at once.
**What:** curated links to books on the subject of the current lesson/section, surfaced in the playground so students always have a deeper-reading path.
**Model (backend):**
- [ ] Add a `Books` collection to the lesson/section model — `SpikerSoft.Data/Mongos/Lesson.cs` (per lesson) with optional category/section-level defaults so one recommendation can cover a lesson range without duplication
- [ ] Shape: title, author(s), url, edition/year, free-vs-paid flag, optional note on why it's recommended, optional per-`TutorialPanel` anchor
- [ ] Expose via the existing catalog endpoints (`GET /api/Lessons`, `GET /api/Lessons/{id}` in `LessonsController` — both already anonymous-readable)
- [ ] Seed data for the C# curriculum first (most complete), then the other four
**Model (frontend):**
- [ ] Extend `LessonCatalogEntry`/lesson detail DTOs in `libraries/shared/lesson-platform/src/lib/lesson-types.ts`
- [ ] Render as a section of a new **Reading** tab/pane in `LanguagePlaygroundShellComponent` (design should anticipate P4's text layer sharing this surface)
- [ ] External links open in a new tab with appropriate `rel` attributes; i18n for all chrome labels (Transloco, es review queue)
**Acceptance:** a lesson with book recommendations shows them in the shell in all five playgrounds; lessons without them render no empty chrome.
Backend model — LessonBook embedded doc + Books on Lesson; central CurriculumBookCatalog supports language-wide AND category-scoped seeds, so one pick covers a lesson range without duplication (placed outside the Wasm link-include globs)
Shape — title, authors, canonical url, edition year, free-vs-paid flag, why-we-recommend note. (Per-TutorialPanel anchors deferred — category scoping covers the need for now; revisit with P5's per-block videos)
Exposure — stamped at hydration onto lesson docs; rides the existing anonymous-readable GET /api/Lessons, no new endpoint
Seeds — C# curated first (Player's Guide, .NET Book Zero free, C# in Depth → Linq/Delegates/Generics, Concurrency in C# Cookbook → Async) + starter picks for Python/JS/C/C++ (Eloquent JavaScript, K&R, Modern C, Tour of C++, …)
Frontend DTO — LessonBookLink on LessonCatalogEntry
Reading tab in the shared shell right pane — lesson-scoped picks, sandbox-mode deduped language view, free-online badge, no chrome when empty; persisted like Concepts/Submissions; designed as the surface P4 (#327) extends
New-tab links with noopener noreferrer; en + es i18n; data-testids per the E2E convention
Guard tests: CurriculumBookCatalogTests 9/9 (per-language coverage, scoping, curation-field completeness). Will close when both PRs merge.
PRs open — backend spikersoft-backend#53 (https://git.spikersoft.com/spikerj/spikersoft-backend/pulls/53) + frontend spikersoft-angular#96 (https://git.spikersoft.com/spikerj/spikersoft-angular/pulls/96). Safe to merge in either order; the Reading tab stays hidden until the API serves `books`.
Against this issue's checklist:
- [x] **Backend model** — `LessonBook` embedded doc + `Books` on `Lesson`; central `CurriculumBookCatalog` supports language-wide AND category-scoped seeds, so one pick covers a lesson range without duplication (placed outside the Wasm link-include globs)
- [x] **Shape** — title, authors, canonical url, edition year, free-vs-paid flag, why-we-recommend note. (Per-`TutorialPanel` anchors deferred — category scoping covers the need for now; revisit with P5's per-block videos)
- [x] **Exposure** — stamped at hydration onto lesson docs; rides the existing anonymous-readable `GET /api/Lessons`, no new endpoint
- [x] **Seeds** — C# curated first (Player's Guide, .NET Book Zero free, C# in Depth → Linq/Delegates/Generics, Concurrency in C# Cookbook → Async) + starter picks for Python/JS/C/C++ (Eloquent JavaScript, K&R, Modern C, Tour of C++, …)
- [x] **Frontend DTO** — `LessonBookLink` on `LessonCatalogEntry`
- [x] **Reading tab** in the shared shell right pane — lesson-scoped picks, sandbox-mode deduped language view, free-online badge, no chrome when empty; persisted like Concepts/Submissions; designed as the surface P4 (#327) extends
- [x] **New-tab links** with `noopener noreferrer`; en + es i18n; data-testids per the E2E convention
Guard tests: `CurriculumBookCatalogTests` 9/9 (per-language coverage, scoping, curation-field completeness). Will close when both PRs merge.
Done — merged to master. Backend Books layer (curated reading picks stamped on lesson docs) in PR #53, and frontend Reading tab (curated book links in the shell right pane) in PR #96. Closing P3.
Done — merged to `master`. Backend Books layer (curated reading picks stamped on lesson docs) in PR #53, and frontend Reading tab (curated book links in the shell right pane) in PR #96. Closing P3.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Phase P3 of epic #323. First of three new lesson content layers (books → text #TBD → videos #TBD); landing it in the shared shell gives it to all five core playgrounds at once.
What: curated links to books on the subject of the current lesson/section, surfaced in the playground so students always have a deeper-reading path.
Model (backend):
Bookscollection to the lesson/section model —SpikerSoft.Data/Mongos/Lesson.cs(per lesson) with optional category/section-level defaults so one recommendation can cover a lesson range without duplicationTutorialPanelanchorGET /api/Lessons,GET /api/Lessons/{id}inLessonsController— both already anonymous-readable)Model (frontend):
LessonCatalogEntry/lesson detail DTOs inlibraries/shared/lesson-platform/src/lib/lesson-types.tsLanguagePlaygroundShellComponent(design should anticipate P4's text layer sharing this surface)relattributes; i18n for all chrome labels (Transloco, es review queue)Acceptance: a lesson with book recommendations shows them in the shell in all five playgrounds; lessons without them render no empty chrome.
PRs open — backend spikersoft-backend#53 (spikerj/spikersoft-backend#53) + frontend spikersoft-angular#96 (spikerj/spikersoft-angular#96). Safe to merge in either order; the Reading tab stays hidden until the API serves
books.Against this issue's checklist:
LessonBookembedded doc +BooksonLesson; centralCurriculumBookCatalogsupports language-wide AND category-scoped seeds, so one pick covers a lesson range without duplication (placed outside the Wasm link-include globs)TutorialPanelanchors deferred — category scoping covers the need for now; revisit with P5's per-block videos)GET /api/Lessons, no new endpointLessonBookLinkonLessonCatalogEntrynoopener noreferrer; en + es i18n; data-testids per the E2E conventionGuard tests:
CurriculumBookCatalogTests9/9 (per-language coverage, scoping, curation-field completeness). Will close when both PRs merge.Done — merged to
master. Backend Books layer (curated reading picks stamped on lesson docs) in PR #53, and frontend Reading tab (curated book links in the shell right pane) in PR #96. Closing P3.