DataTalksClub / DataTalksClub/website

Sub-modules phase B: importer and parser support

Open
#398 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

courses enhancement P1
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

  1. content_sync/course_repository_v2.py _parse_module: accept an optional sub_modules: list, exclusive with a top-level units: (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 same units tuple the parser builds today (part 1's units then part 2's, in list order) so every existing downstream consumer of ModuleSource.units is unaffected. Add a new SubModuleSource tuple (content id, slug, title, summary, unit index range) on ModuleSource. UnitSource gains sub_module_slug: str | None.
  2. _parse_homework_bindings: accept an optional sub_module: <slug> on a binding, validated against module_by_slug[module].sub_modules. HomeworkBindingSource gains sub_module: str | None. duplicate_homework_module becomes 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.
  3. courses/services/curriculum_source.py: update ModuleSource/UnitSource/HomeworkBindingSource dataclasses to match.
  4. 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).
  5. courses/services/curriculum_import.py _import_shared_modules/_upsert_shared_lessons/_import_shared_placements: write SharedSubModule rows, set SharedLesson.sub_module, set CohortSharedModule.sub_module from the binding's anchor.
  6. 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 the zoomcamp-ops checker side uses (coordinate naming/shape, though that repo's own fixtures are out of scope for this issue).

Non-goals

  • No zoomcamp-ops checker 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.yaml are untouched by this phase.

Dependencies

  • Depends on: #397.
  • Blocks: #398 (phase C).

Acceptance criteria

  • make django-check / make migrations-check pass.
  • make test passes, including new parser/importer tests: exclusivity rejected (both units and sub_modules present, 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 invalid sub_module reference 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

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.