Learnr is a Tinder-style educational platform that connects students based on their courses and skills. Swipe through profiles, match with peers, and meet up to teach each other or study together—making learning collaborative and social.
In today's educational landscape, students often struggle to find the right study partners or tutors within their peer group. Learnr bridges this gap by creating a secure, student-exclusive community where knowledge sharing is just a swipe away.
- AI-Powered ID Verification: Upload your student ID and let our multimodal AI verify your identity automatically
- Uses GPT-4 Vision to extract and verify name and student ID
- Instant verification with visual confirmation
- Exclusive access for verified students
- Safe and trusted learning environment
- List courses you need help with
- Showcase subjects you're confident teaching
- Get matched with complementary learners
- Smart matching algorithm finds optimal study partners
- Instant chat with matched students
- Typing indicators and read receipts
- Unread message notifications
- Persistent conversation history
- Custom profile pictures with avatar generation
- Bio and course preferences
- Verification badges
- Edit profile information
- Browse and select from available courses
- Specify courses you can teach
- Indicate courses you want to learn
- Create new course listings
- Framework: Flask 3.0.0
- Database: PostgreSQL with SQLAlchemy ORM
- Authentication: JWT (Flask-JWT-Extended)
- Real-time Communication: Flask-SocketIO
- AI Integration: OpenAI GPT-4 Vision API
- Migrations: Flask-Migrate (Alembic)
- Framework: React 18.2.0
- Build Tool: Vite 5.0.8
- Routing: React Router DOM 6.21.0
- Styling: Tailwind CSS 3.4.0
- HTTP Client: Axios 1.6.5
- Real-time: Socket.IO Client
- Users: Student profiles with authentication and verification
- Courses: Course catalog with codes and descriptions
- Matches: User matching system with swipe history
- Messages: Real-time chat with read status tracking
- Python 3.9 or higher
- Node.js 18 or higher
- PostgreSQL 12 or higher
- OpenAI API key (for student verification)
-
Clone the repository
git clone https://github.com/Nikaagh/learnr.git cd learnr/backend -
Create and activate virtual environment
python -m venv .venv source .venv/bin/activate # On Windows: .venv\Scripts\activate
-
Install dependencies
pip install -r requirements.txt
-
Configure environment variables
cp .env.example .env
Edit
.envand set the following:DATABASE_URL=postgresql://username:password@localhost:5432/learnr SECRET_KEY=your-secret-key-here JWT_SECRET_KEY=your-jwt-secret-key-here OPENAI_API_KEY=sk-your-openai-api-key-here
-
Initialize the database
flask db upgrade
-
Seed the database (optional)
python scripts/seed_1000_users.py --count 10
-
Start the backend server
python run.py
The API will be available at
http://localhost:5000
-
Navigate to frontend directory
cd frontend -
Install dependencies
npm install
-
Configure environment (optional)
cp .env.example .env
Edit
.envif your backend runs on a different URL:VITE_API_URL=http://localhost:5000/api
-
Start the development server
npm run dev
The app will be available at
http://localhost:3000
The student verification feature requires an OpenAI API key:
- Visit OpenAI Platform
- Sign up or log in to your account
- Navigate to the API Keys section
- Create a new API key
- Add it to your
backend/.envfile:OPENAI_API_KEY=sk-proj-...
For production deployments, update your DATABASE_URL with proper credentials and connection settings:
DATABASE_URL=postgresql://user:password@host:port/dbname?sslmode=requireAdjust token expiration times in backend/config.py:
- Access tokens: 24 hours (development), 1 hour (production recommended)
- Refresh tokens: 30 days
┌─────────────────────────────────────────────────────────────┐
│ Frontend │
│ (React + Vite) │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Swipe │ │ Matches │ │ Messages │ │ Profile │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
│ │
│ ┌────────────────────────────────────────────────────┐ │
│ │ Socket.IO Client (Real-time) │ │
│ └────────────────────────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────────────────────────┐ │
│ │ Axios HTTP Client (REST API) │ │
│ └────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
│
│ HTTP/WebSocket
▼
┌─────────────────────────────────────────────────────────────┐
│ Backend │
│ (Flask + Python) │
│ │
│ ┌────────────────────────────────────────────────────┐ │
│ │ Flask-SocketIO Server │ │
│ │ (Real-time messaging & events) │ │
│ └────────────────────────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────────────────────────┐ │
│ │ REST API Endpoints │ │
│ │ /auth /users /matches /messages /verify │ │
│ └────────────────────────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────────────────────────┐ │
│ │ Flask-JWT-Extended (Auth) │ │
│ └────────────────────────────────────────────────────┘ │
│ │
│ ┌────────────────────────────────────────────────────┐ │
│ │ SQLAlchemy ORM + Migrations │ │
│ └────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
│
┌─────────────────────┼─────────────────────┐
│ │ │
▼ ▼ ▼
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ PostgreSQL │ │ OpenAI API │ │ DiceBear │
│ Database │ │(GPT-4 Vision)│ │ Avatars │
└──────────────┘ └──────────────┘ └──────────────┘
Frontend Components
App.jsx- Main application with routingNavbar.jsx- Navigation with notification badgesHome.jsx- Landing pageSwipe.jsx- Swipe interface for matchingMatches.jsx- List of matched usersMessages.jsx- Conversations overviewChat.jsx- Real-time messaging interfaceProfile.jsx- User profile managementVerificationUpload.jsx- Student ID verification UI
Backend Services
routes.py- REST API endpointssocket_events.py- Real-time event handlersmodels.py- Database modelsauth.py- Authentication logicconfig.py- Application configuration
Authentication Flow
- User registers/logs in via
/api/auth/registeror/api/auth/login - Backend validates credentials and generates JWT tokens
- Access token stored in localStorage for API requests
- Refresh token used to obtain new access tokens
- All protected endpoints verify JWT in request headers
Matching Flow
- User views candidate profiles on Swipe page
- Swipe action sends match preference to backend
- Backend creates Match record with swipe type
- If mutual match detected, both users notified
- Match appears in Matches page for both users
Messaging Flow
- User opens chat with matched user
- Frontend connects to Socket.IO server
- User joins specific chat room via socket
- Messages sent via socket, stored in database
- Real-time delivery to recipient if online
- Offline messages queued for next login
- Read receipts updated when messages viewed
Verification Flow
- User uploads student ID image from Profile page
- Image converted to base64 and sent to backend
- Backend calls OpenAI GPT-4 Vision API
- AI extracts name and student ID from image
- Backend compares with user's registered data
- If match, user's
is_verifiedflag set to true - Verification badge displayed on profile
- Navigate to the registration page
- Enter your email, name, student ID, and password
- Complete profile setup with bio and courses
- Verify your student ID for full access
- Go to your Profile page
- Click on the verification upload section
- Upload a clear photo of your student ID
- Wait for AI processing (5-10 seconds)
- Receive instant verification confirmation
- Navigate to the Swipe page
- View potential matches based on courses
- Swipe right to express interest
- Swipe left to pass
- When both users swipe right, you match!
- Go to Matches or Messages page
- Click on a matched user to open chat
- Send messages in real-time
- See typing indicators when they're responding
- Receive notifications for new messages
POST /api/auth/register- Register new userPOST /api/auth/login- Login and receive tokensPOST /api/auth/refresh- Refresh access token
GET /api/users- List all usersGET /api/users/<id>- Get user by IDGET /api/profile- Get current user profilePUT /api/profile- Update current user profile
GET /api/swipe/candidates- Get potential matchesPOST /api/swipe- Record swipe actionGET /api/matches- Get user's matches
GET /api/messages/<user_id>- Get messages with userGET /api/messages/conversations- Get all conversationsGET /api/messages/unread-count- Get unread message countPOST /api/messages/mark-read/<user_id>- Mark messages as read
POST /api/verify-student-id- Verify student ID with AI
GET /api/courses- List all coursesPOST /api/courses- Create new course
Port already in use
# Find and kill process on port 5000
lsof -ti:5000 | xargs kill -9Database connection errors
- Verify PostgreSQL is running
- Check
DATABASE_URLin.env - Ensure database exists and migrations are applied
OpenAI API errors
- Verify
OPENAI_API_KEYis set correctly - Check API key has sufficient credits
- Ensure you're using GPT-4 Vision enabled API
Port already in use
# Change port in vite.config.js or use different port
npm run dev -- --port 3001Socket connection fails
- Verify backend is running
- Check CORS settings in backend
- Ensure Socket.IO client version matches server
Token expiration issues
- Tokens refresh automatically on 401 errors
- Clear localStorage if issues persist
- Check JWT configuration in backend
This is a hackathon project, but we welcome feedback and ideas! Feel free to open an issue or reach out to the team.
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
License information coming soon.
This is our first hackathon project together. Brought to you with ❤️ by BASE2:
- Nika - @Nikaagh
- Ismael - @TheBarzani
Making peer-to-peer learning engaging, accessible, and fun; one swipe at a time.
