Lomda Hub (Mini-LMS)
Mini לומדות platform with locked progression, groups, Google OAuth login, achievements system, file uploads, and admin analytics.
Features
- Locked Progression: Learners must complete module N before unlocking N+1
- Google OAuth: Sign in with Google account
- JWT Authentication: Access and refresh tokens for secure API access
- Achievements System: Earn achievements for completing courses, perfect scores, and consistent learning
- File Uploads: Admin can attach PDF/PPTX presentations to content modules
- Admin Analytics: View statistics on users, courses, enrollments, completions, and quiz attempts
- Groups: Restrict course access to specific user groups
- Dark/Light Theme: Toggle between dark and light modes
Stack
- Frontend: React + Vite + TypeScript + React Router + MUI
- Backend: FastAPI + SQLAlchemy 2.0 + Alembic
- Database: Postgres
- Auth: JWT (access + refresh) + Google OAuth
- Dev: Docker Compose
Quick start (Docker)
- Create a
.envfile (see.env.examplefor reference) or set environment variables docker compose builddocker compose up -d
Services:
- Frontend: http://localhost:5173
- Backend API: http://localhost:8000
- Backend API Docs: http://localhost:8000/docs
- Postgres: localhost:5433
Default admin credentials (seeded):
- Email:
admin@example.com - Password:
admin123
Google OAuth setup (dev)
- Create OAuth credentials in Google Cloud Console.
- Set Authorized redirect URI to
http://localhost:8000/auth/google/callback. - Set the following in
.env:GOOGLE_CLIENT_ID=your_client_idGOOGLE_CLIENT_SECRET=your_client_secretGOOGLE_REDIRECT_URI=http://localhost:8000/auth/google/callbackFRONTEND_URL=http://localhost:5173
Environment Variables
Create a .env file in the project root with the following variables (see .env.example):
# Database
DATABASE_URL=postgresql+psycopg2://postgres:postgres@db:5432/lomda
# JWT Secrets (change in production!)
JWT_SECRET_KEY=change_me_access
JWT_REFRESH_SECRET_KEY=change_me_refresh
# Frontend URL
FRONTEND_URL=http://localhost:5173
# CORS Origins (comma-separated)
CORS_ORIGINS=http://localhost:5173
# Admin Seed Credentials
ADMIN_SEED_EMAIL=admin@example.com
ADMIN_SEED_PASSWORD=admin123
# Google OAuth (optional)
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
GOOGLE_REDIRECT_URI=http://localhost:8000/auth/google/callback
# Upload Directory
UPLOAD_DIR=/data/uploads
# SMTP (optional, for future email features)
SMTP_HOST=
SMTP_PORT=587
SMTP_USER=
SMTP_PASSWORD=
SMTP_FROM=
Local development (no Docker)
Backend:
cd backendpython -m venv .venv && .venv\Scripts\activate(Windows) orsource .venv/bin/activate(Linux/Mac)pip install -r requirements.txtalembic upgrade headpython -m app.scripts.seeduvicorn app.main:app --reload
Frontend:
cd frontendnpm install- Create
frontend/.envwith:VITE_API_URL=http://localhost:8000 npm run dev
Testing Features
Google OAuth Login
- Ensure
GOOGLE_CLIENT_IDandGOOGLE_CLIENT_SECRETare set in.env - Visit http://localhost:5173/login
- Click "Continue with Google"
- Complete Google sign-in flow
- You should be redirected back to the app authenticated
File Uploads
- Login as admin (
admin@example.com/admin123) - Navigate to Admin → Courses → Select a course → Modules
- Edit a content module
- Upload a PDF or PPTX presentation
- Save the module
- As a learner, enroll in the course and open that module
- Click "View Presentation" to open the uploaded file
Achievements
- Login as a learner
- Navigate to "Achievements" in the header
- Complete courses and quizzes to earn achievements:
- First Course Complete: Complete your first course
- Perfect Final: Score 100% on any final exam
- Triple Perfect: Score 100% on three quiz attempts in a row
- Fast Finisher: Complete a course within 24 hours of enrollment
- Consistent Learner: Log in on 5 different days
Admin Analytics
- Login as admin
- Navigate to Admin → Analytics
- View user and course statistics
- Click "View Details" to see detailed information on specific users or courses
Theme Toggle
- Click the sun/moon icon in the header to switch between light and dark themes
- Theme preference is saved in localStorage
Database Migrations
After model changes:
cd backendalembic revision --autogenerate -m "description"alembic upgrade head
In Docker, migrations run automatically on container startup.
Architecture Notes
- Locked Progression: On enrollment, first module is
unlocked, rest arelocked. Content modules mark completed when viewed. Quiz modules mark completed only if score >= pass_score. - Admin vs Learner: Admins can preview courses without enrolling. Learners must enroll and follow progression rules.
- Groups: Courses can be restricted to specific groups. If a course has no groups, it's public (all learners can see).
- Uploads: Stored on disk in
UPLOAD_DIR(/data/uploads by default). Metadata tracked in database. Only authenticated users can download. - Achievements: Evaluated after module completion and quiz submission. Uses login_events table to track consistent learner achievement.
Troubleshooting
Google OAuth 307 Redirects
- Ensure
GOOGLE_REDIRECT_URImatches exactly what's configured in Google Cloud Console - Backend uses
redirect_slashes=Falseto prevent automatic trailing slash redirects
Uploads Not Working
- Ensure
UPLOAD_DIRexists and backend has write permissions - In Docker, uploads are stored in the
upload_datavolume
Dark Mode Not Persisting
- Check browser localStorage for
lomda_themekey - Clear localStorage and try toggling theme again
Environment
- Do not commit real secrets. Use
.envlocally and keep it in.gitignore. - See
.env.examplefor required values.
License
MIT
Description
Languages
Python
58.1%
TypeScript
41.2%
Dockerfile
0.4%
HTML
0.2%
CSS
0.1%