Work / Hackathons
SlugBites
Drone-delivery ordering for UC Santa Cruz dining halls on live-scraped menus. 2 awards at CruzHacks 2026.
- React 18
- React Router 6
- Express 5
- axios
- cheerio
- Vercel serverless functions
- n8n webhook
- Python 3.12
- Microsoft AirSim API
- Android
TL;DR
- Our team’s SlugBites won two of CruzHacks 2026’s single-winner prizes, Most Ambitious Project and MLH Best Use of Solana, in a field of 88 submissions.
- Order from any UC Santa Cruz dining hall and have it flown to you, built on live data: an Express service scrapes the university’s public nutrition site on demand, prices orders by meal period and checks each location’s hours.
- I wrote 20 of the repo’s 23 commits, plus a 939-line Python flight layer against Microsoft AirSim and a companion Android app.
The problem
A delivery app is only as good as its menu data, and UC Santa Cruz publishes its dining menus as a website for people, not an API. I had built this idea once before, with a different team, on mock menus (see AeroBites). This time it had to run on the real thing.
What I built
- Scraper. An axios and cheerio scraper for a site that was never meant to be an API. It reads the location dropdown and falls back to a curated 14-location list if the dropdown is missing, then walks every table row of each location’s menu page, tracking which meal section it is in. It merges any dish served at several meals into one record and pulls calories out with regex.
- Resilience. Results sit in a 2-hour cache backed by JSON snapshots. If a scrape fails, the API serves a mock menu instead of an error.
- Business rules. Meal-period pricing from $12.60 at breakfast to $14.70 at dinner, per-location operating hours, and a 4-item cap per order.
- Checkout. A SOL-priced checkout with a “Why Solana” explainer, built for the MLH Solana track, and a chat assistant wired to an n8n webhook.
- Flight layer. 939 lines of Python against AirSim’s multirotor API: waypoint navigation with a tolerance check on arrival, typed pickup, fly-over, land and drop-off mission steps, and a route builder that saves delivery missions as JSON.
- Android. A companion Android app for SlugBites, built in Android Studio.
Key decisions
- Decision: scrape live menus instead of mocking them. Why: a delivery app that shows yesterday’s menu is a demo, not a product. Trade-off: the app depends on a website whose markup can change without notice.
- Decision: layered fallbacks (curated location list, cache, mock menu). Why: a live demo can’t fail because one page timed out. Trade-off: the fallbacks can hide a broken scrape unless it’s logged.
- Decision: simulate the drone in AirSim. Why: no hardware, but real flight dynamics and a real flight API. Trade-off: the flights are simulated missions, not deliveries.
The hard part
Turning a human-facing nutrition website into a structured menu API. The menu pages have no markup that says which meal a dish belongs to; meal headers are just short rows of text among the item rows.
So the scraper reads the table as a stream. It carries a meal-period cursor from row to row, normalizes Brunch into Lunch to fit the pricing schedule, and folds repeated dishes into one record with a set of meal periods. That set is what lets the app show only what’s being served right now. Resilience comes in layers: a missing dropdown falls back to the curated location list, a failed scrape falls back to mock data, and everything is cached for 2 hours so repeat views don’t re-scrape.
Results
- Two single-winner awards at CruzHacks 2026: Most Ambitious Project and MLH Best Use of Solana, out of 88 submissions.
- A working scraper across 14 dining locations, with meal-period pricing and hours.
- The first local commit and the final push are 16 hours 26 minutes apart.
What I’d do next
- Compute the meal period in Pacific time; on a UTC server clock it drifts.
- Start the nightly re-scrape that is written but not scheduled, and point the production build at relative API paths so the hosted demo works.
- Fly the delivery missions end to end in the simulator and record them.
Links
- Code: github.com/mit37/aerobytes
- Event: CruzHacks 2026
- Round one: AeroBites · Round three: Riptide
Verified numbers
| Metric | Value | Source |
|---|---|---|
| CruzHacks 2026 awards (Most Ambitious Project · MLH Best Use of Solana) | 2 | mitansh-confirmed 2026-09-22 |
| Submissions in the field | 88 | cruzhacks--2026.devpost.com/ |
| Dining locations scraped live | 14 | mit37/aerobytes/backend/locations.js |
| My commits in the repo | 20 of 23 | github.com/mit37/aerobytes/commits |
| Menu cache lifetime | 2 hours | mit37/aerobytes/backend/cache.js:9 |