Inspiration

One of our core project members, Alex, runs an Instagram account called Tritons Thrift with ~1.2k followers. He's had a strong vision of launching an online marketplace ever since creating the account. With a large wardrobe of hoodies, shirts, and jeans to move, and a built-in audience of UCSD students, a niche marketplace at tritonsthrift.tech with personal accommodations for UCSD students was the natural next step to streamline the on-campus shopping experience.

What it does

Tritons Thrift is a UCSD-exclusive clothing marketplace where students can buy and sell used clothes with their fellow Tritons. Unlike generic platforms like Depop or Facebook Marketplace, every feature is _ designed _ around the on-campus experience:

  • Browse & search a live grid of listings by title, category, or tag
  • List items with photo upload, category/condition tagging, and a description
  • Message sellers in real-time via Supabase Realtime
  • Coordinate meetups through a built-in UCSD location picker (Geisel, Sun God Lawn, Price Center Panda, and more) — propose a spot, accept or decline, then lock in a time and add it directly to Google Calendar
  • Seller profiles including what college you’re from, and meetup spot preferences

How we built it

Layer Tech
Frontend Vite + React (JavaScript)
Auth Auth0 (OAuth)
Database + Realtime Supabase (PostgreSQL + Realtime)
Storage Supabase Storage
Backend FastAPI (Python)

We split ownership cleanly across three roles — database schema & RLS policies, frontend UI, and backend/integrations — to minimize merge conflicts in the 7-hour window. The AI pricing feature runs as a separate FastAPI microservice so it doesn't block the frontend if Browser Use times out.

Challenges we ran into

  • Auth loading races — chaining Auth0's load state with a Supabase profile check created a gap where components would flash wrong content. We solved it by keeping isLoading true across the full async chain and wrapping the logic in a single context provider so it only runs once.
  • Real-time message deduplication — rapid re-renders and multiple concurrent fetches caused stale responses to overwrite fresh ones. We added per-fetch ID counters so only the latest response wins.
  • Meetup coordination UX — encoding structured actions (spot proposals, time proposals, accept/decline) as prefixed text messages let us layer rich interaction on top of a plain Supabase messages table without changing the schema.

Accomplishments that we're proud of

  • A fully working end-to-end marketplace — browse, list, message, and coordinate a meetup — built in under 7 hours
  • The UCSD meetup flow: propose a spot with a photo card, accept/decline, lock in a time, and land directly on Google Calendar pre-filled with the item name and location

What we learned

  • Loading state has to cover every async gap — not just the first one
  • Structured messages (prefixed tokens) are a lightweight way to add rich interaction without extra database tables
  • Clear ownership boundaries (who writes to Supabase, who writes React) are worth defining upfront even on a small team

What's next for Tritons Thrift

  • Launch to the real Tritons Thrift audience — Alex already has ~1.2k Instagram followers ready to onboard
  • Size & fit filtering — search by size so students don't message about something that won't fit
  • Offer system — let buyers propose a price below the listing price
  • Push notifications — SMS or email when a new message or meetup confirmation arrives
  • Sold / reserved status — mark items as pending once a meetup is locked in
  • Ratings after meetup — prompt both parties to rate each other once a confirmed meetup time passes

Built With

Share this project:

Updates