Skip to content
<Hyun/>
All projects

Menteetor

Team project · Student mentoring

Verify your campus. Find your mentor.

See both sides of a mentoring request: the student applies, the mentor accepts, and their session gains a conversation.

Interactive explanation · not the live service

Loading interactive explanation…

Watch the original recordingsWeb · Recording notes included

Use the left and right arrow keys to switch slides.

Web

Recorded from a local build with fictional users; university email checks, S3 and the WebSocket host point at local stand-ins.

Verifying a university email at sign-up, applying to a mentor's post, then scrolling back through a chat and sending an image.

1 / 6
Explore the architectureSystem diagrams, design decisions and detailed flows

System overview

  1. Next.js web clientAuth.js, STOMP.js
    Step 1, sign-up
    SPRING BOOT APIAuth & sign-upJWT, refresh, blacklist
    verify code
    univcert APIuniversity email codes
  2. Next.js web client
    Step 2, apply
    SPRING BOOT APIMentoringapply, match, room
    match, room
    MySQLJPA
  3. Next.js web client
    Step 3, STOMP
    SPRING BOOT APIChatSTOMP + interceptor
    messages
    MySQL
  4. Chat
    presence
    Redisroom presence, blacklist

Other connections

  • Next.js web clienttoBoardsREST + JWT
  • BoardstoMySQLpaged queries
  • MentoringtoNotifications
  • ChattoNotificationsalerts
  • ChattoAmazon S3files (HTTP)
  • NotificationstoFirebase Cloud Msgpush
The Next.js client calls the Spring Boot API over REST and STOMP. API modules persist to MySQL, track chat presence in Redis, store files in S3, and call univcert and Firebase Cloud Messaging. The purple path: (1) sign-up verifies a university email through univcert, (2) applying creates the match and chat room in MySQL, (3) chat runs over STOMP with presence in Redis.
View the diagram as text

Parts

  • Next.js web client (Auth.js, STOMP.js): Client / UI
  • Amazon S3 (profile, post, chat files): Data store / broker
  • Auth & sign-up (JWT, refresh, blacklist): Owned service
  • Boards (posts, Q&A, search): Owned service
  • Mentoring (apply, match, room): Owned service
  • Chat (STOMP + interceptor): Owned service
  • Notifications (FCM + unread badges): Owned service
  • univcert API (university email codes): External service
  • MySQL (JPA): Data store / broker
  • Redis (room presence, blacklist): Data store / broker
  • Firebase Cloud Msg (device push): External service

Connections

  • Step 1: Next.js web client → Auth & sign-up: sign-up
  • Auth & sign-up → univcert API: verify code
  • Step 2: Next.js web client → Mentoring: apply
  • Mentoring → MySQL: match, room
  • Step 3: Next.js web client → Chat: STOMP
  • Chat → MySQL: messages
  • Chat → Redis: presence
  • Next.js web client → Boards: REST + JWT
  • Boards → MySQL: paged queries
  • Mentoring → Notifications
  • Chat → Notifications: alerts
  • Chat → Amazon S3: files (HTTP)
  • Notifications → Firebase Cloud Msg: push

From university-email sign-up to a mentoring chat

  1. Verify university email

    The sign-up form loads the university list, asks univcert to send a code with an enrollment check and confirms it before allowing sign-up, which stores a BCrypt-hashed member.

  2. Sign in, get tokens

    Auth.js on the Next.js server signs in and receives a short-lived access token and a refresh token. Signing out blacklists the access token in Redis until it expires.

  3. Apply to a mentor post

    The student filters the boards by category, school, favorites or keyword and applies for a date and time with a message. Self-applications and duplicates are rejected, and the mentor gets a push and a stored notification.

  4. Mentor accepts

    Accepting creates a match for the requested slot, opens a chat room for the pair if none exists, blocks that slot on the post and notifies the mentee.

  5. Join the room over STOMP

    The client subscribes to the room with its token and room id. The interceptor resolves the member, adds them to the room's Redis set and marks the other side's messages read.

  6. Send a message

    Each message is stored already marked read or unread depending on who is in the room, broadcast to the room topic and followed by unread-count updates over STOMP and an async FCM push to the receiver.

The project & my contribution

Problem
Korean university students needed a student-only place to find senior mentors and book time with them.
Solution
A mentoring community with university-email verification, mentor posts with time slots, applications, Q&A boards and real-time chat.
Result
Supports students at 309 universities; accepted matches move straight into a chat with unread badges and push alerts.
  • 309 universities supported

How it's built

  • Spring Boot API with JWT refresh tokens and a Redis logout blacklist
  • Next.js PWA client with Auth.js, React Query and STOMP.js

Real-time chat

  • STOMP over WebSocket, authenticated per subscription by a channel interceptor
  • Redis tracks who is in each room, so messages are saved already read or unread
  • Unread badges over STOMP, async FCM pushes and file uploads to S3