AI-Powered Smart Study Platform
Plan smarter, track progress, quiz yourself, and learn with an AI tutor — all in one place.
Features •
Tech Stack •
Architecture •
Getting Started •
API Docs •
Deployment
🧠 AI-Powered Study Plan Generator Generate personalized study plans using Google Gemini AI . Input your exam date, subjects, and daily availability — the AI creates a day-by-day schedule with specific topics and time allocations. Falls back gracefully to a smart dummy generator when AI is unavailable.
Take dynamically generated multiple-choice quizzes on any subject. Questions are created on-the-fly by Gemini AI with real-time grading and detailed result tracking. Falls back to a curated question bank when needed.
🤖 AI Tutor (Chat Assistant) Get instant academic help from an AI tutor. The assistant maintains conversation context, adapts to your class level, and ends each response with a practice question. Includes daily rate limiting (20 messages/day on Free plan).
Study Streak Tracking — Consecutive day counterWeekly/Monthly Reports — Hours studied with daily & subject breakdownQuiz Performance — Average scores over timeGamification — Points system (10 pts per quiz, 5 pts per study hour)📚 Subject & Chapter Management Add/remove subjects with auto-generated chapters Track chapter status: Not Started → Learning → Completed Soft-delete support for safe removals Visual progress indicators Centralized view of all key metrics: current study plan, weekly chart, subject progress, task list, and AI tips.
🔐 Enterprise-Grade Security JWT with access + refresh token rotation Password hashing (bcrypt, 12 rounds) Helmet security headersRate limiting (200 req/15min per IP)NoSQL injection prevention (mongo-sanitize)Zod request validationHTTP-only cookies for refresh tokensPayload size limits (10kb) Layer Technology Runtime Node.js 20+ Framework Express.js 4.21 Database MongoDB + Mongoose 8.x ODM Auth JWT (access 15m, refresh 7d) + bcryptjs Validation Zod 4.x AI Google Gemini AI (@google/generative-ai) Logging Winston 3.x Security Helmet, CORS, express-rate-limit, express-mongo-sanitize Architecture Modular MVC (controllers, services, routes, models)
Layer Technology Framework React 19 Build Tool Vite 8.x Routing React Router 7.x Styling Tailwind CSS 4.x Icons Lucide React Charts Recharts 3.x HTTP Client Axios 1.x Linting ESLint 10.x Deployment Vercel (with SPA rewrites)
Production-Grade Directory Structure studyflow-ai/
│
├── backend/ # 🖥 Express API Server
│ ├── src/
│ │ ├── config/
│ │ │ ├── db.js # MongoDB connection
│ │ │ └── env.js # Zod-enforced env validation
│ │ │
│ │ ├── middleware/
│ │ │ ├── validate.js # Zod schema validation middleware
│ │ │ └── verifyToken.js # JWT access token verification
│ │ │
│ │ ├── models/ # Mongoose schemas
│ │ │ ├── User.js # User with password hashing & refreshToken
│ │ │ ├── Subject.js # Subjects with soft-delete
│ │ │ ├── Chapter.js # Chapters with status tracking
│ │ │ ├── StudyPlan.js # Day-by-day study plans
│ │ │ ├── StudyLog.js # Study session logs
│ │ │ └── QuizAttempt.js # Quiz attempt records
│ │ │
│ │ ├── modules/ # 🧩 Feature modules (bounded contexts)
│ │ │ ├── auth/ # Authentication & authorization
│ │ │ │ ├── auth.controller.js
│ │ │ │ ├── auth.service.js # Business logic + transactions
│ │ │ │ ├── auth.route.js
│ │ │ │ └── auth.validator.js # Zod schemas
│ │ │ │
│ │ │ ├── users/ # User profile management
│ │ │ │ ├── users.controller.js
│ │ │ │ └── users.route.js
│ │ │ │
│ │ │ ├── subjects/ # Subject CRUD with soft-delete
│ │ │ │ ├── subjects.controller.js
│ │ │ │ └── subjects.route.js
│ │ │ │
│ │ │ ├── chapters/ # Chapter management & status
│ │ │ │ ├── chapters.controller.js
│ │ │ │ └── chapters.route.js
│ │ │ │
│ │ │ ├── studyPlan/ # AI + fallback plan generation
│ │ │ │ ├── studyPlan.controller.js
│ │ │ │ ├── studyPlan.service.js # Dummy plan generator
│ │ │ │ └── studyPlan.route.js
│ │ │ │
│ │ │ ├── quiz/ # AI + fallback quiz engine
│ │ │ │ ├── quiz.controller.js
│ │ │ │ └── quiz.route.js
│ │ │ │
│ │ │ ├── studyLogs/ # Study session tracking
│ │ │ │ ├── studyLogs.controller.js
│ │ │ │ └── studyLogs.route.js
│ │ │ │
│ │ │ ├── dashboard/ # Aggregated stats
│ │ │ │ ├── dashboard.controller.js
│ │ │ │ └── dashboard.route.js
│ │ │ │
│ │ │ └── aiChat/ # Gemini AI tutor
│ │ │ ├── aiChat.controller.js
│ │ │ └── aiChat.route.js
│ │ │
│ │ └── utils/
│ │ ├── ApiError.js # Custom operational error class
│ │ ├── catchAsync.js # Async error wrapper
│ │ ├── geminiClient.js # Gemini API client (timeout, truncation guard)
│ │ ├── helpers.js # Markdown stripper, quiz validator
│ │ └── logger.js # Winston logger (console + file transports)
│ │
│ ├── server.js # 🚀 Entry point (env validation, security, routes)
│ ├── package.json
│ └── .env.example # Template for environment variables
│
├── frontend/ # 🎨 React SPA
│ ├── src/
│ │ ├── api/ # 🕸 API client layer (Axios)
│ │ │ ├── axios.js # Configured instance with interceptors
│ │ │ ├── auth.js # Auth endpoints
│ │ │ ├── subjects.js
│ │ │ ├── chapters.js
│ │ │ ├── studyPlan.js
│ │ │ ├── quiz.js
│ │ │ ├── studyLogs.js
│ │ │ ├── dashboard.js
│ │ │ ├── aiChat.js
│ │ │ └── users.js
│ │ │
│ │ ├── context/ # 🔄 React contexts
│ │ │ └── AuthContext.jsx # Auth state + token management
│ │ │
│ │ ├── components/ # 🧩 Reusable UI components
│ │ │ ├── Dashboard.jsx # Dashboard layout
│ │ │ ├── Sidebar.jsx # Navigation sidebar
│ │ │ ├── Topbar.jsx # Top navigation bar
│ │ │ ├── Navbar.jsx # Landing page navbar
│ │ │ ├── Hero.jsx # Landing page hero
│ │ │ ├── Features.jsx
│ │ │ ├── Pricing.jsx
│ │ │ ├── Footer.jsx
│ │ │ ├── StatsRow.jsx
│ │ │ ├── WeeklyChart.jsx # Recharts weekly chart
│ │ │ ├── StudyPlanner.jsx
│ │ │ ├── StudyPlanCard.jsx
│ │ │ ├── PlanGeneratorForm.jsx
│ │ │ ├── PlanSummaryPanel.jsx
│ │ │ ├── SubjectCard.jsx
│ │ │ ├── SubjectProgress.jsx
│ │ │ ├── ChapterDrawer.jsx
│ │ │ ├── ChapterRow.jsx
│ │ │ ├── TaskList.jsx
│ │ │ ├── TaskRow.jsx
│ │ │ ├── QuizForm.jsx
│ │ │ ├── QuizPage.jsx
│ │ │ ├── QuizResultCard.jsx
│ │ │ ├── QuestionCard.jsx
│ │ │ ├── AiAssistant.jsx
│ │ │ ├── ChatBubble.jsx
│ │ │ ├── ChatTab.jsx
│ │ │ ├── TypingIndicator.jsx
│ │ │ ├── AITipCard.jsx
│ │ │ ├── Analytics.jsx
│ │ │ ├── Gamification.jsx
│ │ │ ├── Settings.jsx
│ │ │ ├── AccountTab.jsx
│ │ │ ├── ProfileTab.jsx
│ │ │ ├── NotificationsTab.jsx
│ │ │ ├── PreferencesTab.jsx
│ │ │ ├── SubscriptionTab.jsx
│ │ │ ├── DangerZoneTab.jsx
│ │ │ ├── LoginPage.jsx
│ │ │ ├── AddSubjectModal.jsx
│ │ │ ├── DayCard.jsx
│ │ │ ├── OnboardingFlow.jsx
│ │ │ ├── ProtectedRoute.jsx
│ │ │ ├── StatusBadge.jsx
│ │ │ ├── ToggleSwitch.jsx
│ │ │ ├── Toast.jsx
│ │ │ └── ... more
│ │ │
│ │ ├── pages/ # 📄 Route pages (re-export from components)
│ │ │ ├── Dashboard.jsx
│ │ │ ├── Landing.jsx
│ │ │ ├── Login.jsx
│ │ │ ├── Planner.jsx
│ │ │ ├── Subjects.jsx
│ │ │ ├── AiAssistant.jsx
│ │ │ ├── Quiz.jsx
│ │ │ ├── Analytics.jsx
│ │ │ ├── Settings.jsx
│ │ │ ├── Onboarding.jsx
│ │ │ └── NotFound.jsx
│ │ │
│ │ ├── App.jsx # 🧭 Root component (routing + providers)
│ │ ├── main.jsx # 🚀 Entry point
│ │ └── index.css # Tailwind + custom animations
│ │
│ ├── index.html
│ ├── vite.config.js
│ ├── vercel.json # SPA rewrites for Vercel
│ └── package.json
│
├── doc/
│ └── implementation_plan.md # Refactoring plan documentation
│
├── setup.md # Deployment guide (Bengali)
├── .gitignore
└── README.md # 📘 You are here
Key Architectural Decisions Decision Rationale Modular monolith (modules/) Feature-based grouping instead of technical layers — higher cohesion, easier to extract microservices later Service layer Business logic extracted from controllers → testable, reusable, keeps controllers thin Soft delete Subjects & chapters use isDeleted flag + query middleware → reversible, audit-friendly AI fallback chain Gemini AI → dummy generator / question bank → zero-downtime resilience Token rotation Refresh tokens are rotated on each use → limits stolen-token window MongoDB transactions Registration uses transactions for data consistency; falls back gracefully on single-node setups JWT split secrets Separate JWT_ACCESS_SECRET and JWT_REFRESH_SECRET → compartmentalized compromise Rate limiting Global (200/15min) + per-feature (AI chat: 20/day) → multi-layer abuse prevention Zod validation Runtime + type safety without TypeScript compilation overhead Lazy loading React.lazy() for all page components → smaller initial bundle
┌──────────┐ HTTPS ┌──────────────────┐ Mongoose ┌──────────┐
│ Browser │ ──────────────▶ │ Express Server │ ──────────────────▶ │ MongoDB │
│ (React) │ ◀────────────── │ (backend/) │ ◀────────────────── │ │
└──────────┘ │ │ └──────────┘
│ ┌─────────────┐ │
│ │ JWT Auth │ │
│ │ Middleware │ │
│ └──────┬──────┘ │
│ │ │
│ ┌──────▼──────┐ │ ┌──────────────┐
│ │ Controllers │ │ │ Google │
│ └──────┬──────┘ │ │ Gemini AI │
│ │ │ │ │
│ ┌──────▼──────┐ │ └──────┬───────┘
│ │ Services │ ─┼───────────▶│
│ └──────┬──────┘ │ ◀──────┤
│ │ │
│ ┌──────▼──────┐ │
│ │ Models │ │
│ └─────────────┘ │
└──────────────────┘
Node.js 20+ (with --env-file support)MongoDB (local or Atlas )Google Gemini API Key (Get one free )git clone https://github.com/yourusername/studyflow-ai.git
cd studyflow-ai
# Install backend dependenciescd backend
npm install
# Install frontend dependenciescd ../frontend
npm install 2️⃣ Configure Environment # Backend environment
cp .env.example .env
# Edit .env with your values.env file (backend/):
PORT = 5000 NODE_ENV = development MONGO_URI = mongodb+srv://user:pass@cluster.mongodb.net/studyflow?retryWrites=true JWT_SECRET = your-super-secret-key-min-8-chars JWT_ACCESS_SECRET = your-access-secret-min-8-chars JWT_REFRESH_SECRET = your-refresh-secret-min-8-chars GEMINI_API_KEY = your-gemini-api-key FRONTEND_URL = http://localhost:5173 3️⃣ Run Development Servers # Terminal 1: Backend (auto-restart on changes)cd backend
npm run dev
# Terminal 2: Frontendcd frontend
npm run dev# Backendcd backend && npm start
# Frontendcd frontend && npm run build && npm run previewAll API routes are prefixed with /api/v1.
Method Endpoint Description Auth POST /auth/registerCreate account + generate plan ❌ POST /auth/loginLogin ❌ POST /auth/refreshRefresh access token ❌ (cookie) POST /auth/logoutLogout (clear refresh token) ✅ GET /auth/meGet current user ✅
Method Endpoint Description Auth GET /users/profileGet user profile ✅ PUT /users/profileUpdate profile ✅
Method Endpoint Description Auth GET /subjectsList all subjects ✅ POST /subjectsCreate subject (auto-creates chapters) ✅ PUT /subjects/:idUpdate subject ✅ DELETE /subjects/:idSoft-delete subject ✅
Method Endpoint Description Auth GET /chapters/:subjectIdList chapters for subject ✅ POST /chaptersCreate chapter ✅ PATCH /chapters/:id/statusUpdate chapter status ✅ DELETE /chapters/:idSoft-delete chapter ✅
Method Endpoint Description Auth GET /study-planGet current plan ✅ POST /study-plan/generateGenerate new AI plan ✅ PATCH /study-plan/:planId/day/:dayIndex/task/:taskIdToggle task completion ✅
Method Endpoint Description Auth GET /quiz/questions?subject=X&count=5&difficulty=mediumGet sample questions ✅ POST /quiz/submitSubmit quiz attempt ✅ GET /quiz/history?limit=20Get quiz history ✅
Method Endpoint Description Auth POST /study-logsLog study session ✅ GET /study-logs/weeklyGet weekly summary ✅ GET /study-logs/monthlyGet monthly summary ✅
Method Endpoint Description Auth GET /dashboardAggregated stats (streak, points, avg score, hours) ✅
Method Endpoint Description Auth POST /ai-chat/askAsk AI tutor (rate-limited: 20/day) ✅
Method Endpoint Description GET /healthHealth check (no prefix)
Field Type Notes nameString Required emailString Unique, lowercase passwordString bcrypt(12), select: false classLevelString e.g., "HSC", "Undergraduate" goalString e.g., "Exam preparation" subjects[String] Array of subject names examDateDate Target exam date plan"free" | "pro" Subscription tier dailyAiMessagesNumber Resets daily refreshTokenString select: false
Field Type Notes userIdObjectId Ref → User nameString Required totalChaptersNumber Default 0 colorString UI color indicator isDeletedBoolean Soft-delete, select: false
Field Type Notes subjectIdObjectId Ref → Subject nameString Required status"not-started" | "learning" | "completed" Progress tracking orderNumber Display ordering isDeletedBoolean Soft-delete, select: false
Field Type Notes userIdObjectId Ref → User examDateDate Target date dailyHoursNumber Default 4 days[Day] Sub-documents with tasks
Field Type Notes userIdObjectId Ref → User subjectString Quiz subject questions[QuestionResult] Full question data scoreNumber Correct answers totalQuestionsNumber Total questions
Field Type Notes userIdObjectId Ref → User dateDate Session date hoursStudiedNumber ≥ 0 subjectString Subject name topicString Optional topic
Push code to GitHub Create Web Service on Render Configure:
Root Directory : backendBuild Command : npm installStart Command : npm start Add all environment variables in Render dashboard Deploy Import repo on Vercel Configure:
Root Directory : frontendFramework : ViteBuild Command : npm run buildOutput Directory : dist Add VITE_API_URL environment variable pointing to your Render backend Deploy 📖 See setup.md for detailed deployment instructions (Bengali).
Measure Implementation Password hashing bcrypt with 12 salt rounds JWT access tokens 15-minute expiry JWT refresh tokens 7-day expiry, rotated on use HTTP-only cookies Refresh tokens stored in cookies Request validation Zod middleware rejects malformed input Rate limiting 200 requests per 15 minutes per IP NoSQL injection express-mongo-sanitize strips $ and .Security headers Helmet sets CSP, X-Frame-Options, etc. Payload limit JSON body limited to 10kb CORS Explicit whitelist + credentials: true Soft delete Data never truly lost
🧹 Code Quality & Patterns ES Modules ("type": "module") throughoutcatchAsync wrapper — no try-catch boilerplate in controllersCustom ApiError class — consistent operational error handlingSentry-ready error format — global error handler produces structured JSONGraceful AI fallbacks — Gemini → dummy logic → zero-downtimeQuery middleware — automatic soft-delete filtering via Mongoose pre(/^find/)Indexed queries — All frequent queries have MongoDB indexesEnvironment validation — Zod schema at startup catches misconfiguration earlyAuto-cleanup — Quiz cache purges entries older than 1 hourFork the repository Create a feature branch (git checkout -b feat/amazing-feature) Commit changes (git commit -m 'feat: add amazing feature') Push to branch (git push origin feat/amazing-feature) Open a Pull Request We follow Conventional Commits :
feat: — New featurefix: — Bug fixrefactor: — Code restructuringdocs: — Documentationchore: — MaintenanceThis project is licensed under the MIT License.
Built with ❤️ using React, Node.js, MongoDB & Google Gemini AI