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:
@@ -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
|
||||
Reference in New Issue
Block a user