Back to projects

SolveIt

A platform I built for students to exchange academic help and mentoring safely.

This project started as a university final year project, but I wanted to build something I’d actually use. I noticed that most students use WhatsApp or Discord to find academic help, but it’s hard to track tasks and payments aren’t always secure. I wanted a way to make mentoring a more professional and safe experience for everyone.

Building the Core

I spent a lot of time on the real-time features. Since I’m using Go for the backend, I built a custom WebSocket hub to handle everything from notifications to mentor chats. Go's concurrency model made it much easier to keep everything in sync without any lag.

One of the more interesting parts was the "Task Categorization" feature. I integrated OpenAI to automatically read a student's description and suggest the right subject category. It helps keep the platform organized without making students fill out massive forms.

func (h *WsHub) handleWS(w http.ResponseWriter, r *http.Request, appChan chan IncomingMessage) { conn, err := upgrader.Upgrade(w, r, nil) if err != nil { fmt.Println("failed to upgrade conn:", err) return } conn.SetReadLimit(5 << 20) conn.SetReadDeadline(time.Now().Add(pongWait)) conn.SetPongHandler(func(string) error { conn.SetReadDeadline(time.Now().Add(pongWait)) return nil }) channelID := r.URL.Query().Get("channel") if channelID == "" { conn.Close() return } h.mu.Lock() h.conns[channelID] = append(h.conns[channelID], conn) h.mu.Unlock() go h.cleanUp(conn, channelID, appChan) go func() { ticker := time.NewTicker(pingPeriod) defer ticker.Stop() for range ticker.C { h.mu.RLock() stillActive := slices.Contains(h.conns[channelID], conn) h.mu.RUnlock() if !stillActive { return } conn.SetWriteDeadline(time.Now().Add(writeWait)) if err := conn.WriteControl(websocket.PingMessage, nil, time.Now().Add(writeWait)); err != nil { log.Printf("Ping failed for %s: %v (will retry next tick)", channelID, err) continue } } }() log.Println("New connection for channel:", channelID) }

What I Struggled With

Database performance was a huge challenge as I added more features. I initially thought just having PostgreSQL would be enough, but I had to learn how to properly index foreign keys like mentorId to keep the dashboard snappy. It was a great lesson in how real-world apps put pressure on the database.

I also used Stripe to handle payments safely. It was my first time dealing with real-world transactions, and making sure the "bidding" and "escrow" process worked correctly was a huge part of the development process.

I’m currently looking at adding WebRTC for video mentoring, so mentors can actually jump on a call and explain things directly when text isn't enough.