# irc.now Platform Roadmap

High-level vision and phase overview. Detailed implementation plans are written
per-phase as work begins.

## Vision

irc.now is a hosted IRC services platform. Sign up, get a bouncer. Upgrade to
pro, get a dedicated bouncer with a custom hostname. Host your own IRC network.
Run bots with Lua scripts. Share images and pastes. Everything connected
through one account with SSO.

## Phases

### Phase 1: Foundation

Get the core platform running: users can sign up, create a bouncer, and pay.

| Item | Description | Status |
|------|-------------|--------|
| Rust workspace | Monorepo with shared `common` crate | done |
| GitOps manifests | CNPG clusters, namespace, RBAC, secrets | done |
| Keycloak | Dedicated instance at `auth.irc.now`, `irc-now` realm, OIDC clients | done |
| soju-operator | Existing 14-task plan, manages SojuBouncer CRDs | done |
| Account portal | `my.irc.now` -- Axum, OIDC auth, bouncer CRUD, Stripe billing | done |
| Landing page | `irc.now` -- deploy existing static site, link to portal | done |

**Detailed plan:** `docs/plans/2026-03-03-irc-now-phase1-plan.md`

---

### Phase 1.5: Fill the Gaps

Phase 1 code is deployed but most handlers are stubs. This phase makes
everything the landing page promises actually work.

| Item | Description | Status |
|------|-------------|--------|
| Auth guard | `FromRequestParts` extractor, redirect to login if unauthenticated | done |
| Users table | DB table + upsert on OIDC callback, plan/stripe_customer_id in session | done |
| Dashboard/bouncers | Wire to kube API, real plan from session, bouncer CRUD via SojuBouncer CRs | done |
| Stripe checkout | Checkout session, billing page, customer portal, webhook handler | done |
| Content pages | docs, clients, faq, what-is-irc static pages, extract CSS | done |
| Profile page | Display name, email (synced to Keycloak), content expiry settings for pro users | done |
| Favicons/OG images | apple-touch-icon, favicon.ico, favicon.svg, og.png across all services | done |
| status.irc.now | Upptime on GitHub Pages, monitors all endpoints | planned |
| Decommission ZNC | Remove znc.josie.lol deployment and DNS | planned |

**Detailed plan:** `docs/plans/2026-03-04-irc-now-phase1.5-plan.md`

---

### Phase 2: Observability

Instrument everything before deploying more services. If it's not monitored,
it's not production.

| Item | Description | Status |
|------|-------------|--------|
| Prometheus | OCP user workload monitoring, ServiceMonitors for all services | done |
| Grafana | `stats.irc.now` -- grafana-operator, Keycloak SSO, admin/viewer roles, design system palette | done |
| Metrics endpoints | `/metrics` on web-api, txt, pics, bot (metrics + metrics-exporter-prometheus crates) | done |
| Alertmanager | Alert rules: service down, HTTP error rate, high latency (web-api, txt, pics, bot) | done |
| Alert delivery | Email to ops@irc.now via SMTP. IRC ops channel via bot webhook relay planned | done |

**Key metrics:**
- Axum: request rate, latency p50/p95/p99, error rate per route
- Operators: reconciliation loop duration, queue depth, error count
- CNPG: connection pool usage, replication lag, storage usage
- Keycloak: login success/failure rate, active sessions

---

### Phase 3: Supporting Services

The tools that make the platform useful beyond just a bouncer.

| Item | Description | Status |
|------|-------------|--------|
| chat.irc.now | Gamja web client, OAuth2 SSO via Keycloak, WebSocket to soju | done |
| txt.irc.now | Pastebin -- PostgreSQL, nanoid IDs, syntax highlighting. Free: 5 pastes, 24h expiry. Pro: 90d expiry (opt-out to unlimited) | done |
| irc.pics | Image host -- S3 (MinIO), WebP thumbnails. Free: 50MB, 90d expiry. Pro: 1GB, 90d expiry (opt-out to unlimited) | done |
| Content expiry | Pro users default to 90-day expiry, opt-out via profile settings. Plan/content_expires synced to Keycloak claims for txt/pics | done |
| OIDC plan detection | txt/pics decode JWT custom claims for plan + content_expires (previously hardcoded None) | done |
| Log search | Full-text search across scrollback history. Add-on: $2/mo | planned |

**Dependencies:** Phase 1 (auth, DB infrastructure) must be complete. Phase 2
(monitoring) should be in place so new services are instrumented from day one.

---

### Phase 4: Network Hosting

Let users run their own IRC networks. Starter: $12/mo (50 users, 1 server, 3 bots).
Growth: $24/mo (200 users, 3 servers, 10 bots).

| Item | Description | Status |
|------|-------------|--------|
| ergo-operator | kube.rs operator managing ErgoNetwork CRDs, OAuth2, IP cloaking | done |
| ErgoNetwork CRD | Reconciles into Deployment, ConfigMap, Service, Route, Certificate | done |
| net.irc.now | First ErgoNetwork instance, upstream auto-configured via bouncer watcher (SASL PLAIN) | done |
| IRCCloud migration | `/migrate` flow: import servers + channels from IRCCloud into soju | done |
| Portal integration | Network management tab in account portal | planned |
| DNS | Wildcard `*.irc.now` or per-tenant subdomain creation | planned |

**Architecture note:** ergo is MIT licensed, so if you need to patch it for
multi-tenant features (custom MOTD, connection limits, telemetry hooks) there
are no license constraints.

---

### Phase 5: Analytics

Understand how the platform is used. Inform product decisions.

| Item | Description | Status |
|------|-------------|--------|
| Events table | Append-only `events` table in accounts-db (signup, login, bouncer_create/delete, plan_upgrade/downgrade) | done |
| Event recording | Inline recording at auth callback, bouncer CRUD, billing webhook | done |
| Business metrics | Prometheus gauges: users, signups, conversion rate, churn rate, active users (soju-based) | done |
| Stripe MRR | Background task queries Stripe API for MRR, active subscriptions (test key deployed) | done |
| Per-user stats | Dashboard shows networks, channels, messages, uptime, paste/pic storage via internal APIs | done |
| Grafana dashboards | Admin + public dashboards, design system colors, feature stripping, dark theme | done |
| Internal usage APIs | txt + pics expose `/api/usage/{sub}` for cross-service stats | done |
| Retention cohorts | Monthly signup cohorts with % still active | planned |
| Onboarding funnel | signup -> bouncer create -> first message -> first week active | planned |
| Feature adoption | % pro users with content_expires=false, % migrated from irccloud | planned |

**Design:** `docs/plans/2026-03-06-phase5-metrics-design.md`
**Plan:** `docs/plans/2026-03-06-phase5-metrics-plan.md`

**Privacy note:** Analytics are first-party only. No third-party tracking.
Aggregate metrics in Grafana, per-user stats visible only to the user and ops.

---

### Phase 6: Bots

Managed IRC bot runtime. The differentiating feature. Standalone: $2/mo per bot.
Network hosting plans include bot quotas.

| Item | Description | Status |
|------|-------------|--------|
| Bot runner | Rust service, manages bot instances in-process, one mlua (Lua 5.4) VM per bot | done |
| IRC connectivity | Bots connect through user's soju bouncer to any network | done |
| Built-in modules | Moderation (anti-spam, flood, pattern ban), utility (URL titles, !seen, stats), feeds (RSS, webhook relay, reminders) | planned |
| Lua sandbox | Event-driven API: on_message/on_join/etc, IRC commands, KV store, timers, rate-limited http_get | done |
| Portal UI | Bot CRUD, module toggles, Lua script editor (Monaco/CodeMirror), live log viewer (WebSocket), KV browser | planned |

**Runtime model:** All bots run in a single Deployment, multiplexed on async
IRC connections via tokio. Scales horizontally by sharding users across
replicas. No per-bot CRD -- configs live in the database. This keeps it simple
and avoids operator overhead for application-level multiplexing.

**Sandbox boundaries:** No `os`, `io`, `require`, `loadfile`. Scripts can only
call the IRC API and KV store. `http_get` is allowlisted and rate-limited. Each
Lua VM has a memory ceiling and instruction count limit.

---

## Cross-Cutting Concerns

### Auth
All services authenticate via Keycloak OIDC. The `common` crate provides Axum
middleware that validates tokens and extracts `UserClaims` (sub, email, plan,
stripe_customer_id). Gamja authenticates through a proxy that resolves the
user's bouncer endpoint.

### Design System
All user-facing HTML uses the irc.now design system: Newsreader/Outfit/JetBrains
Mono fonts, green-on-dark palette, IRC-native component patterns. Shared via
static CSS files from `design/tokens/` and `design/components/`.

### Deployment
Everything runs on OCP. Container images built via `oc builds` (multi-stage
Rust builds to UBI9-minimal). OCP Routes handle TLS termination per subdomain.
cert-manager issues certificates via LetsEncrypt. CNPG manages PostgreSQL.
platform-operator manages WebService/ChatService/MinioInstance CRDs -- all
platform services are declared as CRs in `deploy/instances/`.

### Database Strategy
Single CNPG cluster. Separate databases per service (keycloak, accounts, paste,
pics). Per-tenant databases for operators (soju_*, ergo_*). Operators hold
master credentials and create scoped roles per tenant.
