Katkat

Design a Hierarchical Learning Content API

Fora TravelSoftware Engineer · Onsite

Last updated

Design a relational schema and REST API for a three-tiered learning curriculum (Tracks, Modules, Lessons) supporting drag-and-drop reordering, transactional updates, and versioned caching.

Scenario

You are building the core curriculum service for an online travel advisor platform. Advisors complete structured training programs organized in a strict 3-level hierarchy:

  1. Track (e.g., "Luxury Hotel Specialist")
  2. Module (e.g., "Booking Amenities & Perks")
  3. Lesson (e.g., "Adding Breakfast Credits in Amadeus")

Advisors read published content heavily, while internal curriculum designers frequently draft, reorder, and publish updates.

Requirements

Functional

  • Hierarchy Navigation: Read full track structures (with modules and lessons) in a single request, or fetch individual modules/lessons with parent context.
  • Content Management: Create, update, archive, and move items (e.g., move a lesson from Module A to Module B, or reorder modules within a track).
  • Stable Ordering: Items within a parent must maintain deterministic order even under concurrent edits.
  • Publishing & Caching: Allow curriculum designers to edit drafts and publish changes atomically. Published content should be heavily cached and immediately invalidated upon release.

Non-Functional

  • Low Read Latency: Track hierarchy reads must serve in under 30 ms (p95).
  • Consistency: Structural edits (reorders, moves across parents) must be transactional to prevent orphaned or duplicated items.
  • Bounded Depth: The domain strictly enforces 3 tiers; arbitrary recursion is not required.

Scale & Traffic

  • 1,000 active tracks, 10,000 modules, 100,000 lessons.
  • 50,000 daily active advisors generating 500 read requests per second at peak.
  • ~50 curriculum editors making ~1,000 writes per day (99.9% read-heavy).

Deliverables

  1. Data Model: Relational schema showing primary keys, foreign keys, and ordering strategy.
  2. API Design: RESTful endpoints for reading hierarchy and reordering items.
  3. Ordering & Transactions: Mechanism to handle reordering without expensive table rewrites or race conditions.
  4. Caching & Invalidation: Cache layer design ensuring advisors never see stale or partially published structures.

Hints

Hint 1

To avoid shifting entire arrays of integers on reordering, consider floating-point or lexicographical position keys (e.g., LexoRank or fractional indexing).

Hint 2

Because the tree depth is strictly fixed to three tiers, normalized tables with foreign keys and composite indexes are much simpler and safer than nested-set or closure-table models.

Hint 3

Tagging cached objects with a track-level version or generation counter allows instant cache invalidation without deleting keys individually.

Follow-up questions

  • How would you handle fractional indexing precision exhaustion when two items are repeatedly inserted between each other?
  • How does your design change if the company decides to support arbitrary nesting depth (e.g., sub-modules or units)?
  • How would you store and update advisor completion progress when a track is updated or lessons are removed?