DataTalksClub / DataTalksClub/website
Shared-curriculum sub-modules: umbrella
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 0
- Forks
- 0
- PR merge metrics
- No merged PRs in 30d
Description
Design doc: _docs/planning/shared-curriculum-submodules-design.md (committed 7a9816e5) — read it in full before implementing any phase; this issue is a summary and phase tracker, not the source of truth.
Motivation
LLM Zoomcamp's real content already has modules that informally split into parts (module 1: "Part 1: RAG" / "Part 2: Agents" in its README prose; module 3 has five parts; module 4 has two) — but there is currently zero machine-readable representation of this anywhere in the pipeline. module.yaml has a flat units: list, and the website builds a flat SharedModule -> SharedLesson graph with no second level.
Verified in the real content: the current single homework for module 1 spans both parts (Q1-5 are Part 1, Q6 is Part 2) — so the model must support a module keeping ONE homework across its parts, not force a split. Separately, Part 2 already advertises a standalone workshop entry point, so a future cohort anchoring a homework to just one part is realistic, not hypothetical. Both shapes (homework on the whole module, homework on one part) are first-class requirements, not one common case and one rare edge case.
Design summary
SharedSubModule— a new, flat (one level only, no self-referential tree) model, required FK toSharedModule. Rejected a self-referentialparentFK onSharedModuleitself: every existingSharedModulequery (module page, family syllabus count, sitemap, inventory, the two-segment router) would need aparent__isnull=Trueguard it doesn't have today, andSharedModule's own constraints (slug/position uniqueness, the cohort-identifier collision check) are root-shaped.SharedLesson.sub_module— new nullable FK, validated to belong to the lesson'smodule. A module with no sub-modules is simply all-None— zero change for the common case.- Homework anchoring —
CohortSharedModule(the per-cohort homework placement) gains a nullablesub_moduleFK: a homework anchors to either the whole module OR one specific sub-module, per cohort, never both, never neither. Because homework is cohort-owned and the shared module graph isn't, two different cohorts can anchor differently against the same shared content (2026 keeps one module-level homework; a future 2027 could split it) with no change to the shared rows. - Three DB constraints ship in the first phase (not deferred): one module-level homework per module per cohort, one homework per sub-module per cohort, and each homework anchored at most once — see the design doc section 4 for the exact conditional-unique SQL shape (a plain 3-column unique constraint does NOT work here; Postgres treats NULLs as distinct).
- Course-repository side:
module.yamlgains an optionalsub_modules:list (nested, exclusive withunits:);cohort.yamlhomework bindings gain an optionalsub_module: <slug>. No schema version bump — additive schema-2 extension, safe because both the parser and thezoomcamp-opschecker already reject unknown keys (that strictness IS the rollout safety net). Folders stay flat; no lesson/image/code file moves — the grouping lives only inmodule.yaml, matching how authors already number parts in ranges (module 4's06→11gap). Full field-by-field YAML shape and checker rule list in the design doc's "Course-repository representation" section. - llm-zoomcamp's real 2026 content needs zero changes to ship this — all seven of its homework bindings stay module-level anchors. Splitting
sub_modules:into module.yaml for modules 1/3/4 is Phase D, separate from and not required by Phases A-C.
Phases (in dependency order)
| Phase | Summary |
|---|---|
| A | Additive DB models only: SharedSubModule, nullable SharedLesson.sub_module, nullable CohortSharedModule.sub_module, the three constraints, clean() validation, admin. Zero renderer changes. Ships safely with zero sub-modules in real data. |
| B | Website importer/parser support for optional sub_modules: in module.yaml and optional sub_module: in cohort homework bindings, plus all-or-nothing and lesson-contiguity import-time validators. Absent keys mean today's behavior, unchanged. |
| C | Rendering: module page and rail group lessons by sub-module when present (flat fallback otherwise), place each anchored homework after its anchor's last lesson, ModuleFlowItem gains an optional sub-module, anchor-aware homework breadcrumb, inventory report gains the anchor. |
| D | Course-repository side, in this exact order (each step independently revertible): (1) zoomcamp-ops checker rules/fixtures for the new schema + tests green; (2) website Phase B/C deployed and dry-run tested against the checker's fixture; (3) the pinned checker-workflow commit llm-zoomcamp's CI calls gets updated to the new pin (a reviewed change); (4) llm-zoomcamp content: author sub_modules: for modules 1, 3, 4 in three separate commits, CI green, merge, import. cohorts/2026/cohort.yaml is not touched — Homework 1 keeps closing the whole module. |
Open questions (design doc has full detail; flagging here for visibility)
- Should a module ever be allowed both a module-level AND a sub-module-level homework anchor in the same cohort? Schema permits it (each has a well-defined rendering); if it should be forbidden, that's an opt-in
zoomcamp-opschecker rule (mixed_homework_anchors), not a DB constraint. Not enabled by default. - Phase D timing — author real
sub_modules:content for llm-zoomcamp as soon as B/C ship, or leave the capability built but unused for now? - Sub-module pages: this design gives parts headings + fragment anchors on the existing module page, not their own routes/URLs. Confirm that's sufficient (a standalone "Part 2: Agents" workshop page could be added later without touching content, since the sub-module slug is already a stable identity).
- Sub-module
slug/titleconvention: proposed ordinal-free slugs (rag,agents) with README-matching titles ("Part 1: RAG") — confirm, or prefer ordinal-free titles with the website deriving "Part N" from list position.
Each phase will be filed as its own groomed sub-issue per _docs/PROCESS.md, dependent on the previous phase.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Read _docs/planning/shared-curriculum-submodules-design.md at commit 7a9816e5 in full; this umbrella issue is only a phase tracker. Start with the independently groomed Phase A–D sub-issues in dependency order, and treat completion as shipping each phase with its listed models, validators, rendering, repository, and checker work while resolving the open design questions.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- backend, database, full-stack
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100