Inspiration
What it does
How we built it
Inspiration
Losing something on campus means digging through Instagram posts, group chats, and emails to lost-and-found. Finders have no easy way to get items back to owners, and owners have no way to prove an item is theirs without handing out personal details. We built FindBack to remove the searching and make claiming an item safe.
What it does
FindBack is an AI-powered lost-and-found platform for campus.
- Owners report a lost item with a description, a location, and a time.
- Finders upload a photo of what they found. Google Gemini reads the photo and extracts structured attributes like brand, color, and scratches.
- A matching engine ranks candidates using semantic similarity (vector search), attributes, time, and distance between SFU campus locations.
- Ownership check: the finder can attach a private detail only the real owner would know (like "red sticker underneath"). The owner must answer it correctly, with a limited number of attempts.
- Handoff: once verified, the owner chooses Meet in Person (the finder's contact is revealed) or Secure Drop-off (a one-time
claim_tokenshown as a QR code to claim the item at a secure location). - Nothing is ever deleted. Finished items are soft-deleted as
REUNITEDand excluded from future searches.
How we built it
- Frontend: Next.js (App Router), TypeScript, Tailwind CSS, NextAuth.js, Cloudinary for images
- Backend: FastAPI, Pydantic, SQLAlchemy, PyJWT, bcrypt
- AI: Google Gemini (vision and text embeddings)
- Database: TiDB Cloud (relational tables plus
VECTOR(768)search)
We treated security as a feature, not an afterthought:
- Passwords are hashed with bcrypt, and login is timing-safe so it doesn't reveal which emails exist.
- Every payload is validated by Pydantic. Unknown fields are rejected, so a client can't spoof
statusoruser_id. - SQL goes through the ORM, so queries are parameterized.
- Image URLs must come from Cloudinary, which blocks server-side request forgery when we fetch images for Gemini.
- The private detail is write-only. It sits in the database, appears in no response schema, and is never sent to Gemini or embedded. Ownership is checked with a deterministic comparison, not an AI judge, so it can't be prompt-injected.
- Verification uses row locking and a hard attempt cap, so parallel requests can't brute-force the answer.
- Strangers get a
404instead of a403, so match IDs can't be probed.
Challenges we ran into
- Letting an owner prove ownership without exposing the secret anywhere, including to our own AI pipeline.
- Making fuzzy answer-checking forgiving (typos, paraphrases) without letting someone brute-force it by dumping lots of words.
- Keeping three people productive in parallel by agreeing on an API contract early and building the frontend against mocks.
- Rotating credentials mid-hackathon after a secret was pasted into an outside tool. We caught it, rotated the keys, and confirmed nothing was committed to git.
Accomplishments that we're proud of
- A privacy model we tested end to end: the secret is stored but never returned.
- A backend with real auth, validation, and error handling, not just a demo happy path.
- Soft-delete lifecycle so every item has an auditable history.
What we learned
- Designing the security rules first made every later feature simpler.
- Vector search plus hard filters (status, time, location) gives better matches than either alone.
- Deterministic checks beat LLM checks anywhere a user can type text that influences the outcome.
What's next
- Staff accounts at drop-off points to scan and redeem QR codes
- Email notifications when a likely match appears
- More campuses (locations are data, not code, so adding one is just new rows)
- Better handling for finders who skip the private detail ## Challenges we ran into
Accomplishments that we're proud of
What we learned
What's next for FindBack
Built With
- bcrypt
- cloudinary
- fastapi
- gemini-api
- google-gemini
- next-auth
- next.js
- pydantic
- pyjwt
- pymysql
- python
- qr-code
- react
- sqlalchemy
- tailwindcss
- tidb
- tidb-vector
- typescript
- vector-search
Log in or sign up for Devpost to join the conversation.