Underfoot: The ChatPot for Hidden Places (and Why I Don’t Do Hackathons)

Banner image for Underfoot: The ChatPot for Hidden Places (and Why I Don’t Do Hackathons)

Published: 2025-09-01T07:00:38Z

Tags: #devchallenge #n8nbrightdatachallenge #ai #webdev

My updated submission for the first hackathon I've done in more than 10 years, here's how it really happened.

📝 Originally published on Dev.to
by Ashley Childress on 2025-09-01T07:00:38Z

→ Read the original article on Dev.to

This is a submission for the AI Agents Challenge powered by n8n and Bright Data.

**UPDATED**

I just noticed my n8n trial is officially expired 😢 So I've turned the chat back off so it doesn't seem like it should be doing something. I have bigger plans for this guy though, so stay tuned. More updates from future me will follow. 🫶

Also, the "prequel" I wrote up a couple of days later. If you're curious about the whole "no hackathons" rule and want the whole story, it's here.


🦄 FYI: I updated this after the fact—I did plan two full weeks down to the minute—but I didn’t plan for not having the data or not having a solid backup when it didn’t arrive. Also, I lost half a day to Figma’s decorative quicksand. The rushed thing I pasted to make the buzzer didn’t sound like me, so this is the version I can live with (and you can actually read for fun). 🪄


What I Built

Underfoot (my stubborn little ChatPot) is a chatbot that finds locals-only, off-the-map places you won’t see on Yelp or TripAdvisor. You give it a location and intent (music, coffee, hiking, spider farms…) and it returns unique results with a Stonewalker rating. Each query also adds anonymous whispers to the cache, so the dataset grows as people use it. 🎯

GitHub Repository — docs, flows, screenshots

Underfoot Chat — The Stonewalker Agent (try it)

Underfoot logo generated by Leonardo.ai and ChatGPT


Underfoot — the locals-only treasure hunter 🎒

I didn’t try to cram this into a weekend; I mapped two weeks like a flight plan. The part that snapped first was the one I trusted too much: a data preload that was “ready” on paper and nowhere in reality. My beautiful schedule grew a crater where the testing window used to be, and from there it was just me, the agent, the caches, and a lot of swearing said lovingly at my own ambition. 🧭


The whisper-network: project background 📼

Late ’90s / early 2000s Georgia, when cell phones were for emergencies and you rationed the battery like it owed you money. My brother and I chased off-the-wall spots through a whisper network: backyard mini-festivals with passwords in the backs of free magazines, odd museums, ghost tours that were either hilariously fake or so real you quietly recalibrated your cosmology on the drive home. Too public and the cops came; too secret and the field stayed empty. We loved that balance.

Underfoot bottles that energy. You give the resident Stonewalker an intent you actually feel (“live music,” “odd museums,” “strange gardens,” “spider farm”) plus a location. It crawls the not-obvious places first, normalizes the messy HTML, then returns a ranked list that says, “this is probably your kind of weird—go now.” 🕵️‍♀️

The “catch”: sometimes these events haven’t been discovered yet— that's how these things work. Besides, a chatbot can’t politely wait for scraping, so every {intent, location} pair sends out separate whispers that build the cache for that combo. The next person’s list is a little louder and a little wilder than the last. 🔁


I can’t do simple (and I stopped pretending otherwise) 🧶

I promise “tiny demo,” and five minutes later I have: an ADR (revised twice), a color palette in Leonardo, three caches, and a Future Enhancements page that looks like a subway map someone cried coffee onto. It’s not scope creep; it’s scope pre-planning. I need to see the whole creature to ship a slice.

Vibe-coding lasted maybe two minutes. Copilot drafted the UI, I took a scenic (unnecessary) tour through Figma, flirted with Stitch, sprinted to n8n because hosted chat looked fast, missed my UI and dragged it back, and somewhere in there I wrote the agent I actually wanted—decisions like a product, not a science-fair trifold. 🧪


Why I don’t do hackathons (and why I did this one anyway) ⏱️

Hackathons want a snapshot; I build ecosystems. They want “Friday by midnight”; I want to label the stations, run one line today, and the others next week. I joined anyway because this is the exact agent I’ve wanted to build for months. It was fun—and it reminded me why trusting a green checkbox you don’t control is a dice roll. 🟩


What it looks like — the sprint with real nouns 🧵

Two mouths, one brain:

Both funnel free-form requests into { intent, location }.

Then:

I hit n8n’s memory ceiling right when the first end-to-end run smiled at me. Reflex: vectors + RAG + tidy GCP attic. Reality: the clock. I did the boring, correct thing—pull less, trim sooner, cache earlier. Two caches unlocked; the third is a miniboss I’ll beat when I’m not running on midnight. 🧱


AI agents: saints on Monday, goblins on Tuesday 👾

Agents in the system and agents helping build the system—both truths can be true in the same hour:

Rule that saved me: no agent writes straight to storage. The normalizer is the law. Drafts can be flammable; data cannot. 🧯


The cache: Sheets vs Supabase (be a database, not a vibe) 🗄️

I tried to keep the prototype in Google Sheets because it was there and felt simple. Simple lied. As soon as you care about de-dupe, TTLs, hit/miss tracking, and “please don’t melt anyone’s hobby site,” you need grown-up storage. I pivoted to Supabase, met Row-Level Security (RLS) and grants like a mini-boss in a fresh dungeon (v17 feels spicier), learned just enough to stop tripping over my new underfoot schema, and came out with two caches behaving—and a third that now knows the sound of my footsteps. 🪪


Underfoot belongs in your pocket (laptops were the proving ground) 📱

It runs on a computer because that’s where the tools live, but Underfoot is meant for your phone—a “you’re already out, what’s weird nearby?” companion. One-tap location, swipeable cards you can skim at a red light (responsibly), save/share that doesn’t fight you, and a quiet toggle: “nudge me when something odd appears within five miles.”

Path: PWA now (installable, offline last results, Share Target) → push later (saved intents → “new oddities near you”) → Expo wrap with haptics and deep links like underfoot://place/:id so maps feel native. 🧭


What I did wrong (say it out loud) 🧨

🦄 I still had a blast, learned a ton, and might even do it again—after a nap and a vacation from permissions dialogs. 🌙


Future plans (also in the repo) 🧱

High-impact next: dataset preload I control (seeded batches), vector search via pgvector once the pipeline is boring, Google Places (Text/Nearby + Details) through the same normalizer, and a curated “weird web” seed list (40–50 URLs you wouldn’t know to google, scheduled fetcher, quality scoring so the noisy ones get benched). 🧰

Cache-first response: the Whisper Network runs in the background, but the agent should hit the cache first. Update the prompt/flow to enforce cache → live tools.

Cache management planning: I put a lot of design work into how the cache could be structured to allow for future RAG-type navigation, along with simpler embeds for straight vector search. However, I put zero thought (asides from "I need to think about that at some point") into actually managing it after the data is there. For now, it's all dependent on a merge that's unique by URL.

Localization: right now it returns the first geocoder result for speed. Flesh this out so results match what people meant, not just what a geocoder guessed.

Experience: transparent Stonewalker scoring you can peek and tweak; richer cards (images, tags, map snaps, save/share lists, quick filters); a quieter Discord bot that delivers value, not noise; mobile that respects thumbs and daylight. ✨

Reliability: Normalization 2.0 is the law; a tiny “repair” agent only when validation fails; better cross-source entity linking so “The Old Mill” is one place—not fourteen. 🔐


Technical Stuff


Screenshots 🖼️

Primary workflow

Flow overview diagram showing inputs, fetchers, parse/de-dupe, scoring, cache, and output

Last-minute solution instead of pre-cached data

Scraping Google Maps when the dataset didn't show

Google SERP flow

Google search SERP workflow

Reddit scraper

Reddit scraper workflow

Facebook Events scraper

Facebook Events scraper

The Whisper Network (background caching)

The Whisper Network behind-the-scenes caching

Discord notifications baked in

The annoying notifier that dinged every single time something went wrong


Quick links 🔗

Repo: https://github.com/CheckMarKDevTools/underfoot-underground-travel-planner

Live link: https://checkmarkdevtools.app.n8n.cloud/webhook/d92bc454-8f78-4471-ae25-ffa0c9bb87b3/chat


🛡️ R.A.I. — Responsible AI (how this stays good on purpose)

🦄 Confession: Yes I cheated — I let ChatGPT write the initial submission, which honestly I didn't even have time to read. There is no telling what was on it, but I know it wasn't mine and it was making me crazy. 🤪 So please, do not judge this writing as part of whatever scoring happens with the project. It was all done after the deadline.

Last updated: 2025-09-01. If I miss the mark on any of this, file an issue and I’ll fix it._ ✅


Epilogue 📝

Half of what I attempted was a bad idea—which is why I deferred the other half on purpose—and somehow I still had the best time. I’m tired in the satisfying way. I want a nap and I want to open my phone in a random city and hear Stonewalker whisper “turn left.” That’s how I know I’m not done—just paused long enough to tell you what really happened. 🌆


🧠💥 The Oomph (mic-drop)

The clock ran out; the curiosity didn’t. Underfoot / Stonewalker already finds the odd little places that make a town feel alive, and the desk was just a proving ground because your pocket is the point—one tap, one intent, a handful of cards that feel like a friend leaning in to whisper, psst, go here. 🌙

💬 Join the discussion about "Underfoot: The ChatPot for Hidden Places (and Why I Don’t Do Hackathons)" on Dev.to:

View comments and reactions →

📚 Related Articles

Read on Dev.to →