Zenit is an edtech web app: marketing site, authenticated student and teacher dashboards, AI-assisted study tools (chat, roadmaps, quizzes, podcasts, visualizer videos), gamification (coins, XP, study pass), and Razorpay checkout. It is a Next.js 16 monolith with MongoDB persistence and NextAuth (Google).
| Layer | Choice |
|---|---|
| Framework | Next.js 16 (App Router), React 19, TypeScript |
| Styling | Tailwind CSS v4, Radix UI, Framer Motion |
| Data | MongoDB (mongodb driver) |
| Auth | NextAuth v4, Google OAuth |
| AI | Google Gemini (@google/genai / @google/generative-ai), OpenAI where configured |
| Payments | Razorpay |
| Voice | Vapi (mentor calls), ElevenLabs (TTS) |
Project conventions and AI agent notes live in AGENTS.md (this repo targets a newer Next.js than classic tutorials).
- Node.js 20+ (recommended)
- npm (or compatible client)
- MongoDB URI (Atlas or local)
- Google OAuth client (Web application) for sign-in
npm installCreate .env.local in the repo root. Set at least the variables in Required below, then:
npm run devOpen http://localhost:3000.
npm run build
npm startProduction build and start.
npm run lintRun ESLint.
Create .env.local in the repo root (never commit secrets). Grouped by concern; only Required is needed for a minimal local run with auth + DB + core AI chat.
| Variable | Purpose |
|---|---|
MONGODB_URI |
MongoDB connection string |
MONGODB_DB_NAME |
Database name (many routes default to lr_hacks if unset; align with your cluster) |
NEXTAUTH_SECRET |
NextAuth signing secret |
NEXTAUTH_URL |
App origin, e.g. http://localhost:3000 |
GOOGLE_CLIENT_ID |
Google OAuth client ID |
GOOGLE_CLIENT_SECRET |
Google OAuth client secret |
GEMINI_API_KEY |
Google AI / Gemini (chat, roadmaps, visualizer, many API routes) |
| Variable | Purpose |
|---|---|
NEXT_PUBLIC_APP_URL |
Public site URL (metadata, some API headers) |
| Variable | Purpose |
|---|---|
NEXT_PUBLIC_RAZORPAY_KEY_ID |
Razorpay key id (client) |
RAZORPAY_KEY_SECRET |
Razorpay secret (server) |
| Variable | Purpose |
|---|---|
VAPI_PRIVATE_API_KEY |
Vapi server key |
VAPI_PHONE_NUMBER_ID |
Vapi outbound number id |
NEXT_PUBLIC_VAPI_GENERATE_ASSISTANT_ID |
Default assistant id (optional override from client) |
Examples used across the codebase: OPENAI_API_KEY, DEEPSEEK_API_KEY, OPENROUTER_API_KEY, ELEVENLABS_API_KEY, GEMINI_MODEL, GEMINI_VEO_MODEL. Routes fail gracefully or return errors if a key is missing for that feature.
| Path | Role |
|---|---|
src/app/ |
App Router: (marketing), dashboard/*, teacher/*, auth/*, api/* |
src/components/ |
UI, student-dashboard/, ui/ primitives |
src/lib/ |
Mongo client, auth config, AI helpers, quiz/roadmap logic |
src/config/ |
Copy, nav, tool flags (dashboard-chat-tools, dashboard-chat-persistence, etc.) |
src/models/ |
User-oriented types aligned with Mongo documents |
public/ |
Static curriculum assets (roadmaps, cheat sheets, visualizer media) |
Route: /dashboard/chat. Primary UI: src/components/student-dashboard/DashboardChatView.tsx. Backend for plain Q&A: POST /api/dashboard-chat (src/app/api/dashboard-chat/route.ts), using Gemini with a system prompt tuned for students and Zenit’s Visualizer (so the model does not treat random YouTube links as the main answer when an in-app clip is appropriate).
- Hero state when there are no messages: headline, Claude-style composer (
src/components/ui/claude-style-chat-input.tsx) with attachments, optional Do vs Chat mode, and idea carousel presets (summarize, quiz me, study plan, “I want to learn …”, etc.). - Thread state after the first message: scrollable transcript, same composer docked at the bottom, Zenit-branded bubbles.
Assistant and user bubbles render Markdown (react-markdown, GFM, remark-breaks, rehype-highlight, GitHub-dark code styling). Rich assistant cards exist for roadmaps, podcasts (audio + link to library), generated videos (inline player + optional topic breakdown from /api/generate-topic-info), and quizzes (deep link into AI Quiz).
If the user’s text matches “learn X” / roadmap-style intents, the chat runs a short agent flow: fetch three focus paths (/api/roadmap-focus-options), then inline chips for focus → level → (optional) JS/TS stack for web topics, then /api/ai-generate-roadmap and /api/save-roadmap, and finally a roadmap card linking to /dashboard/roadmap.
From the composer row users can trigger (with coin checks where applicable, aligned with the rest of the app):
| Chip | Behavior |
|---|---|
| Roadmap | Prefills “I want to learn …” in the composer. |
| Podcast | Requires a PDF attachment; spends coins → /api/generate-podcast → podcast bubble. |
| Quiz | PDF or typed topic; coins → /api/generate-quiz → quiz bubble. |
| Video | PDF or typed topic; coins (visualizer) → /api/generate-animation with videoIntent → video bubble + optional topic panel. |
| My videos | Opens a gallery dialog (GET /api/visualizer/videos); picking a row inserts a saved video message (no extra coin spend). |
| Mentor (end chip) | Opens a dialog with phone + /api/call (Vapi), same as /dashboard/ai-mentor. |
If the latest user message matches configurable regex intents (src/config/dashboard-chat-tools.ts → agenticVideo), the chat skips a generic text reply and instead builds a merged prompt from recent user lines + recent assistant explanations, then runs the same Visualizer pipeline (coins + animation + optional topic info). Example intent: asking to visualize with a video after discussing a topic.
Config-driven flow (mentorCallFromChat): phrases like “call me” / “I have a doubt” → assistant asks for E.164 number → next message triggers POST /api/call and XP award, mirroring the dedicated mentor page.
- Collection (default):
dashboard_chat_sessions— seesrc/config/dashboard-chat-persistence.ts(listLimit,maxMessagesStored,autoLoadLatestOnMount,saveDebounceMs). - API:
GET/POST /api/dashboard-chat/sessions,GET/PATCH /api/dashboard-chat/sessions/[id]— scoped by NextAuth user email. - UI: top bar with session picker (recent titles + relative time), New chat (creates an empty session), loading state while the list hydrates. Messages are debounced to the server after edits.
| File | Role |
|---|---|
src/config/dashboard-chat-tools.ts |
Mentor call copy/cancel regex, agentic video patterns and copy, Visualizer gallery toggle, topic panel after video, mentor assistant id (NEXT_PUBLIC_VAPI_GENERATE_ASSISTANT_ID). |
src/config/dashboard-chat-persistence.ts |
Mongo collection name, caps, auto-load latest, save debounce. |
- Landing (
src/app/(marketing)): public home, pricing-style sections, FAQ, navbar/footer. - Auth: Google sign-in via NextAuth; role selection and protected dashboard routes (
src/app/auth,src/lib/auth-config.ts).
- Home (
/dashboard): stats, quick links, activity graph, entry to tools. - Roadmap (
/dashboard/roadmap): full roadmap experience linked from chat-generated paths. - AI Notes (
/dashboard/ai-notes): AI Quiz and AI Podcasts flows (upload / generate, libraries). - Visualizer (
/dashboard/visualizer): prompt → coin-gated educational video (/api/generate-animation), topic info panel, gallery of saved clips per user. - AI Mentor (
/dashboard/ai-mentor): phone number + Vapi outbound call UI. - AR Learning (
/dashboard/ar-learning): AR-oriented chat/experiences where configured. - Online code / interview prep (
/dashboard/onlineCode, nested routes): tracks, questions, system-design markdown hubs underpublic/, flat markdown readers. - Shop (
/dashboard/shop): Razorpay orders, coin packs, study pass tiers (src/configshop + study pass). - Leaderboard, job automation entry, and other dashboard links as wired in
src/config/student-dashboard.tsand the shell.
/teacher/*: tools such as diagrams, slides, question papers, stats, prompt enhancement — backed by dedicated/api/teacher/*routes and Gemini where applicable.
- Coins, XP, study pass checks appear in API routes (e.g. spend-coins, award-xp) and Mongo-backed user documents (
src/models/User.tspatterns).
- Large public curriculum (e.g. CN, DBMS, system-design, roadmap JSON) for interview prep and learning paths.
- Podcasts, PPT, PDFs, animations produced through various
/api/generate-*and storage patterns (Cloudinary, Mongo metadata, etc., depending on feature).
- Socket.io client where quiz battles or live features need it.
- ElevenLabs, DeepSeek/OpenAI routes where enabled by env.
Private project ("private": true in package.json). Adjust if you open-source the repo.