Selected projects

SJSU capstone project, built by a team

LessGo

A carpooling app for SJSU students, with a SwiftUI app for riders and drivers, student ID checks, and a three stage ride matching pipeline across Node.js and Python services.

Type
SJSU capstone project, built by a team
My contribution
The initial microservices backend, the first complete iOS app with backend integration, the student ID verification screen, later iOS features, and trip cost settlement.
Technologies
Swift · SwiftUI · Apple Vision · Node.js · TypeScript · Python · FastAPI · PostgreSQL · PostGIS

Problem and users

LessGo is a carpooling platform for San Jose State students traveling to and from campus. Riders need a driver heading the same way at a similar time. Drivers need riders who will not pull them far off their route. Both need some assurance that the other person is a student.

What I did

LessGo was a team capstone project in a shared repository, and teammates wrote most of the commits. Based on my own commits, my part included:

  • The initial microservices backend, including the API gateway and the auth, user, trip, booking, and payment services
  • The first complete SwiftUI app with backend integration, including sign up, login, and the student ID verification screen
  • Later iOS work on notifications, account management, help and support, the driver experience, and ride flow fixes
  • Trip cost settlement based on the driver’s vehicle MPG, with a surcharge on detour mileage

The ride matching pipeline below describes the system the team built. I am not claiming it as my individual work.

How it works

Student ID check

On the phone, the app uses Apple’s Vision framework (VNRecognizeTextRequest) to read the text on a photo of the student ID. This is Apple’s built in text recognition; no custom model is trained. The app accepts the photo only if the text mentions SJSU or San Jose State, plus either a student or Tower Card keyword or a nine digit ID number.

Text recognition runs on the device, but the ID photo is then uploaded to the auth service with the account.

Ride matching

  1. Location filterPostGIS finds pending trips within 5 km of the rider and within 30 minutes of the requested departure, plus drivers already en route with open seats.
  2. Embedding rankingA Python service ranks candidates by the similarity of embeddings learned from a network of zones and times, following Tang et al. (2020).
  3. Shared cost scoreCandidates are scored on detour, walking, extra distance, waiting, and route compatibility, following He et al. (2014).
The matching pipeline as implemented in the trip service and embedding service. Schematic, not a screenshot.

The shared cost stage also rejects adding a rider to a carpool if it would lengthen the trip for existing passengers by more than 30 percent. Route directions come from the Google Maps API.

Decision and tradeoff

Fall back to proximity when the model has no answer. If the embedding model has not been trained, or a zone is outside its vocabulary, the embedding service returns an empty ranking and matching falls back to PostGIS proximity alone. Riders still get matches, at the cost of losing the learned ranking exactly where training data is thin.

The embeddings were trained on NYC taxi trip data mapped onto Bay Area zones. That gave the model trip patterns to learn from without local ride history, but those patterns may not match how SJSU students travel.

Evaluation and limitations

  • I have not documented matching quality or latency measurements, so this note reports none.
  • The ID check looks for keywords and a number pattern. It filters out obviously wrong photos but does not prove current enrollment.
  • The embedding model learned from another city’s trips, mapped onto local zones.