A MERN (MongoDB, Express, React, Node.js) stack application for an online skill-learning platform with an adaptive recommendation engine that personalizes learning paths in real-time.
Skill-stream is an MVP platform designed around 4 core features:
- 🛠️ Catalog - Content library (assets, courses, topics, levels)
- 👤 User Progress - Track learner activity and course enrollments
- 🧠 Adaptive Engine - Resequence learning paths based on performance
- 🧪 Quiz System - Attempt tracking and score-based format switching
MVP/
├── client/
│ ├── src/
│ │ ├── components/ # Reusable React components (SidebarLayout, etc.)
│ │ ├── pages/ # Page components (Dashboard, Path, Quiz, Asset)
│ │ ├── services/ # API service calls (api.js)
│ │ ├── utils/ # Utility functions (formatTitle, activeUser, etc.)
│ │ ├── App.jsx # Main App component
│ │ └── main.jsx # React entry point
│ ├── index.html # HTML template
│ ├── vite.config.js # Vite configuration
│ ├── package.json # Client dependencies
│ └── .env.example # Example env variables
├── server/
│ ├── src/
│ │ ├── config/ # Configuration files (db.js)
│ │ ├── controllers/ # Route handlers (catalog, user, engine)
│ │ ├── data/ # Seed data (JSON files for seeding)
│ │ ├── models/ # MongoDB data models (User, Course, Asset, Path, Attempt, etc.)
│ │ ├── routes/ # API route definitions (catalog, user, engine)
│ │ ├── services/ # Business logic (engine resequencing, quiz scoring)
│ │ ├── app.js # Express app setup
│ │ └── server.js # Server entry point
│ ├── seed.js # MongoDB seed script
│ ├── package.json # Server dependencies
│ └── .env.example # Example env variables
├── .gitignore # Git ignore rules
└── README.md # This file
- Node.js 16+
- MongoDB running locally or Atlas connection string
1. Install dependencies:
# Server
cd server
npm install
# Client
cd ../client
npm install2. Start the application:
Terminal 1 (Server):
cd server
npm startTerminal 2 (Client):
cd client
npm run devServer runs on http://localhost:5000
Client runs on http://localhost:5173
| Model | Purpose | Key Fields |
|---|---|---|
| User | Learner profile | userId, name, role, email |
| Course | Learning program | courseId, title, moduleAssetIds, level |
| Asset | Content item | assetId, title, format (video/doc/lab), level, expectedTimeMin |
| Path | Learner's sequence | userId, courseId, nodes (assetId + status), currentIndex, nextAssetId |
| Attempt | Quiz/format result | assetId, userId, score, timeSpentSec, format, status (pass/fail) |
| Enrollment | User-Course link | userId, courseId, status (active/paused) |
| Question | Quiz questions | questionId, topic, difficulty, options, correctAnswer |
The engine automatically adjusts learning paths based on attempt results:
| Scenario | Action |
|---|---|
| Fail Video | Switch to Doc format at same level |
| Fail Doc | Drop one level (Advanced → Intermediate → Beginner) |
| Pass | Advance to next asset in sequence |
| Incomplete (timeout) | Retry same asset |
Signals used:
score- Quiz performance (pass threshold: 70%)format- Content type (video, doc, lab)level- Difficulty tier (beginner, intermediate, advanced)timeSpentSec- Duration (compared to expectedTimeMin)attemptNo- Number of tries
| Method | Endpoint | Purpose |
|---|---|---|
| GET | /api/catalog/assets |
List all assets |
| GET | /api/catalog/courses |
List all courses |
| GET | /api/catalog/assets/:assetId |
Get single asset |
| GET | /api/catalog/courses/:courseId |
Get single course with moduleAssetIds |
| Method | Endpoint | Purpose |
|---|---|---|
| GET | /api/user/all |
List all users |
| GET | /api/user/:userId/dashboard |
Get user dashboard (active course + path + next asset) |
| GET | /api/user/:userId/enrollments |
List user's enrollments |
| POST | /api/user/:userId/enroll/:courseId |
Enroll user in course (activates + pauses others) |
| Method | Endpoint | Purpose |
|---|---|---|
| GET | /api/engine/:userId/quiz |
Get quiz for user (topic-based attempts) |
| POST | /api/engine/:userId/quiz/submit |
Submit attempt + trigger resequencing |
- Real-time adaptation based on performance
- Format switching (video ↔ doc) on fail
- Level dropping on repeated failures
- Transparent engine decision logging
- localStorage-based user switching (dev/testing)
- Separate paths per user per course
- Enrollment management (active/paused)
- Removes course prefix from titles (e.g., "Git: Version Control Basics" → "Version Control Basics")
- Cleans up "(Corporate Track)" tags
- Collapses extra whitespace
- Attempts tracked per asset + format
- Pass/fail determination (70% threshold)
- Time spent vs. expected time comparison
- Deferred "needs_review" status for borderline scores
server/.env:
PORT=5000
NODE_ENV=development
MONGODB_URI=mongodb://localhost:27017/Skill-stream
client/.env:
VITE_API_URL=http://localhost:5000
- Feature-based modular design - Each domain (catalog, user, engine) has clear routes/controllers/services
- Service-oriented backend - Business logic in services, routes handle HTTP contracts
- Real-time adaptation - Immediate resequencing on attempt submit (no batch jobs)
- Centralized state management - localStorage for user context, MongoDB for persistence
- Composable frontend - Cards + lanes = flexible learning UI
Coming soon: Docker, vercel/heroku steps
For questions or feedback, open an issue or contact the team.