resource-platform-be / LEARNING.md
Auspicious14's picture
Upload 11 files
446494a verified
|
Raw
History Blame Contribute Delete
8.78 kB
# Learning Journey: Building a Project-Based Learning Platform
This document serves as a comprehensive guide to the architectural changes and new technologies introduced in this project. We've shifted from a traditional MongoDB setup to a high-performance, structured backend using PostgreSQL, Prisma, and Redis.
---
## πŸš€ The Core Tech Stack
### 1. PostgreSQL (The Database)
**What it is:** A powerful, open-source **Relational Database (RDBMS)**.
**Why we used it:** Unlike MongoDB (which is NoSQL/Document-based), PostgreSQL excels at handling complex relationships between data (e.g., a User has many Projects, a Project has many Milestones). It ensures "Data Integrity" through schemas and constraints.
### 2. Prisma ORM (The Bridge)
**What it is:** **Prisma** is a next-generation Node.js and TypeScript ORM (Object-Relational Mapper).
**Why we used it:**
- **Type Safety:** It generates a TypeScript client based on your schema. If you try to query a field that doesn't exist, your code won't compile.
- **Auto-migrations:** Instead of writing manual SQL, we define our models in `schema.prisma`, and Prisma handles the database structure.
- **Visual Exploration:** You can use `npx prisma studio` to view and edit your data in a browser.
### 3. Redis (The Speedster)
**What it is:** An in-memory data structure store, used as a database, cache, and message broker. We use the **`ioredis`** library, which is the industry standard for robust Redis connections in Node.js.
**How to get the URL:**
The connection URL is stored in the `REDIS_URL` environment variable.
- **Local Development:** Usually `redis://localhost:6379`.
- **Production:** A secure URL provided by your hosting provider (e.g., Upstash, Redis Labs).
- **Ephemeral Data:** For things like OTP (One-Time Passwords) that expire quickly, writing to a disk-based database is slow and creates "trash" data.
- **Performance:** Redis stores data in RAM, making it incredibly fast for short-term storage.
- **Caching:** We use Redis to cache the global **Leaderboard** (`leaderboard:top20`). Instead of querying the database every time someone views the leaderboard, we serve the result in milliseconds from memory.
---
## πŸ›  Step-by-Step Implementation
### Phase 1: Authentication & Identity
**Goal:** Securely manage user access and state.
1. **User Schema**: We defined a `User` model with roles (`STUDENT`, `ADMIN`, `CONTRIBUTOR`) and skill levels.
2. **Argon2 Hashing**: Instead of plain text, we use `argon2` for industry-standard password hashing.
3. **JWT Strategy**: Upon login, we generate a JSON Web Token (JWT) with a 7-day expiry. This token is stored in an `httpOnly` cookie for security against XSS.
4. **OTP via Redis**: For "Forgot Password", we generate a 6-digit OTP, store it in Redis with a 1-hour TTL (`redis.setex`), and email it using `nodemailer`. This avoids database bloat for temporary data.
### Phase 2: The Project Engine
**Goal:** Create a structured environment for project-based learning.
1. **Hierarchical Data**: Projects are linked to multiple `ProjectMilestone` records. Each milestone acts as a step in the learning journey.
2. **Multi-Mode Progression**: Users can choose between `GUIDED`, `STANDARD`, or `HARDCORE` modes. This is stored in the `UserProject` join table.
3. **Milestone Tracking**: As users complete steps, we create `UserMilestone` records. This allows the frontend to show a granular progress bar.
4. **Contextual Metadata**: Projects store `technologies`, `categories`, and `learningObjectives` as arrays, enabling powerful filtering in the `getProjects` API.
### Phase 3: AI Mentorship (Gemini 1.5)
**Goal:** Provide 24/7 personalized guidance without giving away answers.
1. **Context Injection**: Every chat request to `/api/ai/chat` fetches the current project's title, description, and all milestones.
2. **Mode-Specific Prompts**:
- **Guided**: AI is instructed to be helpful and provide small code snippets.
- **Hardcore**: AI is instructed to be brief and only provide conceptual hints.
3. **Chat Persistence**: Every message is saved to the `ChatMessage` table, allowing the AI to maintain a conversation history even if the user refreshes the page.
4. **On-Demand Hints**: The `/api/ai/hint` endpoint uses Gemini to generate a _new_ hint based on the milestone's description and existing hints, ensuring students don't get stuck.
### Phase 4: Gamification & Performance
**Goal:** Keep users motivated through progress visualization.
1. **XP Awarding**: Completing milestones triggers the `awardXP` utility, which increments the user's `xp` field in PostgreSQL.
2. **Redis-Backed Leaderboard**:
- To avoid heavy `ORDER BY xp DESC` queries on every page load, we cache the Top 20 users in Redis (`leaderboard:top20`).
- **Cache Invalidation**: Whenever someone earns XP, we run `redis.del(LEADERBOARD_CACHE_KEY)` to ensure the next viewer sees updated rankings.
3. **Achievement Engine**: We use the `UserAchievement` model to link users to specific milestones (e.g., "First Project Completed").
### Phase 5: Community & Collaboration
**Goal:** Enable peer-to-peer learning and social validation.
1. **Submissions & Feedback**: Users "publish" their work via `Submission`. This records their repo URL and AI-generated feedback.
2. **Voting System**: A `Vote` model (Up/Down) allows the community to surface high-quality solutions.
3. **Discussion Threads**: The `Comment` model supports nested conversations on projects and submissions.
4. **Team Formation**: The `Team` and `TeamMember` models allow users to group up, sharing the same project progress and milestones.
### Phase 6: Automated Code Review
**Goal:** Bridge the gap between coding and professional feedback.
1. **GitHub API Integration**: When a user submits a repo URL, the backend uses `axios` to hit the GitHub API, fetching repo metadata (stars, description, primary language).
2. **AI Code Analysis**: We send the repository context to Gemini to act as a "Senior Developer," providing constructive feedback on project structure and best practices.
3. **Scoring Logic**: A simulated scoring system provides immediate gratification and a baseline for improvement.
---
## πŸ’‘ New Concepts to Master
### 1. Migrations
When you change the `schema.prisma` file, you need to sync it with your database.
- Command: `npx prisma migrate dev --name init`
- This creates a SQL file and updates your database structure.
### 2. Global Error Handling
We moved away from individual `try/catch` blocks sending responses. Instead, we use a central middleware:
1. Controller catches error.
2. Calls `next(error)`.
3. `middlewares/errorHandler.ts` formats the error and sends a consistent JSON response.
### 3. Progressive Scaffolding
The "Tutorial Hell" killer. Instead of a single "Build this" instruction, projects are broken into `ProjectMilestone`. Each milestone has its own:
- **Validation Criteria:** What the user must achieve.
- **Hints:** Step-by-step clues.
- **AI Context:** The AI Guide specifically focuses on the current milestone number.
### 4. Aggregations & Analytics
We use Prisma's `groupBy` and `_count` features to generate user and admin dashboards (e.g., counting total submissions, calculating project completion rates).
---
## πŸ›  Useful Commands for Learning
- `npx prisma generate`: Re-generates the TypeScript types (run this after changing the schema).
- `npx prisma studio`: Opens a GUI to see your PostgreSQL data.
- `npx tsc --noEmit`: Checks your whole project for TypeScript errors.
---
## 🎯 Next Steps for You
1. **Explore the Schema:** Look at `prisma/schema.prisma` and try adding a new field (like `twitterHandle` to the User model).
2. **Check the Logs:** Run the server and watch the terminal to see how Redis connects.
3. Test an API: Use Postman or Insomnia to hit `POST /api/ai/chat` and see how the AI responds based on the project context.
---
## 🎯 Next Steps for You
1. **Explore the Schema:** Look at `prisma/schema.prisma` and try adding a new field (like `twitterHandle` to the User model).
2. **Check the Logs:** Run the server and watch the terminal.
3. **Test an API:** Use Postman or Insomnia to hit `POST /api/ai/chat` and see how the AI responds based on the project context.
---
## πŸ›  How to Start the Project
Follow these steps to get everything running correctly:
### 1. Sync the Database
Ensure your Prisma client and database schema are in sync:
```bash
npx prisma generate
npx prisma migrate dev
```
### 2. Seed the Database (Optional)
If you need initial data:
```bash
npm run seed
```
### 3. Start the Backend Server
Now you can start your development server:
```bash
npm run dev
```
---
## πŸ” Troubleshooting