Graph-driven hospitality discovery and night-planning app for London.
Serious, boring, usable consumer UI on top of a structured backend: deterministic query parsing, venue graph relationships, itinerary planning, and explainable recommendations. No LLM dependency.
Prerequisites: Docker, Node.js 18+, pnpm, Python 3.12+, uv
# 1. Clone and install
git clone <repo-url> && cd OSNightLifeGraph
pnpm install
cd apps/api && uv sync && cd ../..
# 2. Start Postgres
make db
# Wait a few seconds for the container to initialize
# 3. Run migrations and seed data
make migrate
make seed
# 4. Start the API (terminal 1)
make api
# 5. Start the frontend (terminal 2)
make webOpen http://localhost:3000 — that's it.
- Open the app → venue list + map loads
- Type "cocktails in Soho" → results filter to Soho bars
- Click a venue card → detail panel with hours, tags, events, similar places
- Switch to "Graph" tab → venue relationship graph renders
- Click "Plan a night" → describe a night ("dinner then drinks in Shoreditch, £80 budget")
- Hit "Generate plan" → multi-stop itinerary with explanations
| Layer | Tech |
|---|---|
| Frontend | Next.js 15 (App Router), React 19, TypeScript, Tailwind, TanStack Query, MapLibre GL JS |
| Backend | Python 3.12, FastAPI, Pydantic v2, SQLAlchemy 2.x, Alembic |
| Optimizer | C++17 + pybind11 (Python fallback if not built) |
| Database | PostgreSQL 16, pg_trgm, UUID primary keys |
| Tooling | pnpm workspaces, uv, Docker, Makefile |
| Method | Path | Purpose |
|---|---|---|
| GET | /health |
Health check |
| GET | /filters |
Available filter options |
| GET | /venues |
Venue list with filtering |
| GET | /venues/{slug} |
Venue detail |
| POST | /query/parse |
NLP query → structured filters |
| POST | /plans/generate |
Generate night itinerary |
| GET | /graph/venue/{slug} |
Venue relationship graph |
/
├── apps/
│ ├── web/ # Next.js frontend
│ └── api/ # FastAPI backend
├── packages/
│ ├── optimizer/ # C++17 + Python fallback
│ └── shared-types/ # TypeScript types
├── infra/
│ └── docker-compose.yml
└── docs/ # Spec files (source of truth)
make dev # Start everything (db + api + web)
make db # Start Postgres container
make api # Start FastAPI server
make web # Start Next.js dev server
make migrate # Run Alembic migrations
make seed # Load seed data (120 venues, 30 events)
make test # Run pytest suite
make clean # Remove build artifactsmake test
# or directly:
cd apps/api && uv run pytest -vTests cover:
- Parser: area, venue type, route, budget, party size, vibes, flags, cuisines, genres, confidence — plus all 6 demo queries from the product spec
- API smoke: health, filters, venue list/detail, query parse, plan generation, graph endpoint
Seeded with 120 synthetic London venues across 10 neighborhoods, 30 events,
bidirectional similarity links, opening hours, and transit node associations.
All deterministic (uuid5-based) so make seed is idempotent.
- London only
- No auth, payments, scraping, or LLM on critical path
- No heavy infra (no K8s, Kafka, Neo4j, Elasticsearch)
- Runs locally with seeded synthetic data
- Must be understandable by a recruiter in under 2 minutes