Sub-modules phase B: importer and parser support
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 35/100
- Issue type
- Feature
- Clarity
- Clearly specified
- Activity status
- Active
- Domain
- backend, database, testing-qa
Research direction
Start with _docs/planning/shared-curriculum-submodules-design.md, then read _parse_module and _parse_homework_bindings in content_sync/course_repository_v2.py alongside the phase-A models. Trace the source dataclasses, curriculum validators, and _import_shared_modules/_upsert_shared_lessons/_import_shared_placements before examining the mirrored fixture. Done means the stated parser, validation, import, fixture, and regression checks pass without changing behavior for existing fixtures.
Written by the indexing model from the issue text.
Description
Part of the shared-curriculum sub-modules umbrella (#396), phase B of 4. Depends on #397 (phase A models). Full design: _docs/planning/shared-curriculum-submodules-design.md, "Course-repository representation" section 1/3/5 for the exact YAML shape, and section 4's "Website parser parity" paragraph.
Goal
The website's content-source parser and curriculum importer understand the optional sub_modules: key in module.yaml and the optional sub_module: key in cohort.yaml homework bindings, and populate the phase-A models correctly. Absent keys must mean exactly today's behavior — this phase must not require any real course repository to change.
Scope
content_sync/course_repository_v2.py_parse_module: accept an optionalsub_modules:list, exclusive with a top-levelunits:(a module has one or the other, never both, never neither — mirror the design doc's exact validation wording as parser error messages). Flatten sub-module units into the sameunitstuple the parser builds today (part 1's units then part 2's, in list order) so every existing downstream consumer ofModuleSource.unitsis unaffected. Add a newSubModuleSourcetuple (content id, slug, title, summary, unit index range) onModuleSource.UnitSourcegainssub_module_slug: str | None._parse_homework_bindings: accept an optionalsub_module: <slug>on a binding, validated againstmodule_by_slug[module].sub_modules.HomeworkBindingSourcegainssub_module: str | None.duplicate_homework_modulebecomes a duplicate-anchor check:(module, None)mapped twice, or(module, sub_module)mapped twice — a module anchor and a part anchor on the same module are NOT a duplicate.courses/services/curriculum_source.py: updateModuleSource/UnitSource/HomeworkBindingSourcedataclasses to match.courses/curriculum_source_validators.py: new all-or-nothing rule (within one module, either every lesson has a sub-module or none does) and contiguity rule (each sub-module's lessons are contiguous in module position order, matching sub-module list order) — both import-time checks, not DB constraints, per the design doc's reasoning (they're what make "after the anchor's last lesson" unambiguous for phase C rendering).courses/services/curriculum_import.py_import_shared_modules/_upsert_shared_lessons/_import_shared_placements: writeSharedSubModulerows, setSharedLesson.sub_module, setCohortSharedModule.sub_modulefrom the binding's anchor.- Add a mirrored test fixture:
content_sync/tests/fixtures/course_repository/llm_zoomcamp_shared/gets a split module (a new one, don't rewrite the existing single-part fixture module that other tests depend on) with a sub-module-anchored homework binding in a fixture cohort — matching whatever fixture thezoomcamp-opschecker side uses (coordinate naming/shape, though that repo's own fixtures are out of scope for this issue).
Non-goals
- No
zoomcamp-opschecker changes (a separate repository, phase D coordinates with it but doesn't implement it here). - No rendering changes (phase C) — this phase only gets data into the database correctly; module/lesson pages continue rendering exactly as before (they simply don't yet read the new fields).
- No real content repository changes — llm-zoomcamp's actual
module.yaml/cohort.yamlare untouched by this phase.
Dependencies
- Depends on: #397.
- Blocks: #398 (phase C).
Acceptance criteria
-
make django-check/make migrations-checkpass. -
make testpasses, including new parser/importer tests: exclusivity rejected (bothunitsandsub_modulespresent, or neither), a valid split module imports correctly (sub-module rows created, lessons correctly assigned, flattened unit order matches today's ordering rules), a sub-module-anchored homework binding imports correctly, an invalidsub_modulereference in a binding is rejected with a clear error, all-or-nothing and contiguity validators reject malformed fixtures. - A dry-run import of the mirrored fixture (module with sub_modules content) succeeds end to end against a test database.
- Re-running the full existing content-sync/curriculum-import test suite shows zero behavior change for every fixture that doesn't use
sub_modules:.
- Dominant language
- Python
- Stars
- 0
- Forks
- 0
- PR merge metrics
- No merged PRs in 30d
Getting set up
- Ships a Dockerfile or Docker Compose file
- No pull request template
- No contributing guide
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.
More from DataTalksClub/website
-
bug infra operations P1 testing
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
DataTalksClub/website#329 ·
-
bug content data-migration documentation events operations P1
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
DataTalksClub/website#327 ·
-
bug frontend P0 testing
Difficulty 2/5 1-3 hours Newbie friendliness 90/100
DataTalksClub/website#300 · 7 comments ·
-
bug data-migration events P0 testing
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
DataTalksClub/website#295 · 6 comments ·
-
courses enhancement P2
Difficulty 4/5 3-5 days Newbie friendliness 35/100
DataTalksClub/website#455 · 6 comments ·
All issues in DataTalksClub/website
Similar issues
-
Difficulty 1/5 Under an hour Newbie friendliness 85/100
-
Difficulty 1/5 Under an hour Newbie friendliness 75/100
-
Difficulty 1/5 Under an hour Newbie friendliness 85/100
-
Difficulty 1/5 Under an hour Newbie friendliness 85/100
data-umbrella/du-event-board#225 ·
-
Difficulty 2/5 1-3 hours Newbie friendliness 75/100