🦄 Yes — I know... another project. It can't be helped! I really do plan on finishing them all (at some point). So, since I'm already over-worked and short on time as-is. Here's my 2nd attempt at vibe coding with ChatGPT at the wheel and GitHub Copilot playing backup. We'll see how it goes without me going to crazy with the overbearing-OCD. 🤞
P.S. I'll keep notes of how it goes in the JOURNEY file, because... why not?
🧭 Quirky, snarky, absolutely-not-your-typical travel planner for finding the coolest, least obvious spots — the ones the big travel sites forgot.
Underfoot helps you find hidden gems in any given location by digging into local blogs, indie magazines, and offbeat sources. No TripAdvisor Top 10 lists here — we're all about the "Wait, this exists?!" moments.
If you find this project useful or want to support its development, consider sharing it, starring the repo, or even buying me a coffee! Your support keeps the code flowing and the caffeine strong 💪
| Pulse Points | Badges |
|---|---|
| 🫶 Show Some Love | |
| 🛼 Recent Activity | |
| 📊 At a Glance | |
| 🧩 The Non-Negotiable | |
| 🔧 Nerd Tools I Can't Live Without - Dependencies |
|
| 👾 Bots in the Basement | |
| 💬 Meta Magic & Shiny Things |
This is the first Labs repo — our hackathon playground for weird, experimental, and possibly genius projects. If it's useful, fun, or both, it stays.
🎯 Target Deployment: checkmarkdevtools.dev/underfoot
🏗️ Architecture: Python FastAPI Workers + Supabase + React
🎨 Design System: Dream Horizon (accessible underground theme)
📊 Test Coverage: Backend 20% (models + scoring), Frontend 96.99%
- ✅ Python FastAPI backend with 7 services (OpenAI, Geocoding, Cache, SERP, Reddit, Eventbrite, Scoring)
- ✅ Google Maps API integration with secure environment variables
- ✅ Streaming chat interface with SSE
- ✅ Security-first middleware (rate limiting, XSS protection)
- ✅ Comprehensive frontend test suite (96.99% coverage)
- ✅ Documentation reorganized into architecture/, tech_guides/, user_guides/, planning/
- 🚀 Supabase backend integration (current)
- 🎨 Dream Horizon UI polish
- 🗺️ Google Maps visualization ($300 GCP credits active)
- 🧠 Vector search caching with Supabase
- 🌐 Production deployment to checkmarkdevtools.dev/underfoot
- 🎯 Location-based underground travel picks
- 🗓️ Flexible date range search (always slightly broadened for best results)
- 🕵️ Sources: local blogs, indie publications, and niche community recs
- 🛡️ Privacy-first — all API keys live in
.env - 🖥️ Debug view for server output
- 🧠 Smart context (e.g., "graveyards" → suggests haunted houses)
- 📊 Result scoring with underground keyword detection
- 💾 Vector search caching for improved performance
Quick Start:
-
Frontend (
/frontend/.env)cp frontend/.env.example frontend/.env # Add: VITE_GOOGLE_MAPS_API_KEY=your_key # Add: VITE_API_BASE=http://localhost:8000
-
Backend (
/backend/.env)cp backend/.env.example backend/.env # Configure API keys as needed
cd frontend
npm install
npm run devcd backend
poetry install
poetry run uvicorn src.workers.chat_worker:app --reloadnpm run dev # Starts both frontend and backend
npm run test # Run all testsThe backend supports an EventSource-compatible pseudo-streaming interface (currently a single final payload framed as events; ready to evolve into true token streaming).
Endpoint (GET):
/underfoot/chat?chatInput=Your+prompt&stream=true
Events (protocolVersion 1):
| Event | Data Shape | Notes |
|---|---|---|
start |
{ requestId, protocolVersion:1, cacheHit:boolean } |
First event confirming stream accepted |
complete |
Full JSON chat payload ({ response, items?, debug }) |
Same object shape as POST response |
heartbeat |
{ ts, requestId } |
Sent every ~20s if connection held long enough |
error |
{ message, fatal?, requestId } |
Only on internal failure before completion |
end |
{ requestId } |
Terminates stream |
Cache hits emit: start(cacheHit:true) → complete → end rapidly.
Example (browser):
const es = new EventSource('/underfoot/chat?stream=true&chatInput=' + encodeURIComponent('Hello'));
es.addEventListener('complete', (e) => {
const data = JSON.parse(e.data);
console.log('Reply:', data.response);
});
es.addEventListener('end', () => es.close());Non‑streaming: You can use POST /underfoot/chat with { "chatInput": "Hello" }.
:root {
/* Light Theme */
--color-bg: #fdfdfe; /* Pearl White */
--color-surface: #f3f5f8; /* Mist Surface */
--color-text: #0d1b2a; /* Midnight Navy */
--color-accent: #9d4edd; /* Aurora Purple */
--color-info: #1faaa0; /* Soft Teal */
--color-cta: #ff914d; /* Mid Orange */
/* Dark Theme */
--color-bg-dark: #0a0e1a; /* Deep Space */
--color-surface-dark: #1a1f2e; /* Dark Surface */
--color-text-dark: #fdfdfe; /* Pearl White */
}- Headers: Google Flavors (mystical, underground theme)
- Body: Inter (clean, accessible, readable)
- Code: JetBrains Mono (development context)
Comprehensive documentation is organized in /docs:
- Architecture - Design decisions and system diagrams
- Technical Guides - Setup, deployment, and configuration
- User Guides - End-user documentation and testing
- Planning - Project roadmap and implementation notes
See Documentation Index for the complete guide.
# Frontend tests
cd frontend && npm test
npm run test:coverage
# Backend tests
cd backend && poetry run pytest
poetry run pytest --cov=src
# All tests (from root)
npm testThe automation workflows powering the experimental chat / data stitching layer (used during the hackathon phase) are published as a sharable gist so you can import or remix them directly inside your own n8n instance:
👉 https://gist.github.com/anchildress1/cab1237affe75f0bed6629faeb940f2c
Import Instructions (quick):
- Open your n8n dashboard.
- Create New Workflow → Menu (⋮) → Import from URL.
- Paste the gist raw URL (or download the JSON and import from file).
- Review credentials placeholders, add your own keys (OpenAI, data sources, etc.).
- Activate and test.
Notes:
- Gist may evolve; pin a specific revision hash if you need reproducibility.
- Secrets are never stored in the gist—remember to configure them locally.
- Feel free to open an issue suggesting enhancements to the workflows.
- Fork the repository
- Create feature branch:
git checkout -b feature/amazing-feature - Commit changes:
git commit -m 'feat: add amazing feature' - Push to branch:
git push origin feature/amazing-feature - Open Pull Request
- Commits: Conventional Commits
- Linting: ESLint + Prettier
- Testing: Minimum 90% coverage for new code
- Security: No hardcoded secrets, XSS protection required
Custom License - This project is not open source but allows broad usage.
TL;DR: Do what you want—as long as you're not turning it into the next big SaaS or selling subscriptions. For commercial use, ask first.
See LICENSE for full details.
🛡️ This entire project was built with the help of ChatGPT and GitHub Copilot
Built with ❤️ and way too much coffee
🎯 Verdent AI: The coding assistant that actually understands the assignment and doesn't try to rewrite your entire codebase "for better practices." Thanks for being the sane voice in the room, AI buddy!
This document was generated with Verdent AI assistance.