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
This commit is contained in:
root
2026-08-05 07:34:35 -04:00
parent 7f31eb0f98
commit 538876ac16
9 changed files with 3910 additions and 4 deletions
+985
View File
@@ -0,0 +1,985 @@
# 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