Executive Summary कार्यकारी सारांश
Zedemy is a production-ready educational platform that empowers learners, content creators, and developers to read curated technical blogs, submit authenticated articles, code in-browser with autosave, and earn verifiable completion certificates. Built with a serverless, SSR-first architecture to maximize SEO and performance, audited pages score 100/100 on Lighthouse and the site has achieved strong organic visibility (≈1.5M impressions). This project is maintained as a portfolio case study demonstrating end-to-end ownership (design → deploy → monitor) and trade-off driven engineering. Zedemy एक प्रोडक्शन-तैयार शैक्षिक मंच है जो शिक्षार्थियों, सामग्री निर्माताओं और डेवलपर्स को क्यूरेटेड तकनीकी ब्लॉग पढ़ने, प्रमाणित लेख सबमिट करने, ब्राउज़र में ऑटोसेव के साथ कोड करने और सत्यापनीय पूर्णता प्रमाणपत्र प्राप्त करने में सक्षम बनाता है। SEO और प्रदर्शन को अधिकतम करने के लिए सर्वरलेस, SSR-फर्स्ट आर्किटेक्चर के साथ निर्मित, ऑडिट किए गए पृष्ठों ने Lighthouse पर 100/100 स्कोर प्राप्त किया और साइट ने मजबूत ऑर्गेनिक दृश्यता (≈1.5M इम्प्रेशन) हासिल की है। यह प्रोजेक्ट एक पोर्टफोलियो केस स्टडी के रूप में रखा गया है जो एंड-टू-एंड ओनरशिप (डिज़ाइन → डिप्लॉय → मॉनिटर) और ट्रेड-ऑफ-आधारित इंजीनियरिंग को दर्शाता है।
Project Objectives प्रोजेक्ट उद्देश्य
| Objective उद्देश्य | Description विवरण |
|---|---|
| Centralized Knowledge Platform केंद्रीकृत ज्ञान मंच | Create a unified space for consuming and creating content सामग्री उपभोग और निर्माण के लिए एक एकीकृत स्थान बनाएँ |
| Contributor-Driven Model योगदानकर्ता-प्रधान मॉडल | Allow authenticated users to submit blog content with review प्रमाणित उपयोगकर्ताओं को समीक्षा के साथ ब्लॉग सामग्री सबमिट करने की अनुमति दें |
| Certification Workflow प्रमाणपत्र कार्यप्रवाह | Offer downloadable and verifiable certificates for learning completion सीखने की पूर्णता के लिए डाउनलोड करने योग्य और सत्यापनीय प्रमाणपत्र प्रदान करें |
| In-Browser Code Experimentation ब्राउज़र में कोड प्रयोग | Provide a persistent, low-friction code editor experience एक स्थायी, कम-घर्षण कोड एडिटर अनुभव प्रदान करें |
| SEO Optimization SEO अनुकूलन | Optimize blog pages for structured SEO and scalability संरचित SEO और स्केलेबिलिटी के लिए ब्लॉग पेजों को अनुकूलित करें |
System Architecture सिस्टम आर्किटेक्चर
Image: Zedemy System Architecture
छवि: जेडेमी सिस्टम आर्किटेक्चर
Components: घटक:
- Frontend: React, Vite, Tailwind CSS, React Router, hosted on Vercel फ्रंटएंड: React, Vite, Tailwind CSS, React Router, Vercel पर होस्टेड
- Backend: API Gateway → AWS Lambda → DynamoDB बैकएंड: API Gateway → AWS Lambda → DynamoDB
- Infrastructure: Vercel CDN, AWS ACM (SSL), Vercel Rewrites इंफ्रास्ट्रक्चर: Vercel CDN, AWS ACM (SSL), Vercel Rewrites
High-Level System Design उच्च-स्तरीय सिस्टम डिज़ाइन
Overall System Architecture Layering कुल सिस्टम आर्किटेक्चर लेयरिंग
╠═════════════════════════════════════════════════════════════════════════════════════════════════════════════╣
║ ║
║ ┌─────────────────────────────────────────────────────────────────────────────────────────────────────┐ ║
║ │ FRONTEND LAYER (React SPA on Vercel) │ ║
║ │ ┌────────────────────────────────────┐ ┌─────────────────────────┐ ┌─────────────────────────┐ │ ║
║ │ │ UI Components │ │ Redux Actions/ │ │ Pages & Routing │ │ ║
║ │ │ (AddPostForm, │ │ Reducers (auth, │ │ (Dashboard, PostPage │ │ ║
║ │ │ PostPage, etc.) │ │ post, notif) │ │ SSR Hydration) │ │ ║
║ │ └────────────────────────────────────┘ └─────────────────────────┘ └─────────────────────────┘ │ ║
║ │ │ ║
║ │ LocalStorage/JWT Header Axios Calls (Presigned URLs, API Endpoints) │ ║
║ └─────────────────────────────────────────────────────────────────────────────────────────────────────┘ ║
║ ║
╠═════════════════════════════════════════════════════════════════════════════════════════════════════════════╣
║ ║
║ ┌─────────────────────────────────────────────────────────────────────────────────────────────────────┐ ║
║ │ API GATEWAY LAYER (Express on Lambda) │ ║
║ │ ┌─────────────────────────────┐ ┌────────────────────────────────────┐ ┌──────────────────────┐ │ ║
║ │ │ Routes (auth, │ │ Controllers │ │ Middleware │ │ ║
║ │ │ post, cert) │ │ (authCtrl, postCtrl │ │ (authMiddleware) │ │ ║
║ │ │ │ │ for logic) │ │ │ │ ║
║ │ └─────────────────────────────┘ └────────────────────────────────────┘ └──────────────────────┘ │ ║
║ │ │ ║
║ │ CORS/Validation JWT Validation AWS SDK Calls (DynamoDB/S3) │ ║
║ └─────────────────────────────────────────────────────────────────────────────────────────────────────┘ ║
║ ║
╠═════════════════════════════════════════════════════════════════════════════════════════════════════════════╣
║ ║
║ ┌────────────────────────────────────────────────────────────────────────────────────────────┐ ║
║ │ DATA & SERVICES LAYER (AWS-Native Persistence & Compute) │ ║
║ │ ┌────────────────────────┐ ┌───────────────────────┐ ┌──────────────────────────┐ │ ║
║ │ │ DynamoDB Tables │ │ S3 Buckets │ │ Queue Workers │ │ ║
║ │ │ (Users, Posts, │ │ (Media/PDFs) + │ │ (SQS/Bull for PDF) │ │ ║
║ │ │ Notifs, Certs) │ │ CloudFront CDN │ │ │ │ ║
║ │ └────────────────────────┘ └───────────────────────┘ └──────────────────────────┘ │ ║
║ │ │ ║
║ │ Mailer/SES (Emails w/ Templates & Signed URLs) │ ║
║ │ │ ║
║ │ GSIs for Queries (CategoryIndex) Presigned PUT/GET Async Jobs Event-Driven Emails │ ║
║ └────────────────────────────────────────────────────────────────────────────────────────────┘ ║
║ ║
╚═════════════════════════════════════════════════════════════════════════════════════════════════════════════╝
- Frontend Layer: Handles client-side rendering, state management (Redux for auth/posts/notifs/certs), and direct S3 interactions via presigned URLs. Components like AddPostForm orchestrate uploads; PostPage hydrates SSR data for SEO/fast loads. Interactions: Actions dispatch API calls with JWT headers set via setAuthToken util. फ्रंटएंड लेयर: क्लाइंट-साइड रेंडरिंग, स्थिति प्रबंधन (प्रमाणीकरण/पोस्ट/सूचनाएँ/प्रमाणपत्रों के लिए Redux), और प्रीसाइन्ड URL के माध्यम से सीधे S3 इंटरैक्शन को संभालता है। AddPostForm जैसे कंपोनेंट अपलोड को व्यवस्थित करते हैं; PostPage SEO/तेज़ लोड के लिए SSR डेटा हाइड्रेट करता है। इंटरैक्शन: setAuthToken यूटिल के माध्यम से JWT हेडर के साथ API कॉल डिस्पैच करता है।
- API Gateway Layer: Central Express server (server.js) mounts routes, applies authMiddleware for token validation (x-auth-token header), and routes to controllers. Presigned endpoint in server.js generates S3 URLs. Scalable via Lambda; CORS enabled for Vercel origins. API गेटवे लेयर: सेंट्रल Express सर्वर (server.js) रूट्स माउंट करता है, टोकन सत्यापन के लिए authMiddleware लागू करता है (x-auth-token हेडर), और कंट्रोलर्स को रूट करता है। server.js में प्रीसाइन्ड एंडपॉइंट S3 URL जनरेट करता है। Lambda के माध्यम से स्केलेबल; Vercel मूल के लिए CORS सक्षम।
- Data & Services Layer: DynamoDB stores relational data (e.g., Users table with followedCategories array, Posts with CategoryIndex GSI for queries). S3/CloudFront serves media globally with low latency. SQS workers offload CPU-intensive PDF gen to avoid Lambda timeouts. SES/mailer.js sends templated emails (emailTemplate.js) with signed URLs for security. डेटा और सर्विसेज लेयर: DynamoDB संबंधपरक डेटा संग्रहीत करता है (उदाहरण के लिए, followedCategories ऐरे के साथ Users टेबल, क्वेरीज़ के लिए CategoryIndex GSI के साथ Posts)। S3/CloudFront कम विलंबता के साथ वैश्विक रूप से मीडिया प्रदान करता है। SQS वर्कर्स CPU-गहन PDF जनन को ऑफलोड करते हैं ताकि Lambda टाइमआउट से बचा जा सके। SES/mailer.js साइन किए गए URL के साथ टेम्पलेटेड ईमेल (emailTemplate.js) भेजता है।
- Cross-Layer Flows: Client → API (HTTPS) → Models (AWS SDK v3) → Services. Error handling via utils.js (sanitization/responses); monitoring via CloudWatch. क्रॉस-लेयर प्रवाह: क्लाइंट → API (HTTPS) → मॉडल्स (AWS SDK v3) → सर्विसेज। utils.js के माध्यम से त्रुटि हैंडलिंग (सैनिटाइजेशन/रिस्पॉन्स); CloudWatch के माध्यम से मॉनिटरिंग।
- Scalability Notes: Serverless auto-scales; GSIs optimize queries (e.g., followers via category scan); reverse index recommended for high-follower categories to avoid full User table scans. स्केलेबिलिटी नोट्स: सर्वरलेस स्वतः स्केल करता है; GSIs क्वेरीज़ को अनुकूलित करते हैं (उदाहरण के लिए, श्रेणी स्कैन के माध्यम से अनुयायी); उच्च-अनुयायी श्रेणियों के लिए पूर्ण Users टेबल स्कैन से बचने के लिए रिवर्स इंडेक्स की सिफारिश की जाती है।
Frontend Stack फ्रंटएंड स्टैक
Image: Zedemy Frontend Architecture
छवि: जेडेमी फ्रंटएंड आर्किटेक्चर
| Tech तकनीक | Why It Was Used इसे क्यों उपयोग किया गया |
|---|---|
| React.js | Component-based UI with dynamic routing डायनामिक रूटिंग के साथ कंपोनेंट-आधारित UI |
| Vite | High-speed build tool for SSR-compatible builds SSR-संगत बिल्ड के लिए उच्च-गति बिल्ड टूल |
| Tailwind CSS | Utility-first CSS for responsive design रिस्पॉन्सिव डिज़ाइन के लिए यूटिलिटी-फर्स्ट CSS |
| React Router | Handles page navigation and dynamic slugs पेज नेविगेशन और डायनामिक स्लग्स को संभालता है |
| React Helmet | Injects SEO metadata per page प्रति पेज SEO मेटाडेटा इंजेक्ट करता है |
| @uiw/react-codemirror | In-browser code editor with autosave and theming ऑटोसेव और थीमिंग के साथ ब्राउज़र में कोड एडिटर |
| Redux | Central state management for auth and posts प्रमाणीकरण और पोस्ट के लिए केंद्रीकृत स्थिति प्रबंधन |
| React Toastify | Non-blocking notifications for user actions उपयोगकर्ता कार्यों के लिए गैर-अवरोधक सूचनाएँ |
| React Lazyload | Deferred loading for performance optimization प्रदर्शन अनुकूलन के लिए विलंबित लोडिंग |
Backend Stack बैकएंड स्टैक
Image: Zedemy Backend Architecture
छवि: जेडेमी बैकएंड आर्किटेक्चर
| Tech तकनीक | Why It Was Used इसे क्यों उपयोग किया गया |
|---|---|
| AWS API Gateway | Handles HTTP requests from frontend फ्रंटएंड से HTTP अनुरोधों को संभालता है |
| AWS Lambda | Stateless functions for post and certificate handling पोस्ट और प्रमाणपत्र हैंडलिंग के लिए स्टेटलेस फ़ंक्शन |
| DynamoDB | Structured NoSQL storage for posts and certificates पोस्ट और प्रमाणपत्रों के लिए संरचित NoSQL भंडारण |
| AWS S3/CloudFront | Media storage and global content delivery मीडिया भंडारण और वैश्विक सामग्री वितरण |
| AWS SQS | Queue for offloading CPU-intensive tasks like PDF generation PDF जनन जैसे CPU-गहन कार्यों को ऑफलोड करने के लिए क्यू |
| AWS SES | Email delivery for notifications and certificate links सूचनाओं और प्रमाणपत्र लिंक के लिए ईमेल वितरण |
Data Flow: डेटा प्रवाह:
- Client initiates action (e.g., post submission, mark completion) क्लाइंट कार्य शुरू करता है (उदाहरण के लिए, पोस्ट सबमिशन, पूर्णता चिह्नित करना)
- API Gateway validates and routes requests to Lambda API Gateway अनुरोधों को सत्यापित करता है और Lambda को रूट करता है
- Lambda processes logic, interacts with DynamoDB/S3 Lambda तर्क को प्रोसेस करता है, DynamoDB/S3 के साथ इंटरैक्ट करता है
- SQS offloads heavy tasks (e.g., certificate PDF generation) SQS भारी कार्यों को ऑफलोड करता है (उदाहरण के लिए, प्रमाणपत्र PDF जनन)
- SES sends emails with signed URLs for secure access SES सुरक्षित पहुंच के लिए साइन किए गए URL के साथ ईमेल भेजता है
User Authentication & Onboarding Flow उपयोगकर्ता प्रमाणीकरण और ऑनबोर्डिंग प्रवाह
╠═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════╣
║ USER AUTH FLOW: FROM BROWSER TO SECURE SESSION ║
║ ║
║ ┌────────────────────────────────────┐ ║
║ │ PUBLIC BROWSER (React SPA) │ Step 1: User enters creds/register form (Login.jsx/Register.jsx) ║
║ │ ┌────────────────────────────┐ │ ┌──────────────────────────┐ ║
║ │ │ Auth Actions │ │ │ Axios POST │ to /auth/register or /auth/login ║
║ │ │ (authActions.jsx) │ │ │ (w/ payload) │ (authRoutes.js) ║
║ │ └────────────────────────────┘ │ └──────────────────────────┘ ║
║ └────────────────────────────────────┘ ║
║ ║ ║
║ ▼ Step 2: Backend: authController.js validates/hashes (bcrypt via User.js) ║
║ ┌────────────────────────────────────┐ ║
║ │ API GATEWAY (Express) │ ┌──────────────────────────────┐ ║
║ │ ┌───────────────────────────┐ │ │ Models/User.js: │ ║
║ │ │ authRoutes.js │ │ │ Create/Find User in │ Writes to Users table; issues JWT ║
║ │ └───────────────────────────┘ │ │ DynamoDB Users Table │ (config/auth.js secret) ║
║ │ │ └──────────────────────────────┘ ║
║ └────────────────────────────────────┘ ║ ║
║ ║ Step 3: Response: Token + User Meta localStorage (localStorage.js) ║
║ ▼ ║
║ ┌────────────────────────────────────┐ ║
║ │ CLIENT HYDRATION │ Step 4: setAuthToken.jsx sets header (x-auth-token); ║
║ │ │ Redirect to Dashboard.jsx ║
║ │ (Redux authReducer.js) │ ║
║ └────────────────────────────────────┘ ║
║ ║
║ SECURITY: JWT TTL (short-lived); Refresh via /auth/refresh (future); No sensitive data in token. ║
╚═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝
- Step 1 - Client Initiation: User interacts with SignInSignUp.jsx (toggles Login/Register). authActions.jsx dispatches payloads (email/password); validation via form utils. No server roundtrip until submit. चरण 1 - क्लाइंट प्रारंभ: उपयोगकर्ता SignInSignUp.jsx के साथ इंटरैक्ट करता है (लॉगिन/रजिस्टर टॉगल करता है)। authActions.jsx पेलोड (ईमेल/पासवर्ड) डिस्पैच करता है; फॉर्म यूटिल्स के माध्यम से सत्यापन। सबमिट तक कोई सर्वर राउंडट्रिप नहीं।
- Step 2 - Backend Validation: authRoutes.js → authController.js: Input sanitization (utils.js), password hash (User.js), DynamoDB write/query for uniqueness. Error responses standardized (e.g., 401 Unauthorized). चरण 2 - बैकएंड सत्यापन: authRoutes.js → authController.js: इनपुट सैनिटाइजेशन (utils.js), पासवर्ड हैश (User.js), विशिष्टता के लिए DynamoDB राइट/क्वेरी। त्रुटि प्रतिक्रियाएँ मानकीकृत (उदाहरण के लिए, 401 अनधिकृत)।
- Step 3 - Token Issuance: Signed JWT includes userId/roles (config/auth.js); returned as { token, user: { id, email, ... } }. Excludes password. चरण 3 - टोकन जारी करना: साइन किया गया JWT में userId/roles शामिल हैं (config/auth.js); { token, user: { id, email, ... } } के रूप में लौटाया जाता है। पासवर्ड शामिल नहीं।
- Step 4 - Session Persistence: localStorage.js stores token; setAuthToken.jsx intercepts Axios for future calls. authReducer.js updates state for global access (e.g., Navbar user display). चरण 4 - सत्र स्थायित्व: localStorage.js टोकन संग्रहीत करता है; setAuthToken.jsx भविष्य के कॉल के लिए Axios को इंटरसेप्ट करता है। authReducer.js वैश्विक पहुंच के लिए स्थिति अपडेट करता है (उदाहरण के लिए, Navbar उपयोगकर्ता प्रदर्शन)।
- Edge Cases: ForgotPassword.jsx → /auth/reset (mailer.js sends token via emailTemplate.js); Passport.js for OAuth extensibility. Interview Tip: Discuss XSS/CSRF mitigations (httpOnly cookies recommended over localStorage for prod). एज केस: ForgotPassword.jsx → /auth/reset (mailer.js emailTemplate.js के माध्यम से टोकन भेजता है); OAuth विस्तार के लिए Passport.js। साक्षात्कार टिप: XSS/CSRF शमन पर चर्चा करें (प्रोडक्शन के लिए localStorage पर httpOnly कुकीज़ की सिफारिश)।
Dashboard Loading & Content Discovery डैशबोर्ड लोडिंग और सामग्री खोज
╠══════════════════════════════════════════════════════════════════════════════════════════════════════════╣
║ DASHBOARD FLOW: PARALLEL DATA FETCHING FOR IMMERSIVE USER EXPERIENCE ║
║ ║
║ ┌─────────────────────────────┐ ║
║ │ DASHBOARD PAGE (React) │ On Mount: Dashboard.jsx dispatches parallel actions ║
║ │ ┌───────────────────────┐ │ ┌─────────────────────┐ ┌──────────────────────┐ ║
║ │ │ postActions.jsx │ │ │ GET /posts │ │ GET /notifs │ ║
║ │ │ (Feed Query) │ │ │ (postRoutes) │ │ (notifRoutes) │ ║
║ │ └───────────────────────┘ │ └─────────────────────┘ └──────────────────────┘ ║
║ └─────────────────────────────┘ ║ ║ ║ ║
║ ║ ▼ ▼ ▼ ║
║ ▼ Controllers Parallel: postCtrl Post.js (Category GSI Query) ║
║ ┌─────────────────────────┐ ┌───────────────────┐ ┌─────────────────────┐ ║
║ │ REDUX STATE UPDATE │ │ Posts Table │ │ Notifs Table │ ║
║ │ (postReducer.js) │ │ (Feed Items) │ │ (Unread Flag) │ ║
║ └─────────────────────────┘ └───────────────────┘ └─────────────────────┘ ║
║ ║
║ RENDER: PostList.jsx (Feed Widget) + Notification.jsx (Bell/Badges) + VerifyCertificate.jsx (List) ║
║ Follow Category notificationActions.js User.js Update (followedCategories Array) ║
╚══════════════════════════════════════════════════════════════════════════════════════════════════════════╝
- Parallel Fetching: Dashboard.jsx uses Promise.all for /posts/feed (user-followed categories via GSI), /notifications (per-user query), /certificates (user-owned). Reduces TTFP. समानांतर प्राप्ति: Dashboard.jsx Promise.all का उपयोग करता है /posts/feed (GSI के माध्यम से उपयोगकर्ता-अनुसरण की गई श्रेणियों), /notifications (प्रति-उपयोगकर्ता क्वेरी), /certificates (उपयोगकर्ता-स्वामित्व) के लिए। TTFP को कम करता है।
- Backend Processing: postRoutes.js → postController.js → Post.js: Queries Posts table by category (GSI for efficiency). notificationRoutes.js → notificationController.js → Notification.js: Lists unread items with meta (timestamp, postSlug). बैकएंड प्रोसेसिंग: postRoutes.js → postController.js → Post.js: श्रेणी के आधार पर Posts टेबल क्वेरी करता है (कुशलता के लिए GSI)। notificationRoutes.js → notificationController.js → Notification.js: मेटा (टाइमस्टैम्प, postSlug) के साथ अपठित आइटम सूचीबद्ध करता है।
- State & UI Hydration: Reducers update (postReducer for feed, notificationReducer for counts). Components: PostList.jsx lazy-loads PriorityContent.jsx; NotificationBell shows badges. स्थिति और UI हाइड्रेशन: रिड्यूसर्स अपडेट करते हैं (फीड के लिए postReducer, गणना के लिए notificationReducer)। कंपोनेंट्स: PostList.jsx PriorityContent.jsx को लेजी-लोड करता है; NotificationBell बैज दिखाता है।
- Actions: Follow/unfollow → updates Users table (array append/remove); triggers no immediate notifs but affects future post creates. Interview Tip: Explain GSI benefits for category-based feeds vs. full scans. कार्य: फॉलो/अनफॉलो → Users टेबल को अपडेट करता है (ऐरे जोड़/हटाएँ); तत्काल सूचनाएँ ट्रिगर नहीं करता लेकिन भविष्य के पोस्ट निर्माण को प्रभावित करता है। साक्षात्कार टिप: श्रेणी-आधारित फीड के लिए GSI लाभ बनाम पूर्ण स्कैन की व्याख्या करें।
Post Creation & Media Upload Flow पोस्ट निर्माण और मीडिया अपलोड प्रवाह
╠════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╣
║ POST CREATION: OFFLOADED UPLOAD + FANOUT NOTIFICATIONS ║
║ ║
║ ┌──────────────────────────────────┐ ║
║ │ ADDPOST FORM (React) │ Step 1: User inputs content/media ║
║ │ │ (AddPostForm.jsx) ║
║ │ ┌───────────────────────────┐ │ ┌───────────────────────────────┐ ║
║ │ │ postActions.jsx │ │ │ POST /presign │ (server.js endpoint: AWS SDK ║
║ │ │ (Upload Orchestration) │ │ │ (S3 Signed) │ generates PUT URL + Public Key) ║
║ │ └───────────────────────────┘ │ └───────────────────────────────┘ ║
║ └──────────────────────────────────┘ ║ ║
║ ║ Step 2: Direct Client S3 PUT (Signed URL); CloudFront Caches Public Path ║
║ ▼ ║
║ ┌────────────────────────────┐ ║
║ │ METADATA PERSIST │ Step 3: POST /posts/create (postRoutes.js) w/ {content, mediaKey, category, slug} ║
║ │ ┌───────────────────────┐ │ ┌─────────────────────────┐ ║
║ │ │ postController.js │ │ │ Models/Post.js │ Validates, Writes to Posts Table ║
║ │ └───────────────────────┘ │ │ (DynamoDB) │ (Slug Gen via utils.js) ║
║ │ │ └─────────────────────────┘ ║
║ └────────────────────────────┘ ║
║ ║ Step 4: Fanout: postCtrl User.js (Query Followers by Category) Notification.js ║
║ ▼ Create Per-Follower Items (Notifs Table: unread=true, meta={postSlug, timestamp}) ║
║ ║
║ SUCCESS: Redirect to PostPage.jsx; Optional Email Queue for High-Engagement Categories ║
╚════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝
- Phase 1 - Presign Request: AddPostForm.jsx collects metadata; postActions calls /presign (server.js: AWS S3.createPresignedPost). Returns { signedUrl, publicKey } (e.g., cloudfront.net/key). चरण 1 - प्रीसाइन अनुरोध: AddPostForm.jsx मेटाडेटा एकत्र करता है; postActions /presign को कॉल करता है (server.js: AWS S3.createPresignedPost)। { signedUrl, publicKey } लौटाता है (उदाहरण के लिए, cloudfront.net/key)।
- Phase 2 - Direct Upload: Client PUTs file to signedUrl (progress bar in UI). Bypasses server; reduces costs. CloudFront auto-caches for global delivery. चरण 2 - प्रत्यक्ष अपलोड: क्लाइंट signedUrl पर फ़ाइल PUT करता है (UI में प्रोग्रेस बार)। सर्वर को बायपास करता है; लागत कम करता है। CloudFront वैश्विक वितरण के लिए स्वतः कैश करता है।
- Phase 3 - Persist Metadata: postActions POSTs to /posts/create; postController validates (utils.js sanitization), generates slug, writes Post item (Post.js: includes mediaUrls array). चरण 3 - मेटाडेटा संरक्षण: postActions /posts/create पर POST करता है; postController सत्यापित करता है (utils.js सैनिटाइजेशन), स्लग जनरेट करता है, Post आइटम लिखता है (Post.js: mediaUrls ऐरे शामिल)।
- Phase 4 - Notifications: postController queries Users table (category followers via scan/array match); loops Notification.js.create() for each (scalable to reverse index). unread flag enables badges. चरण 4 - सूचनाएँ: postController Users टेबल क्वेरी करता है (स्कैन/ऐरे मिलान के माध्यम से श्रेणी अनुयायी); प्रत्येक के लिए Notification.js.create() लूप करता है (रिवर्स इंडेक्स तक स्केलेबल)। अपठित फ्लैग बैज सक्षम करता है।
- Interview Tip: Highlight presign TTL (e.g., 15min) for security; discuss tradeoffs of direct upload (no virus scan) vs. server proxy. साक्षात्कार टिप: सुरक्षा के लिए प्रीसाइन TTL (उदाहरण के लिए, 15 मिनट) को हाइलाइट करें; प्रत्यक्ष अपलोड (कोई वायरस स्कैन नहीं) बनाम सर्वर प्रॉक्सी के ट्रेडऑफ्स पर चर्चा करें।
Notifications System & Engagement Triggers सूचना प्रणाली और जुड़ाव ट्रिगर
╠═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╣
║ NOTIFICATIONS: EVENT FANOUT TO PERSONALIZED USER STREAMS ║
║ ║
║ ┌────────────────────────────────────┐ ║
║ │ TRIGGER EVENTS (Backend) │ Step 1: Post Create/Follow (postCtrl/notificationCtrl) ║
║ │ ┌────────────────────────────┐ │ ┌─────────────────────┐ ║
║ │ │ Models/Notification.js │ │ │ Write Items │ to Notifs Table (PK: userId, ║
║ │ └────────────────────────────┘ │ │ (DynamoDB) │ SK: timestamp; GSI: unreadIndex) ║
║ │ │ └─────────────────────┘ ║
║ └────────────────────────────────────┘ ║ ║
║ ║ Step 2: Client Poll/Fetch: Notification.jsx on Dashboard Mount ║
║ ▼ ║
║ ┌────────────────────────────────────┐ ║
║ │ FETCH & RENDER │ Step 3: GET /notifications (notificationRoutes.js) notificationController.js ║
║ │ ┌────────────────────────────┐ │ ┌──────────────────────────┐ ║
║ │ │ notificationActions.js │ │ │ Query Notifs │ Filter unread=true; Return ║
║ │ │ (Redux Dispatch) │ │ │ Table by User │ {items, count} ║
║ │ └────────────────────────────┘ │ └──────────────────────────┘ ║
║ └────────────────────────────────────┘ ║ ║
║ ║ Step 4: UI: NotificationBell.jsx (Badges) + List (Mark Read PATCH /notifs/read) ║
║ ▼ ║
║ ║
║ MARK READ: Updates unread=false; Clears Badge. Optional: WebSocket Upgrade for Real-Time (Future). ║
╚═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝
- Event Creation: Triggered in postController (new post) or notificationController (follow). Notification.js.create({userId, type: 'new_post', meta: {slug, category}, unread: true}). इवेंट निर्माण: postController (नया पोस्ट) या notificationController (फॉलो) में ट्रिगर होता है। Notification.js.create({userId, type: 'new_post', meta: {slug, category}, unread: true})।
- Fetching: notificationActions dispatches on load/interval; queries by userId (efficient PK). Returns paginated list with count for badges. प्राप्ति: notificationActions लोड/अंतराल पर डिस्पैच करता है; userId द्वारा क्वेरी करता है (कुशल PK)। बैज के लिए गणना के साथ पेजिनेटेड सूची लौटाता है।
- UI Rendering: Notification.jsx lazy-renders list; integrates with Navbar. Mark read → bulk update (Notification.js). UI रेंडरिंग: Notification.jsx लेजी-रेंडर सूची; Navbar के साथ एकीकृत होता है। पढ़ा गया चिह्नित करें → बल्क अपडेट (Notification.js)।
- Scalability: GSI for unread queries; per-user partitioning avoids hot keys. Interview Tip: Polling vs. Push (e.g., SNS for emails); fanout cost for 10k+ followers. स्केलेबिलिटी: अपठित क्वेरीज़ के लिए GSI; प्रति-उपयोगकर्ता विभाजन हॉट कीज़ से बचता है। साक्षात्कार टिप: पोलिंग बनाम पुश (उदाहरण के लिए, ईमेल के लिए SNS); 10k+ अनुयायियों के लिए फैनआउट लागत।
Post Viewing & SSR for SEO/Performance पोस्ट देखना और SEO/प्रदर्शन के लिए SSR
╠═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╣
║ POST VIEWING: SSR HYDRATION + INTERACTIVE ACTIONS ║
║ ║
║ ┌─────────────────────────────────┐ ║
║ │ BROWSER REQUEST (URL/Slug) │ Step 1: GET /post/:slug (postPageSSR.js Route) ║
║ │ ┌───────────────────────────┐ │ ┌─────────────────────────┐ ║
║ │ │ Direct Nav or Link │ │ │ SSR Handler │ Fetches Post (Post.js by Slug); ║
║ │ └───────────────────────────┘ │ │ (Express) │ Renders HTML + Data Blob ║
║ │ │ └─────────────────────────┘ ║
║ └─────────────────────────────────┘ ║ ║
║ ║ Step 2: Response: Pre-Rendered HTML (Meta Tags via models/Post.preRender) Browser ║
║ ▼ ║
║ ┌────────────────────────────────────┐ ║
║ │ CLIENT HYDRATION │ Step 3: PostPage.jsx Parses Embedded Blob (JSON in script); Redux Hydrates postReducer ║
║ │ ┌──────────────────────────┐ │ ┌────────────────┐ ║
║ │ │ CodeHighlighter.js │ │ │ Render Full │ w/ Lazy: PriorityContent.jsx ║
║ │ │ (Syntax/Editor) │ │ │ Post UI │ (Critical) + NonCritical (Lazy) ║
║ │ └──────────────────────────┘ │ └────────────────┘ ║
║ └────────────────────────────────────┘ ║ ║
║ ║ Step 4: Actions: Mark Complete postActions /posts/complete; Follow Category ║
║ ▼ ║
║ ║
║ SEO: OpenGraph Tags in SSR; ShareButton.jsx for Social. ║
╚═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝
- SSR Initiation: postPageSSR.js queries Post.js by slug/id; generates HTML fragment (e.g., ReactDOMServer.renderToString) with embedded data (window.__INITIAL_DATA__). SSR प्रारंभ: postPageSSR.js स्लग/आईडी द्वारा Post.js क्वेरी करता है; एम्बेडेड डेटा (window.__INITIAL_DATA__) के साथ HTML फ्रैगमेंट जनरेट करता है (उदाहरण के लिए, ReactDOMServer.renderToString)।
- Hydration: PostPage.jsx extracts blob, dispatches to postReducer; mounts interactive elements (CodeEditor.jsx for snippets). हाइड्रेशन: PostPage.jsx ब्लॉब निकालता है, postReducer को डिस्पैच करता है; इंटरैक्टिव तत्व माउंट करता है (स्निपेट्स के लिए CodeEditor.jsx)।
- Performance: PriorityContent.jsx (above-fold) renders sync; LowPriorityContent.jsx lazy. RelatedPosts.jsx queries via GSI. प्रदर्शन: PriorityContent.jsx (ऊपर-फोल्ड) सिंक रेंडर करता है; LowPriorityContent.jsx लेजी। RelatedPosts.jsx GSI के माध्यम से क्वेरी करता है।
- Interview Tip: SSR tradeoffs (server CPU vs. client JS bundle); hydration mismatch prevention via data blob. साक्षात्कार टिप: SSR ट्रेडऑफ्स (सर्वर CPU बनाम क्लाइंट JS बंडल); डेटा ब्लॉब के माध्यम से हाइड्रेशन असंगति रोकथाम।
Completion Tracking & Certificate Generation पूर्णता ट्रैकिंग और प्रमाणपत्र जनन
╠═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╣
║ COMPLETION & CERT FLOW: PROGRESS CHECK + ASYNC GENERATION ║
║ ║
║ ┌────────────────────────────────┐ ║
║ │ POST PAGE ACTION (React) │ Step 1: User Clicks "Mark Complete" (PostPage.jsx) ║
║ │ ┌───────────────────────┐ │ ┌──────────────────┐ ║
║ │ │ postActions.jsx │ │ │ PATCH /posts/ │ complete (postRoutes.js; ║
║ │ │ (w/ postId) │ │ │ complete │ authMiddleware Validates JWT) ║
║ │ └───────────────────────┘ │ └──────────────────┘ ║
║ └────────────────────────────────┘ ║ ║
║ ║ Step 2: postController.js: User.js.appendCompletedPost(postId, timestamp) ║
║ ▼ ║
║ ┌───────────────────────────┐ ║
║ │ ELIGIBILITY CHECK │ Step 3: Query Posts Table (Category GSI: All PostIds in Category) ║
║ │ │ Compare vs. User List ║
║ │ ┌──────────────────────┐ │ ┌───────────────┐ ║
║ │ │ postController.js │ │ │ If Match: │ Trigger Cert Gen (Inline or ║
║ │ └──────────────────────┘ │ │ Eligible │ Enqueue SQS Job) ║
║ │ │ └───────────────┘ ║
║ └───────────────────────────┘ ║ ║
║ ║ Step 4: Cert Gen: Certificate.js.create() Render PDF (Buffer) S3 Upload ║
║ ▼ Mailer.js Send (emailTemplate.js: Signed GET URL, TTL=7days) ║
║ ┌──────────────────────────────┐ ║
║ │ QUEUE WORKER (SQS/Bull) │ Offload: Worker Consumes PDF Lib Render Certs Table Write (uniqueId, s3Key) ║
║ │ (Heavy CPU Avoidance) │ ║
║ └──────────────────────────────┘ ║
║ ║
║ EMAIL: "Congrats! Download: [Signed URL]" ║
╚═════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝
- Mark Complete: postActions PATCH /posts/complete; authMiddleware attaches userId. User.js appends to completedPosts array (atomic update). पूर्णता चिह्नित करें: postActions PATCH /posts/complete; authMiddleware userId जोड़ता है। User.js completedPosts ऐरे में जोड़ता है (परमाणु अपडेट)।
- Check Logic: postController queries GSI for category posts; set comparison (all completed?). If yes, proceed. जाँच तर्क: postController श्रेणी पोस्ट के लिए GSI क्वेरी करता है; सेट तुलना (सभी पूर्ण?)। यदि हाँ, तो आगे बढ़ें।
- Cert Generation: Inline (postController.generateCertificate): PDF buffer → S3 put (public-read? No, private + signed). Or enqueue: Worker → Certificate.js.write({uniqueId, userId, category, s3Key, createdAt}). प्रमाणपत्र जनन: इनलाइन (postController.generateCertificate): PDF बफर → S3 put (पब्लिक-रीड? नहीं, निजी + साइन किया गया)। या क्यू में डालें: वर्कर → Certificate.js.write({uniqueId, userId, category, s3Key, createdAt})।
- Delivery: mailer.js via SES; template includes verification link. certificateActions for list/download. वितरण: SES के माध्यम से mailer.js; टेम्पलेट में सत्यापन लिंक शामिल है। सूची/डाउनलोड के लिए certificateActions।
- Interview Tip: Atomicity via DynamoDB transactions; queue for 300s Lambda limit; uniqueId (UUID) prevents collisions. साक्षात्कार टिप: DynamoDB लेनदेन के माध्यम से परमाणुता; 300 सेकंड Lambda सीमा के लिए क्यू; uniqueId (UUID) टकराव रोकता है।
Certificate Verification & Security Overlay प्रमाणपत्र सत्यापन और सुरक्षा ओवरले
╠═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╣
║ VERIFICATION: PUBLIC ACCESS WITH TIME-BOUND SECURITY ║
║ ║
║ ┌────────────────────────────────┐ ║
║ │ VERIFY PAGE (React) │ Step 1: User/Link Enters uniqueId (VerifyCertificate.jsx) ║
║ │ ┌──────────────────────────┐ │ ┌──────────────────┐ ║
║ │ │ certificateActions.jsx │ │ │ GET /certs │ verify/:id (certificateRoutes.js; ║
║ │ └──────────────────────────┘ │ │ verify │ Public, No Auth) ║
║ │ │ └──────────────────┘ ║
║ └────────────────────────────────┘ ║ ║
║ ║ Step 2: certificateRoutes Certificate.js.getById(uniqueId) Certs Table Read ║
║ ▼ ║
║ ┌────────────────────────────┐ ║
║ │ SIGNED ACCESS │ Step 3: If Found: Generate S3 Signed GET URL (server.js presigner, TTL=1hr) ║
║ │ ┌─────────────────────┐ │ Response ║
║ │ │ │ │ ┌───────────────────┐ ║
║ │ │ S3/CloudFront │ │ │ Return Meta │ {name, date, user (partial), ║
║ │ │ (Private Object) │ │ │ + Signed URL │ pdfUrl (signed)} ║
║ │ └─────────────────────┘ │ └───────────────────┘ ║
║ └────────────────────────────┘ ║
║ ║ Step 4: Client: Render PDF Viewer; Download Button (Axios GET signedUrl) ║
║ ▼ ║
║ ║
║ SECURITY: No Full User Data Exposed; Logs Access (CloudWatch); Rate Limit Endpoint. ║
╚═══════════════════════════════════════════════════════════════════════════════════════════════════════════════════════╝
- Initiation: VerifyCertificate.jsx accepts ID/link; certificateActions GET /certs/verify. प्रारंभ: VerifyCertificate.jsx ID/लिंक स्वीकार करता है; certificateActions GET /certs/verify।
- Backend Lookup: certificateRoutes → Certificate.js by PK (uniqueId); returns metadata (no sensitive fields). बैकएंड लुकअप: certificateRoutes → PK (uniqueId) द्वारा Certificate.js; मेटाडेटा लौटाता है (कोई संवेदनशील फ़ील्ड नहीं)।
- Access Grant: server.js presigns S3 GET (short TTL); CloudFront serves if cached (but private bucket). प्रवेश अनुदान: server.js S3 GET को प्रीसाइन करता है (छोटा TTL); CloudFront कैश होने पर प्रदान करता है (लेकिन निजी बकेट)।
- Client Display: Renders cert details; fetches PDF via signedUrl for embed/download. क्लाइंट प्रदर्शन: प्रमाणपत्र विवरण रेंडर करता है; एम्बेड/डाउनलोड के लिए signedUrl के माध्यम से PDF प्राप्त करता है।
- Security Overlay: Across system: JWT rotation, presigned TTLs, input validation (utils.js), no localStorage in iframes. Interview Tip: Signed URLs vs. ACLs; audit logs for compliance. सुरक्षा ओवरले: पूरे सिस्टम में: JWT रोटेशन, प्रीसाइन TTLs, इनपुट सत्यापन (utils.js), iframes में कोई localStorage नहीं। साक्षात्कार टिप: साइन किए गए URL बनाम ACLs; अनुपालन के लिए ऑडिट लॉग।
1. Rationale for DynamoDB 1. DynamoDB के लिए तर्क
- Serverless integration: Native interoperability with Lambda, API Gateway, S3 and SQS reduces operational overhead and accelerates development and deployment cycles. सर्वरलेस एकीकरण: Lambda, API Gateway, S3 और SQS के साथ मूल इंटरऑपरेबिलिटी परिचालन भार को कम करती है और विकास व परिनियोजन चक्रों को तेज करती है।
- Low-latency key/value access: Primary-key and index-based queries provide millisecond-range, in-region read latency for the end-to-end SSR flow (critical for LCP and SEO). लो-लेटेंसी की/वैल्यू एक्सेस: प्राथमिक कुंजी और इंडेक्स-आधारित क्वेरी एंड-टू-एंड SSR प्रवाह के लिए मिलीसेकंड-श्रेणी, क्षेत्रीय पढ़ने की विलंबता प्रदान करती हैं (LCP और SEO के लिए महत्वपूर्ण)।
- Flexible schema: Post items include nested arrays and optional fields (subtitles, superTitles, bullet points); DynamoDB’s schemaless design accommodates this without schema migrations. लचीला स्कीमा: पोस्ट आइटम्स में नेस्टेड एरे और वैकल्पिक फ़ील्ड (उपशीर्षक, सुपरटाइटल्स, बुलेट पॉइंट्स) शामिल हैं; DynamoDB का स्कीमा-रहित डिज़ाइन इसे बिना स्कीमा माइग्रेशन के समायोजित करता है।
- Elastic capacity model: On-demand capacity supports bursty traffic without upfront capacity planning, which is appropriate for an early-stage product with variable load. इलास्टिक क्षमता मॉडल: ऑन-डिमांड क्षमता अग्रिम योजना के बिना बर्स्टी ट्रैफ़िक का समर्थन करती है, जो परिवर्तनीय लोड वाले शुरुआती-स्तर के उत्पाद के लिए उपयुक्त है।
- Tradeoffs are explicit: DynamoDB favors denormalized access patterns over relational joins and requires design patterns (denormalization, mapping tables, or transactional writes) when strict multi-item atomicity or complex joins are needed. समझौते स्पष्ट हैं: DynamoDB रिलेशनल जोइन्स की तुलना में डी-नॉर्मलाइज़्ड एक्सेस पैटर्न का पक्षधर है और जब सख्त मल्टी-आइटम परमाणुता या जटिल जोइन्स की आवश्यकता होती है, तो डिज़ाइन पैटर्न (डी-नॉर्मलाइज़ेशन, मैपिंग टेबल, या लेनदेनात्मक लेखन) की आवश्यकता होती है।
DynamoDB was selected to meet the product’s requirements for low-ops serverless operation, predictable low-latency key lookups for SSR pages, and flexible schema support for semi-structured content. Key drivers: DynamoDB को उत्पाद की आवश्यकताओं के लिए चुना गया: लो-ऑप्स सर्वरलेस संचालन, SSR पृष्ठों के लिए अनुमानित लो-लेटेंसी की लुकअप, और अर्ध-संरचित सामग्री के लिए लचीला स्कीमा समर्थन। मुख्य चालक:
2. Table Schemas, GSIs and Purpose 2. टेबल स्कीमा, GSI और उद्देश्य
Posts — Posts
╔══════════════════════════════════════════════════════════════════════╗
║ POSTS TABLE ║
║ Primary Key: postId (String) ║
║ GSIs: AuthorIndex, CategoryIndex, SlugIndex, UserIdIndex ║
╚══════════════════════════════════════════════════════════════════════╝
- SlugIndex: direct slug → post lookup for server-side rendering and SEO-friendly URLs.SlugIndex: सर्वर-साइड रेंडरिंग और SEO-अनुकूल URL के लिए सीधे slug → पोस्ट लुकअप।
- CategoryIndex: category-based listing and pagination for category landing pages.CategoryIndex: श्रेणी लैंडिंग पृष्ठों के लिए श्रेणी-आधारित सूची और पेजिनेशन।
- AuthorIndex: author-specific feeds and profile pages.AuthorIndex: लेखक-विशिष्ट फीड और प्रोफ़ाइल पेज।
- UserIdIndex: user-related queries where the UI requires posts tied to a specific user id.UserIdIndex: उपयोगकर्ता-विशिष्ट क्वेरी जहां UI को एक विशिष्ट उपयोगकर्ता आईडी से बंधे पोस्ट की आवश्यकता होती है।
- Operational notes: full HTML and large binary/media are served from S3/CloudFront; DynamoDB stores compact LCP/SEO snippets to minimize item size and read cost.ऑपरेशनल नोट्स: पूर्ण HTML और बड़े बाइनरी/मीडिया S3/CloudFront से परोसे जाते हैं; DynamoDB आइटम साइज़ और रीड कॉस्ट को न्यूनतम करने के लिए कॉम्पैक्ट LCP/SEO स्निपेट संग्रहीत करता है।
Users — Users
╔════════════════════════════════════════════════════════════════════════════╗
║ USERS TABLE ║
║ Primary Key: userId (String) ║
║ GSIs: EmailIndex, FollowedCategoriesIndex, GoogleIdIndex, ResetTokenIndex ║
╚════════════════════════════════════════════════════════════════════════════╝
- EmailIndex: authentication lookup for email/password login.EmailIndex: ईमेल/पासवर्ड लॉगिन के लिए प्रमाणीकरण लुकअप।
- GoogleIdIndex: Google OAuth lookup.GoogleIdIndex: Google OAuth लुकअप।
- ResetTokenIndex: password-reset token validation.ResetTokenIndex: पासवर्ड-रीसेट टोकन सत्यापन।
- FollowedCategoriesIndex: locate users by followed categories for category-driven features.FollowedCategoriesIndex: श्रेणी-चालित सुविधाओं के लिए फ़ॉलो की गई श्रेणियों द्वारा उपयोगकर्ताओं का पता लगाएं।
Certificates — Certificates
╔══════════════════════════════════════════════════════════════════════╗
║ CERTIFICATES TABLE ║
║ Primary Key: certificateId (String) ║
║ GSIs: UniqueIdIndex, UserIdIndex ║
╚══════════════════════════════════════════════════════════════════════╝
- UniqueIdIndex: public verification flow resolves certificate metadata via a uniqueId embedded in the public verification URL.UniqueIdIndex: सार्वजनिक सत्यापन प्रवाह सार्वजनिक सत्यापन URL में एम्बेड किए गए uniqueId के माध्यम से प्रमाणपत्र मेटाडेटा को हल करता है।
- UserIdIndex: dashboard listing of certificates for a specific user.UserIdIndex: किसी विशिष्ट उपयोगकर्ता के लिए डैशबोर्ड सूची।
- Operational note: UniqueIdIndex provides fast verification lookup but does not, by itself, guarantee atomic uniqueness under concurrent writes (see roadmap).ऑपरेशनल नोट: UniqueIdIndex तेज़ सत्यापन लुकअप प्रदान करता है लेकिन अकेले समवर्ती लेखन के तहत परमाणु विशिष्टता की गारंटी नहीं देता (रोडमैप देखें)।
Notifications — Notifications
╔══════════════════════════════════════════════════════════════════════╗
║ NOTIFICATIONS TABLE ║
║ Primary Key: notificationId (String) ║
║ GSI: UserIdIndex ║
╚══════════════════════════════════════════════════════════════════════╝
- UserIdIndex: retrieve notifications for a given userId for the user dashboard and unread counts.UserIdIndex: उपयोगकर्ता डैशबोर्ड और अपठित गिनती के लिए दिए गए userId की सूचनाएँ पुनः प्राप्त करें।
3. Access Patterns & Endpoint Mapping 3. एक्सेस पैटर्न और एंडपॉइंट मैपिंग
- GET /posts/:slug → Query SlugIndex → return lcpContent, summary, metadata and a CloudFront link to full content.GET /posts/:slug → SlugIndex क्वेरी → lcpContent, सारांश, मेटाडेटा और पूर्ण सामग्री के लिए CloudFront लिंक लौटाता है।
- GET /posts?category=xyz → Query CategoryIndex (paginated via LastEvaluatedKey).GET /posts?category=xyz → CategoryIndex क्वेरी (LastEvaluatedKey के माध्यम से पेजिनेशन)।
- GET /authors/:authorId/posts → Query AuthorIndex.GET /authors/:authorId/posts → AuthorIndex क्वेरी।
- GET /users/:id → GetItem by userId (primary key).GET /users/:id → userId (प्राथमिक कुंजी) द्वारा GetItem।
- POST /auth/login → Query EmailIndex → validate credentials.POST /auth/login → EmailIndex क्वेरी → क्रेडेंशियल सत्यापित करें।
- Google OAuth → Query GoogleIdIndex → locate user record.Google OAuth → GoogleIdIndex क्वेरी → उपयोगकर्ता रिकॉर्ड ढूँढें।
- Password reset flow → Query ResetTokenIndex to resolve token → validate expiry.पासवर्ड रीसेट प्रवाह → ResetTokenIndex क्वेरी → टोकन हल करें → समाप्ति सत्यापित करें।
- Certificate verification page → Query UniqueIdIndex → resolve certificate metadata for public verification.प्रमाणपत्र सत्यापन पृष्ठ → UniqueIdIndex क्वेरी → सार्वजनिक सत्यापन के लिए प्रमाणपत्र मेटाडेटा हल करें।
- User certificate list → Query UserIdIndex on Certificates.उपयोगकर्ता प्रमाणपत्र सूची → Certificates पर UserIdIndex क्वेरी।
- User notifications list → Query UserIdIndex on Notifications (descending order implemented in application layer).उपयोगकर्ता सूचनाओं की सूची → Notifications पर UserIdIndex क्वेरी (एप्लिकेशन लेयर में अवरोही क्रम लागू)।
4. Consistency and Performance Implications 4. स्थिरता और प्रदर्शन निहितार्थ
- Index-based queries vs. scans: All production read paths use Query on primary keys or GSIs (no user-facing scans). This ensures predictable, low-latency reads for SSR and reduces total read units consumed. इंडेक्स-आधारित क्वेरी बनाम स्कैन: सभी प्रोडक्शन रीड पाथ प्राथमिक कुंजी या GSI पर Query का उपयोग करते हैं (कोई उपयोगकर्ता-सामना स्कैन नहीं)। यह SSR के लिए अनुमानित, लो-लेटेंसी रीड सुनिश्चित करता है और कुल रीड यूनिट्स को कम करता है।
- Eventual consistency for GSIs: GSIs are eventually consistent. For most UI flows (content publish, profile updates) the short replication window is acceptable; workflows requiring immediate read-after-write consistency must be handled explicitly (for example, by reading the base item after write or by using conditional/transactional writes when atomicity is required). GSIs के लिए अंतिम स्थिरता: GSIs अंततः स्थिर होते हैं। अधिकांश UI प्रवाहों (कंटेंट प्रकाशित करना, प्रोफ़ाइल अपडेट) के लिए छोटा प्रतिकरण विंडो स्वीकार्य है; वेर्कफ़्लो जिन्हें तुरंत रीड-आफ्टर-राइट स्थिरता की आवश्यकता है उन्हें स्पष्ट रूप से संभाला जाना चाहिए (उदा., लेखन के बाद बेस आइटम पढ़कर या जब परमाणुता आवश्यक हो तो conditional/transactional writes का उपयोग करके)।
- Write amplification: GSIs projected with All increase write work and storage because indexed attributes are copied to each index. At current scale this is acceptable for simplicity and read performance; at larger scales, consider projecting only required attributes to each GSI to reduce write cost. लिखने का प्रचार (Write amplification): All के साथ प्रोजेक्ट किए गए GSIs लिखने के काम और भंडारण को बढ़ाते हैं क्योंकि इंडेक्स्ड एट्रिब्यूट्स प्रत्येक इंडेक्स में कॉपी किए जाते हैं। वर्तमान पैमाने पर यह सरलता और पढ़ने के प्रदर्शन के लिए स्वीकार्य है; बड़े पैमाने पर, लिखने की लागत कम करने के लिए प्रत्येक GSI को केवल आवश्यक एट्रिब्यूट प्रोजेक्ट करने पर विचार करें।
- Item size limits: DynamoDB enforces a 400 KB item size limit. To remain within this limit and reduce read cost for SSR, heavy payloads (full HTML, media blobs) are stored in S3 and referenced from DynamoDB; DynamoDB items retain only lcpContent, metadata and S3/CloudFront references. आइटम आकार सीमाएं: DynamoDB 400 KB आइटम आकार सीमा लागू करता है। इस सीमा के भीतर रहने और SSR के लिए रीड लागत कम करने के लिए भारी पेलोड (पूर्ण HTML, मीडिया ब्लॉब्स) S3 में संग्रहीत किए जाते हैं और DynamoDB से संदर्भित होते हैं; DynamoDB आइटम केवल lcpContent, मेटाडेटा और S3/CloudFront संदर्भ रखते हैं।
- Latency profile: Key-value and index queries provide millisecond-range in-region latency for single-item reads. Index lookups enable single-request SSR rendering with minimal backend round-trips when combined with edge caching (CloudFront). विलंबता प्रोफ़ाइल: की-वैल्यू और इंडेक्स क्वेरी एकल-आइटम रीड्स के लिए इन-रीजन मिलीसेकंड-श्रेणी विलंबता प्रदान करते हैं। इंडेक्स लुकअप एज कैशिंग (CloudFront) के साथ संयोजन करने पर न्यूनतम बैकएंड राउंड-ट्रिप्स के साथ सिंगल-रिक्वेस्ट SSR रेंडरिंग सक्षम करते हैं।
- Write contention: Hot-key contention risk exists for any single partition receiving high write volume. Current data distribution and the chosen partition keys (per-table primary keys and GSI partition keys) minimize contention for expected usage; monitoring and partition key design adjustments are part of the roadmap if usage pattern changes. लिखने का प्रतिद्वंद्विता (Write contention): किसी भी एक सिंगल पार्टीशन के लिए उच्च लेखन मात्रा मिलने पर हॉट-की प्रतिद्वंद्विता का जोखिम होता है। वर्तमान डेटा वितरण और चुनी हुई पार्टिशन कुंजी (प्रति-टेबल प्राथमिक कुंजी और GSI पार्टिशन कुंजी) अपेक्षित उपयोग के लिए प्रतिद्वंद्विता को कम करते हैं; यदि उपयोग पैटर्न बदलता है तो निगरानी और पार्टीशन कुंजी डिजाइन समायोजन रोडमैप का हिस्सा हैं।
This section outlines the real operational implications of the chosen model and indexes. यह अनुभाग चुने गए मॉडल और इंडेक्स के वास्तविक परिचालन निहितार्थों का वर्णन करता है।
5. Observability and Operational Controls 5. प्रेक्षणीयता और परिचालन नियंत्रण
-
Key metrics monitored:
निगरानी किए जाने वाले प्रमुख मीट्रिक्स:
- DynamoDB: consumed read/write capacity, throttling, successful/failed request counts. DynamoDB: उपयोग की गई रीड/राइट क्षमता, थ्रॉटलिंग, सफल/विफल अनुरोध गणना।
- Lambda: invocation count, duration (p50/p95/p99), errors, throttles, concurrent executions. Lambda: इनवोकेशन काउंट, अवधि (p50/p95/p99), त्रुटियाँ, थ्रॉटल्स, समवर्ती निष्पादन।
- API Gateway: 4xx/5xx error rates, integration latency. API Gateway: 4xx/5xx त्रुटि दर, इंटीग्रेशन विलंबता।
- SQS: queue depth and DLQ counts for background jobs (certificate generation). SQS: पृष्ठभूमि जॉब्स (प्रमाणपत्र जनरेशन) के लिए कतार गहराई और DLQ गणना।
-
Alerts:
अलर्ट्स:
- Elevated 5xx rate on API Gateway (threshold configured per service). API Gateway पर बढ़ी हुई 5xx दर (प्रति सेवा थ्रेशोल्ड कॉन्फ़िगर)।
- DynamoDB throttling detected on any table or GSI. किसी भी तालिका या GSI पर DynamoDB थ्रॉटलिंग का पता चलना।
- SQS backlog rising beyond configured threshold. SQS बैकलॉग कॉन्फ़िगर्ड थ्रेशोल्ड से ऊपर बढ़ना।
- Certificate generation job DLQ messages > 0. प्रमाणपत्र जनरेशन जॉब DLQ संदेश > 0।
-
Logging & tracing:
लॉगिंग और ट्रेसिंग:
- Structured JSON logs include requestId, userId, path, and latencies. संरचित JSON लॉग में requestId, userId, path और latencies शामिल हैं।
- Distributed traces (X-Ray) track request flows across API Gateway → Lambda → DynamoDB → S3 to correlate slow or failing paths. वितरित ट्रेस (X-Ray) API Gateway → Lambda → DynamoDB → S3 के पार अनुरोध प्रवाह को ट्रैक करते हैं ताकि धीमे या विफल पथों को सहसंबंधित किया जा सके।
Active observability is configured to link database usage to application health and user experience. सक्रिय प्रेक्षणीयता को डेटाबेस उपयोग को एप्लिकेशन स्वास्थ्य और उपयोगकर्ता अनुभव से जोड़ने के लिए कॉन्फ़िगर किया गया है।
6. Roadmap — Planned updates for next release 6. रोडमैप — अगले रिलीज़ के लिए नियोजित अपडेट
- These items are scoped as planned, backward-compatible improvements that address edge cases and scale considerations while preserving current behavior. ये आइटम योजनाबद्ध, बैकवर्ड-कम्पैटिबल सुधार के रूप में परिभाषित हैं जो वर्तमान व्यवहार को बनाए रखते हुए किनारे के मामलों और स्केल विचारों को संबोधित करते हैं।
- Atomic uniqueness for certificate uniqueId: Enforce uniqueId uniqueness at write-time using a transactional write pattern (TransactWrite or a dedicated UniqueCertificateMap table) to guarantee no duplicate public identifiers under concurrent writes. प्रमाणपत्र uniqueId के लिए परमाणु अनन्यता: समवर्ती लेखन के तहत कोई डुप्लिकेट सार्वजनिक पहचानकर्ता न हो यह सुनिश्चित करने के लिए ट्रांज़ैक्शनल लेखन पैटर्न (TransactWrite या समर्पित UniqueCertificateMap तालिका) का उपयोग करके write-time पर uniqueId की अनन्यता लागू करें।
- User-post mapping migration: Replace createdPosts and completedPosts list attributes on the Users record with a dedicated UserPosts mapping table keyed by (userId, postId). This eliminates potential unbounded list growth and reduces write contention on the Users item. User-post मैपिंग माइग्रेशन: Users रिकॉर्ड पर createdPosts और completedPosts सूची एट्रिब्यूट को (userId, postId) द्वारा की गई समर्पित UserPosts मैपिंग तालिका से बदलें। यह संभावित अनबाउंडेड सूची वृद्धि को खत्म करता है और Users आइटम पर लिखने की प्रतिद्वंद्विता को कम करता है।
- Category follower mapping: Replace the current comma-separated followedCategories attribute with a CategoryFollowers mapping table keyed by (category, userId) to enable efficient fanout and pagination for category-based operations. Category follower मैपिंग: श्रेणी-आधारित ऑपरेशनों के लिए कुशल फैनआउट और पेजिनेशन सक्षम करने के लिए वर्तमान कॉमा-सेपरेटेड followedCategories एट्रिब्यूट को (category, userId) के द्वारा की गई CategoryFollowers मैपिंग तालिका से बदलें।
- Notification primary-key refinement: Migrate notifications to a composite key (userId, createdAt) to enable naturally sorted queries and efficient pagination for notification lists. Notification प्राथमिक-कुंजी परिष्करण: नोटिफिकेशन सूचियों के लिए स्वाभाविक रूप से क्रमबद्ध क्वेरीज और कुशल पेजिनेशन सक्षम करने के लिए नोटिफिकेशनों को सम्मिलित कुंजी (userId, createdAt) में माइग्रेट करें।
- GSI projection optimization: As write volume grows, convert selected GSIs from All projection to minimal projected attributes for highly written tables to reduce write amplification and storage costs. GSI प्रोजेक्शन अनुकूलन: जैसे-जैसे लेखन मात्रा बढ़ती है, उच्च लेखित तालिकाओं के लिए लिखने की प्रचार (write amplification) और भंडारण लागत को कम करने के लिए चयनित GSI को All प्रोजेक्शन से न्यूनतम प्रोजेक्टेड एट्रिब्यूट्स में बदलें।
7. Summary of design trade-offs 7. डिज़ाइन ट्रेड-ऑफ़ का सारांश
- Read performance vs write cost: Current design favors index-driven, single-query reads (optimized for SSR and UX) at the cost of higher write amplification (GSIs projected as All). This is an intentional trade-off for developer velocity and low-latency content rendering in the product’s early stage. रीड प्रदर्शन बनाम राइट लागत: वर्तमान डिज़ाइन इंडेक्स-ड्रिवन, सिंगल-क्वेरी रीड (SSR और UX के लिए अनुकूलित) को बढ़ी हुई लिखने की प्रचार (GSIs को All के रूप में प्रोजेक्ट करना) की कीमत पर प्राथमिकता देता है। यह उत्पाद के शुरुआती चरण में डेवलपर वेग और कम-लेटेंसी सामग्री रेंडरिंग के लिए एक जानबूझकर ट्रेड-ऑफ़ है।
- Operational simplicity vs relational features: DynamoDB reduces operational burden and provides low-latency key-based access but requires denormalization patterns and mapping tables for relational semantics and multi-item atomicity. Planned roadmap items address these concerns while preserving the serverless model. ऑपरेशनल सरलता बनाम रिलेशनल सुविधाएँ: DynamoDB परिचालन बोझ को कम करता है और कम-लेटेंसी की-आधारित पहुंच प्रदान करता है लेकिन रिलेशनल अर्थ और मल्टी-आइटम परमाणुता के लिए डी-नॉर्मलाइज़ेशन पैटर्न और मैपिंग टेबल की आवश्यकता होती है। नियोजित रोडमैप आइटम इन चिंताओं को सर्वरलेस मॉडल को बनाए रखते हुए संबोधित करते हैं।
Deployment & DevOps तैनाती और DevOps
Image: Zedemy Deployment Pipeline
छवि: जेडेमी तैनाती पाइपलाइन
Deployment Workflow: तैनाती कार्यप्रवाह:
- Feature branches pushed to GitHub GitHub पर फीचर ब्रांच पुश किए गए
- Vercel auto-triggers build via GitHub hooks Vercel GitHub हुक के माध्यम से स्वचालित रूप से बिल्ड शुरू करता है
- Vite optimizes and bundles code Vite कोड को अनुकूलित और बंडल करता है
- Assets served over Vercel CDN Vercel CDN पर परिसंपत्तियाँ प्रदान की जाती हैं
- Vercel rewrites route API calls to AWS Gateway Vercel रीराइट्स API कॉल को AWS Gateway पर रूट करता है
Challenges & Solutions चुनौतियाँ और समाधान
| Challenge चुनौती | Solution समाधान |
|---|---|
| Scalable Notification Fanout स्केलेबल सूचना फैनआउट | Used DynamoDB GSI for category-based queries; implemented SQS for async notification writes to handle high follower counts. श्रेणी-आधारित क्वेरीज़ के लिए DynamoDB GSI का उपयोग किया; उच्च अनुयायी गणना को संभालने के लिए async सूचना लेखन के लिए SQS लागू किया। |
| SEO for Dynamic Content डायनामिक सामग्री के लिए SEO | Implemented SSR with Vite and React Helmet; used structured data (JSON-LD) for Google AI Overview indexing. Vite और React Helmet के साथ SSR लागू किया; Google AI ओवरव्यू इंडेक्सिंग के लिए संरचित डेटा (JSON-LD) का उपयोग किया। |
| Certificate Security प्रमाणपत्र सुरक्षा | Private S3 buckets with signed URLs (TTL=7 days for emails, 1hr for verification); no sensitive data in public responses. साइन किए गए URL के साथ निजी S3 बकेट (ईमेल के लिए TTL=7 दिन, सत्यापन के लिए 1 घंटा); सार्वजनिक प्रतिक्रियाओं में कोई संवेदनशील डेटा नहीं। |
| Lambda Timeout for PDF Generation PDF जनन के लिए Lambda टाइमआउट | Offloaded to SQS workers; used lightweight PDF lib to generate buffers within 300s limit. SQS वर्कर्स को ऑफलोड किया; 300 सेकंड की सीमा के भीतर बफर जनरेट करने के लिए हल्के PDF लाइब्रेरी का उपयोग किया। |
| Rate Limiting Public Endpoints सार्वजनिक एंडपॉइंट्स की दर सीमा | API Gateway throttling; CloudWatch monitoring for abuse detection. API Gateway थ्रॉटलिंग; दुरुपयोग का पता लगाने के लिए CloudWatch मॉनिटरिंग। |
Impact & Results प्रभाव और परिणाम
- User Engagement: Over 10,000 monthly active users within 6 months, driven by intuitive UX and gamified certificate system. उपयोगकर्ता जुड़ाव: 6 महीनों के भीतर 10,000 से अधिक मासिक सक्रिय उपयोगकर्ता, सहज UX और गेमिफाइड प्रमाणपत्र प्रणाली द्वारा संचालित।
- SEO Success: Google AI Overview feature within 3 months; 80% of blog posts rank on page 1 for targeted keywords. SEO सफलता: 3 महीनों के भीतर Google AI ओवरव्यू फीचर; लक्षित कीवर्ड के लिए 80% ब्लॉग पोस्ट पेज 1 पर रैंक करते हैं।
- Performance: Page load times under 2s globally (Vercel CDN + CloudFront); 99.9% uptime via serverless. प्रदर्शन: वैश्विक रूप से पेज लोड समय 2 सेकंड से कम (Vercel CDN + CloudFront); सर्वरलेस के माध्यम से 99.9% अपटाइम।
- Cost Efficiency: Serverless architecture reduced hosting costs by 60% compared to traditional EC2 setups. लागत दक्षता: सर्वरलेस आर्किटेक्चर ने पारंपरिक EC2 सेटअप की तुलना में होस्टिंग लागत को 60% कम किया।
Featured in Google AI Overview / Featured Snippet गूगल एआई ओवरव्यू / फीचर्ड स्निपेट में प्रदर्शित
Within months of launch, Zedemy was featured in Google's AI Overview for the search query “Zedemy”, showcasing its technical architecture and crediting Sanjay Patidar as the developer. This recognition was earned through serverless-first engineering, schema-rich documentation, and optimized meta content using React Helmet — allowing Google AI to index and present the content as a native knowledge snippet. लॉन्च के कुछ महीनों के भीतर, “Zedemy” खोज शब्द के लिए Zedemy को Google के AI ओवरव्यू में प्रदर्शित किया गया, जिसमें इसके तकनीकी आर्किटेक्चर को दर्शाया गया और डेवलपर के रूप में संजय पाटीदार को श्रेय दिया गया। यह सर्वरलेस-फर्स्ट इंजीनियरिंग, स्कीमा-समृद्ध डोक्युमेंटेशन, और React Helmet द्वारा अनुकूलित मेटा कंटेंट के कारण संभव हुआ — जिससे Google AI ने कंटेंट को मूल ज्ञान स्निपेट के रूप में इंडेक्स और प्रस्तुत किया।
Image: Zedemy Google AI Overview Featured Snippet Screenshot
छवि: गूगल एआई ओवरव्यू में Zedemy का फीचर्ड स्निपेट स्क्रीनशॉट
Future Enhancements भविष्य के संवर्धन
- Real-Time Notifications: Upgrade to WebSocket (AWS API Gateway WebSocket) for instant updates. वास्तविक समय सूचनाएँ: तत्काल अपडेट के लिए WebSocket (AWS API Gateway WebSocket) में अपग्रेड करें।
- ML Recommendations: Integrate SageMaker for personalized post suggestions based on user history. ML सिफारिशें: उपयोगकर्ता इतिहास के आधार पर व्यक्तिगत पोस्ट सुझावों के लिए SageMaker को एकीकृत करें।
- Multi-Language Support: Expand beyond English/Hindi with i18n for content and UI. बहु-भाषा समर्थन: सामग्री और UI के लिए i18n के साथ अंग्रेजी/हिन्दी से आगे बढ़ें।
- Analytics Dashboard: Add user analytics (e.g., completion rates, popular categories) using AWS QuickSight. विश्लेषण डैशबोर्ड: AWS QuickSight का उपयोग करके उपयोगकर्ता विश्लेषण जोड़ें (उदाहरण के लिए, पूर्णता दर, लोकप्रिय श्रेणियाँ)।
Conclusion निष्कर्ष
Zedemy demonstrates a robust, scalable, and user-centric educational platform built with modern web technologies and serverless architecture. Its success in user engagement, SEO, and cost efficiency highlights the effectiveness of Sanjay Patidar’s engineering choices. The platform continues to evolve, with plans for enhanced interactivity and personalization. जेडेमी आधुनिक वेब प्रौद्योगिकियों और सर्वरलेस आर्किटेक्चर के साथ निर्मित एक मजबूत, स्केलेबल और उपयोगकर्ता-केंद्रित शैक्षिक मंच को प्रदर्शित करता है। उपयोगकर्ता जुड़ाव, SEO और लागत दक्षता में इसकी सफलता संजय पाटीदार के इंजीनियरिंग विकल्पों की प्रभावशीलता को उजागर करती है। मंच में उन्नत अन्तरक्रियाशीलता और वैयक्तिकरण की योजनाओं के साथ निरंतर विकास जारी है।