Files
root 538876ac16 docs: infrastructure gap assessment + project updates
- infrastructure-gap-assessment: full audit doc
- project-log: recent completions
- hotnow, hotnow-phase1, ops-portal-runcloud-design-brief, schoolcart PTA docs
- intelsight and schoolcart updates
2026-08-05 07:34:35 -04:00

986 lines
45 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 <access_token>
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