You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
POST /api/auth/login β { token: "eyJ..." } (7 day expiry)
All requests β Authorization: Bearer <token>
JwtAuthFilter β validate β inject into SecurityContext
SecurityConfig Rules
/api/auth/** β permitAll
/api/admin/** β hasRole("ADMIN")
POST /api/courses β hasRole("INSTRUCTOR")
POST /api/lessons β hasRole("INSTRUCTOR")
POST /api/quiz β hasRole("INSTRUCTOR")
all other β authenticated()
Ownership Checks (Service layer)
// Example in LessonService:if (!course.getInstructorId().equals(currentUserId))
thrownewForbiddenException("You do not own this course");
βοΈ AWS S3 Upload Flow
1. React β POST /api/upload/presigned-url { fileName, contentType, folder }
2. Spring β generate presigned PUT URL (15 min validity) + final fileUrl
3. React β PUT presignedUrl with file binary (direct to S3, no server hop)
4. React saves fileUrl in form state β sends to course/lesson create endpoint
π³ Razorpay Payment Flow
1. Student clicks Pay β POST /api/payments/create-order { courseId }
2. Spring β calls Razorpay REST API β { orderId, amount, currency }
3. Frontend β opens Razorpay checkout widget
4. On success β POST /api/payments/verify { orderId, paymentId, signature, courseId }
5. Spring β HMAC-SHA256 verify β save Payment β enroll β remove from cart
// Authorization: Bearer <token> on every request// On 401 β auto logout
TanStack Query Hooks
useCourses(filters) β GET /api/courses
useCourseDetail(id) β GET /api/courses/:id
useProgress(courseId) β GET /api/progress/:courseId
useDiscussion(courseId) β GET /api/discussions/:courseId
useInstructorCourses() β GET /api/courses/my
POST /api/auth/register β BCrypt, Cart create, send OTP
POST /api/auth/login β JWT
POST /api/auth/send-otp (Bucket4j rate limit)
POST /api/auth/verify-email
POST /api/auth/forgot-password
POST /api/auth/reset-password
POST /api/auth/google
POST /api/auth/instructor-apply
GET /api/auth/me
EmailService.java with HTML templates
Phase 4 β AWS S3 Upload
AwsS3Config.java β S3Client + S3Presigner beans
S3Service.java β presigned PUT URL generation
POST /api/upload/presigned-url
S3FileUploader React component (drag & drop + progress bar)
Phase 5 β Course Management (Instructor)
POST /api/courses + Discussion auto-create
GET /api/courses/my
POST /api/lessons (ownership check)
PUT /api/lessons/{id}
POST /api/quiz (upsert)
GET /api/quiz/lesson/{lessonId}
Instructor Dashboard page
Course Management page
Quiz Management page
Phase 6 β Student Features
GET /api/courses (paginated, search + filter)
GET /api/courses/{id} (enrollment gate)
Browse page
Course Detail page
Student Dashboard page
GET /api/progress/{courseId}
PATCH /api/progress/update
Course Viewer page
POST /api/quiz/submit (auto-grade)
Discussion endpoints + UI
Phase 7 β Payments
Razorpay create-order via RestTemplate
verify endpoint with HMAC check β enroll β cart cleanup
Cart CRUD endpoints
Frontend payment modal + cart page
Phase 8 β Admin
GET /api/admin/stats
GET /api/admin/pending-requests
POST /api/admin/verify-instructor
POST /api/admin/reject-instructor + email
Admin Dashboard page
Phase 9 β Polish & UX
Skeleton loaders everywhere
React error boundaries
react-hot-toast notifications
Framer Motion transitions
Mobile responsive layouts
Dark mode
π Key Improvements Over Original
Area
Original (EduCore)
LearnFlow (Spring Boot)
Backend lang
JavaScript
Java 21 (type-safe)
Auth
Manual JWT + cookies
Spring Security + JWT Bearer
API style
All POST routes
RESTful (proper HTTP verbs)
Validation
Manual if-checks
@Valid + Bean Validation
Error handling
Scattered try/catch
@ControllerAdvice
Quiz schema
Flat parallel arrays
Embedded typed objects
Progress schema
[[Number]] matrix
LessonProgress objects
Forms
Manual state
React Hook Form + Zod
Data fetching
Axios + useEffect
TanStack Query
Uploads
Multer via server
S3 presigned URLs
Rate limiting
express-rate-limit
Bucket4j
Role naming
"user"
"student"
π¦ Development Order
Week 1: Setup + Auth + Models
Day 1-2: Spring Boot + React + Vite + Tailwind init, CORS
Day 3-4: All 10 models + Repositories + DTOs
Day 5-7: Spring Security + JWT + all auth endpoints + OTP email
Week 2: Core Features
Day 8-9: AWS S3 presigned URLs + React FileUploader
Day 10-11: Course + Lesson CRUD
Day 12-14: Quiz system (create, fetch, submit, grade)
Week 3: Student & Payments
Day 15-16: Browse + Course Detail + enrollment
Day 17-18: Course Viewer (video + progress)
Day 19: Cart system
Day 20-21: Razorpay integration
Week 4: Admin + Polish
Day 22: Admin dashboard + instructor approval
Day 23-24: Discussion system
Day 25-26: UI polish (skeletons, animations)
Day 27-28: Testing + deployment
ποΈ Notes
Important
Token storage: JWT in localStorage, sent as Authorization: Bearer <token>. Spring is fully stateless β no cookies, no sessions.
Tip
Use Bucket4j for rate limiting /api/auth/send-otp. Runs as a Spring component β no extra infra needed.
Warning
Razorpay has no official Maven SDK. Call their REST API via RestTemplate with Basic Auth (Base64(key_id:key_secret) in Authorization header).
Note
The original UserProgress uses a confusing [[Number]] matrix. LearnFlow uses a clean List<LessonProgress> with named fields: videoWatched, quizScore, notesDownloaded.
Caution
Always verify Razorpay HMAC-SHA256 signature server-side before enrolling. Never trust the client on payment success.