DataTalksClub / DataTalksClub/website
Sub-modules phase B: importer and parser support
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 0
- Forks
- 0
- PR merge metrics
- No merged PRs in 30d
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:.
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
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.
Assessment
- Tech stack
- django, python
- Domain
- backend, database, testing-qa
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 35/100