-
-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Description
Problem
The CourseRouter component (/packages/platform-ui/src/components/Courses/CourseRouter.vue
) exhibits severe performance issues when resolving human-readable course names to course IDs. To navigate to /q/TypeScript
, the system makes database requests to every single course database to find the matching course.
Root Cause
The performance bottleneck stems from a data architecture mismatch:
- coursedb-lookup database: Contains only course IDs (
name
field) anddisambiguator
- no human-readable names - CourseConfig documents: Stored individually in separate
coursedb-{courseID}
databases - CourseRouter resolution: Must fetch CourseConfig from every course database to match human-readable names
Current Flow (O(N) complexity)
/q/TypeScript → CourseRouter.vue:78 → getCourseList() →
1. Fetch all course IDs from coursedb-lookup
2. For each course ID: fetch CourseConfig from coursedb-{courseID}
3. Match course.name === "TypeScript"
4. Return matching course ID
Impact
- E2E tests: 20+ second load times for single course pages
- User experience: Slow navigation, especially for new users
- Database load: Unnecessary queries to every course database
- Scalability: Performance degrades linearly with number of courses
Evidence
E2E test logs show 30+ database requests for a single course page:
(fetch)GET 200 coursedb-lookup/_all_docs?include_docs=true
(fetch)GET 403 coursedb-05e74ba12a77282a175853c646005387/
(fetch)GET 403 coursedb-2aeb8315ef78f3e89ca386992d004974/
(fetch)GET 200 coursedb-2aeb8315ef78f3e89ca386992d00825b/
... (20+ more coursedb requests)
Proposed Solutions
Option A: Enhance coursedb-lookup with Metadata (Recommended)
- Approach: Add course metadata (name, description, public flag) to coursedb-lookup
- Implementation: Add sync hooks to
updateCredentialledCourseConfig()
and course creation flows - Benefits: Reduces CourseRouter queries from O(N) to O(1), maintains backward compatibility
- Files:
/packages/db/src/impl/couch/courseAPI.ts
,/packages/db/src/impl/couch/courseLookupDB.ts
Option B: Centralize CourseConfig Storage
- Approach: Move CourseConfig documents entirely to coursedb-lookup
- Benefits: Single source of truth, eliminates sync issues
- Risks: Requires significant refactoring, potential breaking changes
Option C: Implement Caching Layer
- Approach: Cache CourseConfig documents in memory/browser storage
- Benefits: Reduces repeat queries
- Limitations: Doesn't solve initial load performance
Technical Details
Key Files
/packages/platform-ui/src/components/Courses/CourseRouter.vue:78
- Triggers bulk fetch/packages/db/src/impl/couch/courseDB.ts:42-64
- getCourseList() implementation/packages/db/src/impl/couch/courseLookupDB.ts:109
- Course lookup database/packages/common/src/wire-format.ts:121
- CourseConfig interface
Current coursedb-lookup Structure
interface CourseLookupEntry {
name: string; // Course ID, not human name
disambiguator: string; // Unique suffix
}
Proposed Enhanced Structure
interface CourseLookupEntry {
name: string; // Course ID
disambiguator: string; // Unique suffix
courseName: string; // Human-readable name
description: string; // Course description
public: boolean; // Visibility flag
deleted?: boolean; // Soft delete flag
}
Acceptance Criteria
- Course name resolution should require ≤2 database queries (coursedb-lookup + target course)
- Existing CourseConfig functionality remains intact
- Course creation/updates sync metadata to coursedb-lookup
- E2E test performance improves significantly
- Backward compatibility maintained
Priority
High - This affects user experience and test performance significantly, and will get worse as more courses are added to the system.
Metadata
Metadata
Assignees
Labels
No labels