First-year international students arrive in Melbourne without the informal networks domestic students rely on. We built the platform that fills that gap — weighted mentor matching, a content library, community forums, live Q&A sessions, and a self-sustaining cycle where students graduate into mentors themselves. Placed 2nd at Study Melbourne's 4Impact Program.
"International students land in Melbourne without the networks domestic students grow up with. We needed a platform that could match them with verified seniors, let mentors share knowledge at scale, and build a community worth coming back to. Six weeks, one developer."
— Hoddle Melbourne · Study Melbourne Leadership 4Impact 2026
The calls that meaningfully moved the outcome. Not the cosmetic stuff.
Row Level Security enforces data access at the database layer — not the application layer. Every table has explicit RLS policies from day one. A bug in middleware can expose data; a bug in application code cannot bypass RLS. The admin client is the only surface that bypasses RLS — used only for system operations.
scoreMentor() is a pure function — zero database calls. country_of_origin match +30 (shared migration context is the strongest signal), field overlap +15 each, challenges and goals overlap +10 each. Scores pre-computed nightly via Vercel cron; recomputed immediately on profile update. Students see a 'why this mentor' reasoning line on their dashboard.
Admin sends an invite → row written to mentor_invites with a hashed token, 14-day expiry, and full audit columns. Owning the invite row means owning the full lifecycle: custom expiry, re-invite without blocking, revocation, and reuse prevention. No dependency on third-party link delivery.
Mentors author articles with a Tiptap rich-text editor, embed YouTube/Vimeo via URL, and attach downloadable resources with signed storage URLs. Community forums have two-level nested replies, 4 reaction types, and anonymous posting for sensitive questions. Live Q&A sessions with capacity limits and post-session recording storage.
In-app notification bell subscribes to the notifications table via Supabase Realtime — unread count stays live without polling. Single notify() helper writes to the table and conditionally dispatches email based on per-type, per-channel preference toggles. 6 notification types across 3 delivery channels.
Every PR gets a preview URL. Co-founders reviewed each feature in context before merge. No surprises on pitch day. Three Vercel cron jobs handle the full session lifecycle and nightly recommendation recompute.


"We had the idea, we had people who were interested — but the solution that Sam put together really brought the product to life. Usually the website is the cherry on top, but for us, Hoddle became the cake."