diff --git a/absolute-beginners/full-stack/authentication/_category_.json b/absolute-beginners/full-stack/authentication/_category_.json
new file mode 100644
index 0000000..d6dcdeb
--- /dev/null
+++ b/absolute-beginners/full-stack/authentication/_category_.json
@@ -0,0 +1,9 @@
+{
+ "label": "Authentication",
+ "position": 10,
+ "link": {
+ "type": "generated-index",
+ "title": "Authentication: Securing Your Application",
+ "description": "Learn how to implement secure authentication mechanisms in your applications. This track covers everything from basic login systems to advanced topics like OAuth, JWT, and multi-factor authentication."
+ }
+}
\ No newline at end of file
diff --git a/absolute-beginners/full-stack/authentication/best-practices.mdx b/absolute-beginners/full-stack/authentication/best-practices.mdx
index e345ed2..4980cf6 100644
--- a/absolute-beginners/full-stack/authentication/best-practices.mdx
+++ b/absolute-beginners/full-stack/authentication/best-practices.mdx
@@ -1 +1,98 @@
-
\ No newline at end of file
+---
+title: "Authentication Best Practices"
+sidebar_label: "7. Best Practices"
+sidebar_position: 7
+description: "Essential security checklist for building professional and secure authentication systems."
+tags: ["authentication", "security", "best practices", "full-stack development"]
+keywords: ["authentication best practices", "password security", "HTTPS", "JWT security", "rate limiting", "multi-factor authentication", "RBAC", "security checklist"]
+---
+
+In the world of security, we assume that attackers are smart and persistent. Following these rules will protect your application from 99% of common attacks.
+
+## 1. Password Security
+
+### Use Salted Hashing
+
+As we learned, never store passwords as plain text. Use **Bcrypt** with at least **10-12 salt rounds**.
+
+### Enforce Strong Password Policies
+
+Don't let users use `password123`. Require a mix of:
+* Minimum 8-12 characters.
+* At least one uppercase letter.
+* At least one number and one special character.
+
+## 2. Transport & Storage
+
+### HTTPS is Non-Negotiable
+Without SSL/TLS (HTTPS), passwords and JWTs are sent across the internet in plain text. Any "man-in-the-middle" can steal them. **Always use HTTPS in production.**
+
+### Use HttpOnly and Secure Cookies
+If you store tokens in cookies, set these flags:
+* `HttpOnly`: Prevents JavaScript from reading the cookie (stops XSS attacks).
+* `Secure`: Ensures the cookie is only sent over HTTPS.
+* `SameSite=Strict`: Prevents CSRF (Cross-Site Request Forgery) attacks.
+
+## 3. Handling JWTs (Tokens)
+
+### Keep Secrets Secret
+Never hardcode your `JWT_SECRET`. Use environment variables (`.env`) and make sure `.env` is in your `.gitignore`.
+
+### Use Short Expiration Times
+Tokens should not last forever. A good standard is **15 minutes to 1 hour** for access tokens.
+
+## 4. Protection Against Attacks
+
+### Rate Limiting
+Prevent "Brute Force" attacks (where a bot tries thousands of passwords) by limiting how many requests an IP can make to your `/login` route.
+
+```javascript title="rateLimiter.js"
+const rateLimit = require('express-rate-limit');
+
+const loginLimiter = rateLimit({
+ windowMs: 15 * 60 * 1000, // 15 minutes
+ max: 5, // Limit each IP to 5 login requests per window
+ message: "Too many login attempts, please try again after 15 minutes"
+});
+
+app.use('/api/auth/login', loginLimiter);
+
+```
+
+### Generic Error Messages
+
+Never tell a hacker *which* part of the login was wrong.
+
+* **Bad:** "User not found" or "Incorrect password."
+* **Good:** "Invalid email or password."
+
+## 5. Multi-Factor Authentication (MFA)
+
+For high-security apps, a password isn't enough. Implement MFA using:
+
+* **TOTP:** Apps like Google Authenticator.
+* **Email/SMS:** Sending a one-time code (OTP).
+
+## 6. The "Master" Checklist
+
+| Category | Requirement | Check |
+| --- | --- | --- |
+| **Passwords** | Hashed with Bcrypt + Salt | ☐ |
+| **Transport** | All traffic over HTTPS | ☐ |
+| **Tokens** | Short-lived + Securely stored | ☐ |
+| **Database** | Roles (RBAC) implemented | ☐ |
+| **Monitoring** | Logs for failed login attempts | ☐ |
+
+## Practice: The Vulnerability Hunt
+
+Go through your current project and check:
+
+1. Is your `JWT_SECRET` in a `.env` file?
+2. Do your login routes have a rate limiter?
+3. Are you using generic error messages?
+
+If you answered "No" to any of these, now is the time to fix it!
+
+:::info Security Audits
+Use tools like `npm audit` frequently. It will scan your project for libraries with known security holes and tell you how to patch them.
+:::
\ No newline at end of file
diff --git a/absolute-beginners/full-stack/authentication/intro.mdx b/absolute-beginners/full-stack/authentication/intro.mdx
index e345ed2..d8ad304 100644
--- a/absolute-beginners/full-stack/authentication/intro.mdx
+++ b/absolute-beginners/full-stack/authentication/intro.mdx
@@ -1 +1,65 @@
-
\ No newline at end of file
+---
+title: "Introduction to Authentication"
+sidebar_label: "1. Introduction"
+sidebar_position: 1
+description: "Learn the fundamental concepts of Authentication vs. Authorization and how security works in web apps."
+tags: ["authentication", "authorization", "security", "full-stack development"]
+keywords: ["authentication", "authorization", "security", "JWT", "sessions", "hashing", "bcrypt"]
+---
+
+In full-stack development, security isn't just an "add-on"—it's the foundation. Before we write any code, we need to understand the two most important concepts in security.
+
+## 1. Authentication vs. Authorization
+
+These terms sound similar, but they do very different things. Think of a **Hotel**:
+
+* **Authentication (AuthN):** This is the **Check-in** process. You show your ID to prove you are who you say you are. The hotel gives you a Key Card.
+ * *Question:* "Who are you?"
+* **Authorization (AuthZ):** This is the **Key Card** itself. Your card lets you into your room (Room 302), but it won't let you into the Manager's office or the Kitchen.
+ * *Question:* "What are you allowed to do?"
+
+## 2. How it works on the Web
+
+The web is "stateless," meaning the server forgets you the moment a request is finished. To stay logged in, we use a cycle:
+
+1. **Identify:** The user sends their `email` and `password`.
+2. **Verify:** The server checks the database (MongoDB/Postgres) to see if the password matches.
+3. **Token/Session:** The server sends back a "Proof of Identity" (like a JWT or a Session ID).
+4. **Persistence:** The browser stores this proof (usually in a Cookie or LocalStorage) and sends it with every future request.
+
+## 3. Common Auth Methods
+
+At the Hub, we focus on the two industry standards:
+
+### JSON Web Tokens (JWT)
+The most popular method for modern MERN apps. The server gives you a "Digital Ticket" (the token). You keep the ticket. Every time you want data, you show the ticket. The server doesn't need to check the database every time; it just validates the ticket.
+* **Best for:** Mobile apps, APIs, and Scalable apps.
+
+### Session-Based (Cookies)
+The server creates a "file" for you in its memory (or Redis) and gives you an ID number. Your browser saves that ID in a cookie.
+* **Best for:** Traditional websites and high-security banking apps.
+
+## 4. The Golden Rules of Security
+
+As you start building auth systems, follow these "Master" principles:
+
+1. **Never store plain-text passwords:** If a hacker steals your database, they shouldn't see "password123." We use **Hashing** (like Bcrypt) to turn passwords into unreadable gibberish.
+2. **Always use HTTPS:** Without encryption, anyone on the same Wi-Fi can see the passwords being sent to your server.
+3. **Don't reinvent the wheel:** Security is hard. Use trusted libraries like `Passport.js`, `Bcrypt`, or `JsonWebToken`.
+
+## 5. Key Vocabulary
+
+* **Credentials:** Your username and password.
+* **Hashing:** A one-way mathematical function that hides passwords.
+* **Salt:** Random data added to a password before hashing to make it even harder to crack.
+* **Middleware:** The code that stands between a user and a protected route to check if they are logged in.
+
+## Practice: The Security Audit
+
+Look at the apps on your phone (Instagram, WhatsApp, Bank).
+* How do they **Authenticate** you? (Password? FaceID? OTP?)
+* What are you **Authorized** to see? (Can you see your friend's private messages? Why not?)
+
+:::info
+Authentication is where most beginners make mistakes. In the next few lessons, we will build a "Safe" login system step-by-step. **Take your time here—it’s the most important skill in a backend developer's resume.**
+:::
\ No newline at end of file
diff --git a/absolute-beginners/full-stack/authentication/jwt.mdx b/absolute-beginners/full-stack/authentication/jwt.mdx
index e345ed2..3452a0d 100644
--- a/absolute-beginners/full-stack/authentication/jwt.mdx
+++ b/absolute-beginners/full-stack/authentication/jwt.mdx
@@ -1 +1,104 @@
-
\ No newline at end of file
+---
+title: "JWT (JSON Web Tokens) Explained"
+sidebar_label: "3. JWT Tokens"
+sidebar_position: 3
+description: "Learn how to use JSON Web Tokens for stateless authentication in your MERN stack applications."
+tags: ["authentication", "JWT", "json web tokens", "security", "full-stack development"]
+keywords: ["JWT", "json web tokens", "authentication", "Node.js", "Express", "MongoDB", "PostgreSQL", "jsonwebtoken", "token-based authentication"]
+---
+
+A **JWT** is a compact, URL-safe way of representing claims to be transferred between two parties. In simple terms: it is a digital ID card that proves who you are.
+
+## 1. Why use JWT?
+
+In modern web apps (like the ones we build at the Hub), we want our backend to be **Stateless**.
+* **Stateful:** The server must remember every logged-in user in its RAM. (Heavy and hard to scale).
+* **Stateless (JWT):** The server doesn't remember you. You carry your own "Identity" in your token. The server just verifies the signature on the token.
+
+
+## 2. Anatomy of a JWT
+
+A JWT looks like a long string of gibberish separated by two dots: `xxxxx.yyyyy.zzzzz`. It has three parts:
+
+1. **Header:** Tells the server what algorithm is used (e.g., HS256).
+2. **Payload:** Contains the user data (claims) like `userId` or `username`. **Warning:** Never put passwords here! This part is encoded, not encrypted (anyone can read it).
+3. **Signature:** This is the secret sauce. It is a combination of the Header, Payload, and a **Secret Key** known only to your server.
+
+> If a user tries to change the `userId` in the Payload, the **Signature** will no longer match, and the server will reject the token!
+
+## 3. Using JWT in Node.js
+
+We use the `jsonwebtoken` library to handle tokens.
+
+### Installation
+
+```bash
+npm install jsonwebtoken
+```
+
+### Generating a Token (On Login)
+
+When a user successfully logs in, you "Sign" a token and send it to them.
+
+```javascript title="generateToken.js"
+const jwt = require('jsonwebtoken');
+
+const token = jwt.sign(
+ { userId: user._id, role: 'student' }, // Payload
+ process.env.JWT_SECRET, // Your Secret Key
+ { expiresIn: '1h' } // Token expires in 1 hour
+);
+
+res.json({ token });
+
+```
+
+### Verifying a Token (Middleware)
+
+When the user wants to access a "Protected" route, they send the token in the **Header**. Your server verifies it:
+
+```javascript title="verifyToken.js"
+const verifyToken = (req, res, next) => {
+ const token = req.header('Authorization');
+
+ if (!token) return res.status(401).send("Access Denied!");
+
+ try {
+ const verified = jwt.verify(token, process.env.JWT_SECRET);
+ req.user = verified; // Add user info to the request object
+ next(); // Move to the actual route
+ } catch (err) {
+ res.status(400).send("Invalid Token!");
+ }
+};
+
+```
+
+## 4. Where to store the Token?
+
+As a developer, you have two main choices for where the browser should save the token:
+
+| Location | Security | Complexity |
+| --- | --- | --- |
+| **LocalStorage** | Vulnerable to XSS (Scripts can steal it). | Very Easy to use. |
+| **HttpOnly Cookie** | Immune to XSS. (Best Practice). | Requires more setup. |
+
+At **CodeHarborHub**, we recommend starting with LocalStorage for learning, but moving to **HttpOnly Cookies** for professional projects.
+
+## 5. The "Secret Key" Rule
+
+Your `JWT_SECRET` is the most important piece of data in your backend.
+
+* If someone gets your secret, they can create tokens for **any user** and log in as anyone (even the Admin!).
+* **Always** store your secret in a `.env` file and **never** push it to GitHub.
+
+## Practice: The Token Decoder
+
+1. Go to [JWT.io](https://jwt.io/).
+2. Paste a token you generated in your code.
+3. Look at the "Payload" on the right. Can you see your `userId`?
+4. Try changing a single letter in the token string. Watch how the "Signature Invalid" warning appears!
+
+:::info Token Expiration
+Always set an expiration time (like `1h` or `7d`). If a token is ever stolen, it won't be useful forever. For "Master" level security, look into **Refresh Tokens** later!
+:::
\ No newline at end of file
diff --git a/absolute-beginners/full-stack/authentication/oauth.mdx b/absolute-beginners/full-stack/authentication/oauth.mdx
index e345ed2..754f415 100644
--- a/absolute-beginners/full-stack/authentication/oauth.mdx
+++ b/absolute-beginners/full-stack/authentication/oauth.mdx
@@ -1 +1,89 @@
-
\ No newline at end of file
+---
+title: "OAuth & Social Login"
+sidebar_label: "4. OAuth (Social Login)"
+sidebar_position: 4
+description: "Understand how OAuth works and how to integrate Login with Google using Passport.js."
+tags: ["authentication", "oauth", "social login", "passport.js", "google login", "full-stack development"]
+keywords: ["oauth", "social login", "passport.js", "google login", "authentication", "Node.js", "Express", "MongoDB", "PostgreSQL"]
+---
+
+**OAuth 2.0** is an open-standard authorization protocol that allows a website to access a user's information from another service (like Google or Facebook) without actually seeing the user's password.
+
+## 1. How the OAuth Flow Works
+
+Think of OAuth as a **Valet Key** for a car. You give the valet a special key that lets them park the car, but it won't let them open the trunk or glove box.
+
+1. **The Request:** The user clicks "Login with Google."
+2. **The Permission:** Google asks the user, "Do you allow CodeHarborHub to see your email and profile?"
+3. **The Code:** Google sends a temporary "Authorization Code" back to your server.
+4. **The Exchange:** Your server sends that code + your **Secret Key** to Google to prove it's really you.
+5. **The Token:** Google gives your server an `access_token` and the user's profile data.
+6. **The Session:** Your server saves the user to the database and logs them in.
+
+## 2. Key Terms You Need to Know
+
+* **Resource Owner:** The User (You).
+* **Client:** Your Application (CodeHarborHub).
+* **Authorization Server:** The service providing the login (Google/GitHub).
+* **Client ID:** A public identifier for your app (given by Google).
+* **Client Secret:** A private password for your server (KEEP THIS SECRET!).
+* **Callback URL (Redirect URI):** The specific link where Google sends the user after they log in.
+
+## 3. Implementing OAuth with Passport.js
+
+In the Node.js ecosystem, **Passport.js** is the "Master" middleware for authentication. It uses "Strategies" for different providers.
+
+### Installation
+
+```bash
+npm install passport passport-google-oauth20 express-session
+```
+
+### Basic Configuration
+
+```javascript title="passportConfig.js"
+const passport = require('passport');
+const GoogleStrategy = require('passport-google-oauth20').Strategy;
+
+passport.use(new GoogleStrategy({
+ clientID: process.env.GOOGLE_CLIENT_ID,
+ clientSecret: process.env.GOOGLE_CLIENT_SECRET,
+ callbackURL: "/auth/google/callback"
+ },
+ async (accessToken, refreshToken, profile, done) => {
+ // 1. Check if user exists in our DB
+ // 2. If not, create a new user using profile.id and profile.emails[0].value
+ // 3. Return the user
+ return done(null, profile);
+ }
+));
+
+```
+
+## 4. The Developer Console Step
+
+You cannot code OAuth without first registering your app with the provider.
+
+1. Go to the [Google Cloud Console](https://console.cloud.google.com/).
+2. Create a Project and go to **APIs & Services > Credentials**.
+3. Create an **OAuth 2.0 Client ID**.
+4. Set the **Authorized Redirect URI** to `http://localhost:5000/auth/google/callback`.
+5. Copy your `CLIENT_ID` and `CLIENT_SECRET` to your `.env` file.
+
+## 5. Pros and Cons of OAuth
+
+| Pros | Cons |
+| --- | --- |
+| **User Experience:** One-click login is faster. | **Dependence:** If Google goes down, users can't log in. |
+| **High Security:** No passwords stored on your server. | **Privacy:** Some users don't like sharing data between sites. |
+| **Verified Emails:** You know the user's email is real. | **Complexity:** Setting up multiple providers can be tedious. |
+
+## Practice: The Social Audit
+
+1. Go to your Google Account settings under **"Security"**.
+2. Find **"Your connections to third-party apps & services"**.
+3. See which websites you have given "Valet Keys" to. Notice how you can revoke access at any time!
+
+:::info
+When building a real project, always offer a **Hybrid** approach: Let users sign up with an Email/Password (using Bcrypt) OR use Social Login (OAuth). This gives your users the most flexibility!
+:::
\ No newline at end of file
diff --git a/absolute-beginners/full-stack/authentication/password-hashing.mdx b/absolute-beginners/full-stack/authentication/password-hashing.mdx
index e345ed2..29c7cc7 100644
--- a/absolute-beginners/full-stack/authentication/password-hashing.mdx
+++ b/absolute-beginners/full-stack/authentication/password-hashing.mdx
@@ -1 +1,102 @@
-
\ No newline at end of file
+---
+title: "Password Hashing with Bcrypt"
+sidebar_label: "2. Password Hashing"
+sidebar_position: 2
+description: "Learn how to securely store passwords using hashing and salting with the Bcrypt library."
+tags: ["authentication", "password hashing", "bcrypt", "security", "full-stack development"]
+keywords: ["password hashing", "bcrypt", "salting", "security", "authentication", "Node.js", "MongoDB", "PostgreSQL"]
+---
+
+In the previous lesson, we learned about the importance of authentication and the concept of credentials. Now, let's dive into one of the most critical aspects of authentication: **Password Hashing**.
+
+Imagine a user signs up for your site with the password `secret123`.
+* **The Wrong Way:** Saving `secret123` directly in MongoDB.
+* **The Master Way:** Saving `$2b$10$nOUIs5kJ7naTuTFkBy1veuK...`
+
+If a hacker steals the "Master Way" data, they have no idea what the real password is.
+
+## 1. What is Hashing?
+
+A **Hash Function** is a one-way mathematical algorithm. You put data in, and you get a fixed-length string out.
+
+### Key Properties of Hashing:
+1. **One-Way:** You can turn a password into a hash, but you **cannot** turn a hash back into a password.
+2. **Deterministic:** The same password will always produce the same hash (unless we add "Salt").
+3. **Fast but Secure:** It needs to be fast enough for users, but slow enough to stop hackers from trying billions of combinations.
+
+## 2. What is "Salting"?
+
+If two users use the same password (like `123456`), they would normally have the same hash. A hacker could use a "Rainbow Table" (a list of pre-calculated hashes) to figure them out instantly.
+
+**Salting** is adding random characters to the password *before* hashing it.
+* Password: `password123`
+* Salt: `ax79!z`
+* Result to be hashed: `password123ax79!z`
+
+This ensures that even if two users have the same password, their hashes will look completely different.
+
+## 3. Using Bcrypt in Node.js
+
+**Bcrypt** is the gold standard library for hashing. It handles both the salt and the hash in one easy process.
+
+### Installation
+```bash
+npm install bcrypt
+```
+
+### Hashing a Password (Signup)
+
+When a user registers, you hash their password before saving it to the database.
+
+```javascript title="hashing.js"
+const bcrypt = require('bcrypt');
+
+const signup = async (password) => {
+ const saltRounds = 10; // The "cost" of hashing (higher = more secure but slower)
+
+ const hashedPassword = await bcrypt.hash(password, saltRounds);
+
+ console.log('Original:', password);
+ console.log('Hashed:', hashedPassword);
+
+ // Save hashedPassword to your Database!
+};
+
+```
+
+### Verifying a Password (Login)
+
+Since you can't "unhash" a password, how do you check if a user entered the right one? You hash the *attempted* password and compare it to the one in the database.
+
+```javascript title="login.js"
+const login = async (enteredPassword, storedHash) => {
+ // Bcrypt handles the salt comparison automatically
+ const isMatch = await bcrypt.compare(enteredPassword, storedHash);
+
+ if (isMatch) {
+ console.log("✅ Access Granted!");
+ } else {
+ console.log("❌ Incorrect Password!");
+ }
+};
+
+```
+
+## 4. Why 10 Salt Rounds?
+
+The `saltRounds` parameter determines how much processing power is required to calculate the hash.
+
+* If it's too low (e.g., 1), it's too fast and easy to hack.
+* If it's too high (e.g., 20), your server will take 10 seconds to log someone in!
+* **10-12 rounds** is currently the "sweet spot" for modern servers.
+
+## Practice: The "Master" Security Script
+
+1. Create a small Node script.
+2. Hash three different passwords: `apple`, `apple1`, and `apple` (again).
+3. Observe how the two `apple` hashes are different because of the random salt.
+4. Try to "log in" by comparing a wrong password to one of your hashes.
+
+:::danger Don't Forget!
+Always `await` your bcrypt functions. Hashing is a CPU-intensive task, and if you don't handle the promises correctly, your code might try to save an empty password to the database!
+:::
\ No newline at end of file
diff --git a/absolute-beginners/full-stack/authentication/rbac.mdx b/absolute-beginners/full-stack/authentication/rbac.mdx
new file mode 100644
index 0000000..9706930
--- /dev/null
+++ b/absolute-beginners/full-stack/authentication/rbac.mdx
@@ -0,0 +1,105 @@
+---
+title: "Role-Based Access Control (RBAC)"
+sidebar_label: "6. RBAC (Authorization)"
+sidebar_position: 6
+description: "Learn how to manage user permissions and protect routes based on user roles like Admin, Editor, or Student."
+tags: ["authentication", "authorization", "rbac", "role-based access control", "security", "full-stack development"]
+keywords: ["rbac", "role-based access control", "authorization", "user roles", "admin", "editor", "student", "middleware", "Node.js", "Express", "MongoDB", "PostgreSQL"]
+---
+
+RBAC is a method of restricting network access based on the roles of individual users within an enterprise. It is the industry-standard way to handle **Authorization**.
+
+## 1. The Hierarchy of Roles
+
+At CodeHarborHub, we typically use three levels of access:
+
+1. **Admin:** Full access. Can create, edit, and delete anything (Users, Courses, Lessons).
+2. **Editor/Instructor:** Can create and edit content but cannot manage users or delete the entire database.
+3. **Student/User:** Can view content and manage their own profile.
+4. **Guest:** Can only view public landing pages.
+
+## 2. Storing Roles in the Database
+
+The first step is adding a `role` field to your User Schema.
+
+**Mongoose Example:**
+
+```javascript title="userModel.js"
+const mongoose = require('mongoose');
+const userSchema = new mongoose.Schema({
+ username: String,
+ email: String,
+ role: {
+ type: String,
+ enum: ['student', 'editor', 'admin'],
+ default: 'student'
+ }
+});
+
+```
+
+## 3. Creating Authorization Middleware
+
+To protect your routes, you need a "gatekeeper" function that checks the user's role before letting them pass.
+
+```javascript title="middleware/authorize.js"
+
+const authorize = (requiredRoles) => {
+ return (req, res, next) => {
+ // req.user is populated by your JWT middleware
+ if (!req.user) {
+ return res.status(401).json({ message: "Unauthorized" });
+ }
+
+ if (!requiredRoles.includes(req.user.role)) {
+ return res.status(403).json({
+ message: "Access Denied: You do not have the required permissions!"
+ });
+ }
+
+ next(); // User has the role, proceed to the controller
+ };
+};
+
+module.exports = authorize;
+
+```
+
+## 4. Protecting Your Routes
+
+Now you can apply this middleware to specific Express routes.
+
+```javascript title="routes.js"
+const express = require('express');
+const router = express.Router();
+const verifyToken = require('./middleware/verifyToken');
+const authorize = require('./middleware/authorize');
+
+// Public route
+router.get('/all-courses', getAllCourses);
+
+// Student/Editor/Admin route
+router.post('/enroll', verifyToken, authorize(['student', 'editor', 'admin']), enrollInCourse);
+
+// Admin-only route
+router.delete('/delete-user/:id', verifyToken, authorize(['admin']), deleteUser);
+
+```
+
+## 5. 401 Unauthorized vs. 403 Forbidden
+
+As a "Master" developer, you must use the correct HTTP status codes:
+
+* **401 Unauthorized:** "I don't know who you are." (The user isn't logged in or the token is invalid).
+* **403 Forbidden:** "I know who you are, but you aren't allowed to be here." (The user is logged in as a Student but is trying to access the Admin panel).
+
+## Practice: The "Admin" Test
+
+1. Log in as a user with the role `'student'`.
+2. Try to send a `DELETE` request to an admin-only route using Postman.
+3. Ensure your server returns a `403 Forbidden` status.
+4. Manually change your role in MongoDB to `'admin'` and try the request again. It should now work!
+
+:::info Frontend Security
+RBAC isn't just for the backend! On your React frontend, you should hide buttons or links that the user doesn't have permission to use. However, **never rely on frontend security alone.** A smart user can always open the console and show a hidden button. Always verify the role on the **Backend**.
+:::
\ No newline at end of file
diff --git a/absolute-beginners/full-stack/authentication/sessions-vs-tokens.mdx b/absolute-beginners/full-stack/authentication/sessions-vs-tokens.mdx
index e345ed2..cd874b0 100644
--- a/absolute-beginners/full-stack/authentication/sessions-vs-tokens.mdx
+++ b/absolute-beginners/full-stack/authentication/sessions-vs-tokens.mdx
@@ -1 +1,76 @@
-
\ No newline at end of file
+---
+title: "Sessions vs. Tokens"
+sidebar_label: "5. Sessions vs. Tokens"
+sidebar_position: 5
+description: "A deep dive comparison between stateful session-based auth and stateless token-based auth."
+tags: ["authentication", "sessions", "tokens", "jwt", "security", "full-stack development"]
+keywords: ["sessions", "tokens", "jwt", "authentication", "Node.js", "Express", "MongoDB", "PostgreSQL", "stateful", "stateless"]
+---
+
+To understand the difference, we have to look at where the "Proof of Identity" is stored: on the **Server** or with the **User**.
+
+## 1. Session-Based Authentication (Stateful)
+
+In a session-based system, the server is responsible for remembering the user. When a user logs in, the server creates a "Session" and stores it in memory or a database. The server then gives the user a unique **Session ID** (usually stored in a cookie). Every time the user makes a request, they send that Session ID, and the server looks it up to see who they are.
+
+1. **Login:** User sends credentials.
+2. **Creation:** Server creates a session record in the database (or Redis) and a unique **Session ID**.
+3. **Cookie:** Server sends the Session ID to the browser in a cookie.
+4. **Verification:** For every request, the browser sends the cookie. The server looks up the ID in its database to see who it belongs to.
+
+**Characteristics:**
+* **Stateful:** The server must keep track of active sessions.
+* **Heavy:** Requires a database lookup for every single request.
+* **Easy Revocation:** If you want to log a user out remotely, you just delete the session from your database.
+
+## 2. Token-Based Authentication (Stateless)
+
+In a token-based system (like JWT), the user is responsible for carrying their own identity.
+
+1. **Login:** User sends credentials.
+2. **Creation:** Server verifies and "signs" a **JSON Web Token (JWT)** containing user info.
+3. **Response:** Server sends the JWT to the user. The server **does not** save anything.
+4. **Verification:** For every request, the user sends the JWT. The server checks the "Signature." If the signature is valid, the server trusts the data inside.
+
+**Characteristics:**
+* **Stateless:** The server doesn't need to store anything.
+* **Lightweight:** No database lookups needed to verify identity.
+* **Difficult Revocation:** Once a token is issued, it is valid until it expires. You can't easily "un-sign" it.
+
+## 3. Direct Comparison
+
+| Feature | Sessions | Tokens (JWT) |
+| :--- | :--- | :--- |
+| **Storage** | Server-side (DB/Redis) | Client-side (Cookie/LocalStorage) |
+| **Scalability** | Harder (Servers must share session data) | Easier (Any server can verify the token) |
+| **Revocation** | Instant (Delete session) | Hard (Must wait for expiry or use Blacklists) |
+| **Payload** | Small (Only an ID) | Large (Contains user data/claims) |
+| **Best For** | Monoliths & High-Security Apps | APIs, Microservices, & Mobile Apps |
+
+## 4. The "MERN" Standard
+
+At **CodeHarborHub**, we primarily teach **JWT (Tokens)** for our MERN stack projects.
+
+**Why?** Because modern web development often separates the Frontend (React) and the Backend (Node/Express). Often, these are hosted on different domains. JWTs are built to work perfectly across different domains and are the native language of mobile applications.
+
+## 5. When to choose what?
+
+### Use Sessions if:
+* You are building a traditional website where the frontend and backend are tightly coupled.
+* You need the ability to instantly kick users off the platform (e.g., a banking app).
+
+### Use Tokens if:
+* You are building a Single Page Application (SPA) with React/Next.js.
+* You plan to have a Mobile App (Android/iOS) using the same API.
+* You want a "Stateless" architecture that is easy to scale to millions of users.
+
+## Practice: The "Network" Test
+
+1. Open your browser's **Developer Tools (F12)**.
+2. Go to the **Application** tab.
+3. Check **Cookies**: If you see a long string labeled `connect.sid` or `session_id`, the site uses **Sessions**.
+4. Check **Local Storage**: If you see a key labeled `token` or `jwt`, the site likely uses **Tokens**.
+
+:::info
+You don't have to choose 100%. Some "Master" developers use **Hybrid** systems: They use JWTs for API access but store those JWTs inside an **HttpOnly Cookie** for the security benefits of sessions with the scalability of tokens!
+:::
\ No newline at end of file
diff --git a/absolute-beginners/full-stack/backend/error-handling.mdx b/absolute-beginners/full-stack/backend/error-handling.mdx
index 8f3e910..6dd4b25 100644
--- a/absolute-beginners/full-stack/backend/error-handling.mdx
+++ b/absolute-beginners/full-stack/backend/error-handling.mdx
@@ -43,6 +43,18 @@ app.use((err, req, res, next) => {
});
```
+:::info Security Tip
+Exposing the error message directly to the client can leak sensitive information about the server's internal state. It is safer to only include detailed error information when the application is running in a development environment.
+
+```javascript title="server.js"
+ res.status(500).json({
+ success: false,
+ message: "Internal Server Error",
+ error: process.env.NODE_ENV === 'development' ? err.message : {}
+ });
+```
+:::
+
## 3. Throwing Custom Errors
Sometimes, the code isn't "broken," but the user did something wrong (like entering the wrong password). In these cases, you can "throw" your own error to trigger the catch block.
diff --git a/absolute-beginners/full-stack/backend/express.mdx b/absolute-beginners/full-stack/backend/express.mdx
index 805a1d2..c075db1 100644
--- a/absolute-beginners/full-stack/backend/express.mdx
+++ b/absolute-beginners/full-stack/backend/express.mdx
@@ -93,6 +93,32 @@ npm install -g nodemon
nodemon server.js
```
+:::info
+Installing packages globally with `-g` is generally discouraged for project-specific tools. It is better to install nodemon as a development dependency to ensure that all developers working on the project use the same version.
+
+```bash
+npm install --save-dev nodemon
+```
+
+Then, you can add a script to your `package.json`:
+
+```json title="package.json"
+{
+ "scripts": {
+ "dev": "nodemon server.js"
+ }
+}
+```
+
+Now you can start your server with:
+
+```bash
+npm run dev
+```
+
+This way, everyone on the project will have the same version of nodemon, and you won't run into issues if someone doesn't have it installed globally.
+:::
+
## Practice: The Dynamic Greeter
Let's use **URL Parameters** to greet users by name!
diff --git a/absolute-beginners/full-stack/backend/mvc-pattern.mdx b/absolute-beginners/full-stack/backend/mvc-pattern.mdx
index e5c8611..3b08753 100644
--- a/absolute-beginners/full-stack/backend/mvc-pattern.mdx
+++ b/absolute-beginners/full-stack/backend/mvc-pattern.mdx
@@ -88,6 +88,21 @@ exports.getProfile = async (req, res) => {
};
```
+:::info
+The `async` controller function lacks error handling. If the database call fails, the promise will reject without being caught, which can lead to unhandled promise rejections. It is best practice to wrap the logic in a `try...catch` block and pass the error to the `next` middleware.
+
+```javascript title="userController.js"
+exports.getProfile = async (req, res, next) => {
+ try {
+ const userData = await User.findById(req.params.id);
+ res.json(userData);
+ } catch (error) {
+ next(error);
+ }
+};
+```
+:::
+
**3. The Model (`/models/userModel.js`):** The definition of the data.
```javascript title="userModel.js"
diff --git a/absolute-beginners/full-stack/backend/nodejs-basics.mdx b/absolute-beginners/full-stack/backend/nodejs-basics.mdx
index 8b8eaf1..fa3d7bd 100644
--- a/absolute-beginners/full-stack/backend/nodejs-basics.mdx
+++ b/absolute-beginners/full-stack/backend/nodejs-basics.mdx
@@ -92,6 +92,20 @@ fs.readFile('note.txt', 'utf8', (err, data) => {
});
```
+:::info Error Handling
+In the above example, if `note.txt` does not exist, the `err` object will contain the error details. Throwing an error inside an asynchronous callback will cause the Node.js process to crash. Instead of throwing, you should log the error or handle it gracefully to keep the server running.
+
+```javascript title="readFile.js"
+fs.readFile('note.txt', 'utf8', (err, data) => {
+ if (err) {
+ console.error("Error reading file:", err);
+ return;
+ }
+ console.log("File content:", data);
+});
+```
+:::
+
## Practice: The Greeting Machine
1. Create a file named `greet.js`.
diff --git a/absolute-beginners/full-stack/backend/routing.mdx b/absolute-beginners/full-stack/backend/routing.mdx
index ff36bc4..53ac3eb 100644
--- a/absolute-beginners/full-stack/backend/routing.mdx
+++ b/absolute-beginners/full-stack/backend/routing.mdx
@@ -118,11 +118,11 @@ router.get('/all', (req, res) => {
router.get('/:id', (req, res) => {
const bookId = req.params.id;
// In a real app, you'd fetch the book from the database
- if (bookId == 1) {
- res.json({ id: 1, title: "The Great Gatsby" });
- } else if (bookId == 2) {
- res.json({ id: 2, title: "To Kill a Mockingbird" });
- } else {
+ if (bookId === "1") {
+ res.json({ id: 1, title: "The Great Gatsby" });
+ } else if (bookId === "2") {
+ res.json({ id: 2, title: "To Kill a Mockingbird" });
+ } else {
res.status(404).send("Book not found!");
}
});
diff --git a/absolute-beginners/full-stack/career/_category_.json b/absolute-beginners/full-stack/career/_category_.json
new file mode 100644
index 0000000..faffa97
--- /dev/null
+++ b/absolute-beginners/full-stack/career/_category_.json
@@ -0,0 +1,9 @@
+{
+ "label": "Career",
+ "position": 15,
+ "link": {
+ "type": "generated-index",
+ "title": "Career: Advancing Your Software Engineering Journey",
+ "description": "Explore opportunities and strategies for advancing your career in software engineering. This track covers everything from resume building to interview preparation and professional development."
+ }
+}
\ No newline at end of file
diff --git a/absolute-beginners/full-stack/cloud/_category_.json b/absolute-beginners/full-stack/cloud/_category_.json
new file mode 100644
index 0000000..69f6a66
--- /dev/null
+++ b/absolute-beginners/full-stack/cloud/_category_.json
@@ -0,0 +1,9 @@
+{
+ "label": "Cloud",
+ "position": 12,
+ "link": {
+ "type": "generated-index",
+ "title": "Cloud Computing: Scalable and Flexible Infrastructure",
+ "description": "Explore the world of cloud computing and learn how to leverage scalable and flexible infrastructure for your applications. This track covers everything from cloud providers and deployment strategies to cost optimization and security."
+ }
+}
\ No newline at end of file
diff --git a/absolute-beginners/full-stack/databases/_category_.json b/absolute-beginners/full-stack/databases/_category_.json
new file mode 100644
index 0000000..ef11009
--- /dev/null
+++ b/absolute-beginners/full-stack/databases/_category_.json
@@ -0,0 +1,9 @@
+{
+ "label": "Databases",
+ "position": 9,
+ "link": {
+ "type": "generated-index",
+ "title": "Databases: The Backbone of Data Management",
+ "description": "Dive into the world of databases and learn how to store, manage, and retrieve data efficiently. This track covers everything from SQL and NoSQL databases to database design, optimization, and security."
+ }
+}
\ No newline at end of file
diff --git a/absolute-beginners/full-stack/databases/introduction.mdx b/absolute-beginners/full-stack/databases/introduction.mdx
index e345ed2..19c84b6 100644
--- a/absolute-beginners/full-stack/databases/introduction.mdx
+++ b/absolute-beginners/full-stack/databases/introduction.mdx
@@ -1 +1,83 @@
-
\ No newline at end of file
+---
+title: "Introduction to Databases"
+sidebar_label: "1. Introduction"
+sidebar_position: 1
+description: "Learn the basics of data persistence and the difference between SQL and NoSQL databases."
+tags: ["databases", "mongodb", "sql", "nosql", "full-stack"]
+keywords: ["database", "sql", "nosql", "mongodb", "data persistence", "collections", "documents", "schemas"]
+---
+
+In the "Absolute Beginners" journey, you've built interfaces and servers. Now, we need a place to store data like user profiles, blog posts, and cricket scores so they don't disappear. This is the role of a **Database**.
+
+## 1. Why do we need a Database?
+
+Imagine you are building a social media app. When a user signs up, you need to save their:
+* Username and Password
+* Profile Picture
+* Followers list
+
+If we stored this in a simple JavaScript variable, it would be deleted the second the server restarted. A database writes this information to a **Physical Disk**, ensuring it stays there until you explicitly delete it.
+
+## 2. The Two Main Types of Databases
+
+In the modern web, databases are generally split into two categories. At **CodeHarborHub**, we focus on both, but we start with NoSQL.
+
+### Relational Databases (SQL)
+Think of these like an **Excel Spreadsheet**. Data is organized into tables with fixed rows and columns.
+* **Examples:** PostgreSQL, MySQL, SQLite.
+* **Best for:** Financial systems, inventory, or apps where data structure never changes.
+
+### Non-Relational Databases (NoSQL)
+Think of these like a **Folder of JSON Files**. Data is stored in flexible "documents."
+* **Examples:** **MongoDB** (Our Choice), Firebase, Cassandra.
+* **Best for:** Social media, content management, and fast-moving startups where the data structure might grow over time.
+
+## 3. Why we use MongoDB for Full-Stack
+
+As a JavaScript developer, **MongoDB** is your best friend because it stores data in a format called **BSON**, which looks and acts exactly like a **JavaScript Object**.
+
+**Traditional SQL (Table):**
+| ID | Name | Role |
+| :--- | :--- | :--- |
+| 1 | Ajay | Mentor |
+
+**MongoDB (Document):**
+
+```json
+{
+ "_id": 1,
+ "name": "Ajay",
+ "role": "Mentor",
+ "skills": ["React", "Node", "Tailwind"]
+}
+```
+
+*Notice how we can easily add an array of "skills" inside the document? That's the power of NoSQL!*
+
+## 4. How the Database fits in the Stack
+
+The database sits at the very end of the "Request-Response" chain.
+
+
+1. **The Client (React):** Asks for data (e.g., "Show me my notes").
+2. **The Server (Express):** Receives the request and asks the database.
+3. **The Database (MongoDB):** Finds the data and sends it back to the server.
+4. **The Server:** Sends the data back to the client to be displayed.
+
+
+## 5. Key Terms to Remember
+
+* **Database:** The entire container for your data.
+* **Collection:** A "folder" inside the database (e.g., a "Users" collection).
+* **Document:** A single item inside a collection (e.g., one specific User's data).
+* **Schema:** The "blueprint" or rules for what a document should look like.
+
+## The "Persistence" Mindset
+
+As you move forward, always ask yourself: *"If I restart my computer right now, will this data still exist?"*
+If the answer is **No**, it’s in the RAM.
+If the answer is **Yes**, it’s in the Database.
+
+:::info
+At the Hub, we use **MongoDB Atlas**. It is a "Database-as-a-Service," meaning your data lives in the cloud, so you don't have to worry about managing a database server on your own computer.
+:::
\ No newline at end of file
diff --git a/absolute-beginners/full-stack/databases/postgresql/_category_.json b/absolute-beginners/full-stack/databases/postgresql/_category_.json
new file mode 100644
index 0000000..4e10725
--- /dev/null
+++ b/absolute-beginners/full-stack/databases/postgresql/_category_.json
@@ -0,0 +1,9 @@
+{
+ "label": "PostgreSQL",
+ "position": 2,
+ "link": {
+ "type": "generated-index",
+ "title": "PostgreSQL: A Powerful Open-Source Database",
+ "description": "Learn how to use PostgreSQL, a powerful open-source relational database system. This track covers everything from basic queries to advanced features like indexing, transactions, and replication."
+ }
+}
\ No newline at end of file
diff --git a/absolute-beginners/full-stack/databases/postgresql/indexing.mdx b/absolute-beginners/full-stack/databases/postgresql/indexing.mdx
index e345ed2..acc78c4 100644
--- a/absolute-beginners/full-stack/databases/postgresql/indexing.mdx
+++ b/absolute-beginners/full-stack/databases/postgresql/indexing.mdx
@@ -1 +1,72 @@
-
\ No newline at end of file
+---
+title: "PostgreSQL Indexing & Performance"
+sidebar_label: 4. Indexing & Performance
+sidebar_position: 4
+description: "Learn how to speed up your database queries using indexes and understand when to use them."
+tags: ["databases", "postgresql", "sql", "indexing", "performance", "full-stack"]
+keywords: ["postgresql", "sql", "indexing", "performance", "explain analyze", "unique index", "b-tree"]
+---
+
+Imagine you are looking for a specific topic in a 500-page textbook.
+* **Without an Index:** You have to read every single page from the beginning until you find what you need. This is called a **Full Table Scan**.
+* **With an Index:** You flip to the back of the book, find the topic alphabetically, see the page number, and jump straight to it.
+
+In PostgreSQL, an **Index** works exactly the same way. It is a separate data structure that allows the database to find rows much faster without scanning the entire table.
+
+## 1. How Indexing Works
+
+When you create an index on a column (like `email`), Postgres creates a separate, sorted data structure (usually a **B-Tree**) that points to the actual rows in your table.
+
+Instead of checking every row, Postgres uses this "map" to find the data in a fraction of the time.
+
+## 2. Creating your first Index
+
+By default, PostgreSQL automatically creates an index for your **Primary Key**. But for other columns you search frequently, you have to create them manually.
+
+```sql title="Creating an Index"
+-- Syntax: CREATE INDEX index_name ON table_name (column_name);
+
+CREATE INDEX idx_user_email ON users (email);
+```
+
+Now, any query using `WHERE email = '...'` will run significantly faster.
+
+## 3. When should you Index?
+
+Indexing isn't free. Every index takes up extra disk space and slows down **INSERT**, **UPDATE**, and **DELETE** operations (because the index must be updated too).
+
+| Index These | Don't Index These |
+| :--- | :--- |
+| Columns used in `WHERE` clauses frequently. | Columns that are rarely searched. |
+| Columns used to `JOIN` tables. | Columns with very few unique values (e.g., `gender`). |
+| Columns used for `ORDER BY` (sorting). | Small tables (Postgres is faster scanning small tables directly). |
+| Columns with unique constraints (like `username`). | Tables that get thousands of writes per second. |
+
+## 4. The "Explain" Command (The Developer's X-Ray)
+
+How do you know if your index is actually working? Use the `EXPLAIN` keyword before your query. It shows you the "Execution Plan" the database intends to use.
+
+```sql title="Using EXPLAIN"
+EXPLAIN ANALYZE SELECT * FROM users WHERE email = 'ajay@hub.com';
+```
+
+Look for **"Index Scan"** in the results. If you see **"Seq Scan"** (Sequential Scan), it means Postgres is reading the whole table because it didn't find a useful index.
+
+## 5. Unique Indexes
+
+A Unique Index does two things: it speeds up searches AND ensures no two rows have the same value in that column. This is perfect for things like `passport_number` or `aadhaar_card`.
+
+```sql title="Creating a Unique Index"
+CREATE UNIQUE INDEX idx_unique_username ON users (username);
+```
+
+## Practice: The Performance Test
+
+1. Create a table called `large_data` with 100,000 random entries.
+2. Run a query searching for a specific ID *without* an index and note the time (using `EXPLAIN ANALYZE`).
+3. Add an index to that column.
+4. Run the same query again. Notice the massive jump in speed!
+
+:::info The "Master" Rule
+Don't over-index! A table with too many indexes becomes heavy and slow to update. Only add an index when you notice a specific query is becoming sluggish. **Measure first, then optimize.**
+:::
\ No newline at end of file
diff --git a/absolute-beginners/full-stack/databases/postgresql/queries.mdx b/absolute-beginners/full-stack/databases/postgresql/queries.mdx
index e345ed2..ed2cb31 100644
--- a/absolute-beginners/full-stack/databases/postgresql/queries.mdx
+++ b/absolute-beginners/full-stack/databases/postgresql/queries.mdx
@@ -1 +1,110 @@
-
\ No newline at end of file
+---
+title: "Basic SQL Queries"
+sidebar_label: "2. Basic Queries"
+sidebar_position: 2
+description: "Master the four basic operations of SQL (CRUD) to interact with your PostgreSQL tables."
+tags: [sql, queries, crud, beginners]
+keywords: [sql, queries, crud, beginners]
+---
+
+In the world of databases, almost everything we do falls under **CRUD**: **C**reate, **R**ead, **U**pdate, and **D**elete. In SQL, we use specific commands for each of these actions.
+
+## 1. CREATE (Insert Dataz)
+
+To add new information to a table, we use the `INSERT INTO` command. You must specify the table name and the columns you are filling.
+
+```sql title="Insert Query"
+INSERT INTO users (username, email, age)
+VALUES ('amaster', 'ajay@codeharborhub.com', 25);
+```
+
+:::tip
+If a column has `SERIAL` (like an ID), you don't need to include it in your query; Postgres will generate it automatically!
+:::
+
+## 2. READ (Select Data)
+
+The `SELECT` statement is the most common command you will use. It allows you to pull data out of your tables.
+
+### Select All Columns
+
+```sql title="Select All"
+SELECT * FROM users;
+```
+
+### Select Specific Columns
+
+```sql title="Select Specific Columns"
+SELECT username, email FROM users;
+```
+
+### Filtering with WHERE
+
+You don't usually want *all* users. Use `WHERE` to narrow it down:
+
+```sql title="Select with WHERE"
+-- Find a specific user
+SELECT * FROM users WHERE username = 'amaster';
+
+-- Find all users older than 18
+SELECT * FROM users WHERE age > 18;
+```
+
+## 3. UPDATE (Change Data)
+
+To change existing information, we use `UPDATE`.
+
+:::warning Warning: The WHERE Clause
+Always use a `WHERE` clause with `UPDATE`. If you forget it, Postgres will update **every single row** in your table!
+:::
+
+```sql title="Update Query"
+UPDATE users
+SET email = 'newemail@hub.com'
+WHERE username = 'amaster';
+```
+
+## 4. DELETE (Remove Data)
+
+To remove a record, use `DELETE`. Like update, this requires a `WHERE` clause to avoid clearing your entire database.
+
+```sql title="Delete Query"
+DELETE FROM users
+WHERE username = 'amaster';
+```
+
+## 5. Sorting and Limiting
+
+As a developer at **CodeHarborHub**, you'll often want to show the "latest" items or "top" scores.
+
+### ORDER BY (Sorting)
+
+```sql title="Order By"
+-- Sort by age (Youngest first)
+SELECT * FROM users ORDER BY age ASC;
+
+-- Sort by age (Oldest first)
+SELECT * FROM users ORDER BY age DESC;
+```
+
+### LIMIT (Pagination)
+
+If you have 1,000,000 users, you only want to show a few at a time.
+
+```sql title="Limit Query"
+-- Get only the first 5 users
+SELECT * FROM users LIMIT 5;
+```
+
+## Practice: The Cricket Scoreboard
+
+Imagine you have a table called `scores` with columns `player_name` and `runs`. Try to write queries for the following:
+
+1. **Add a player:** Insert "MS Dhoni" with 183 runs.
+2. **Find the winner:** Select the player with the highest runs.
+3. **Correction:** Update the runs for a player who just hit a six (+6).
+4. **Cleanup:** Delete players who have 0 runs.
+
+:::info SQL Case Sensitivity
+While SQL keywords (like `SELECT`) are not case-sensitive, it is standard practice to write them in **ALL CAPS** to make your queries easier to read. Table and column names should stay lowercase.
+:::
\ No newline at end of file
diff --git a/absolute-beginners/full-stack/databases/postgresql/relationships.mdx b/absolute-beginners/full-stack/databases/postgresql/relationships.mdx
index e345ed2..f6f5a3c 100644
--- a/absolute-beginners/full-stack/databases/postgresql/relationships.mdx
+++ b/absolute-beginners/full-stack/databases/postgresql/relationships.mdx
@@ -1 +1,131 @@
-
\ No newline at end of file
+---
+title: "PostgreSQL Relationships & Joins"
+sidebar_label: "3. Relationships & Joins"
+sidebar_position: 3
+description: "Learn how to connect different tables using Primary Keys, Foreign Keys, and Joins."
+tags: ["databases", "postgresql", "sql", "relationships", "joins", "full-stack"]
+keywords: ["postgresql", "sql", "relationships", "joins", "primary key", "foreign key", "one-to-many", "many-to-many"]
+---
+
+In PostgreSQL, we don't store everything in one place. We create specialized tables and link them. This prevents data duplication and keeps our "CodeHarbor" projects organized.
+
+:::info
+Think of it like a library. You have a "Books" section and an "Authors" section. Instead of writing the author's name in every book entry, you create an "Authors" table and link it to the "Books" table.
+:::
+
+## 1. The Key Players: PK and FK
+
+To link two tables, we use two types of "Keys":
+
+1. **Primary Key (PK):** A unique identifier for every row in a table (usually an `id`). No two rows can have the same PK.
+2. **Foreign Key (FK):** A column in one table that points to the **Primary Key** of another table.
+
+## 2. Types of Relationships
+
+### One-to-Many (1:N)
+The most common relationship.
+* *Example:* One **User** can write many **Posts**.
+* *Implementation:* Put the `user_id` (FK) inside the `posts` table.
+
+### Many-to-Many (M:N)
+* *Example:* One **Student** can enroll in many **Courses**, and one **Course** has many **Students**.
+* *Implementation:* Use a "Join Table" (also called a Junction Table) that sits in the middle and holds the IDs of both.
+
+```sql title="Many-to-Many Example"
+CREATE TABLE students (
+ id SERIAL PRIMARY KEY,
+ name VARCHAR(100)
+);
+
+CREATE TABLE courses (
+ id SERIAL PRIMARY KEY,
+ title VARCHAR(100)
+);
+
+CREATE TABLE enrollments (
+ student_id INT REFERENCES students(id),
+ course_id INT REFERENCES courses(id),
+ PRIMARY KEY (student_id, course_id)
+);
+```
+
+In this example, `enrollments` is the join table that connects `students` and `courses`. Each row in `enrollments` represents one student enrolling in one course.
+
+## 3. Joining Tables with SQL
+
+When you want to see data from two tables at once, you use the `JOIN` command.
+
+Imagine we have two tables: `users` and `orders`.
+
+### a. The INNER JOIN
+
+This returns only the rows where there is a match in both tables.
+
+```sql title="Inner Join Example"
+SELECT users.username, orders.product_name, orders.price
+FROM users
+INNER JOIN orders ON users.id = orders.user_id;
+```
+
+### b. The LEFT JOIN
+
+This returns all users, even if they haven't placed an order. If they haven't ordered, the order columns will show as `NULL`.
+
+```sql title="Left Join Example"
+SELECT users.username, orders.product_name, orders.price
+FROM users
+LEFT JOIN orders ON users.id = orders.user_id;
+```
+### c. The RIGHT JOIN
+
+This is the opposite of LEFT JOIN. It returns all orders, even if they don't have a matching user. If an order doesn't have a user, the user columns will show as `NULL`.
+
+```sql title="Right Join Example"
+SELECT users.username, orders.product_name, orders.price
+FROM users
+RIGHT JOIN orders ON users.id = orders.user_id;
+```
+### d. The FULL OUTER JOIN
+
+This returns all users and all orders. If there is no match, the missing side will show as `NULL`.
+
+```sql title="Full Outer Join Example"
+SELECT users.username, orders.product_name, orders.price
+FROM users
+FULL OUTER JOIN orders ON users.id = orders.user_id;
+```
+
+## 4. Defining Relationships in Code
+
+When you create your tables, you must tell Postgres about the link.
+
+```sql title="Defining Relationships"
+-- 1. Create the parent table
+CREATE TABLE authors (
+ id SERIAL PRIMARY KEY,
+ name VARCHAR(100) NOT NULL
+);
+
+-- 2. Create the child table with a Foreign Key
+CREATE TABLE books (
+ id SERIAL PRIMARY KEY,
+ title VARCHAR(200),
+ author_id INT REFERENCES authors(id) ON DELETE CASCADE
+);
+```
+
+> **What is `ON DELETE CASCADE`?** This is a "Master" move. It means if you delete an Author, all of their Books will be automatically deleted too. No "orphan" data left behind!
+
+## Practice: The Team & Player Link
+
+Try to build a small system for a Cricket League:
+1. Create a `teams` table (id, team_name).
+2. Create a `players` table (id, player_name, team_id).
+3. Insert your favorite team and a few players (don't forget to link them via `team_id`).
+4. Write a `JOIN` query to show every player alongside their team name.
+
+:::info Aliases
+SQL queries can get long. Use "Aliases" (nicknames) to keep them short!
+`SELECT u.username, o.price FROM users u JOIN orders o ON u.id = o.user_id;`
+(Here, `u` is an alias for `users` and `o` is an alias for `orders`).
+:::
\ No newline at end of file
diff --git a/absolute-beginners/full-stack/databases/postgresql/setup.mdx b/absolute-beginners/full-stack/databases/postgresql/setup.mdx
index e345ed2..82410b9 100644
--- a/absolute-beginners/full-stack/databases/postgresql/setup.mdx
+++ b/absolute-beginners/full-stack/databases/postgresql/setup.mdx
@@ -1 +1,104 @@
-
\ No newline at end of file
+---
+title: "Setting Up PostgreSQL"
+sidebar_label: "1. Setup & Installation"
+sidebar_position: 1
+description: "Step-by-step guide to installing PostgreSQL locally and using pgAdmin for database management."
+tags: ["databases", "postgresql", "sql", "full-stack"]
+keywords: ["postgresql", "pgadmin", "sql", "database setup", "psql", "node-postgres", "database connection"]
+---
+
+PostgreSQL (often called **Postgres**) is a Relational Database Management System (RDBMS). Unlike MongoDB, where you just "throw" data in, Postgres requires a solid foundation. Let's get your environment ready.
+
+## 1. Installation
+
+### For Windows:
+1. Download the installer from the [Official PostgreSQL Website](https://www.postgresql.org/download/windows/).
+2. Run the `.exe` file.
+3. **Components:** Ensure you select **PostgreSQL Server**, **pgAdmin 4** (the visual editor), and **Command Line Tools**.
+4. **Password:** Set a password for the default user (`postgres`). **Do not forget this password!**
+5. **Port:** Keep the default port `5432`.
+
+### For macOS:
+The easiest way is using **Homebrew**:
+
+```bash
+brew install postgresql
+brew services start postgresql
+```
+
+## 2. Meet pgAdmin 4
+
+pgAdmin is the "Dashboard" for your Postgres databases. It allows you to create tables, write queries, and view data without using the terminal.
+
+1. Open **pgAdmin 4**.
+2. Enter the "Master Password" you created during installation.
+3. In the left sidebar, right-click **Servers** > **Register** > **Server**.
+4. Give it a name (e.g., "LocalHost").
+5. In the **Connection** tab, enter `localhost` as the hostname and your password.
+
+## 3. Creating Your First Database
+
+You can create a database using the GUI or the **Query Tool**. As a developer, you should get comfortable with SQL commands.
+
+1. Right-click your server and select **Query Tool**.
+2. Type the following command:
+
+ ```sql
+ CREATE DATABASE codeharbor_db;
+ ```
+
+3. Highlight the text and click the **Execute (Play)** button.
+
+## 4. Connecting via Terminal (psql)
+
+Sometimes you need to access Postgres quickly via your terminal.
+
+```bash
+# Log in as the default postgres user
+psql -U postgres
+```
+
+* `\l` — List all databases.
+* `\c database_name` — Connect to a specific database.
+* `\dt` — Display all tables in the current database.
+* `\q` — Quit the terminal.
+
+## 5. Connecting Postgres to Node.js
+
+To let your Express server talk to Postgres, you need a driver. We use the `pg` library.
+
+**Install it:**
+
+```bash
+npm install pg
+```
+
+**Basic Connection Code:**
+
+```javascript
+const { Pool } = require('pg');
+
+const pool = new Pool({
+ user: 'postgres',
+ host: 'localhost',
+ database: 'codeharbor_db',
+ password: 'your_password',
+ port: 5432,
+});
+
+pool.query('SELECT NOW()', (err, res) => {
+ if (err) console.error("Connection Error:", err);
+ else console.log("Connected to Postgres at:", res.rows[0].now);
+ pool.end();
+});
+```
+
+## Common Pitfalls for Beginners
+
+* **Port Conflicts:** If port `5432` is already in use, Postgres won't start. Ensure no other database (like an old MySQL install) is using it.
+* **Case Sensitivity:** In Postgres, table names are usually lowercase. If you create a table named `Users`, Postgres might look for `users` and throw an error. **Pro Tip: Always use snake_case (`user_profiles`).**
+* **Forgeting the Semicolon:** Unlike JavaScript, every SQL command **must** end with a `;`.
+
+:::info
+If you don't want to install Postgres on your computer, you can use **Supabase** or **ElephantSQL**. They provide cloud-based PostgreSQL databases for free, similar to how MongoDB Atlas works!
+:::
\ No newline at end of file
diff --git a/absolute-beginners/full-stack/databases/redis/_category_.json b/absolute-beginners/full-stack/databases/redis/_category_.json
new file mode 100644
index 0000000..1e3f1fc
--- /dev/null
+++ b/absolute-beginners/full-stack/databases/redis/_category_.json
@@ -0,0 +1,9 @@
+{
+ "label": "Redis",
+ "position": 3,
+ "link": {
+ "type": "generated-index",
+ "title": "Redis: An In-Memory Data Structure Store",
+ "description": "Learn how to use Redis, an in-memory data structure store. This track covers everything from basic operations to advanced features like pub/sub, transactions, and persistence."
+ }
+}
\ No newline at end of file
diff --git a/absolute-beginners/full-stack/databases/redis/caching.mdx b/absolute-beginners/full-stack/databases/redis/caching.mdx
index e345ed2..536932d 100644
--- a/absolute-beginners/full-stack/databases/redis/caching.mdx
+++ b/absolute-beginners/full-stack/databases/redis/caching.mdx
@@ -1 +1,114 @@
-
\ No newline at end of file
+---
+title: "Caching with Redis"
+sidebar_label: "3. Caching Strategy"
+sidebar_position: 3
+description: "Learn the Cache-Aside pattern to speed up your API responses and reduce database load."
+tags: ["Redis", "Caching", "Backend Performance", "Node.js", "Database Optimization"]
+keywords: ["Redis", "Caching", "Cache-Aside Pattern", "Backend Performance", "Node.js", "Database Optimization", "Cache Invalidation"]
+---
+
+Caching is the process of storing copies of data in a temporary storage location (Redis) so that future requests for that data can be served faster.
+
+## 1. The "Cache-Aside" Pattern
+
+This is the most common strategy used by "Master" developers. The logic follows these steps:
+
+1. **Check the Cache:** Does Redis have the data?
+2. **Cache Hit:** If yes, return the data immediately. (Super Fast ⚡)
+3. **Cache Miss:** If no, go to the Database (MongoDB/Postgres).
+4. **Update Cache:** Take the data from the database and save it in Redis for next time.
+5. **Return Data:** Send the data to the user.
+
+## 2. Implementing Caching in Node.js
+
+Let's say we have a slow route that fetches a list of products. Here is how we add a Redis layer:
+
+```javascript title="server.js"
+const client = require('./redisClient');
+const Product = require('./models/productModel');
+
+app.get('/api/products', async (req, res) => {
+ const cacheKey = 'all_products';
+
+ try {
+ // 1. Try to get data from Redis
+ const cachedData = await client.get(cacheKey);
+
+ if (cachedData) {
+ console.log("⚡ Serving from Cache");
+ return res.json(JSON.parse(cachedData));
+ }
+
+ // 2. If not in cache, fetch from Database
+ console.log("🐢 Serving from Database");
+ const products = await Product.find();
+
+ // 3. Save the result in Redis for next time (expires in 1 hour)
+ await client.set(cacheKey, JSON.stringify(products), {
+ EX: 3600
+ });
+
+ // 4. Send response
+ res.json(products);
+
+ } catch (error) {
+ res.status(500).send(error.message);
+ }
+});
+
+```
+
+## 3. When to Cache (and when not to)
+
+Caching is powerful, but it's not for everything.
+
+| Good for Caching | Bad for Caching |
+| --- | --- |
+| **Static Data:** FAQ pages, product catalogs. | **Rapidly Changing Data:** Live stock prices, GPS locations. |
+| **Expensive Queries:** Complex calculations or long reports. | **Personalized Data:** Shopping carts (store these in sessions instead). |
+| **High-Traffic Pages:** The homepage or trending posts. | **Sensitive Data:** Passwords or private bank details. |
+
+## 4. Cache Invalidation (The Hard Part)
+
+There is a famous saying in programming: *"There are only two hard things in Computer Science: cache invalidation and naming things."*
+
+**Cache Invalidation** means deleting the old data from Redis when the database changes. If you update a product's price in MongoDB but don't delete the Redis cache, your users will still see the old, wrong price!
+
+**Solution:** Whenever you `UPDATE` or `DELETE` data in your database, make sure to delete the corresponding key in Redis:
+
+```javascript title="server.js"
+app.put('/api/products/:id', async (req, res) => {
+ // 1. Update the DB
+ await Product.findByIdAndUpdate(req.params.id, req.body);
+
+ // 2. DELETE the old cache!
+ await client.del('all_products');
+
+ res.send("Product updated and cache cleared!");
+});
+
+```
+
+## 5. Performance Comparison
+
+| Action | Time Taken (Approx) |
+| --- | --- |
+| **Database Query (No Cache)** | 100ms - 500ms |
+| **Redis Cache Hit** | 1ms - 5ms |
+
+*By using Redis, you can make your application up to **100x faster** for your users!*
+
+## Practice: The Cricket Live Score Cache
+
+1. Create a route `/api/score`.
+2. Inside, simulate a slow process (like a 2-second delay using `setTimeout`).
+3. Implement the Cache-Aside pattern.
+4. Notice how the first request takes 2 seconds, but every request after that is instant!
+
+:::info Naming Keys
+As your app grows, you will have hundreds of keys. Use a colon `:` to organize them like folders:
+
+* `user:profile:101`
+* `product:details:505`
+* `site:settings`
+:::
\ No newline at end of file
diff --git a/absolute-beginners/full-stack/databases/redis/intro.mdx b/absolute-beginners/full-stack/databases/redis/intro.mdx
index e345ed2..b84c410 100644
--- a/absolute-beginners/full-stack/databases/redis/intro.mdx
+++ b/absolute-beginners/full-stack/databases/redis/intro.mdx
@@ -1 +1,83 @@
-
\ No newline at end of file
+---
+title: "Introduction to Redis"
+sidebar_label: "1. Introduction"
+sidebar_position: 1
+description: "Learn what Redis is, why it's so fast, and how it's used for caching and real-time data."
+tags: ["databases", "redis", "cache", "full-stack"]
+keywords: ["redis", "cache", "in-memory database", "real-time data", "key-value store", "redis commands"]
+---
+
+**Redis** stands for **Remote Dictionary Server**. It is an open-source, in-memory data structure store. In the "Master" developer's toolkit, Redis is primarily used as a **Cache** or a **Message Broker**.
+
+## 1. Why is Redis so Fast?
+
+Standard databases (like MongoDB or Postgres) write data to a **Solid State Drive (SSD)** or **Hard Drive**. Reading from a disk is slow.
+
+Redis keeps all its data in the **RAM**.
+* **Disk access:** Takes milliseconds.
+* **RAM access:** Takes microseconds.
+
+Because of this, Redis can handle **millions of requests per second**, making it perfect for high-traffic apps.
+
+## 2. Common Use Cases
+
+At the Hub, we don't replace our main database with Redis. Instead, we use them together:
+
+### Caching
+If a user requests the same "Top 10 Cricket Scores" 1,000 times a minute, why ask the slow database every time?
+1. Ask the database once.
+2. Save the result in **Redis**.
+3. For the next 999 requests, serve it instantly from Redis.
+
+### Session Management
+When you log in to a website, the server needs to remember you are logged in for every page you click. Storing these "Sessions" in Redis ensures the login check happens instantly.
+
+### Real-time Leaderboards
+Since Redis is great at updating numbers quickly, it is the #1 choice for live game leaderboards or trending topics.
+
+## 3. Redis Data Types
+
+Unlike SQL tables, Redis uses a **Key-Value** system. You give it a "Key" (like a name) and store a "Value" (the data).
+
+| Type | Description | Example |
+| :--- | :--- | :--- |
+| **Strings** | Simple text or numbers. | `name` -> `Ajay` |
+| **Lists** | A list of strings in order. | `recent_searches` -> `[React, Node, Redis]` |
+| **Sets** | Unordered collection of unique items. | `unique_visitors` -> `{User1, User2}` |
+| **Hashes** | Maps between string fields and values (like a JS Object). | `user:101` -> `{name: "Ajay", role: "Admin"}` |
+
+## 4. The "Key" Command Basics
+
+You can test Redis commands directly in your terminal using `redis-cli`.
+
+```bash title="Redis CLI"
+# Setting a value
+SET player "MS Dhoni"
+
+# Getting a value
+GET player
+# Output: "MS Dhoni"
+
+# Setting an Expiration (The most powerful feature!)
+# This key will disappear automatically after 60 seconds
+SETEX temporary_code 60 "123456"
+```
+
+## 5. Redis vs. The Others
+
+| Feature | PostgreSQL / MongoDB | Redis |
+| :--- | :--- | :--- |
+| **Storage** | Disk (Permanent) | RAM (Temporary/Volatile) |
+| **Speed** | Fast | Ultra-Fast |
+| **Capacity** | Massive (Terabytes) | Limited by your RAM size |
+| **Usage** | Primary Data Source | Caching / Speeding up apps |
+
+## Practice: The "Speed-Up" Strategy
+
+Imagine you are building a website for a major Cricket tournament.
+1. **Main Database:** Stores all players, historical stats, and user accounts.
+2. **Redis:** Stores the **Live Score**. Since the score changes every few seconds and everyone is looking at it, Redis handles the thousands of hits per second while the main database stays relaxed.
+
+:::info Don't forget to PERSIST!
+By default, if your server loses power, everything in Redis is deleted. While you can configure Redis to save to disk, always remember: **Never store data in Redis that you cannot afford to lose** (unless it's also backed up in your main database).
+:::
\ No newline at end of file
diff --git a/absolute-beginners/full-stack/databases/redis/redis-node-setup.mdx b/absolute-beginners/full-stack/databases/redis/redis-node-setup.mdx
new file mode 100644
index 0000000..8ed2dd5
--- /dev/null
+++ b/absolute-beginners/full-stack/databases/redis/redis-node-setup.mdx
@@ -0,0 +1,149 @@
+---
+title: "Setting Up Redis with Node.js"
+sidebar_label: "2. Setup & Connection"
+sidebar_position: 2
+description: "Learn how to install Redis and connect it to your Express server using the official Redis client."
+tags: ["databases", "redis", "node.js", "full-stack"]
+keywords: ["redis setup", "redis node.js connection", "redis client", "redis server installation", "redis commands in node", "redis ttl"]
+---
+
+To use Redis in your full-stack projects, you need two things: the **Redis Server** running on your computer (or in the cloud) and the **Redis Client** library in your Node.js code.
+
+## 1. Installing the Redis Server
+
+### For Windows Users:
+Redis was originally built for Linux. For Windows, the easiest way is to use **WSL2** (Windows Subsystem for Linux) or download the pre-compiled `.msi` from the [MicrosoftArchive GitHub](https://github.com/microsoftarchive/redis/releases).
+
+Once installed, start the server:
+
+```bash
+redis-server
+```
+
+### For macOS Users:
+
+```bash
+brew install redis
+brew services start redis
+```
+
+## 2. Installing the Client Library
+
+In your Node.js project folder, install the official Redis package via NPM:
+
+```bash
+npm install redis
+```
+
+## 3. Creating the Connection
+
+Create a file named `redisClient.js`. In modern Redis (version 4+), we use a Promise-based approach which works perfectly with `async/await`.
+
+```javascript title="redisClient.js"
+const redis = require('redis');
+
+// 1. Create the client
+const client = redis.createClient({
+ url: 'redis://localhost:6379' // Default Redis port
+});
+
+// 2. Handle connection events
+client.on('error', (err) => console.log('Redis Client Error', err));
+client.on('connect', () => console.log('✅ Connected to Redis!'));
+
+// 3. Connect to the server
+async function connectRedis() {
+ await client.connect();
+}
+
+connectRedis();
+
+module.exports = client;
+
+```
+
+## 4. Basic Operations (SET & GET)
+
+Now let's use the client in your `server.js` or a controller.
+
+```javascript title="server.js"
+const client = require('./redisClient');
+
+async function testRedis() {
+ // Storing a value
+ await client.set('favorite_shot', 'Helicopter Shot');
+
+ // Retrieving a value
+ const value = await client.get('favorite_shot');
+ console.log('The stored value is:', value);
+}
+
+testRedis();
+
+```
+
+## 5. Storing Complex Data (Objects)
+
+Redis strings can only store text. To store a JavaScript object (like a user profile), you must **Stringify** it first and **Parse** it when you get it back.
+
+```javascript title="server.js"
+const user = {
+ id: 1,
+ name: "Ajay",
+ role: "Developer"
+};
+
+// Saving the object
+await client.set('user:1', JSON.stringify(user));
+
+// Getting the object
+const cachedUser = await client.get('user:1');
+const finalData = JSON.parse(cachedUser);
+
+console.log(finalData.name); // Output: Ajay
+
+```
+
+## 6. The Power of "TTL" (Time to Live)
+
+One of the best features for a "Master" developer is setting an expiration time. This ensures your RAM doesn't get cluttered with old data.
+
+```javascript title="server.js"
+// This key will automatically delete itself after 3600 seconds (1 hour)
+await client.set('weather_data', '32°C', {
+ EX: 3600
+});
+
+```
+
+## Practice: The "Fast-Welcome" Middleware
+
+Try to create a middleware that:
+
+1. Checks if a user's name is in Redis.
+2. If it is, send a response: `"Welcome back, [Name]! (Served from Cache)"`.
+3. If not, set the name in Redis for 30 seconds and send: `"Hello! (Saved to Cache)"`.
+
+```javascript title="welcomeMiddleware.js"
+const client = require('./redisClient');
+async function welcomeMiddleware(req, res) {
+ const name = req.query.name || 'Guest';
+
+ // Check Redis for the name
+ const cachedName = await client.get(`welcome:${name}`);
+
+ if (cachedName) {
+ return res.send(`Welcome back, ${cachedName}! (Served from Cache)`);
+ } else {
+ // Save the name in Redis for 30 seconds
+ await client.set(`welcome:${name}`, name, { EX: 30 });
+ return res.send('Hello! (Saved to Cache)');
+ }
+}
+module.exports = welcomeMiddleware;
+
+```
+
+:::info GUI for Redis
+If you want to see your data visually instead of using the terminal, download **Redis Insight**. It’s a free tool that lets you browse your keys, see memory usage, and debug your data easily.
+:::
\ No newline at end of file
diff --git a/absolute-beginners/full-stack/databases/redis/redis-pub-sub.mdx b/absolute-beginners/full-stack/databases/redis/redis-pub-sub.mdx
new file mode 100644
index 0000000..fe44542
--- /dev/null
+++ b/absolute-beginners/full-stack/databases/redis/redis-pub-sub.mdx
@@ -0,0 +1,91 @@
+---
+title: "Redis Pub/Sub & Real-time Data"
+sidebar_label: "4. Pub/Sub Pattern"
+sidebar_position: 4
+description: "Learn how to build real-time communication systems using the Redis Publish/Subscribe pattern."
+tags: ["Redis", "Pub/Sub", "Real-time Communication", "Node.js", "WebSockets"]
+keywords: ["Redis", "Pub/Sub", "Real-time Communication", "Node.js", "WebSockets", "Message Broadcasting", "Scalability"]
+---
+
+In traditional web apps, the client has to ask the server for updates. With **Pub/Sub**, the server can "push" information to multiple parts of your application instantly.
+
+## 1. How it Works
+
+The Pub/Sub pattern involves three main parts:
+1. **Publisher:** Sends a message to a specific "Channel."
+2. **Channel:** A named pipe (like `chat_room_1` or `live_scores`).
+3. **Subscriber:** Listens to a channel and reacts whenever a message arrives.
+
+**The Key Rule:** Unlike a database, Pub/Sub is "Fire and Forget." If a subscriber is offline when a message is sent, they will **not** see it when they come back online.
+
+## 2. Implementing Pub/Sub in Node.js
+
+To use Pub/Sub, you usually need **two** Redis client connections: one for publishing and one for subscribing.
+
+```javascript title="pubsub.js"
+const redis = require('redis');
+
+async function startPubSub() {
+ const publisher = redis.createClient();
+ const subscriber = redis.createClient();
+
+ await publisher.connect();
+ await subscriber.connect();
+
+ // 1. Subscriber listens to a channel
+ await subscriber.subscribe('cricket_updates', (message) => {
+ console.log(`📢 Live Update: ${message}`);
+ });
+
+ // 2. Publisher sends a message
+ setTimeout(async () => {
+ await publisher.publish('cricket_updates', 'Dhoni hits a helicopter shot! 🚁');
+ }, 2000);
+}
+
+startPubSub();
+
+```
+
+## 3. Real-World Use Case: Global Notifications
+
+Imagine you have a project like **CodeHarborHub** and you want to notify all online students when a new tutorial is uploaded.
+
+1. **Backend:** When the admin uploads a tutorial, the server publishes a message to the `new_content` channel.
+2. **WebSockets:** Your WebSocket server (Socket.io) is subscribed to that channel.
+3. **Client:** The WebSocket server pushes the notification to every connected browser instantly.
+
+## 4. Redis Pub/Sub vs. Message Queues (RabbitMQ/Kafka)
+
+As a "Master" developer, you should know when to use the right tool:
+
+| Feature | Redis Pub/Sub | Message Queues |
+| --- | --- | --- |
+| **Persistence** | None (Messages are lost if no one is listening). | Persistent (Messages wait until read). |
+| **Delivery** | Instant/Real-time. | Can be delayed/scheduled. |
+| **Speed** | Ultra-Fast. | Fast, but heavier. |
+| **Best For** | Chat, Notifications, Live Stats. | Order processing, Email sending. |
+
+## 5. Pattern Matching (PSUBSCRIBE)
+
+What if you want to listen to multiple channels? Redis allows you to use "Wildcards."
+
+* `subscribe('news:*')` will listen to `news:sports`, `news:tech`, and `news:weather`.
+
+```javascript
+await subscriber.pSubscribe('orders:*', (message, channel) => {
+ console.log(`Order event in ${channel}: ${message}`);
+});
+
+```
+
+## Practice: The "Chat Room" Logic
+
+1. Create two separate terminal scripts: `sender.js` and `receiver.js`.
+2. Make `receiver.js` subscribe to a channel called `codeharbor_chat`.
+3. Use the `readline` module in `sender.js` to take user input and publish it.
+4. Open 3 terminals running `receiver.js` and one running `sender.js`. Watch as all three receivers get the message at once!
+
+:::info Scalability
+If you run your app on multiple servers (Load Balancing), standard WebSockets won't work easily because a user on Server A can't talk to a user on Server B. **Redis Pub/Sub solves this!** It acts as the "glue" that connects all your servers together.
+:::
\ No newline at end of file
diff --git a/absolute-beginners/full-stack/databases/redis/sessions.mdx b/absolute-beginners/full-stack/databases/redis/sessions.mdx
index e345ed2..f98c583 100644
--- a/absolute-beginners/full-stack/databases/redis/sessions.mdx
+++ b/absolute-beginners/full-stack/databases/redis/sessions.mdx
@@ -1 +1,99 @@
-
\ No newline at end of file
+---
+title: "Session Management with Redis"
+sidebar_label: "5. Session Management"
+sidebar_position: 5
+description: "Learn how to use Redis to store user sessions for secure and fast authentication."
+tags: ["Redis", "Session Management", "Authentication", "Node.js", "Express"]
+keywords: ["Redis", "Session Management", "Authentication", "Node.js", "Express", "express-session", "connect-redis", "Session Security"]
+---
+
+When a user logs in, we need to keep them logged in as they move from the home page to the dashboard. We store this "logged-in state" in a **Session**.
+
+## 1. Why Redis for Sessions?
+
+In the early days, developers stored sessions in the **Server's Memory (RAM)**. This causes a major problem:
+* If you have two servers (Server A and Server B), and the user logs in on Server A, Server B won't know who they are!
+* If the server restarts, every single user is logged out instantly.
+
+**The Solution:** Use Redis as a centralized session store. All your servers talk to one Redis instance, so the user stays logged in no matter which server they hit.
+
+## 2. Setting Up Express-Session with Redis
+
+To manage sessions in Node.js, we use `express-session` and a "connect" library to link it to Redis.
+
+```bash
+npm install express-session connect-redis redis
+```
+
+## 3. Implementation Code
+
+Here is how you configure your Express app to use Redis for session storage.
+
+```javascript title="server.js"
+const session = require('express-session');
+const { RedisStore } = require('connect-redis');
+const client = require('./redisClient'); // Your redis client from previous lesson
+
+app.use(session({
+ store: new RedisStore({ client: client }),
+ secret: 'my-secret-key', // Use a strong secret in production
+ resave: false,
+ saveUninitialized: false,
+ cookie: {
+ secure: false, // Set to true if using HTTPS
+ httpOnly: true,
+ maxAge: 1000 * 60 * 60 * 24 // Session lasts for 24 hours
+ }
+}));
+
+```
+
+## 4. Using the Session in Routes
+
+Once configured, you can attach data to the `req.session` object. Express will automatically save this to Redis and handle the cookies for you.
+
+### Login Route
+
+```javascript title="server.js"
+app.post('/login', (req, res) => {
+ const { username, password } = req.body;
+
+ // After verifying password...
+ req.session.user = { username: username, role: 'student' };
+ res.send("Logged in and session created in Redis!");
+});
+
+```
+
+### Profile Route (Protected)
+
+```javascript title="server.js"
+app.get('/profile', (req, res) => {
+ if (req.session.user) {
+ res.send(`Hello ${req.session.user.username}`);
+ } else {
+ res.status(401).send("Please login first!");
+ }
+});
+
+```
+
+## 5. What happens in Redis?
+
+When a user logs in, `express-session` creates a unique **Session ID**.
+
+1. **In the Browser:** A cookie is stored with that ID.
+2. **In Redis:** A key is created like `sess:XYZ123...` containing the user's data as a JSON string.
+
+When the user visits a new page, the server reads the ID from the cookie, looks it up in Redis, and populates `req.session` automatically.
+
+## Practice: The "Remember Me" Logic
+
+1. Set up the Redis session store in your project.
+2. Create a route `/count` that increments a counter stored in the session: `req.session.views = (req.session.views || 0) + 1;`.
+3. Open the page in two different browsers. Notice how each has its own count.
+4. Restart your Node.js server. Notice how the count **stays the same** because the data is safe in Redis!
+
+:::info Session Security
+Always use `httpOnly: true` in your cookie settings. This prevents malicious scripts (XSS) from stealing the user's session ID from the browser. In production, also use `secure: true` to ensure the session is only sent over encrypted HTTPS connections.
+:::
\ No newline at end of file
diff --git a/absolute-beginners/full-stack/devops/_category_.json b/absolute-beginners/full-stack/devops/_category_.json
new file mode 100644
index 0000000..dc651ae
--- /dev/null
+++ b/absolute-beginners/full-stack/devops/_category_.json
@@ -0,0 +1,9 @@
+{
+ "label": "DevOps",
+ "position": 11,
+ "link": {
+ "type": "generated-index",
+ "title": "DevOps: Streamlining Software Development and Deployment",
+ "description": "Learn how to implement DevOps practices to streamline your software development and deployment processes. This track covers everything from version control and continuous integration to containerization and cloud deployment."
+ }
+}
\ No newline at end of file
diff --git a/absolute-beginners/full-stack/devops/api-design.mdx b/absolute-beginners/full-stack/devops/api-design.mdx
deleted file mode 100644
index e345ed2..0000000
--- a/absolute-beginners/full-stack/devops/api-design.mdx
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/absolute-beginners/full-stack/devops/apis/api-design.mdx b/absolute-beginners/full-stack/devops/apis/api-design.mdx
new file mode 100644
index 0000000..e440e5c
--- /dev/null
+++ b/absolute-beginners/full-stack/devops/apis/api-design.mdx
@@ -0,0 +1 @@
+3
\ No newline at end of file
diff --git a/absolute-beginners/full-stack/devops/apis/crud.mdx b/absolute-beginners/full-stack/devops/apis/crud.mdx
new file mode 100644
index 0000000..d8263ee
--- /dev/null
+++ b/absolute-beginners/full-stack/devops/apis/crud.mdx
@@ -0,0 +1 @@
+2
\ No newline at end of file
diff --git a/absolute-beginners/full-stack/devops/apis/documentation.mdx b/absolute-beginners/full-stack/devops/apis/documentation.mdx
new file mode 100644
index 0000000..62f9457
--- /dev/null
+++ b/absolute-beginners/full-stack/devops/apis/documentation.mdx
@@ -0,0 +1 @@
+6
\ No newline at end of file
diff --git a/absolute-beginners/full-stack/devops/apis/rate-limiting.mdx b/absolute-beginners/full-stack/devops/apis/rate-limiting.mdx
new file mode 100644
index 0000000..7813681
--- /dev/null
+++ b/absolute-beginners/full-stack/devops/apis/rate-limiting.mdx
@@ -0,0 +1 @@
+5
\ No newline at end of file
diff --git a/absolute-beginners/full-stack/devops/apis/rest-basics.mdx b/absolute-beginners/full-stack/devops/apis/rest-basics.mdx
new file mode 100644
index 0000000..56a6051
--- /dev/null
+++ b/absolute-beginners/full-stack/devops/apis/rest-basics.mdx
@@ -0,0 +1 @@
+1
\ No newline at end of file
diff --git a/absolute-beginners/full-stack/devops/apis/validation.mdx b/absolute-beginners/full-stack/devops/apis/validation.mdx
new file mode 100644
index 0000000..bf0d87a
--- /dev/null
+++ b/absolute-beginners/full-stack/devops/apis/validation.mdx
@@ -0,0 +1 @@
+4
\ No newline at end of file
diff --git a/absolute-beginners/full-stack/devops/crud.mdx b/absolute-beginners/full-stack/devops/crud.mdx
deleted file mode 100644
index e345ed2..0000000
--- a/absolute-beginners/full-stack/devops/crud.mdx
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/absolute-beginners/full-stack/devops/documentation.mdx b/absolute-beginners/full-stack/devops/documentation.mdx
deleted file mode 100644
index e345ed2..0000000
--- a/absolute-beginners/full-stack/devops/documentation.mdx
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/absolute-beginners/full-stack/devops/rate-limiting.mdx b/absolute-beginners/full-stack/devops/rate-limiting.mdx
deleted file mode 100644
index e345ed2..0000000
--- a/absolute-beginners/full-stack/devops/rate-limiting.mdx
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/absolute-beginners/full-stack/devops/rest-basics.mdx b/absolute-beginners/full-stack/devops/rest-basics.mdx
deleted file mode 100644
index e345ed2..0000000
--- a/absolute-beginners/full-stack/devops/rest-basics.mdx
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/absolute-beginners/full-stack/devops/validation.mdx b/absolute-beginners/full-stack/devops/validation.mdx
deleted file mode 100644
index e345ed2..0000000
--- a/absolute-beginners/full-stack/devops/validation.mdx
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/absolute-beginners/full-stack/projects/_category_.json b/absolute-beginners/full-stack/projects/_category_.json
new file mode 100644
index 0000000..4bfd308
--- /dev/null
+++ b/absolute-beginners/full-stack/projects/_category_.json
@@ -0,0 +1,9 @@
+{
+ "label": "Projects",
+ "position": 14,
+ "link": {
+ "type": "generated-index",
+ "title": "Projects: Hands-On Experience",
+ "description": "Apply your knowledge by working on real-world projects. This track provides practical experience in building and deploying applications."
+ }
+}
\ No newline at end of file
diff --git a/absolute-beginners/full-stack/resources/_category_.json b/absolute-beginners/full-stack/resources/_category_.json
new file mode 100644
index 0000000..dda5e89
--- /dev/null
+++ b/absolute-beginners/full-stack/resources/_category_.json
@@ -0,0 +1,9 @@
+{
+ "label": "Resources",
+ "position": 16,
+ "link": {
+ "type": "generated-index",
+ "title": "Resources: Learning Materials and Tools",
+ "description": "Access a collection of learning materials and tools to support your software engineering journey. This track provides everything from documentation and tutorials to community resources and best practices."
+ }
+}
\ No newline at end of file
diff --git a/absolute-beginners/full-stack/system-design/_category_.json b/absolute-beginners/full-stack/system-design/_category_.json
new file mode 100644
index 0000000..ba698a7
--- /dev/null
+++ b/absolute-beginners/full-stack/system-design/_category_.json
@@ -0,0 +1,9 @@
+{
+ "label": "System Design",
+ "position": 13,
+ "link": {
+ "type": "generated-index",
+ "title": "System Design: Building Scalable and Reliable Applications",
+ "description": "Learn the principles and practices of system design to build scalable and reliable applications. This track covers everything from architecture patterns to performance optimization and fault tolerance."
+ }
+}
\ No newline at end of file