# HotNow.io — Phase 1: Architecture + Competitive Intel > **Phase 1 of 4 — $50 Premium Build** > **Date:** August 2, 2026 > **Status:** ✅ Complete — Awaiting Germaine Review --- ## Table of Contents 1. [Competitive Landscape](#1-competitive-landscape) 2. [Opportunity Analysis & HotNow's Edge](#2-opportunity-analysis--hotnows-edge) 3. [Product Architecture](#3-product-architecture) 4. [Data Model](#4-data-model) 5. [API Surface](#5-api-surface) 6. [Real-Time Ranking Algorithm](#6-real-time-ranking-algorithm) 7. [Component Tree & PWA Shell](#7-component-tree--pwa-shell) 8. [Infrastructure & Deployment](#8-infrastructure--deployment) 9. [Build Plan Preview (Phases 2-4)](#9-build-plan-preview-phases-2-4) 10. [Follow-Up Questions for Germaine](#10-follow-up-questions-for-germaine) --- ## 1. Competitive Landscape ### Market Segmentation The local discovery space is fragmented across four segments — nobody owns all of them: | Segment | What It Covers | Key Players | |---------|---------------|-------------| | **Restaurant/Business Discovery** | Finding places to eat, drink, shop | Yelp, Google Maps, Beli, Corner, TripAdvisor | | **Event/Ticketing Platforms** | Buying tickets, browsing events | Eventbrite, DICE/Fever, Songkick, Bandsintown | | **Neighborhood Social** | Hyperlocal community chatter | Nextdoor, Facebook Groups, Ring Neighbors | | **Curated Experiences** | Immersive, premium, one-off events | Fever (Candlelight), Secret Cinema, Airbnb Experiences | ### Competitor Deep Dives --- #### 2. Yelp — The Incumbent Giant - **What it is:** 20-year-old local business discovery platform. 21-22M reviews/year. Massive community-generated content moat. - **What's new (2025 Fall Release):** Massive AI push — Yelp Assistant (AI chatbot on every business page), Menu Vision (AR menu scanning), natural language/voice search, Popular Offerings (LLM-extracted crowd favorites), Yelp Host/Receptionist (AI call answering for businesses). Partnered with DoorDash for delivery. - **Pricing:** Free for consumers. Business advertising: $150-$5,000+/mo. Yelp Host: $99/mo. - **UX Pattern:** List-first with map secondary. Search-driven discovery. - **Weaknesses:** - Not real-time — Yelp ranks on accumulated review history, not "what's hot right now" - Weak on events — events are an afterthought, not core UX - Gen Z exodus — Beli and Corner are eating its lunch with younger demographics - No social buzz integration — no TikTok/Instagram trend signals - **🔴 HotNow opportunity:** Real-time trending that Yelp's batch-oriented ranking can't match. Social buzz as a ranking signal. Event-first UX. --- #### 3. Fever — The Experience Curator - **What it is:** Global ticketing platform for curated experiences. 30+ cities worldwide. Known for Candlelight Concerts, immersive Van Gogh exhibits, themed pop-ups. - **Big news:** **Acquired DICE in 2025** — combined entity now dominates curated event ticketing - **Pricing:** Free to browse. Fever takes a commission on ticket sales (service fees added). No consumer subscription. - **UX Pattern:** Feed-first (curated hero cards). List + grid browse. Map only for venue lookup. - **Weaknesses:** - Curated, not comprehensive — Fever only shows its own catalog (events they ticket) - Not real-time — no trending algorithm, fixed listings - Not local-discovery — it's a ticketing platform, not a "what's happening around me" tool - B2C curation model — doesn't surface grassroots/pop-up/unlisted happenings - **🔴 HotNow opportunity:** Comprehensive vs. curated. Real-time vs. scheduled. Discovery vs. ticketing. --- #### 4. DICE — Transparent Ticketing - **What it is:** Music-first ticketing platform with transparent pricing (no hidden fees). Strong in UK/Europe, expanding in US. Acquired by Fever. - **Pricing:** No consumer fees — built into ticket price. Artist/venue revenue share. - **UX Pattern:** Feed-first with personalized recommendations based on listening history (Spotify/Apple Music integration). - **Weaknesses:** - Music-only — no restaurant/bar/pop-up discovery - Ticketing-centric — useless if you just want to know what's happening without buying a ticket - Post-acquisition uncertainty — Fever integration may shift focus - **🔴 HotNow opportunity:** Cross-category discovery (not just music). Free-form exploration without ticket purchase obligation. --- #### 5. Eventbrite — The Event Marketplace - **What it is:** Largest self-service event platform. 5M+ events/year. 2025 rebrand from utility to "cultural hub." - **New initiatives:** AI personalization, Listener.com partnership for audience reach, AI-powered event recommendations. - **Pricing:** Free to browse. Organizers pay: free tier (up to 25 tickets), then 2% + $0.79 per paid ticket, or subscription plans. - **UX Pattern:** Search-first with category browse. List results. Map secondary. - **Weaknesses:** - Quantity over quality — lots of spam, online webinars, low-quality listings - No real-time signal — static listings sorted by date/relevance - Brand perception: "event Craigslist" — utilitarian, not aspirational - Not Gen Z cool — zero social features - **🔴 HotNow opportunity:** Quality-filtered, social-buzz ranked. Cool brand. Map-first UX. --- #### 6. Nextdoor — Neighborhood Social - **What it is:** Hyperlocal social network for neighborhoods. 15 years old. User-generated content: recommendations, alerts, events. - **2025 redesign:** AI-powered "Faves" for local business discovery, real-time emergency alerts (weather/traffic/power), local news from 3,500+ publisher partners, LLM per neighborhood trained on 15 years of conversations. - **Pricing:** Free. Ad-supported + promoted business posts. - **UX Pattern:** Feed-first (social). Map for alerts. List for businesses. - **Weaknesses:** - Brand damage — associated with racism, misinformation, "Karen" culture - Demographic skew — older homeowners, not Gen Z/Millennials going out - Events are buried — not a discovery tool, it's a neighborhood bulletin board - Reactive, not proactive — "lost cat" dominates over "cool thing happening" - **🔴 HotNow opportunity:** Aspirational, cool brand. Discovery-first. Young demographic. No neighborhood baggage. --- #### 7. Beli — Gen Z Restaurant Ranking - **What it is:** Restaurant ranking + social app. Goodreads/Letterboxd for food. 80% of users under 35. 30M reviews in 2024 (surpassing Yelp's 21M). - **How it works:** Log restaurants, compare them head-to-head (pairwise ranking algorithm assigns scores /10), follow friends, browse feeds. No star ratings. - **Growth engine:** College campus ambassador program. Leaderboards by school. Dating app integration (sharing rankings to vet dates). TikTok/Instagram virality. - **Pricing:** Free (currently). No ads. No monetization yet. - **UX Pattern:** Feed-first (social). Profile-centric. No map. - **Weaknesses:** - Restaurant-only — no events, bars (as venues), pop-ups, activities - Past-tense — about where you've been, not what's happening right now - No map — poor for real-time exploration - No monetization path yet — unclear business model - **🔴 HotNow opportunity:** Real-time + events + map. Broader than restaurants. Clear revenue model from day one. --- #### 8. Corner — Gen Z Social Map - **What it is:** Map-first social app for Gen Z. User-curated map of places (restaurants, bars, shops, sunset spots). No star ratings. Mood-board style lists. $3.75M raised. - **Key features:** AI semantic search ("sexy wine bar" → results), Instagram/TikTok bookmark import, user-generated descriptions (Gen Z voice: "performative male wine bar to break someone's heart"), Mapbox-powered. - **Stats:** 55,000 users, 275,000+ places, 450 cities. Hubs: NYC, SF, Tokyo, LA, Seoul. - **Pricing:** Free. Considering premium trip-planning tier. No sponsored placements (stated philosophy). - **UX Pattern:** Map-first. Feed of friend activity. Profile + lists. - **Weaknesses:** - Tiny scale — 55K users vs. Yelp's millions - User-generated only — no data if nobody has added a place yet - No events — purely place discovery (static) - Gen Z monoculture — alienates 30+ demographic - No monetization — pre-revenue, burning VC - **🔴 HotNow opportunity:** Events + real-time + broader demographic. Data-rich from day one (Super Search v2). Revenue from launch. --- #### 9. Google Maps — The 800-Pound Gorilla - **What it is:** Default map for 1B+ users. 20 years old. "Explore" tab surfaces nearby restaurants, attractions, activities. - **Recent AI:** Gemini-powered conversational search, AR Live View, "Popular Times" (historical foot traffic data), AI-summarized place descriptions. - **Pricing:** Free for consumers. Google Ads for businesses. - **UX Pattern:** Map-first. Everything is on the map. Unbeatable directions + navigation. - **Weaknesses:** - Not events-first — events are buried, inconsistent, often missing - Static data — "Popular Times" is historical, not real-time - No social — no friend activity, no trending rankings - Generic UX — one-size-fits-all, no personality - **🔴 HotNow opportunity:** Events-first UX. Real-time trending. Social layer. Brand personality. --- #### 10. Songkick / Bandsintown — Live Music Trackers - **What it is:** Track artists you follow → get notified when they're playing near you. Songkick acquired by Suno (AI music company). Bandsintown is independent. - **Pricing:** Free for fans. Bandsintown: artist promo packages ($25-$100+/mo). - **UX Pattern:** List-first (concerts by date). Artist-centric. - **Weaknesses:** - Music-only — no other event categories - Artist-dependent — you must follow artists to get value - No real-time trending — chronological, not ranked by buzz - **🔴 HotNow opportunity:** All categories. Buzz-ranked. No following required — discover without pre-configuring. --- #### 11. Resident Advisor (RA) — Electronic Music Authority - **What it is:** The definitive electronic music events platform. Global listings, reviews, news, ticket sales. - **Pricing:** Free to browse. Ticket commission + promoted event listings. - **UX Pattern:** List-first. Deep filtering by genre/city/date. - **Weaknesses:** - Niche (electronic music only) — tiny addressable market - Community-specific — not for general audience - **🔴 HotNow opportunity:** Mass-market appeal. All genres + all categories. --- #### 12. Seeker.io — B2B AI Event Aggregation - **What it is:** AI-native event discovery for tourism boards, CVBs, local media. Crawls any website to extract events. Used by SF Peninsula (500+ sources, 16 cities), Tennessee Tourism (statewide), Calgary Co-op (4 orgs, 1 feed). - **Pricing:** Enterprise B2B SaaS (not publicly listed — likely $500-$5K+/mo depending on scale). - **UX Pattern:** Embeddable calendar widget for partner websites. REST API for custom integrations. - **Weaknesses:** - B2B, not consumer-facing — no social, no map UX, no mobile app - No real-time trending — chronological curation - Expensive — not for small businesses - **🔴 HotNow opportunity:** Consumer experience. Real-time social ranking. Affordable business tiers. --- ## 2. Opportunity Analysis & HotNow's Edge ### The White Space After analyzing 12 competitors, **nobody is doing all of these together:** | Capability | Yelp | Fever/DICE | Eventbrite | Nextdoor | Beli | Corner | Google Maps | **HotNow** | |------------|------|-----------|------------|----------|------|--------|-------------|-------------| | Real-time trending | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | | Social buzz signals | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | | Map-first UX | 🔶 | ❌ | ❌ | 🔶 | ❌ | ✅ | ✅ | ✅ | | Events + Places | ❌ | 🔶 | ✅ | 🔶 | ❌ | ❌ | 🔶 | ✅ | | AI ranking | 🔶 | ❌ | 🔶 | ✅ | ✅ | ✅ | 🔶 | ✅ | | Gen Z cool factor | ❌ | 🔶 | ❌ | ❌ | ✅ | ✅ | ❌ | ✅ | | Business monetization | ✅ | ✅ | ✅ | ✅ | ❌ | ❌ | ✅ | ✅ | | Offline mode (PWA) | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | ✅ | | PWA (no app store) | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ❌ | ✅ | **🔶 = partially / second-class feature** ### HotNow's Core Differentiators 1. **Real-Time Trending Ranking** — The single biggest gap. Everyone ranks by reviews, dates, or manual curation. HotNow ranks by what's buzzing *right now* — social signals, check-in velocity, search volume, AI sentiment. 2. **Super Search v2 Integration** — Already live on Core server with 7 providers. This is HotNow's data engine — aggregates events, venues, reviews, and social signals from multiple sources without needing to build every scraper from scratch. 3. **Map-First PWA** — No app store friction. Instant onboarding. Works offline. Lower CAC than native app competitors. 4. **Three-Tier Consumer Monetization** — Explorer (free), Pro ($4.99/mo), Concierge ($19.99/mo). Competitors are either free/ad-supported or ticket-commission-only. Recurring subscription revenue from day one. 5. **Business Revenue from Launch** — Featured Placement ($97/mo) + Event Boost ($47/event). Affordable for small businesses (unlike Yelp's $500+ minimums). 6. **Brand Identity** — Dark theme, warm gradient accent. "What's good, right now, near you." Gen Z/Millennial voice without alienating 30+. --- ## 3. Product Architecture ### System Overview ``` ┌─────────────────────────────────────────────────────────────────┐ │ USERS (PWA) │ │ app.hotnow.io ─── Map View ─── Discovery Feed ─── etc. │ └─────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ CLOUDFLARE CDN │ │ Static assets (JS/CSS/icons) │ API proxy │ DDoS protection │ └─────────────────────────────────────────────────────────────────┘ │ ▼ ┌─────────────────────────────────────────────────────────────────┐ │ CADDY REVERSE PROXY │ │ SSL termination │ Rate limiting │ Route by subdomain │ └─────────────────────────────────────────────────────────────────┘ │ ┌───────────────────┼───────────────────┐ ▼ ▼ ▼ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐ │ app.hotnow.io │ │ api.hotnow.io │ │ dashboard.hotnow │ │ (Static PWA) │ │ (FastAPI) │ │ (Business Dash) │ │ SvelteKit SPA │ │ Port 8001 │ │ Static + API │ └──────────────────┘ └──────────────────┘ └──────────────────┘ │ ┌───────────────────┼───────────────────┐ ▼ ▼ ▼ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │ PostgreSQL │ │ Redis │ │ Super Search v2 │ │ + PostGIS │ │ Cache + Queue│ │ (7 providers) │ │ │ │ + Real-time │ │ Existing on Core │ └──────────────┘ └──────────────┘ └──────────────────┘ ``` ### Tech Stack | Layer | Technology | Why | |-------|-----------|-----| | **PWA Frontend** | SvelteKit (static adapter) | Fast, small bundles, great PWA support | | **Map** | Leaflet.js + OpenStreetMap tiles | Free, no API keys, works offline with cached tiles | | **Backend API** | FastAPI (Python 3.11) | Async, auto-docs, Python matches existing Core stack | | **Database** | PostgreSQL 16 + PostGIS | Geospatial queries (proximity, radius, bounding box) | | **Cache** | Redis | Trending scores, session cache, rate limit counters, real-time pub/sub | | **Task Queue** | Redis + ARQ (or Celery) | Background: Super Search ingestion, trend recalculation, notifications | | **Auth** | JWT tokens + refresh | Stateless, PWA-friendly, no cookies needed | | **Payments** | Stripe | Consumer subs + business placements, Webhook integration | | **Search** | PostgreSQL full-text search + Super Search v2 | Hybrid: own DB for quick lookups, Super Search for deep aggregation | | **Offline** | Service Worker + IndexedDB | Cache map tiles, event data, user preferences | | **Push Notifications** | Web Push API + VAPID | PWA native, no app store needed | | **Email** | Postmark or SendGrid | Transactional + marketing | ### Subdomain Architecture | Subdomain | Purpose | Technology | |-----------|---------|------------| | `hotnow.io` | Marketing/SEO landing page | Static HTML (existing `/var/www/hotnow/index.html`) | | `app.hotnow.io` | PWA shell | SvelteKit SPA, static export, served by Caddy | | `api.hotnow.io` | REST API backend | FastAPI on Core server (`152.53.192.33`), port 8001 | | `dashboard.hotnow.io` | Business dashboard | SvelteKit SPA (shared component library with app) | | `cdn.hotnow.io` | Static assets (optional) | Cloudflare CDN caching | | `admin.hotnow.io` | Internal admin panel | Protected by Tailscale, minimal FastAPI admin | --- ## 4. Data Model ### Core Entities #### Events ```sql CREATE TABLE events ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), title VARCHAR(255) NOT NULL, description TEXT, category event_category NOT NULL, -- enum: music, food_drink, arts_culture, nightlife, sports, family, pop_up, other start_time TIMESTAMPTZ NOT NULL, end_time TIMESTAMPTZ, timezone VARCHAR(50) DEFAULT 'America/Chicago', is_recurring BOOLEAN DEFAULT false, recurrence_rule VARCHAR(255), -- RRULE format is_featured BOOLEAN DEFAULT false, -- Venue relationship venue_id UUID REFERENCES venues(id) ON DELETE CASCADE, -- Media cover_image_url VARCHAR(500), media_urls JSONB DEFAULT '[]', -- [{url, type, order}] -- Pricing price_info JSONB DEFAULT NULL, -- {type: free|paid|varies, range: {min, max}, currency} ticket_url VARCHAR(500), -- Source attribution source VARCHAR(100) NOT NULL, -- 'manual', 'super_search', 'user_submitted', 'api_partner' source_event_id VARCHAR(255), -- external ID for dedup source_url VARCHAR(500), -- Real-time signals (updated by background worker) trending_score FLOAT DEFAULT 0.0, popularity_pulse INTEGER DEFAULT 0, -- short-term velocity (last 2 hours) social_mention_count INTEGER DEFAULT 0, search_volume_24h INTEGER DEFAULT 0, check_in_count INTEGER DEFAULT 0, ai_sentiment_score FLOAT DEFAULT 0.0, -- -1.0 to 1.0 -- Metadata tags TEXT[] DEFAULT '{}', is_active BOOLEAN DEFAULT true, reviewed_by_admin BOOLEAN DEFAULT false, created_at TIMESTAMPTZ DEFAULT NOW(), updated_at TIMESTAMPTZ DEFAULT NOW() ); -- Geospatial: events inherit location from venue, but can override -- Indexes CREATE INDEX idx_events_trending ON events (trending_score DESC) WHERE is_active = true; CREATE INDEX idx_events_time_range ON events (start_time, end_time) WHERE is_active = true; CREATE INDEX idx_events_category ON events (category) WHERE is_active = true; CREATE INDEX idx_events_venue ON events (venue_id); CREATE INDEX idx_events_source_dedup ON events (source, source_event_id); ``` #### Venues ```sql CREATE TABLE venues ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), name VARCHAR(255) NOT NULL, description TEXT, venue_type venue_type NOT NULL, -- enum: bar, restaurant, club, theater, park, gallery, pop_up, other -- Contact address VARCHAR(500), city VARCHAR(100) NOT NULL, state VARCHAR(50), postal_code VARCHAR(20), country VARCHAR(2) DEFAULT 'US', -- Geospatial (PostGIS) location GEOGRAPHY(POINT, 4326), -- lat/lng for proximity queries geo_json JSONB DEFAULT NULL, -- polygon for venues with boundaries -- Contact phone VARCHAR(20), website VARCHAR(500), social_links JSONB DEFAULT '{}', -- {instagram, facebook, twitter, tiktok} -- Hours hours JSONB DEFAULT NULL, -- [{day, open, close}] is_permanently_closed BOOLEAN DEFAULT false, -- Media cover_image_url VARCHAR(500), media_urls JSONB DEFAULT '[]', -- Real-time signals trending_score FLOAT DEFAULT 0.0, current_busy_level busy_level DEFAULT 'unknown', -- enum: quiet, moderate, busy, packed -- Business owner (links to Stripe customer) owner_user_id UUID REFERENCES users(id), -- Metadata source VARCHAR(100) DEFAULT 'manual', source_venue_id VARCHAR(255), created_at TIMESTAMPTZ DEFAULT NOW(), updated_at TIMESTAMPTZ DEFAULT NOW() ); CREATE INDEX idx_venues_location ON venues USING GIST (location); CREATE INDEX idx_venues_city ON venues (city, state); CREATE INDEX idx_venues_type ON venues (venue_type); ``` #### Users ```sql CREATE TABLE users ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), email VARCHAR(255) UNIQUE, display_name VARCHAR(100), avatar_url VARCHAR(500), -- Auth password_hash VARCHAR(255), auth_provider auth_provider DEFAULT 'email', -- enum: email, google, apple auth_provider_id VARCHAR(255), email_verified BOOLEAN DEFAULT false, -- Subscription tier subscription_tier DEFAULT 'explorer', -- explorer, pro, concierge stripe_customer_id VARCHAR(100), subscription_status subscription_status DEFAULT 'inactive', -- active, past_due, canceled, inactive subscription_expires_at TIMESTAMPTZ, -- Preferences home_city VARCHAR(100), home_location GEOGRAPHY(POINT, 4326), preferred_categories TEXT[] DEFAULT '{}', preferred_radius_km INTEGER DEFAULT 10, notification_prefs JSONB DEFAULT '{}', -- {push, email, sms, categories} -- PWA push_subscription JSONB DEFAULT NULL, -- Web Push subscription object -- Metadata is_business BOOLEAN DEFAULT false, is_admin BOOLEAN DEFAULT false, last_active_at TIMESTAMPTZ, created_at TIMESTAMPTZ DEFAULT NOW() ); CREATE INDEX idx_users_email ON users (email); CREATE INDEX idx_users_stripe ON users (stripe_customer_id); ``` #### Search/Discover Events (Lightweight for feed) ```sql CREATE TABLE discover_events ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), event_id UUID REFERENCES events(id) ON DELETE CASCADE, user_id UUID NOT NULL, -- anonymized session UUID for anonymous users action discover_action NOT NULL, -- enum: view, click, save, share, check_in source_context VARCHAR(50), -- 'map', 'feed', 'search', 'detail' created_at TIMESTAMPTZ DEFAULT NOW() ); CREATE INDEX idx_discover_events_user_time ON discover_events (user_id, created_at DESC); CREATE INDEX idx_discover_events_event ON discover_events (event_id, created_at); ``` #### Business Features ```sql CREATE TABLE business_features ( id UUID PRIMARY KEY DEFAULT gen_random_uuid(), venue_id UUID REFERENCES venues(id) ON DELETE CASCADE, feature_type feature_type NOT NULL, -- featured_placement, event_boost, promoted_listing status feature_status DEFAULT 'active', starts_at TIMESTAMPTZ NOT NULL, ends_at TIMESTAMPTZ NOT NULL, stripe_payment_id VARCHAR(100), amount_paid_cents INTEGER, metadata JSONB DEFAULT '{}', created_at TIMESTAMPTZ DEFAULT NOW() ); ``` #### Cached/Search Index (Redis) ```redis # Trending events by city (sorted set, scored by trending_score) trending:{city}:{category} → Sorted Set {event_id: score} # Real-time pulse (current activity, 15-min TTL) pulse:{event_id} → {view_count, click_count, save_count, last_updated} # User sessions (JWT refresh tokens) session:{user_id}:{device_id} → {refresh_token, expires_at, device_info} # Rate limiting ratelimit:{ip}:{endpoint} → counter with TTL # Geo-index cache (pre-computed bounding boxes) geo:{lat}:{lng}:{radius_km} → Set of event_ids (TTL: 5 min) ``` --- ## 5. API Surface ### REST API (api.hotnow.io/v1) #### Events | Method | Endpoint | Auth | Description | |--------|----------|------|-------------| | `GET` | `/events/trending` | Optional | Trending events (paginated, filtered by location/category) | | `GET` | `/events/nearby` | Optional | Events within radius of lat/lng | | `GET` | `/events/:id` | Optional | Full event detail with venue info | | `GET` | `/events/search` | Optional | Full-text search + Super Search v2 aggregation | | `POST` | `/events/submit` | User | User-submitted event (goes to review queue) | | `POST` | `/events/:id/save` | User | Save/bookmark event | | `POST` | `/events/:id/check-in` | User | Check in (anonymized, feeds trending) | | `GET` | `/events/:id/pulse` | Optional | Real-time activity data for this event | #### Venues | Method | Endpoint | Auth | Description | |--------|----------|------|-------------| | `GET` | `/venues/nearby` | Optional | Venues within radius | | `GET` | `/venues/:id` | Optional | Venue detail + upcoming events | | `GET` | `/venues/:id/busy` | Optional | Current busy level estimate | #### Discovery | Method | Endpoint | Auth | Description | |--------|----------|------|-------------| | `GET` | `/discover/feed` | Optional | Personalized feed (AI if Pro tier, trending if free) | | `GET` | `/discover/recommendations` | Pro | AI-powered recommendations | | `POST` | `/discover/action` | Optional | Log view/click/save for trending signals | #### Auth | Method | Endpoint | Auth | Description | |--------|----------|------|-------------| | `POST` | `/auth/register` | None | Create account (email + password) | | `POST` | `/auth/login` | None | Login → JWT access + refresh token | | `POST` | `/auth/refresh` | Refresh | Get new access token | | `POST` | `/auth/logout` | Access | Revoke refresh token | | `POST` | `/auth/oauth/google` | None | Google OAuth login | | `GET` | `/auth/me` | Access | Current user profile | #### Subscriptions | Method | Endpoint | Auth | Description | |--------|----------|------|-------------| | `GET` | `/billing/plans` | None | Available subscription tiers | | `POST` | `/billing/subscribe` | User | Create Stripe checkout session | | `GET` | `/billing/portal` | User | Redirect to Stripe Customer Portal | | `POST` | `/billing/webhook` | Stripe | Stripe webhook receiver | #### Business | Method | Endpoint | Auth | Description | |--------|----------|------|-------------| | `GET` | `/business/dashboard` | Business | Business metrics and active features | | `POST` | `/business/featured` | Business | Purchase Featured Placement | | `POST` | `/business/boost` | Business | Purchase Event Boost | | `GET` | `/business/analytics` | Business | Impressions, clicks, conversions | #### Admin (internal) | Method | Endpoint | Auth | Description | |--------|----------|------|-------------| | `GET` | `/admin/review-queue` | Admin | Events/venues pending review | | `POST` | `/admin/review/:id` | Admin | Approve/reject submission | | `POST` | `/admin/recalculate-trending` | Admin | Force trend recalculation | | `GET` | `/admin/stats` | Admin | Platform metrics | ### Auth Flow ``` 1. User registers/logs in → receives: - access_token (JWT, 15 min expiry) - refresh_token (opaque, 30 day expiry, stored in Redis) 2. Every API call: Authorization: Bearer 3. Access token expires → POST /auth/refresh → new access_token 4. Logout → revoke refresh_token in Redis 5. Anonymous users: session_id (UUID v4, stored in localStorage) - Limited rate: 100 requests/hour - Cannot save/bookmark (no persistence without account) ``` ### Rate Limits | Tier | Requests/Hour | Special Limits | |------|--------------|----------------| | Anonymous | 100 | Search: 10/hr | | Explorer (Free) | 300 | AI recs: none, Save: 50 | | Pro ($4.99/mo) | 1000 | AI recs: 100/hr, Offline: full | | Concierge ($19.99/mo) | 5000 | AI recs: unlimited, Concierge chat: 50/day | | Business | 500 | Dashboard + analytics | | Admin | Unlimited | All endpoints | --- ## 6. Real-Time Ranking Algorithm ### The HotNow Score The core innovation. Every event has a `trending_score` recalculated every 5 minutes by a background worker. ``` HOT_SCORE = ( SOCIAL_BUZZ × 0.30 + ENGAGEMENT_VELOCITY × 0.25 + RECENCY_DECAY × 0.20 + AI_SENTIMENT × 0.15 + MANUAL_BOOST × 0.10 ) × CITY_NORMALIZATION ``` #### Signal Components | Signal | Weight | Sources | Decay | |--------|--------|---------|-------| | **SOCIAL_BUZZ** | 30% | Instagram geotag mentions, X/Twitter mentions, TikTok location tags (via Super Search) | Half-life: 4 hours | | **ENGAGEMENT_VELOCITY** | 25% | HotNow own telemetry: views/min, clicks/min, saves/min, check-ins/min | Half-life: 2 hours | | **RECENCY_DECAY** | 20% | Time until event start. Events starting soon get boost. | Linear ramp: peaks 2h before, decays after start | | **AI_SENTIMENT** | 15% | Super Search v2 NLP sentiment on social mentions about the venue/event | 24h rolling window | | **MANUAL_BOOST** | 10% | Featured Placement ($97/mo), Event Boost ($47/event) | Fixed duration | #### City Normalization ``` CITY_NORMALIZATION = log10(active_users_in_city + 1) / log10(total_events_in_city + 1) ``` Prevents NYC/London from dominating. Small cities can compete. #### Anti-Gaming Measures - Velocity caps: engagement increase >300% in 15 min → throttled - Bot detection: suspicious patterns (same IP, rapid fire) → excluded - Review queue: user-submitted events require admin approval before trending - Manual boost transparency: clearly labeled in UI ("Promoted") ### Data Pipeline ``` ┌─────────────────┐ │ Super Search v2 │ ← 7 providers, already live on Core │ (aggregator) │ └────────┬────────┘ │ Every 15 min ▼ ┌─────────────────┐ │ Ingestion Worker │ ← Redis queue (ARQ), dedup by source_event_id │ │ enrich with geocoding, AI sentiment └────────┬────────┘ │ ▼ ┌─────────────────┐ │ PostgreSQL │ ← Events + Venues tables └────────┬────────┘ │ Every 5 min ▼ ┌─────────────────┐ │ Trend Calculator │ ← Compute HOT_SCORE for all active events │ (ARQ cron job) │ Update trending_score, write to Redis sorted sets └────────┬────────┘ │ ▼ ┌─────────────────┐ │ Redis │ ← Sorted sets: trending:{city}:{category} │ │ API reads directly from Redis (sub-millisecond) └─────────────────┘ ``` --- ## 7. Component Tree & PWA Shell ### PWA Architecture ``` app.hotnow.io (SvelteKit SPA, static export) │ ├── src/ │ ├── routes/ │ │ ├── +layout.svelte # Shell (nav, bottom tabs, auth state) │ │ ├── +page.svelte # Map view (default/home) │ │ ├── discover/ │ │ │ └── +page.svelte # Discovery feed (list) │ │ ├── event/ │ │ │ └── [id]/ │ │ │ └── +page.svelte # Event detail │ │ ├── venue/ │ │ │ └── [id]/ │ │ │ └── +page.svelte # Venue detail │ │ ├── search/ │ │ │ └── +page.svelte # Search + filters │ │ ├── profile/ │ │ │ └── +page.svelte # User profile, saved events │ │ ├── settings/ │ │ │ └── +page.svelte # Preferences, notifications │ │ ├── auth/ │ │ │ ├── login/+page.svelte │ │ │ └── register/+page.svelte │ │ └── concierge/ │ │ └── +page.svelte # Concierge chat (Pro tier) │ │ │ ├── lib/ │ │ ├── components/ │ │ │ ├── Map.svelte # Leaflet wrapper │ │ │ ├── EventCard.svelte # Horizontal/vertical card variant │ │ │ ├── EventDetail.svelte # Full modal/page detail │ │ │ ├── VenueCard.svelte │ │ │ ├── TrendPulse.svelte # Live activity indicator │ │ │ ├── CategoryFilter.svelte │ │ │ ├── SearchBar.svelte │ │ │ ├── BottomNav.svelte # Mobile bottom tab bar │ │ │ ├── ConciergeChat.svelte # AI chat interface │ │ │ └── PwaInstall.svelte # Install prompt │ │ ├── stores/ │ │ │ ├── auth.ts # JWT + refresh logic │ │ │ ├── location.ts # Geolocation watcher │ │ │ ├── events.ts # Event cache + trending │ │ │ └── settings.ts # User preferences │ │ ├── api/ │ │ │ ├── client.ts # Fetch wrapper with auth │ │ │ ├── events.ts │ │ │ ├── venues.ts │ │ │ ├── discover.ts │ │ │ └── auth.ts │ │ └── utils/ │ │ ├── geo.ts # Distance, bounding box calc │ │ ├── offline.ts # IndexedDB + SW helpers │ │ └── format.ts # Date, price, category formatting │ │ │ ├── service-worker.ts # PWA offline cache │ └── app.css # Tailwind + brand colors │ ├── static/ │ ├── manifest.json # PWA manifest │ ├── icons/ # PWA icons (192, 512) │ └── favicon.ico │ ├── svelte.config.js ├── vite.config.ts ├── tailwind.config.ts └── package.json ``` ### Key UI Patterns #### Map View (Home Screen) - Full-screen Leaflet map (OpenStreetMap tiles pre-cached for offline) - Clustered markers colored by category - Pulsing markers for "hot right now" (pulse speed = trending_score) - Bottom sheet (swipeable): list of nearby trending events - Filter chip bar: All | Music | Food/Drink | Arts | Nightlife | Pop-ups - Location button: recenter, radius slider #### Discovery Feed - Vertical scroll list of EventCards - Each card: cover image, title, venue, distance, trending badge, time - Pull-to-refresh (recalculates location + trending) - "Happening Now" horizontal carousel at top - Skeleton loading states #### Event Detail - Hero image with gradient overlay - Title, venue name (tappable → venue detail), distance - "Hot right now" pulse indicator - Description, category badges, tags - Price info + ticket link - Actions: Save, Share, Check In, Get Directions - Map snippet showing location - "Nearby" section: other trending events nearby #### Business Dashboard (dashboard.hotnow.io) - Auth-gated, only for users with `is_business = true` - Overview: impressions, clicks, saves for their venue/events - Purchase flow: Featured Placement, Event Boost - Analytics: 7-day, 30-day charts - Manage venue details, hours, photos --- ## 8. Infrastructure & Deployment ### Server: Netcup RS 2000 (Core — 152.53.192.33) ```yaml Services: PostgreSQL 16 + PostGIS: database: hotnow user: hotnow_app extensions: postgis, pg_trgm, uuid-ossp Redis 7: instance: hotnow maxmemory: 256mb policy: allkeys-lru FastAPI (api.hotnow.io): port: 8001 workers: 4 (gunicorn + uvicorn) systemd service: hotnow-api ARQ Workers: service: hotnow-worker queues: ingestion, trending, notifications, cleanup Caddy: config: /etc/caddy/Caddyfile routes: hotnow.io → /var/www/hotnow/index.html (landing page) app.hotnow.io → /var/www/hotnow-app/ (SvelteKit build) api.hotnow.io → reverse_proxy localhost:8001 dashboard.hotnow.io → /var/www/hotnow-dashboard/ (SvelteKit build) ``` ### Cloudflare DNS ``` A hotnow.io → 152.53.192.33 A app.hotnow.io → 152.53.192.33 (or CNAME → hotnow.io) A api.hotnow.io → 152.53.192.33 (or CNAME → hotnow.io) A dashboard.hotnow.io → 152.53.192.33 (or CNAME → hotnow.io) CNAME www.hotnow.io → hotnow.io ``` ### Environment Variables ```bash # /etc/hotnow/.env DATABASE_URL=postgresql://hotnow_app:${DB_PASSWORD}@localhost:5432/hotnow REDIS_URL=redis://localhost:6379/0 JWT_SECRET=${JWT_SECRET} JWT_REFRESH_SECRET=${JWT_REFRESH_SECRET} STRIPE_SECRET_KEY=${STRIPE_SECRET_KEY} STRIPE_WEBHOOK_SECRET=${STRIPE_WEBHOOK_SECRET} SUPER_SEARCH_ENDPOINT=http://localhost:8000 # Super Search v2 MCP SUPER_SEARCH_API_KEY=${SUPER_SEARCH_API_KEY} ENVIRONMENT=production CORS_ORIGINS=https://app.hotnow.io,https://dashboard.hotnow.io ``` --- ## 9. Build Plan Preview (Phases 2-4) ### Phase 2: Core Build ($20-25 budget, premium models) **What gets built:** 1. **Database setup** — PostgreSQL + PostGIS on Core server. Run migrations for all tables. 2. **FastAPI backend** — All API endpoints listed above. Auth flow (JWT + refresh). Stripe integration (subscriptions + business payments). 3. **Super Search v2 integration** — Event ingestion pipeline. Dedup logic. Geocoding enrichment. 4. **Trending algorithm** — HOT_SCORE calculator. ARQ cron job. Redis sorted set population. 5. **PWA shell** — SvelteKit SPA. Map view with Leaflet. Discovery feed. Event detail. Search. Auth. Bottom navigation. 6. **Business dashboard** — Basic dashboard with analytics and purchase flow. 7. **Caddy + Cloudflare** — Subdomain routing. SSL. Rate limiting. **Models used:** `claude-sonnet-4-20250514` for complex backend logic, `gpt-4o` for frontend, `deepseek-v4-pro` for architecture decisions. --- ### Phase 3: Review + Hardening ($8-10 budget) **What gets hardened:** 1. **Security audit** — JWT hardening, input validation, SQL injection check, CORS review. 2. **Performance** — API response time optimization, database query tuning, Redis cache hit rate. 3. **Error handling** — Graceful degradation, offline fallbacks, rate limit UX, payment failure flows. 4. **PWA audit** — Lighthouse PWA score, offline functionality, install flow, push notifications. 5. **Mobile testing** — iOS Safari, Chrome Android, Samsung Internet. Responsive breakpoints. 6. **Seed data** — Populate with real events for launch city. Verify trending algorithm with live data. 7. **Business onboarding flow** — Stripe Connect setup, venue claim flow, payment testing. **Models used:** `claude-sonnet-4-20250514` for code review, `gpt-4o` for testing, `deepseek-v4-pro` for security analysis. --- ### Phase 4: Launch Package ($5-7 budget) **What gets packaged:** 1. **Launch city campaign** — SEO landing page for target city. Social media post templates. 2. **Email sequence** — Welcome email, weekly digest ("What's Hot This Weekend"), re-engagement. 3. **Analytics dashboard** — Simple admin analytics: DAU/MAU, event engagement, revenue tracking. 4. **Business outreach kit** — One-page pitch for venues to advertise. "Claim your venue" email template. 5. **Documentation** — Deployment runbook, API docs (auto-generated by FastAPI), admin guide. 6. **Monitoring** — Uptime Kuma check for api.hotnow.io health endpoint. Error alerting. 7. **Launch checklist** — Pre-launch verification items. Go/no-go criteria. --- ## 10. Follow-Up Questions for Germaine ### Launch Strategy 1. **Launch city?** You mentioned Savannah in the doc. Is that the definite first market? Pros: manageable size, tourist economy, strong local culture, your home base. Cons: smaller user base, seasonal tourism. Alternatives to consider: Austin (tech-forward, young demo), Nashville (music + nightlife), Charleston (tourism + culture, close to Savannah). 2. **Savannah-specific considerations?** SCAD students are a natural early adopter demographic. Should we do a SCAD ambassador program (similar to Beli's campus model)? Are there local event organizers / venues we should partner with pre-launch? 3. **City-rollout strategy?** One city at a time (depth-first) or multi-city from launch (breadth-first)? Depth-first: build strong network effects in one market, then expand. Breadth-first: broader appeal but thinner data per city. ### Data Strategy 4. **Seed data sources?** Super Search v2 gives us web crawl + search aggregation. But for launch, should we also: - Manually curate 50-100 events/venues in the launch city to ensure quality? - Partner with local event organizers, venues, tourism boards? - Scrape existing platforms (Eventbrite, Facebook Events) as seed data? - User submissions from day one (UGC)? 5. **Data quality vs. quantity?** Fever/DICE has 100% quality (curated) but narrow scope. Eventbrite has massive scope but low quality. Where should HotNow start on this spectrum? ### Revenue Priority 6. **Consumer subscriptions vs. business placements — which is Priority A?** - Consumer-first: requires user acquisition → conversion to Pro/Concierge. Longer path to revenue. - Business-first: sell Featured Placement + Event Boost to venues immediately. Faster revenue, but need traffic to sell. - Hybrid: launch with free tier + business placements, add Pro/Concierge in month 2-3. 7. **Concierge tier ($19.99/mo) — what should it actually offer at launch?** Curated experiences require human or AI curation effort. Options: - AI-powered concierge chat (lower cost, always available) - Human-curated weekly picks (higher value, higher cost) - Hybrid: AI for instant answers, human for weekly curated lists ### Technical Choices 8. **Map provider — Leaflet (OpenStreetMap) free or splurge on Mapbox?** - Leaflet + OSM: free, no API keys, works offline. Less polished tiles. - Mapbox: beautiful tiles, better dark theme, 3D buildings. $0 for first 50K monthly loads, then ~$200+/mo at scale. - Recommendation: start with Leaflet, swap to Mapbox when revenue supports it. 9. **Hard constraints on tech stack?** You've already chosen FastAPI + SvelteKit + PostgreSQL. Any of these non-negotiable? Any you'd prefer to swap? 10. **Progressive Web App vs. native mobile?** PWA is the plan (no app store, instant updates, offline). When/if should we invest in native iOS/Android? Trigger points: 10K MAU? Revenue milestone? ### Timeline & Budget 11. **Phase 2 timeline expectations?** At $20-25 budget with premium models, I estimate Phase 2 takes about 8-12 hours of build time (subagent + human orchestration). Does that match your timeframe? 12. **MVP definition — what's the absolute minimum for "go live"?** - Must have: map, trending events, search, event detail, basic auth - Nice to have: AI recommendations, offline mode, Concierge chat, business dashboard - Your call on the cutoff for launch --- ## Appendix A: Existing Assets Snapshot | Asset | Path | Status | |-------|------|--------| | Landing page | `/var/www/hotnow/index.html` | ✅ Live (1342 lines, 38KB) | | Mockup | `/var/www/mockup/hotnow/index.html` | ✅ Complete (432 lines, 14KB) | | Project doc | `/root/projects/itpp-infrastructure/projects/hotnow.md` | ✅ Comprehensive (827 lines) | | Domain | `hotnow.io` | ✅ Registered at Cloudflare | | Server | Core (152.53.192.33), Netcup RS 2000 | ✅ Operational | | Super Search v2 | MCP on Core | ✅ 7 providers, all healthy | | Caddy | Reverse proxy on Core | ✅ Configured | | PostgreSQL 16 | On Core | ✅ Running | | Redis | On Core | ✅ Running | ## Appendix B: Key Market Signals - **Gen Z discovery:** 77% discover restaurants on social media (Eater/Vox 2025 survey) - **Beli growth:** 30M reviews in 2024 (surpassing Yelp's 21M) — demand for social-forward discovery - **Fever acquired DICE:** Consolidation in curated event space — leaves gap for comprehensive real-time - **Nextdoor AI pivot:** "LLM for every neighborhood" — validates AI + hyperlocal - **Corner's $3.75M raise:** VCs betting on map-first social discovery for Gen Z - **Yelp's AI transformation:** Incumbent feels threat from new discovery paradigms - **Eventbrite rebrand:** Moving from utility to cultural hub — validates shift toward experience economy