A real Barcelona discovery, planning and booking app: search/filter/map a catalog of activities, plan a week, sign in, save things, and book real inventory through a real (test-mode) Stripe payment flow.
There is exactly one real product in this repo: the app in server/.
Everything else (this README, index.html, docs/) exists to point you at
it honestly — not to duplicate or stand in for it.
docs/design/BCN_NOW_original_design.html
is the original design (open it directly in a browser). It is the source
of truth for how BCN NOW should look — warm near-black background
(#16130D), cream text (#F4F1E9), yellow-lime accent (#D9F25E), rust
for urgency/discount states (#C0522C), Archivo for display type,
JetBrains Mono for labels/meta/data. server/public/styles.css carries
these exact tokens over. Don't replace them with generic dark-mode
defaults (pure black, neon green) — that happened once already and was
wrong; this file is kept specifically so it doesn't happen again.
cd server
npm install
npm run seed # creates the catalog DB + 3 real-sourced events + demo bookable inventory
npm start # http://localhost:4242
That gives you: NOW (live feed), DISCOVER (search + filters), MAP (Leaflet, real venue pins), MY WEEK (planner, needs an account), YOU (sign up / sign in), and a working booking flow — all in one app, one server, one database.
To exercise the real payment path (otherwise booking correctly refuses rather than faking success — see below):
cp .env.example .env # fill in Stripe TEST-mode keys
In a second terminal, forward Stripe webhooks to your local server (needs the Stripe CLI):
stripe listen --forward-to localhost:4242/api/webhooks/stripe
Use a Stripe test card (4242 4242 4242 4242) at checkout — My Week will show the booking as confirmed only once
Stripe's webhook actually fires.
GitHub Pages (what serves index.html at
https://mohamedhasbini.github.io/bcn-now/) only hosts static files — it
cannot run this app's database or payment webhook. A real public URL needs
a real Node host. render.yaml is a ready-to-go blueprint:
Deploy to Render — one click, free tier, then add your Stripe keys in the dashboard.
This step needs your sign-in (Render, Railway, Fly.io — pick any Node
host) — that's not something this repo or an assistant can complete on
your behalf. Once deployed, set STRIPE_WEBHOOK_SECRET from a webhook
endpoint pointed at https://<your-url>/api/webhooks/stripe.
Note: the free tier's filesystem is not persistent across deploys, so the SQLite database resets when you redeploy. Fine for demoing; before real customers use it, migrate to Postgres (see the spec status table below).
docs/HANDOFF_SPEC.md is the full product +
engineering handoff — the target for what BCN NOW should become (data
engine, booking protocol, hotels/trips, achievements, AI concierge, admin
tooling), a phase-by-phase build order, and a status table of what's
actually implemented versus still planned. Keep that table current as work
lands — it's the one place spec-vs-reality drift gets caught.
- Catalog (Phase 1):
categories,venues,listingstables; search with text/category/neighborhood/date filters; a Leaflet map; a distinction between dated "current" listings andis_evergreenideas so the two are never shown as equivalent (spec §2, §7). - Accounts (Phase 1): email/password signup+login, server-side sessions (HttpOnly cookie), auth-gated Saved Items and My Week.
- My Week (Phase 1): manual notes + saved listings on a day/time basis; confirmed bookings appear automatically.
- Real ingestion (Phase 2, partial):
server/ingest/has a normalize → dedupe → store pipeline. It's seeded with 4 real, currently-verifiable Barcelona events (Brunch Electronik, two real exhibitions, the Gothic Quarter Festa Major), each with its actual source URL — found via live search, not invented. This sandbox's network egress is blocked to arbitrary external domains, so it can't run automated, recurring ingestion from official APIs/partner feeds itself; that has to run on the real deployment host. See the spec's status table for what a production ingestion adapter still needs (official city agenda API, ticketing partner feeds, scheduled re-verification, image pipeline). - Booking engine (Phase 3): full
HOLD → PAYMENT_PENDING → CONFIRMED / EXPIRED / FAILED / REFUNDEDstate machine, a pre-payment capacity hold with automatic TTL expiry, Stripe Checkout, signature-verified + idempotent webhooks, unique booking numbers. The 3 bookable demo slots (padel/cooking class/hammam) are explicitly markedunverifieddemo inventory, not real onboarded businesses — don't relabel them as real without actually onboarding those organizers.
- Confirmation/receipt emails, ticket QR codes, cancellation/refund UI.
- Postgres migration (SQLite is fine for a demo, not for concurrent production traffic or surviving redeploys on most free hosts).
- Real, recurring data ingestion from official/partner sources (Phase 2 beyond the one-time real-event seed above).
- Organizer/business platform, hotels/trips/tickets marketplace, achievements/XP/social, AI concierge (Phases 4-6).
None of these need a decision from me to start except: which host, whether Stripe is already set up, and whether organizers onboard manually or self-serve first. Ask before assuming those.