# CloseBot SMS — Definitive Build Plan

> Unified app: Twilio native SMS + CloseBot AI bots. One dashboard to rule them all.

---

## 1. TECH STACK

| Layer | Technology | Why |
|---|---|---|
| **Frontend** | Next.js 14 (App Router) + Tailwind CSS + shadcn/ui | Dark-mode-first, server components, fast |
| **Backend** | Next.js API routes (Edge-compatible) | Same deployment, zero CORS |
| **Database** | SQLite via better-sqlite3 (dev) → Turso/LibSQL (prod) | State tracking, conversation history, routing config |
| **Real-time** | Server-Sent Events (SSE) | Live conversation updates on dashboard |
| **SMS** | Twilio Node SDK (`twilio`) | Send/receive SMS, delivery status |
| **AI Bots** | CloseBot API (direct HTTP) | Webhook Source for inbound, API for bots/leads/metrics |
| **Auth** | NextAuth.js with credentials provider | Simple login, protect all routes |
| **Deploy** | Railway / Fly.io / Vercel | Needs persistent process for webhooks |

---

## 2. SYSTEM ARCHITECTURE

```
┌─────────────┐     ┌──────────────────────────┐     ┌─────────────┐
│   Customer   │────>│     Twilio (SMS)          │────>│  CloseBot   │
│   Phone      │<────│                          │<────│  SMS App    │
└─────────────┘     └──────────────────────────┘     └──────┬──────┘
                                                            │
                    ┌──────────────────────────┐            │
                    │   CloseBot API           │<───────────┘
                    │   (Webhook Source)        │────────────┐
                    └──────────────────────────┘            │
                                                            v
                                                    ┌──────────────┐
                                                    │   SQLite DB   │
                                                    │  (state/logs) │
                                                    └──────────────┘
```

**Message Flow — Inbound:**
1. Customer sends SMS to Twilio number
2. Twilio POSTs to `POST /api/webhooks/twilio/inbound`
3. App looks up routing: which Twilio number → which CloseBot bot/source
4. App sends inbound event to CloseBot via `POST /webhook/event/{sourceId}` with:
   - `type: "message"`
   - `contactId` (phone number as unique identifier)
   - `message` (SMS body)
   - `state` (JSON: `{ twilioNumber, phoneFrom, messageSid }`)
5. CloseBot processes through bot flow
6. CloseBot POSTs response to our webhook retrieval URL: `POST /api/webhooks/closebot/response`
7. App receives response, extracts `state` to get the Twilio number + customer phone
8. App sends SMS via Twilio API
9. App logs everything to SQLite + broadcasts via SSE for live dashboard

**Message Flow — Manual Override (from Conversations view):**
1. User types message in the conversation UI
2. App sends SMS directly via Twilio (bypassing CloseBot)
3. Logs to SQLite with `source: "manual"` flag

---

## 3. DATABASE SCHEMA

```sql
-- Routes: Twilio number → CloseBot bot mapping
CREATE TABLE routes (
  id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(8)))),
  twilio_number TEXT NOT NULL UNIQUE,
  twilio_number_sid TEXT,
  closebot_source_id TEXT NOT NULL,
  closebot_bot_id TEXT,
  bot_name TEXT,
  greeting_message TEXT,
  after_hours_reply TEXT,
  business_hours_json TEXT, -- {"mon": {"start": "09:00", "end": "17:00"}, ...}
  max_concurrent INTEGER DEFAULT 50,
  active BOOLEAN DEFAULT TRUE,
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
  updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
);

-- Contacts: phone numbers we've interacted with
CREATE TABLE contacts (
  id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(8)))),
  phone TEXT NOT NULL UNIQUE,
  name TEXT,
  email TEXT,
  status TEXT DEFAULT 'new', -- new, active, qualified, booked, closed, cold
  closebot_lead_id TEXT,
  assigned_bot_id TEXT,
  assigned_route_id TEXT REFERENCES routes(id),
  tags TEXT, -- JSON array
  fields_json TEXT, -- collected fields from CloseBot
  first_contact DATETIME DEFAULT CURRENT_TIMESTAMP,
  last_contact DATETIME DEFAULT CURRENT_TIMESTAMP,
  message_count INTEGER DEFAULT 0
);

-- Messages: every SMS in/out
CREATE TABLE messages (
  id TEXT PRIMARY KEY DEFAULT (lower(hex(randomblob(8)))),
  contact_id TEXT REFERENCES contacts(id),
  route_id TEXT REFERENCES routes(id),
  direction TEXT NOT NULL, -- 'inbound' | 'outbound'
  source TEXT NOT NULL, -- 'customer' | 'bot' | 'manual'
  body TEXT NOT NULL,
  twilio_sid TEXT,
  twilio_status TEXT, -- queued, sent, delivered, failed, undelivered
  closebot_message_id TEXT,
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);

-- Settings: app-wide config
CREATE TABLE settings (
  key TEXT PRIMARY KEY,
  value TEXT NOT NULL,
  updated_at DATETIME DEFAULT CURRENT_TIMESTAMP
);

-- Events: activity log for dashboard feed
CREATE TABLE events (
  id INTEGER PRIMARY KEY AUTOINCREMENT,
  type TEXT NOT NULL, -- 'message_in', 'message_out', 'booking', 'new_lead', 'status_change'
  contact_id TEXT REFERENCES contacts(id),
  route_id TEXT REFERENCES routes(id),
  data_json TEXT,
  created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
```

---

## 4. API ROUTES

### Webhook Endpoints (public, Twilio/CloseBot call these)
| Route | Method | Purpose |
|---|---|---|
| `/api/webhooks/twilio/inbound` | POST | Receive inbound SMS from Twilio |
| `/api/webhooks/twilio/status` | POST | Receive delivery status updates |
| `/api/webhooks/closebot/response` | POST | Receive CloseBot bot responses |

### Internal API (authenticated, frontend calls these)
| Route | Method | Purpose |
|---|---|---|
| `/api/dashboard/stats` | GET | Active convos, messages today, bookings, response rate |
| `/api/dashboard/activity` | GET | Recent activity feed (SSE endpoint) |
| `/api/conversations` | GET | List conversations with pagination/filters |
| `/api/conversations/[contactId]` | GET | Get single conversation with messages |
| `/api/conversations/[contactId]/send` | POST | Send manual SMS message |
| `/api/bots` | GET | List CloseBot bots (proxied from CloseBot API) |
| `/api/bots/[id]` | GET | Get bot details + metrics |
| `/api/contacts` | GET | List/search contacts with filters |
| `/api/contacts/[id]` | GET/PUT/DELETE | Contact CRUD |
| `/api/contacts/export` | GET | Export CSV |
| `/api/analytics/overview` | GET | Summary metrics with date range |
| `/api/analytics/messages` | GET | Message volume time series |
| `/api/analytics/bots` | GET | Per-bot conversation counts |
| `/api/analytics/outcomes` | GET | Outcome distribution |
| `/api/analytics/leaderboard` | GET | Top performing bots |
| `/api/routes` | GET/POST | List routes, create new route |
| `/api/routes/[id]` | GET/PUT/DELETE | Route CRUD |
| `/api/settings` | GET/PUT | App settings (Twilio creds, CloseBot key) |
| `/api/settings/test-connection` | POST | Test Twilio + CloseBot connections |

---

## 5. PAGE-BY-PAGE UI SPEC

### 5A. DASHBOARD (`/`)
**Matches mockup: closebot-sms-dashboard.png**

**Layout:**
- Left sidebar (240px): Logo "CloseBot SMS" + 6 nav items with icons
- Top bar: Global search input
- Main content area

**Components:**
1. **Stat Cards Row** — 4 cards in a grid
   - Active Conversations (chat bubble icon, count from DB)
   - Messages Today (envelope icon, count from DB where date = today)
   - Bookings Made (calendar icon, from CloseBot metrics API)
   - Response Rate (trending icon, calculated: bot_responses / inbound_messages * 100)
   - Each card: dark glass-morphism background (`bg-slate-800/50 backdrop-blur`), cyan border glow, icon top-left, label + big number

2. **Real-time Activity Table**
   - Columns: SMS (phone number), Bot Name, Badges (status pill), Timestamp
   - Status pills: `active` (green), `pending` (yellow), `closed` (gray)
   - Auto-updates via SSE — new rows slide in at top
   - Click row → navigate to conversation

**Data sources:**
- Stats: `GET /api/dashboard/stats` → queries SQLite counts
- Activity: `GET /api/dashboard/activity` → SSE stream from events table

---

### 5B. CONVERSATIONS (`/conversations`)
**Matches mockup: closebot-sms-conversations.png**

**Layout:** Two-panel split (left 380px list, right flexible chat)

**Left Panel — Conversation List:**
- Search bar with filter icon + settings icon
- "All Filters" dropdown (by status, bot, date range)
- Conversation rows: avatar (generated from initials), name, phone, last message preview (truncated), timestamp, unread badge (cyan circle with count)
- Selected conversation highlighted with left cyan border
- Sorted by most recent message

**Right Panel — Chat Thread:**
- Header: avatar, name, phone number, "CloseBot SMS AI" badge, status dot + "Active" label
- Message bubbles:
  - Inbound (customer): dark gray background (`bg-slate-700`), left-aligned with avatar
  - Outbound (bot): cyan/blue gradient background, right-aligned
  - Each bubble shows text, no timestamps on individual messages (clean look)
- Bottom: text input "Type a message..." with cyan send button
  - Sending from here = manual override, bypasses CloseBot

**Data sources:**
- List: `GET /api/conversations?search=&status=&bot=&page=`
- Messages: `GET /api/conversations/[contactId]`
- Send: `POST /api/conversations/[contactId]/send`
- Live updates: SSE for new messages appended to thread

---

### 5C. BOTS (`/bots`)
**Matches mockup: closebot-sms-bots.png**

**Layout:** Grid of bot cards (3 columns on desktop)

**Top Bar:**
- "Bot Management" heading
- Search bots input + filter icon + sort icon
- "+ Create New Bot" button (cyan, calls CloseBot create_bot_with_ai)

**Bot Cards:**
- Card header: bot name in bold, gradient top border (different colors per bot)
- Fields: Status toggle (Active/Inactive), Twilio # (from route mapping), Messages count, Conversion % (from CloseBot metrics), Last Active
- Inactive bots appear dimmed/grayed
- Click expand chevron → expanded card shows:
  - Connected Sources list
  - Recent Performance sparkline (mini chart, last 7 days)
  - "Edit Flow" button (opens CloseBot dashboard in new tab)

**Data sources:**
- Bots list: `GET /api/bots` → proxies CloseBot `GET /bot` + merges route data from SQLite
- Metrics: CloseBot `GET /botMetric/agencySummary`
- Toggle active: `PUT /api/routes/[id]` to enable/disable route

---

### 5D. CONTACTS (`/contacts`)
**Matches mockup: closebot-sms-contacts.png**

**Layout:** Full-width data table with optional slide-out detail panel

**Top Bar:**
- Search input
- Filter dropdowns: "Filter by Status" (hot/warm/cold/new), "Filter by Bot", date range picker
- "Import Contacts" button (cyan outline) + "Export CSV" button (cyan outline)

**Table Columns:**
- Name (bold)
- Phone Number
- Assigned Bot
- Status (colored dot: red=Hot Lead, orange=Warm, gray=Cold + text label)
- Messages Exchanged (number)
- Last Contact (relative time: "2 hours ago", "Yesterday")
- Tags (colored pills)

**Slide-out Detail Panel (on row click):**
- Contact name (large, bold)
- Phone, Email, Company fields
- "Conversation Summary" section — AI-generated from CloseBot
  - Bullet points: "Product Interest", "Budget Discussion", etc.
- "Field Values Collected" — mini table of CloseBot-collected fields (Company Size, Industry, Priority)
- Action buttons: "View Full History" + "Send Message" (cyan)

**Data sources:**
- Table: `GET /api/contacts?search=&status=&bot=&dateFrom=&dateTo=&page=&limit=`
- Detail: `GET /api/contacts/[id]`
- Export: `GET /api/contacts/export` → CSV download
- Import: `POST /api/contacts/import` (CSV upload, creates contacts + optionally sends first message)

---

### 5E. ANALYTICS (`/analytics`)
**Matches mockup: closebot-sms-analytics.png**

**Layout:** Scrollable dashboard with multiple chart sections

**Top Bar:**
- "Analytics" heading
- Tab navigation: Dashboard, Conversations, Bots, Contacts, Settings
- Date range picker dropdown (top right): "Last 30 Days (Oct 1 - Oct 30, 2024)"

**Section 1 — Stat Cards (4 across):**
- Total Conversations (large number + sparkline + % change vs last period)
- Booking Rate (percentage + sparkline + change)
- Avg Response Time (duration format "1m 45s" + sparkline + change)
- Customer Satisfaction (rating "4.8/5" + sparkline + change)
- Each card has colored gradient background (red→pink, green, blue, purple)

**Section 2 — Messages Over Time (full width):**
- Line chart with dual lines: Inbound (blue) vs Outbound (green)
- X-axis: dates over selected range
- Y-axis: message count
- Tooltip on hover showing exact values
- Chart library: Recharts (React-native, works with Next.js)

**Section 3 — Two charts side by side:**
- Left: "Conversations by Bot" — horizontal bar chart with colored bars per bot
- Right: "Outcome Distribution" — donut chart with segments (Booked 40%, Qualified 30%, Dropped 18%, Pending 12%), total in center

**Section 4 — Top Performing Bots:**
- Mini leaderboard table: Rank, Bot Name (with icon), Conversations, Booking Rate, CSAT Score
- Sorted by booking rate descending

**Data sources:**
- Stats: `GET /api/analytics/overview?start=&end=`
- Messages chart: `GET /api/analytics/messages?start=&end=&resolution=daily`
- By bot: `GET /api/analytics/bots?start=&end=`
- Outcomes: `GET /api/analytics/outcomes?start=&end=`
- Leaderboard: `GET /api/analytics/leaderboard?start=&end=`
- All backed by SQLite queries (message counts, conversation outcomes) + CloseBot metrics API for bookings/CSAT

---

### 5F. ROUTING (`/routing`)
**Matches mockup: closebot-sms-routing.png**

**Layout:** Three-column visual routing display

**Top Bar:**
- Breadcrumb: "Routing / Phone Number Routing"
- Top nav tabs: Dashboard, Routing, Bots, Analytics, Settings
- "+ Add New Route" button (top right)
- Search bar + filter icon

**Three Columns:**
- **Left: Twilio Phone Numbers** — list of phone number cards with phone icon
- **Center: Routing** — animated connection lines (CSS/SVG) linking numbers to bots
- **Right: CloseBot Bots & Sources** — bot cards with: name, source badge (WEB_LEAD, EMAIL_INQUIRY, etc.), Active/Paused toggle, message count badge, "Configure" button

**Expanded Route Configuration (on Configure click):**
- Modal/drawer overlaying the route:
  - Greeting Message Override (textarea, optional)
  - After-Hours Auto-Reply Text (textarea)
  - Business Hours Schedule — day-of-week toggle grid (Mon-Sun), time range "Mon-Fri: 9:00 AM - 5:00 PM", "Add Exception" link
  - Max Concurrent Conversations — slider (1-100) with current value displayed
  - Save + Close Configuration buttons

**Data sources:**
- Routes: `GET /api/routes` → SQLite routes table
- Twilio numbers: fetched from Twilio API on settings save, cached
- Bots: `GET /api/bots` → CloseBot API
- Update: `PUT /api/routes/[id]` with config JSON

---

### 5G. SETTINGS (`/settings`)
**Matches mockup: closebot-sms-settings.png**

**Layout:** Two-column card layout

**Cards:**
1. **Twilio Connection** — Account SID input (masked), Auth Token input (masked), "Connection Status" indicator (green dot + "Connected")
2. **CloseBot Connection** — API Key input (masked), Webhook Source ID (display), "Connection Status" indicator
3. **Phone Numbers** — list of Twilio numbers with assigned bot + toggle switch
4. **Notifications** — toggles: Email Alerts, SMS Delivery Failures, New Lead Alerts
5. **Webhook URLs** — read-only display of:
   - Inbound URL (the URL you give to Twilio)
   - Response URL (the URL you give to CloseBot Webhook Source)
   - Copy buttons next to each

**Data sources:**
- Settings: `GET/PUT /api/settings`
- Test: `POST /api/settings/test-connection` → pings both APIs

---

## 6. FILE STRUCTURE

```
closebot-sms/
├── package.json
├── next.config.js
├── tailwind.config.ts
├── tsconfig.json
├── .env.local.example
├── BUILD_PLAN.md
├── README.md
├── prisma/ (or drizzle/)
│   └── schema.sql
├── src/
│   ├── app/
│   │   ├── layout.tsx              # Root layout with sidebar
│   │   ├── page.tsx                # Dashboard
│   │   ├── conversations/
│   │   │   └── page.tsx            # Conversations split view
│   │   ├── bots/
│   │   │   └── page.tsx            # Bot grid
│   │   ├── contacts/
│   │   │   └── page.tsx            # Contacts table
│   │   ├── analytics/
│   │   │   └── page.tsx            # Analytics dashboard
│   │   ├── routing/
│   │   │   └── page.tsx            # Phone number routing
│   │   ├── settings/
│   │   │   └── page.tsx            # Settings/config
│   │   └── api/
│   │       ├── webhooks/
│   │       │   ├── twilio/
│   │       │   │   ├── inbound/route.ts
│   │       │   │   └── status/route.ts
│   │       │   └── closebot/
│   │       │       └── response/route.ts
│   │       ├── dashboard/
│   │       │   ├── stats/route.ts
│   │       │   └── activity/route.ts  # SSE
│   │       ├── conversations/
│   │       │   ├── route.ts
│   │       │   └── [contactId]/
│   │       │       ├── route.ts
│   │       │       └── send/route.ts
│   │       ├── bots/
│   │       │   ├── route.ts
│   │       │   └── [id]/route.ts
│   │       ├── contacts/
│   │       │   ├── route.ts
│   │       │   ├── export/route.ts
│   │       │   └── [id]/route.ts
│   │       ├── analytics/
│   │       │   ├── overview/route.ts
│   │       │   ├── messages/route.ts
│   │       │   ├── bots/route.ts
│   │       │   ├── outcomes/route.ts
│   │       │   └── leaderboard/route.ts
│   │       ├── routes/
│   │       │   ├── route.ts
│   │       │   └── [id]/route.ts
│   │       └── settings/
│   │           ├── route.ts
│   │           └── test-connection/route.ts
│   ├── components/
│   │   ├── layout/
│   │   │   ├── sidebar.tsx
│   │   │   ├── topbar.tsx
│   │   │   └── nav-item.tsx
│   │   ├── dashboard/
│   │   │   ├── stat-card.tsx
│   │   │   └── activity-feed.tsx
│   │   ├── conversations/
│   │   │   ├── conversation-list.tsx
│   │   │   ├── conversation-item.tsx
│   │   │   ├── chat-thread.tsx
│   │   │   ├── message-bubble.tsx
│   │   │   └── chat-input.tsx
│   │   ├── bots/
│   │   │   ├── bot-grid.tsx
│   │   │   └── bot-card.tsx
│   │   ├── contacts/
│   │   │   ├── contacts-table.tsx
│   │   │   ├── contact-detail-panel.tsx
│   │   │   └── contact-filters.tsx
│   │   ├── analytics/
│   │   │   ├── stat-card-sparkline.tsx
│   │   │   ├── messages-chart.tsx
│   │   │   ├── bots-bar-chart.tsx
│   │   │   ├── outcome-donut.tsx
│   │   │   └── bot-leaderboard.tsx
│   │   ├── routing/
│   │   │   ├── routing-view.tsx
│   │   │   ├── phone-number-card.tsx
│   │   │   ├── bot-route-card.tsx
│   │   │   ├── connection-lines.tsx  # SVG animated lines
│   │   │   └── route-config-modal.tsx
│   │   └── settings/
│   │       ├── twilio-card.tsx
│   │       ├── closebot-card.tsx
│   │       ├── phone-numbers-card.tsx
│   │       ├── notifications-card.tsx
│   │       └── webhook-urls-card.tsx
│   ├── lib/
│   │   ├── db.ts                  # SQLite connection + queries
│   │   ├── twilio.ts              # Twilio client wrapper
│   │   ├── closebot.ts            # CloseBot API client (reuse from MCP server)
│   │   ├── sse.ts                 # SSE broadcast utility
│   │   └── utils.ts               # Formatters, helpers
│   └── styles/
│       └── globals.css            # Tailwind base + custom dark theme
```

---

## 7. DESIGN SYSTEM

**Colors (from mockups):**
```css
--bg-primary: #0f1729;       /* deepest navy */
--bg-secondary: #1a2332;     /* card backgrounds */
--bg-tertiary: #1e293b;      /* elevated surfaces */
--bg-hover: #2d3748;         /* table row hover */
--text-primary: #e2e8f0;     /* main text */
--text-secondary: #94a3b8;   /* muted text */
--text-muted: #64748b;       /* timestamps, labels */
--accent-cyan: #22d3ee;      /* primary accent */
--accent-blue: #3b82f6;      /* secondary accent */
--accent-green: #22c55e;     /* success, active */
--accent-yellow: #eab308;    /* warning, pending */
--accent-red: #ef4444;       /* error, hot lead */
--accent-orange: #f97316;    /* warm */
--accent-purple: #a855f7;    /* bot cards */
--border: #334155;           /* subtle borders */
--border-glow: rgba(34, 211, 238, 0.2); /* cyan card glow */
```

**Typography:**
- Font: `Inter` (system-ui fallback)
- Headings: 600-700 weight
- Body: 400 weight
- Monospace numbers: `font-variant-numeric: tabular-nums`

**Card Style:**
```css
.card {
  background: rgba(30, 41, 59, 0.5);
  backdrop-filter: blur(12px);
  border: 1px solid rgba(51, 65, 85, 0.5);
  border-radius: 12px;
  box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.3);
}
```

**Status Badges:**
- Active: `bg-green-500/20 text-green-400 border-green-500/30`
- Pending: `bg-yellow-500/20 text-yellow-400 border-yellow-500/30`
- Closed: `bg-gray-500/20 text-gray-400 border-gray-500/30`

---

## 8. BUILD PHASES

### Phase 1 — Foundation (Day 1)
- [ ] Next.js project scaffold with Tailwind + shadcn/ui
- [ ] SQLite schema + db.ts with all queries
- [ ] Global layout with sidebar navigation (matches dashboard mockup)
- [ ] Dark theme CSS variables
- [ ] Environment config (.env.local)
- [ ] Twilio client wrapper
- [ ] CloseBot API client (port from closebot-mcp)

### Phase 2 — Core Webhook Bridge (Day 1-2)
- [ ] `POST /api/webhooks/twilio/inbound` — receive SMS, forward to CloseBot
- [ ] `POST /api/webhooks/closebot/response` — receive bot reply, send via Twilio
- [ ] `POST /api/webhooks/twilio/status` — delivery status updates
- [ ] Contact auto-creation on first inbound
- [ ] Message logging to SQLite
- [ ] Route lookup logic (Twilio number → CloseBot source)
- [ ] Business hours check + after-hours auto-reply
- [ ] State passthrough (phone + route info in CloseBot state field)

### Phase 3 — Dashboard + Real-time (Day 2)
- [ ] Dashboard page with 4 stat cards
- [ ] Real-time activity feed (SSE)
- [ ] Activity table with status badges
- [ ] Auto-refresh stats

### Phase 4 — Conversations (Day 2-3)
- [ ] Conversation list with search/filter
- [ ] Chat thread with message bubbles
- [ ] Manual message send
- [ ] Unread badges
- [ ] Live message updates via SSE

### Phase 5 — Bots + Contacts (Day 3)
- [ ] Bot grid with cards from CloseBot API
- [ ] Bot status toggle (enable/disable route)
- [ ] Contacts table with all filters
- [ ] Slide-out detail panel
- [ ] CSV export

### Phase 6 — Analytics (Day 3-4)
- [ ] Stat cards with sparklines
- [ ] Messages over time chart (Recharts)
- [ ] Conversations by bot bar chart
- [ ] Outcome distribution donut chart
- [ ] Bot leaderboard table
- [ ] Date range picker

### Phase 7 — Routing + Settings (Day 4)
- [ ] Phone number routing view with visual connections
- [ ] Route config modal (business hours, greeting, max concurrent)
- [ ] Settings page with credential cards
- [ ] Connection testing
- [ ] Webhook URL display with copy

### Phase 8 — Polish (Day 4-5)
- [ ] Loading states + skeletons
- [ ] Error handling + toast notifications
- [ ] Mobile responsive adjustments
- [ ] Auth gate (simple login)
- [ ] README with deploy instructions

---

## 9. EXTERNAL DEPENDENCIES

### npm packages:
```json
{
  "dependencies": {
    "next": "^14.2",
    "react": "^18.3",
    "twilio": "^5.0",
    "better-sqlite3": "^11.0",
    "recharts": "^2.12",
    "lucide-react": "^0.400",
    "@radix-ui/react-dialog": "^1.0",
    "@radix-ui/react-dropdown-menu": "^2.0",
    "@radix-ui/react-toggle": "^1.0",
    "@radix-ui/react-slider": "^1.0",
    "class-variance-authority": "^0.7",
    "clsx": "^2.1",
    "tailwind-merge": "^2.3",
    "next-auth": "^4.24"
  }
}
```

### Environment Variables:
```env
# Twilio
TWILIO_ACCOUNT_SID=ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
TWILIO_AUTH_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

# CloseBot
CLOSEBOT_API_KEY=cb_xxxxxxxxxxxxxxxx

# App
NEXTAUTH_SECRET=random-secret-here
NEXTAUTH_URL=https://your-domain.com
APP_URL=https://your-domain.com  # Used to construct webhook URLs

# Database
DATABASE_PATH=./data/closebot-sms.db
```

---

## 10. WHAT MAKES THIS DIFFERENT

1. **No GHL required** — CloseBot's Webhook Source is the channel, Twilio is the pipe
2. **Multi-tenant ready** — one app, many Twilio numbers, many bots
3. **Human takeover** — click into any convo and type a manual reply
4. **Business hours built-in** — auto-reply after hours, resume bot in morning
5. **Full audit trail** — every message logged with direction, source, status
6. **Real-time everything** — SSE for live dashboard, no polling
7. **CloseBot metrics integrated** — booking rates, leaderboards, CSAT from their API
8. **$0.0079/SMS** — Twilio pricing, no GHL middleman markup

---

*Plan version: 1.0 | Last updated: 2026-02-06*
