Skip to content

Sub-modules phase C: module page and cohort-flow rendering #399

Description

@alexeygrigorev

Part of the shared-curriculum sub-modules umbrella (#396), phase C of 4. Depends on #398 (phase B importer). Full design: _docs/planning/shared-curriculum-submodules-design.md, "Constraints and what the renderers must know" section.

Goal

Module pages, the cohort curriculum flow, the homework breadcrumb, and the shared-curriculum inventory correctly render/report sub-module structure and per-anchor homework placement, when present. Flat modules (the common case, zero sub-modules) must render byte-identical to today.

Scope

  1. courses/views/shared_course.py (module page view) and courses/templates/courses/shared_module.html / _shared_module_rail.html: when a module has sub-modules, group its lesson list by sub-module in order (each group gets a heading with a fragment anchor, not its own route/URL — confirmed in the design doc as sufficient for now); after each sub-module's lesson group, render that sub-module's anchored homework link if one exists; after the last group (or immediately, for a flat module), render the module-anchored homework link if one exists. A flat module (no sub-modules) renders exactly as today — verify with a snapshot/diff test.
  2. courses/services/curriculum_flow.py _shared_flow: unchanged loop shape (one ModuleFlowItem per placement, ordered by placement position). ModuleFlowItem gains an optional sub_module, so the cohort page can title an entry "Module 1 · Part 2: Agents" when anchored to a part. A module with two anchored homeworks (a module-level and a part-level, if that ever occurs) correctly yields two flow entries.
  3. courses/views/homework_context.py: the shared-curriculum breadcrumb resolves homework.shared_module_placements to its anchor and links the module page, including the sub-module's fragment anchor when the homework is anchored to a part.
  4. courses/services/shared_curriculum_inventory.py: add sub_module_slug to each placement row in the reconciliation report.
  5. Confirm (per the design doc's explicit check) that courses/views/course_page_context.py:349 (family syllabus module count) and content/public_views.py:1296 (sitemap) need NO changes — both are root-SharedModule-only by construction and must stay that way (add a regression test asserting a split module still counts as one module in the family syllabus count and produces one sitemap entry, not one per sub-module).

Non-goals

  • No zoomcamp-ops/course-repository changes (phase D).
  • No sub-module standalone pages/routes (explicitly deferred per the design doc's open question 3 — fragment anchors on the existing module page only).
  • No change to courses/views/dashboard_homeworks.py (confirmed in the design doc: it's keyed purely on Homework rows and never reads placements, so it needs no change — verify this holds, don't change it speculatively).

Dependencies

Acceptance criteria

Django and integration

  • make django-check passes; make test passes.
  • New rendering tests using the phase B fixture: a split module's page groups lessons correctly, shows the right homework link after each anchor, fragment anchors resolve; a flat module's page is byte-identical to its pre-phase-C rendering (regression guard).
  • ModuleFlowItem.sub_module renders correctly in the cohort page's flow list for both anchor types.
  • Family syllabus module count and sitemap entry count are unaffected by a split module (both stay root-only).
  • Inventory report includes sub_module_slug for anchored placements and is null/absent for module-level placements.

Browser

  • make test-playwright-core passes.
  • Screenshot verification: a split-module page (using the phase B fixture data seeded into a local dev DB) renders sensibly at desktop and mobile, light and dark, with clear visual grouping between parts.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1Important follow-upcoursesArea: coursesenhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions