Welcome to Talo +!
- High-Level Overview
- Architecture Breakdown
- Tech Stack
- How It Works
- Important Features
- API/Backend Flow
- Frontend Flow
- Deployment Details
- Getting Started
- Potential Improvements
Talo+ is a full-stack healthcare Q&A platform inspired by StackOverflow, specifically designed for medical questions and answers. It allows users to post medical questions about symptoms or health concerns, and receive answers from medical professionals like doctors, nurses, medical students, pharmacists, and coaches.
- Provides a centralized platform for health-related questions
- Connects users with verified medical professionals
- Creates a community-driven knowledge base for healthcare information
- Enables role-based interactions between patients and healthcare providers
Talo +
├── backend/ # Node.js/Express API server
│ ├── config/ # Configuration files
│ │ ├── config.js # Environment variables
│ │ └── db.js # MongoDB connection
│ ├── controllers/ # Business logic handlers
│ │ ├── userController.js # Auth & user management
│ │ ├── postController.js # Question CRUD operations
│ │ └── answerController.js # Answer creation & retrieval
│ ├── middlewares/ # Request interceptors
│ │ └── authenticate.js # JWT authentication
│ ├── models/ # Mongoose schemas
│ │ ├── User.js # User model
│ │ ├── Questions.js # Question model
│ │ └── Answers.js # Answer model
│ ├── routes/ # API route definitions
│ │ ├── userRoutes.js
│ │ ├── postRouter.js
│ │ └── answerRouter.js
│ ├── lib/ # Utility functions
│ │ └── generateToken.js # JWT token generation
│ ├── server.js # Express app entry point
│ └── vercel.json # Vercel deployment config
│
└── frontend/ # Next.js 15 React application
├── app/ # Next.js App Router
│ ├── (auth)/ # Authentication routes group
│ │ ├── login/ # Login page
│ │ └── register/ # Registration page
│ ├── (dashboard)/ # Protected dashboard routes
│ │ ├── dashboard/ # Main dashboard pages
│ │ │ ├── page.tsx # Questions feed
│ │ │ ├── [id]/ # Individual question view
│ │ │ ├── post/ # Create question page
│ │ │ ├── questions/ # User's questions
│ │ │ ├── profile/ # User profile
│ │ │ └── discover/ # Discover page
│ │ └── _components/ # Dashboard components
│ ├── (root)/ # Public routes
│ │ └── page.tsx # Landing page
│ ├── context/ # React Context providers
│ │ └── AuthContext.tsx # Authentication state
│ └── lib/ # Frontend utilities
├── components/ # Reusable UI components
│ └── ui/ # shadcn/ui components
├── action/ # Server actions
│ └── post.ts # Question submission action
└── public/ # Static assets
User Request → Frontend (Next.js)
↓
AuthContext (checks auth state)
↓
API Call (Axios with credentials)
↓
Backend Express Server
↓
Authentication Middleware (JWT verification)
↓
Controller (business logic)
↓
Mongoose Model (database operations)
↓
MongoDB Database
| Technology | Purpose | Why Used |
|---|---|---|
| Node.js | Runtime environment | JavaScript ecosystem, async I/O |
| Express.js 5.1 | Web framework | RESTful APIs, middleware support |
| MongoDB | Database | Document model, flexible schema |
| Mongoose 8.17 | ODM | Schema validation, relationships |
| JWT (jsonwebtoken) | Authentication | Stateless, secure tokens |
| bcryptjs | Password hashing | Secure password storage |
| Google Auth Library | OAuth integration | Social login |
| cookie-parser | Cookie handling | HttpOnly cookies for tokens |
| CORS | Cross-origin requests | Frontend-backend communication |
| validator | Input validation | Email/password validation |
| Technology | Purpose | Why Used |
|---|---|---|
| Next.js 15.4 | React framework | SSR, routing, optimization |
| React 19.1 | UI library | Component-based UI |
| TypeScript 5 | Type safety | Type checking, better DX |
| Tailwind CSS 4 | Styling | Utility-first CSS |
| Axios | HTTP client | API requests with interceptors |
| Radix UI | Component primitives | Accessible, unstyled components |
| Lucide React | Icons | Icon library |
| js-cookie | Cookie management | Client-side cookie handling |
- User fills registration form (
/register) - Frontend sends POST to
/api/user/signUp - Backend validates email/username uniqueness
- Password is hashed with bcrypt (pre-save hook)
- User document created in MongoDB
- JWT token generated (7-day expiry)
- Token stored in HttpOnly cookie
- User data stored in localStorage
- Redirect to
/dashboard
- User submits credentials (
/login) - POST to
/api/user/signIn - Backend finds user by email
- Password compared with bcrypt
- JWT token generated and set in cookie
- User data returned and stored
- Redirect to
/dashboard
- User navigates to
/dashboard/post - Form submission triggers server action (
action/post.ts) - Client-side validation (title, description, tags)
- POST to
/api/post/create-postwith JWT cookie authenticatemiddleware verifies token- Controller creates Question document
- Question linked to author (User reference)
- Success response → redirect/refresh
- Dashboard loads (
/dashboard) AllQuestionscomponent fetches from/api/post/questions- Backend applies pagination, search, filtering
- Questions populated with author info
- Rendered with tags, answer count, timestamps
- Infinite scroll loads more pages
- User clicks question →
/dashboard/[id] - Page fetches question details and existing answers
- User types answer in
PostAnswercomponent - POST to
/api/answer/create-answer - Answer document created with question reference
- Answer ID added to question's answers array
- New answer appears in list (optimistic update)
- ✅ JWT-based authentication with HttpOnly cookies
- ✅ Password hashing with bcrypt
- ✅ Google OAuth integration
- ✅ Role-based user system (user, medical_student, nurse, doctor, pharmacist, coach, admin)
- ✅ Protected routes via authentication middleware
- ✅ Create questions with title, description, and tags
- ✅ Edit/delete own questions
- ✅ Search by title/description
- ✅ Filter by tags
- ✅ Sort by newest/oldest
- ✅ Pagination (20 per page, infinite scroll)
- ✅ Post answers to questions
- ✅ View all answers for a question
- ✅ Answers linked to authors with role display
- ✅ Chronological ordering
- ✅ Responsive design (mobile/desktop)
- ✅ Loading states and error handling
- ✅ Real-time answer updates
- ✅ User profile display (avatar, username, role)
- ✅ Sidebar navigation
/api/user/
POST /signUp → Create new user account
POST /signIn → Login user
POST /logout → Clear auth cookie
POST /googleSignIn → OAuth Google login
/api/post/
POST /create-post → Create question (authenticated)
GET /questions → Get all questions (paginated, searchable)
GET /get-post/:id → Get single question
GET /get-user-posts → Get current user's questions
PUT /update-post/:id → Update question (author only)
DELETE /delete-post/:id → Delete question (author only)
/api/answer/
POST /create-answer → Create answer (authenticated)
GET /get-answers/:id → Get answers for a question
User Schema:
{
fullname: String (required)
username: String (required, unique, lowercase)
email: String (required, unique, validated)
password: String (required, hashed, select: false)
profilePic: String (default: "")
role: Enum [user, medical_student, nurse, doctor, pharmacist, coach, admin]
timestamps: true
}Question Schema:
{
title: String (required)
description: String (required)
tags: [String]
author: ObjectId → User (required)
answers: [ObjectId] → Answer
timestamps: true
}Answer Schema:
{
content: String (required)
author: ObjectId → User (required)
question: ObjectId → Question (required)
timestamps: true
}- Token Extraction: Checks cookies first, falls back to Authorization header
- JWT Verification: Validates token with secret key
- User Attachment: Attaches user ID to
req.user - Route Protection: Protected routes check
req.user.id
/ (root)
└── Landing page
/login (auth group)
└── Login form → AuthContext.login()
/register (auth group)
└── Registration form → AuthContext.registerUser()
/dashboard (dashboard group, protected)
├── /dashboard (page.tsx)
│ └── AllQuestions component
├── /dashboard/[id] (dynamic)
│ └── Question detail + answers
├── /dashboard/post
│ └── Create question form
├── /dashboard/questions
│ └── User's own questions
├── /dashboard/profile
│ └── User profile page
└── /dashboard/discover
└── Discover page
- AuthContext: Global authentication state (user, login, logout)
- Local State: Component-level state (posts, answers, loading, errors)
- localStorage: Persists user data across sessions
- Server State: Fetched via Axios (no global cache library)
DashboardLayout
└── AuthProvider
└── DashboardShell
├── Sidebar (navigation)
└── {children}
├── AllQuestions (feed)
├── QuestionDetail ([id])
├── PostQuestion (post)
└── ...
vercel.jsonconfigures serverless function- Entry point:
server.jsexported as default - Environment variables required:
MONGO_URL- MongoDB connection stringJWT_SECRET- Secret key for JWT tokensGOOGLE_CLIENT_ID- Google OAuth client IDPORT- Server portNODE_ENV- Environment (production/development)
- CORS configured for production URL:
https://talo-plus.vercel.app
- Next.js build:
npm run build - Static assets optimized automatically
- Environment variable:
NEXT_PUBLIC_BACKEND_URL
- MongoDB (likely MongoDB Atlas)
- Connection string stored in
MONGO_URLenvironment variable
- Node.js (v18 or higher)
- MongoDB database (local or Atlas)
- npm or yarn
-
Clone the repository:
git clone https://github.com/yourusername/talo-plus.git cd talo-plus -
Backend Setup:
cd backend npm installCreate a
.envfile in thebackenddirectory:PORT=5000 MONGO_URL=your_mongodb_connection_string JWT_SECRET=your_jwt_secret_key GOOGLE_CLIENT_ID=your_google_client_id GOOGLE_CLIENT_SECRET=your_google_client_secret NODE_ENV=development
-
Frontend Setup:
cd ../frontend npm installCreate a
.env.localfile in thefrontenddirectory:NEXT_PUBLIC_BACKEND_URL=http://localhost:5000
-
Start Backend Server:
cd backend npm run server # Uses nodemon for auto-reload # or npm start # Production mode
-
Start Frontend Development Server:
cd frontend npm run dev -
Access the Application:
- Frontend: http://localhost:3000
- Backend API: http://localhost:5000
- Rate limiting (express-rate-limit)
- Input sanitization (express-validator)
- CSRF protection
- Password reset flow
- Email verification
- Stronger password requirements
- Redis caching for frequent queries
- Database indexing (username, email, question tags)
- Image optimization/upload for profile pictures
- React Query/SWR for server state management
- Lazy loading for components
- Upvote/downvote answers
- Mark best answer
- Notification system
- User reputation/points system
- Rich text editor (Markdown support)
- File attachments
- Question categories
- Follow users
- Bookmark questions
- Error handling middleware
- Request validation middleware
- API response standardization
- Unit/integration tests (Jest)
- E2E tests (Playwright/Cypress)
- API documentation (Swagger/OpenAPI)
- TypeScript for backend
- ESLint/Prettier configuration
- Loading skeletons
- Optimistic updates
- Toast notifications
- Search autocomplete
- Tag suggestions
- Answer editing/deletion
- Question status (solved/open)
- Dark mode
- Separate API and frontend repositories
- Docker containerization
- CI/CD pipeline
- Environment-specific configurations
- Logging (Winston/Pino)
- Monitoring (Sentry)
- Database migrations
This project is licensed under the MIT License.
Contributions are welcome! Please feel free to submit a Pull Request.
For questions or support, please open an issue on GitHub.