# Bot Portal Integration Design

Date: 2026-03-06

## Problem

The bot service (crates/bot/) runs as a standalone Axum server at irc.bot with its own
auth, templates, and web UI. This creates two problems:

1. **Route conflict**: bot-landing and bot compete for the irc.bot hostname. OCP rejects
   the bot route (HostAlreadyClaimed), making the bot service unreachable.

2. **Fragmented UX**: Users manage bouncers at my.irc.now but bots at irc.bot. The portal
   has no bot management at all.

## Walkthrough Findings

Issues found walking the live product as a new user:

- irc.bot "deploy a bot" CTA links to /signup (404)
- irc.bot "log in" nav links to /login (404)
- irc.bot footer links (/docs, /status, /marketplace, /faq, /cli) all 404
- Bot service route rejected (HostAlreadyClaimed)
- my.irc.now root / returns 404 (no redirect to /dashboard)
- Portal has no bot section: no nav item, no dashboard card, no pages

The user journey dead-ends at registration.

## Decision

Follow the irc.now pattern: irc.bot is a marketing landing page, bot management lives
in the my.irc.now portal alongside bouncers, billing, and profile.

Architecture: internal API. The bot service keeps its IRC runtime and Lua sandbox,
exposes internal REST endpoints. web-api adds bot pages that call the bot service.
Same pattern as txt/pics usage APIs.

## Bot Service Internal API

The bot crate drops its web UI (templates, auth guard, session middleware, static assets)
and becomes a headless service. Internal endpoints (ClusterIP only, no public Route):

```
GET    /api/bots?user_id={sub}          List user's bots
POST   /api/bots                        Create bot (JSON body with user_id)
GET    /api/bots/{id}                   Get bot detail
PUT    /api/bots/{id}                   Update bot config
DELETE /api/bots/{id}                   Delete bot (stops if running, cascading delete)
POST   /api/bots/{id}/start             Start bot
POST   /api/bots/{id}/stop              Stop bot

GET    /api/bots/{id}/scripts           List scripts
POST   /api/bots/{id}/scripts           Create script
GET    /api/bots/{id}/scripts/{sid}     Get script
PUT    /api/bots/{id}/scripts/{sid}     Update script
DELETE /api/bots/{id}/scripts/{sid}     Delete script

GET    /api/bots/{id}/logs              Recent logs (200 entries)
GET    /api/bots/{id}/logs/ws           WebSocket live log stream

GET    /api/bots/{id}/kv                List KV pairs
PUT    /api/bots/{id}/kv/{key}          Set KV pair
DELETE /api/bots/{id}/kv/{key}          Delete KV pair

GET    /api/usage/{sub}                 Per-user usage stats (bot count, enabled, running)
GET    /health                          Health check
GET    /metrics                         Prometheus metrics
```

No auth on internal API. web-api passes user_id, bot service enforces ownership on
all endpoints that reference a specific bot.

All responses are JSON. Create/update endpoints accept JSON bodies.

## Portal Pages (my.irc.now)

Navigation: add "bots" between "bouncers" and "billing" in the nav bar.

Dashboard: new "bots" card showing bot count + status summary, linking to /bots.

Routes:

```
GET  /bots                          List user's bots
GET  /bots/create                   Create bot form
POST /bots/create                   Submit creation
GET  /bots/{id}                     Bot detail (config, status, scripts, logs, KV)
POST /bots/{id}/update              Update config
POST /bots/{id}/delete              Delete bot
POST /bots/{id}/start               Start bot
POST /bots/{id}/stop                Stop bot
GET  /bots/{id}/scripts/create      New script form
POST /bots/{id}/scripts/create      Submit script
GET  /bots/{id}/scripts/{sid}       Edit script
POST /bots/{id}/scripts/{sid}/update   Update script
POST /bots/{id}/scripts/{sid}/delete   Delete script
GET  /bots/{id}/logs                Log viewer (historical + WebSocket)
GET  /bots/{id}/kv                  KV browser
POST /bots/{id}/kv/set              Set KV pair
POST /bots/{id}/kv/{key}/delete     Delete KV pair
```

Templates follow existing card-based layout with portal.css styles.
HTMX for status polling (same pattern as bouncer status fragment).
WebSocket for live log streaming (proxied through web-api or direct to bot service).

## Landing Page Fixes (irc.bot)

Fix broken links in bot-landing/index.html:

- "deploy a bot" / "start free" -> https://my.irc.now/bots/create
- "log in" -> https://my.irc.now/auth/login
- "+ new bot" (dashboard mock) -> https://my.irc.now/bots/create
- "go pro" -> https://my.irc.now/billing?plan=pro
- "go team" -> https://my.irc.now/billing?plan=team
- Footer docs/marketplace/faq/cli/status -> placeholder anchors or content pages

## Route Cleanup

- Delete the bot OCP Route (no longer needed, bot service is internal-only)
- Delete the bot WebService CR or update it to remove the host field
- Add GET / -> redirect to /dashboard on web-api
- Bot service keeps its ClusterIP Service (bot:8080) for internal access
- web-api gets BOT_INTERNAL_URL env var (like TXT_INTERNAL_URL, PICS_INTERNAL_URL)

## Environment

web-api Deployment gets:
```
BOT_INTERNAL_URL=http://bot.irc-josie-cloud.svc:8080
```

## Plan Limits

Carried over from existing bot service:
- Free: 1 bot, 1 network
- Pro: 5 bots, unlimited networks

Enforced by bot service on create endpoint (checks user's plan from request body).
