Shared-curriculum sub-modules: umbrella
まだ誰も着手していません。
評価
- 難易度
- 5/5
- 見積もり時間
- 1週間以上
- 初心者へのやさしさ
- 35/100
- issue の種類
- 機能追加
- 明瞭さ
- おおむね明確
- 活発さ
- 活発
- 技術スタック
- python
- 領域
- backend, database, full-stack
調査の方向性
コミット 7a9816e5 の docs/planning/shared-curriculum-submodules-design.md を全文読んでください。この umbrella issue はフェーズの追跡だけを目的としています。まず、独立してグルーミングされた Phase A–D のサブ issue に依存関係の順序で取り組み、オープンな設計上の疑問を解決しながら、一覧にある models、validators、rendering、repository、checker の作業を含む各フェーズを提供することを完了条件としてください。
索引モデルが issue の本文から書いたものです。
説明
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.
- 主要言語
- Python
- スター
- 0
- フォーク
- 0
- PR マージ指標
- 30日以内にマージされた PR はありません
環境構築
- Dockerfile または Docker Compose ファイルあり
- プルリクエストのテンプレートなし
- コントリビューションガイドなし
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
DataTalksClub/website のほかの issue
-
bug infra operations P1 testing
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
DataTalksClub/website#329 ·
-
bug content data-migration documentation events operations P1
難易度 2/5 1〜3時間 初心者へのやさしさ 84/100
DataTalksClub/website#327 ·
-
bug frontend P0 testing
難易度 2/5 1〜3時間 初心者へのやさしさ 90/100
DataTalksClub/website#300 · コメント 7 件 ·
-
bug data-migration events P0 testing
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
DataTalksClub/website#295 · コメント 6 件 ·
-
admin courses data-migration email enhancement integration operations P1
難易度 4/5 3〜5日 初心者へのやさしさ 35/100
DataTalksClub/website#468 · コメント 6 件 ·
DataTalksClub/website の issue をすべて見る
似ている issue
-
Examples say cnxオープンdocumentation embedded
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
メンテナーはふだん 1 日以内に返信
-
難易度 1/5 1時間未満 初心者へのやさしさ 88/100
Alishahryar1/free-claude-code#2111 ·
メンテナーはふだん 1 日以内に返信
-
bug
難易度 2/5 1〜3時間 初心者へのやさしさ 68/100
メンテナーはふだん 1 日以内に返信
-
namespace operations
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
EclipseFdn/open-vsx.org#14373 ·
メンテナーはふだん 1 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 85/100
メンテナーはふだん 1 日以内に返信