Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

5 Commits

Repository files navigation

StatusLicenseNodeReactMongoDBGemini AI

📚 StudyFlow AI

AI-Powered Smart Study Platform
Plan smarter, track progress, quiz yourself, and learn with an AI tutor — all in one place.

FeaturesTech StackArchitectureGetting StartedAPI DocsDeployment


✨ Features

🧠 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.

📝 AI-Generated Quizzes

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).

📊 Progress Analytics

  • Study Streak Tracking — Consecutive day counter
  • Weekly/Monthly Reports — Hours studied with daily & subject breakdown
  • Quiz Performance — Average scores over time
  • Gamification — 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

🎯 Dashboard

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 headers
  • Rate limiting (200 req/15min per IP)
  • NoSQL injection prevention (mongo-sanitize)
  • Zod request validation
  • HTTP-only cookies for refresh tokens
  • Payload size limits (10kb)

🛠 Tech Stack

Backend

LayerTechnology
RuntimeNode.js 20+
FrameworkExpress.js 4.21
DatabaseMongoDB + Mongoose 8.x ODM
AuthJWT (access 15m, refresh 7d) + bcryptjs
ValidationZod 4.x
AIGoogle Gemini AI (@google/generative-ai)
LoggingWinston 3.x
SecurityHelmet, CORS, express-rate-limit, express-mongo-sanitize
ArchitectureModular MVC (controllers, services, routes, models)

Frontend

LayerTechnology
FrameworkReact 19
Build ToolVite 8.x
RoutingReact Router 7.x
StylingTailwind CSS 4.x
IconsLucide React
ChartsRecharts 3.x
HTTP ClientAxios 1.x
LintingESLint 10.x
DeploymentVercel (with SPA rewrites)

🏗 Architecture

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

DecisionRationale
Modular monolith (modules/)Feature-based grouping instead of technical layers — higher cohesion, easier to extract microservices later
Service layerBusiness logic extracted from controllers → testable, reusable, keeps controllers thin
Soft deleteSubjects & chapters use isDeleted flag + query middleware → reversible, audit-friendly
AI fallback chainGemini AI → dummy generator / question bank → zero-downtime resilience
Token rotationRefresh tokens are rotated on each use → limits stolen-token window
MongoDB transactionsRegistration uses transactions for data consistency; falls back gracefully on single-node setups
JWT split secretsSeparate JWT_ACCESS_SECRET and JWT_REFRESH_SECRET → compartmentalized compromise
Rate limitingGlobal (200/15min) + per-feature (AI chat: 20/day) → multi-layer abuse prevention
Zod validationRuntime + type safety without TypeScript compilation overhead
Lazy loadingReact.lazy() for all page components → smaller initial bundle

Data Flow

┌──────────┐ HTTPS ┌──────────────────┐ Mongoose ┌──────────┐
│ Browser │ ──────────────▶ │ Express Server │ ──────────────────▶ │ MongoDB │
│ (React) │ ◀────────────── │ (backend/) │ ◀────────────────── │ │
└──────────┘ │ │ └──────────┘
│ ┌─────────────┐ │
│ │ JWT Auth │ │
│ │ Middleware │ │
│ └──────┬──────┘ │
│ │ │
│ ┌──────▼──────┐ │ ┌──────────────┐
│ │ Controllers │ │ │ Google │
│ └──────┬──────┘ │ │ Gemini AI │
│ │ │ │ │
│ ┌──────▼──────┐ │ └──────┬───────┘
│ │ Services │ ─┼───────────▶│
│ └──────┬──────┘ │ ◀──────┤
│ │ │
│ ┌──────▼──────┐ │
│ │ Models │ │
│ └─────────────┘ │
└──────────────────┘

🚀 Getting Started

Prerequisites

  • Node.js 20+ (with --env-file support)
  • MongoDB (local or Atlas)
  • Google Gemini API Key (Get one free)

1️⃣ Clone & Install

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=5000NODE_ENV=developmentMONGO_URI=mongodb+srv://user:pass@cluster.mongodb.net/studyflow?retryWrites=trueJWT_SECRET=your-super-secret-key-min-8-charsJWT_ACCESS_SECRET=your-access-secret-min-8-charsJWT_REFRESH_SECRET=your-refresh-secret-min-8-charsGEMINI_API_KEY=your-gemini-api-keyFRONTEND_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

4️⃣ Run Production

# Backendcd backend && npm start
# Frontendcd frontend && npm run build && npm run preview

📡 API Documentation

All API routes are prefixed with /api/v1.

Authentication

MethodEndpointDescriptionAuth
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

Users

MethodEndpointDescriptionAuth
GET/users/profileGet user profile
PUT/users/profileUpdate profile

Subjects

MethodEndpointDescriptionAuth
GET/subjectsList all subjects
POST/subjectsCreate subject (auto-creates chapters)
PUT/subjects/:idUpdate subject
DELETE/subjects/:idSoft-delete subject

Chapters

MethodEndpointDescriptionAuth
GET/chapters/:subjectIdList chapters for subject
POST/chaptersCreate chapter
PATCH/chapters/:id/statusUpdate chapter status
DELETE/chapters/:idSoft-delete chapter

Study Plan

MethodEndpointDescriptionAuth
GET/study-planGet current plan
POST/study-plan/generateGenerate new AI plan
PATCH/study-plan/:planId/day/:dayIndex/task/:taskIdToggle task completion

Quiz

MethodEndpointDescriptionAuth
GET/quiz/questions?subject=X&count=5&difficulty=mediumGet sample questions
POST/quiz/submitSubmit quiz attempt
GET/quiz/history?limit=20Get quiz history

Study Logs

MethodEndpointDescriptionAuth
POST/study-logsLog study session
GET/study-logs/weeklyGet weekly summary
GET/study-logs/monthlyGet monthly summary

Dashboard

MethodEndpointDescriptionAuth
GET/dashboardAggregated stats (streak, points, avg score, hours)

AI Chat

MethodEndpointDescriptionAuth
POST/ai-chat/askAsk AI tutor (rate-limited: 20/day)

Health

MethodEndpointDescription
GET/healthHealth check (no prefix)

🧪 Database Models

User

FieldTypeNotes
nameStringRequired
emailStringUnique, lowercase
passwordStringbcrypt(12), select: false
classLevelStringe.g., "HSC", "Undergraduate"
goalStringe.g., "Exam preparation"
subjects[String]Array of subject names
examDateDateTarget exam date
plan"free" | "pro"Subscription tier
dailyAiMessagesNumberResets daily
refreshTokenStringselect: false

Subject

FieldTypeNotes
userIdObjectIdRef → User
nameStringRequired
totalChaptersNumberDefault 0
colorStringUI color indicator
isDeletedBooleanSoft-delete, select: false

Chapter

FieldTypeNotes
subjectIdObjectIdRef → Subject
nameStringRequired
status"not-started" | "learning" | "completed"Progress tracking
orderNumberDisplay ordering
isDeletedBooleanSoft-delete, select: false

StudyPlan

FieldTypeNotes
userIdObjectIdRef → User
examDateDateTarget date
dailyHoursNumberDefault 4
days[Day]Sub-documents with tasks

QuizAttempt

FieldTypeNotes
userIdObjectIdRef → User
subjectStringQuiz subject
questions[QuestionResult]Full question data
scoreNumberCorrect answers
totalQuestionsNumberTotal questions

StudyLog

FieldTypeNotes
userIdObjectIdRef → User
dateDateSession date
hoursStudiedNumber≥ 0
subjectStringSubject name
topicStringOptional topic

🌐 Deployment

Backend → Render

  1. Push code to GitHub
  2. Create Web Service on Render
  3. Configure:
    • Root Directory: backend
    • Build Command: npm install
    • Start Command: npm start
  4. Add all environment variables in Render dashboard
  5. Deploy

Frontend → Vercel

  1. Import repo on Vercel
  2. Configure:
    • Root Directory: frontend
    • Framework: Vite
    • Build Command: npm run build
    • Output Directory: dist
  3. Add VITE_API_URL environment variable pointing to your Render backend
  4. Deploy

📖 See setup.md for detailed deployment instructions (Bengali).


🔒 Security Hardening

MeasureImplementation
Password hashingbcrypt with 12 salt rounds
JWT access tokens15-minute expiry
JWT refresh tokens7-day expiry, rotated on use
HTTP-only cookiesRefresh tokens stored in cookies
Request validationZod middleware rejects malformed input
Rate limiting200 requests per 15 minutes per IP
NoSQL injectionexpress-mongo-sanitize strips $ and .
Security headersHelmet sets CSP, X-Frame-Options, etc.
Payload limitJSON body limited to 10kb
CORSExplicit whitelist + credentials: true
Soft deleteData never truly lost

🧹 Code Quality & Patterns

  • ES Modules ("type": "module") throughout
  • catchAsync wrapper — no try-catch boilerplate in controllers
  • Custom ApiError class — consistent operational error handling
  • Sentry-ready error format — global error handler produces structured JSON
  • Graceful AI fallbacks — Gemini → dummy logic → zero-downtime
  • Query middleware — automatic soft-delete filtering via Mongoose pre(/^find/)
  • Indexed queries — All frequent queries have MongoDB indexes
  • Environment validation — Zod schema at startup catches misconfiguration early
  • Auto-cleanup — Quiz cache purges entries older than 1 hour

🤝 Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feat/amazing-feature)
  3. Commit changes (git commit -m 'feat: add amazing feature')
  4. Push to branch (git push origin feat/amazing-feature)
  5. Open a Pull Request

Commit Convention

We follow Conventional Commits:

  • feat: — New feature
  • fix: — Bug fix
  • refactor: — Code restructuring
  • docs: — Documentation
  • chore: — Maintenance

📄 License

This project is licensed under the MIT License.


Built with ❤️ using React, Node.js, MongoDB & Google Gemini AI

Releases

Packages

Contributors

Languages