Web Platform
Summary
Telemy’s web platform is a static-plus-functions site hosted on Cloudflare Pages at telemyapp.com, backed by a Go control plane API at api.telemyapp.com. The platform evolved through three landing page iterations (v0 under-construction placeholder on 2026-02-28, v1 generic SaaS template on 2026-02-28, v2 compact warm-toned redesign on 2026-03-01) before the current W1 design (2026-03-23) which replaced all prior work with a single-page site featuring the real dock UI running on simulated data as the interactive hero element. Beta signups are stored in Cloudflare KV. The landing page was initially gated behind an operator login wall with plans to go public once ready.
The platform expanded in W2 (2026-03-24/25) with a Preact SPA dashboard at /dashboard containing Account, Linked Accounts, and Plan & Usage pages, using hash-based client-side routing and a BFF proxy pattern through Cloudflare Pages Functions to the Go API. An admin portal followed on 2026-03-29 at /admin for user lookup and account management, incorporating 18 security audit findings (3 CRIT, 5 HIGH, 6 MED, 5 LOW, 4 INFO). The signup/registration flow was designed on 2026-04-01 to wire end-to-end email verification using Resend (Go SDK, free tier 3K emails/month) with auto-login on verification and password reset delivery.
The tech stack is intentionally lightweight: no framework for the landing page (static HTML/CSS/JS), Preact (~3KB) for dashboard and admin SPAs, esbuild for bundling, and Cloudflare Pages Functions for server-side logic. Three Preact apps share the same build pipeline, theme system (telemy-theme localStorage key with system/dark/light modes), and CSS token vocabulary. The Go backend provides the auth, billing, and admin APIs with chi router, pgx for PostgreSQL, and bcrypt for password hashing.
Timeline
- 2026-02-28: Initial web plan approved — Cloudflare Pages for landing, Stripe for payments, Vercel for webhooks (later abandoned), Resend for email. Domain
telemyapp.comalready on Cloudflare DNS. - 2026-02-28: Landing page v0 design approved — static dark theme with interactive dock mockup as hero, Oxanium + Inter fonts, blue accent (#2d7aed), CSS noise texture, split hero layout, 2x2 feature cards, dual pricing columns.
- 2026-02-28: Implementation plan written for v0 — 11 tasks covering HTML, CSS, dock mockup, animations, pricing cards, FAQ accordion.
- 2026-03-01: Landing page v2 redesign approved — warm orange accent (#f97316), Space Grotesk headings, light/dark/system theme toggle, compact layout (~2.5 viewport heights), text-only feature list replacing cards, inline pricing strip replacing columns, 3-item mini FAQ. Removed noise textures, glow gradients, staggered scroll reveals.
- 2026-03-01: v2 implementation plan written — 10 tasks: HTML rewrite, CSS token foundation, nav/theme toggle, hero layout, dock CSS carry-over, features list, pricing strip, footer, JS rewrite, responsive polish.
- 2026-03-23: W1 landing page design approved — pivoted from CSS dock mockup to embedding the real dock React components via
useSimulatedState(). Added beta signup form (email-only, KV-backed). Auth wall via operator session cookie. Removed pricing, features cards, FAQ, and all marketing sections. - 2026-03-23: W1 implementation plan written — 7 tasks: auth middleware, dock demo esbuild bundle entry point, landing page HTML, landing page CSS, beta signup API (KV), deploy/verify, visual polish.
- 2026-03-24: W2 dashboard design approved — Preact SPA at
/dashboardwith 5 planned pages (Account, Linked Accounts, Plan & Usage shipped in W2; Billing deferred to W2b after LemonSqueezy; Remote Control as W2c stretch goal). JetBrains Mono + DM Sans typography, dark/light/system theme, OAuth popup linking flow. - 2026-03-25: W2 dashboard implementation plan written — 13 tasks across 5 phases: backend endpoints (profile update, password change, OAuth popup callback), dashboard shell (HTML, CSS, Preact app with router/nav/sidebar/theme), dashboard pages (account, linked, plan), landing page update + polish, backend deploy to Advin server.
- 2026-03-29: Admin portal design approved — internal portal at
/adminfor user lookup, support triage, account management. Security audit incorporated 18 findings. Database migration 0027 addsis_admincolumn +admin_audit_logtable. Admin middleware with 30-second in-memory cache. All mutating endpoints require password re-authentication. - 2026-03-29: Admin portal implementation plan written — tasks include CRIT-01 fix (JWT
subclaim was never set, breakingtelemy_uidcookie binding for all users), migration 0027, admin store methods, Go middleware + rate limiting, admin API handlers, BFF defense-in-depth, Preact admin SPA with search + user detail pages. - 2026-04-01: Signup registration flow design approved — end-to-end signup wiring: register, Resend verification email, auto-login on verification, password reset email. New
internal/email/Go package with Resend SDK. New CF pages/verify-emailand/reset-password. NewPOST /api/v1/auth/resend-verificationendpoint (rate-limited 3/hr per IP). - 2026-04-01: Signup registration flow implementation plan written — tasks: add Resend Go SDK dependency, config vars, email service package with HTML+plain text templates, handler integration, verify-email auto-login, CF pages for verify-email + reset-password.
Current State
The platform has design + implementation plans approved for four major features: landing page (W1), dashboard (W2), admin portal, and signup/registration flow. The infrastructure is live on Cloudflare Pages (telemyapp.pages.dev / telemyapp.com) with DNS configured (CNAME @ and www to telemyapp.pages.dev).
Landing page: Serves the real dock React components bundled via esbuild (dock-demo-bundle.js, ~260-300KB). Beta signup stores emails in Cloudflare KV (BETA_SIGNUPS namespace). Auth wall controlled by _middleware.js checking telemy_operator_session cookie.
Dashboard: Preact SPA at /dashboard with hash routing (#account, #linked, #plan). Auth gate via Pages Function checks JWT session. Two new Go API endpoints: PATCH /api/v1/auth/profile (display name) and POST /api/v1/auth/change-password. OAuth popup flow for linking Twitch/YouTube/Discord accounts. Plan & Usage page is read-only from existing session API entitlement/usage data.
Admin portal: At /admin, gated by is_admin DB column + Go middleware + BFF proxy defense-in-depth. User search (min 3 chars, cursor-paginated, max 25/page), user detail with 8 collapsible sections, 5 admin actions (override plan, toggle unlimited, verify email, revoke sessions, force-stop relay). All mutations are audit-logged transactionally and require password re-authentication. Rate limited: 30 req/min admin-wide, 10 req/min for search.
Signup flow: Email delivery via Resend Go SDK (internal/email/ package). Verification emails link to /verify-email?uid=X&token=Y. Successful verification auto-creates a session and redirects to /dashboard. Password reset emails link to /reset-password?uid=X&token=Y. Tokens are 24-byte opaque, SHA256-hashed before storage.
Environment variables required in Cloudflare Pages:
TELEMY_OPERATOR_PASSWORD,TELEMY_OPERATOR_SESSION_SECRET(operator auth)AEGIS_API_BASE_URL,AEGIS_PLUGIN_LOGIN_COMPLETE_KEY(control plane)TELEMY_RESEND_API_KEY,TELEMY_EMAIL_FROM,TELEMY_BASE_URL(email, on Go backend)
Routes:
/— landing page with interactive dock demo + beta signup/login/— operator/user login form/login/plugin?attempt=pla_...— plugin auth completion/logout— clears session cookie/dashboard— user dashboard SPA (account, linked accounts, plan)/admin— admin portal SPA (user search, user detail + actions)/verify-email— email verification with auto-login/reset-password— password reset form/api/beta-signup— POST beta signup (KV storage)
Key Decisions
- 2026-02-28: Chose Cloudflare Pages over Vercel for landing page — zero cost, DNS already on Cloudflare, auto-SSL, CDN + DDoS included.
- 2026-02-28: Chose Stripe for payments over alternatives — maximum customer trust via hosted checkout page, 2.9% + 30c per transaction.
- 2026-02-28: License key validation via Vercel serverless — later abandoned in favor of the Go control plane handling all auth/billing.
- 2026-03-01: Switched from Oxanium + blue accent to Space Grotesk + orange (#f97316) — warm palette breaks “every AI SaaS template” mold.
- 2026-03-01: Added light/dark/system theme toggle — system default, persisted to localStorage as
telemy-theme. - 2026-03-01: Removed 2x2 feature cards, “How It Works” steps, dual pricing columns, 6-item FAQ, noise textures, glow gradients — design was “functional but generic.”
- 2026-03-23: Replaced CSS dock mockup with real dock React components via
useSimulatedState()— visitors interact with the actual product, not a screenshot. - 2026-03-23: Chose Cloudflare KV for beta signups over D1 or email forwarding — simplest option, free tier sufficient, exportable via wrangler.
- 2026-03-23: Landing page gated behind operator auth wall — remove middleware check on index route when ready to go public.
- 2026-03-24: Chose Preact (~3KB) over React for dashboard/admin — minimal bundle size, compatible API via
preact/compat. - 2026-03-24: Client-side hash routing over server-side routing — single HTML page, no server routing needed.
- 2026-03-24: JetBrains Mono for dashboard headings over Space Grotesk — “instrument panel” feel for the control-room aesthetic.
- 2026-03-24: OAuth popup flow (Google-style) over redirect flow — dashboard stays open,
postMessageback to parent on completion. - 2026-03-29: Admin gating via
is_adminDB column (manual SQL) over admin user management UI — not needed at <100 users. - 2026-03-29: Password re-authentication required for all admin mutations (HIGH-03 finding) — prevents session hijack from executing admin actions.
- 2026-03-29: Audit logging in same DB transaction as admin actions (MED-01) — guarantees no unlogged mutations.
- 2026-03-29: BFF proxy defense-in-depth for admin paths (CRIT-02) — BFF verifies
is_adminvia API call before forwarding, Go middleware remains primary gate. - 2026-04-01: Chose Resend for transactional email over alternatives — Go SDK, free tier 3K/month, simple integration.
- 2026-04-01: Auto-login on email verification — verify-email handler creates session and returns JWT + refresh token (same shape as login response).
- 2026-04-01: Enumeration-safe responses on all public auth endpoints — resend-verification always returns success regardless of account existence.
Experiments & Results
| Experiment | Status | Finding | Source |
|---|---|---|---|
| CSS dock mockup with OBS theme switcher (Dark/Acri/Rachni/System) | Replaced | Functional but static — replaced with real React dock components running useSimulatedState() for authentic interactive demo | 2026-02-28-landing-page-design.md |
| Dark navy + blue accent landing page (#0a0e1a, 2d7aed) | Replaced | ”Follows every AI-generated SaaS template pattern” — switched to warm orange on warm stone/black | 2026-03-01-landing-page-v2-design.md |
| Vercel for webhook + license validation backend | Abandoned | Architecture simplified to Go control plane handling all auth/billing, eliminating Vercel dependency | 2026-02-28-telemyapp-web-plan.md |
| Stripe Checkout for direct payment + UUID license keys | Evolved | Replaced by LemonSqueezy integration with account-based auth (JWT sessions) instead of license keys | 2026-02-28-telemyapp-web-plan.md |
| Split hero layout (text left, dock right) | Evolved | W1 design moved to centered dock as full-width hero with minimal text above, removing the split layout | 2026-03-23-w1-landing-page-design.md |
Gotchas & Known Issues
- CRIT-01 (pre-existing):
SignSessionJWTnever setRegisteredClaims.Subject, soextractJwtSubin the BFF proxy returned empty string for ALL users. Thetelemy_uidcookie cross-check was a fixed constant providing zero per-user binding. Fix: setSubject: userIDinSignSessionJWT. Must be fixed before admin portal deployment. - Dock demo theme gap: The dock’s
getDockCss()uses OBS Qt palette injection. In the webpage context where no Qt palette exists, a default dark theme override may be needed. - Dock demo mobile: The dock was designed for narrow OBS dock width (~300-400px). At landing page full-content width, frame sizing (max-height, border-radius, shadow) needs adjustment. Compact mode thresholds may need tuning for small screens.
- Operator auth is temporary: The operator login system (
TELEMY_OPERATOR_PASSWORD+ session cookie) is intentionally temporary, meant to bridge until the customer-facing account system is ready. Remove middleware check on index route to go public. - LemonSqueezy blocks billing page: Dashboard billing page (W2b) is deferred until Phase 5a E2E billing unblocks. “Manage Subscription” button shows “Coming soon” placeholder.
- Dashboard user data injection: Pages Function was planned to inject user data as
window.__telemyUser, but the implementation uses the BFF proxy pattern with JWT session cookies instead. Dashboard JS callsGET /api/v1/auth/sessionon mount. - Admin CSP headers: Admin pages should include strict Content-Security-Policy:
default-src 'self'; script-src 'self'; connect-src 'self'; style-src 'self' 'unsafe-inline'. No unsafe HTML rendering allowed in admin Preact code. - No build step for landing page vs. esbuild for SPAs: The landing page uses the dock demo bundle (
dock-demo-bundle.js) which requires an esbuild step, while the HTML/CSS is static. Dashboard and admin each have their own esbuild entry points and output bundles. - Resend email failures are non-blocking: If Resend fails during signup, the user is still created but won’t receive verification email. They can use the resend-verification endpoint later.
- Admin self-protection: Admin cannot revoke their own sessions (MED-03 finding).
Open Questions
- When to remove the operator auth wall and make the landing page public?
- Pricing page content — deferred until billing is live. What pricing will be displayed?
- Remote Control page (W2c) — requires WebSocket or SSE real-time connection from control plane. No design or timeline yet.
- Admin impersonation (login-as-user) — deferred as complex. Will it be needed?
- Admin overview dashboard with aggregate metrics — deferred until user count justifies it. What metrics?
- Email change flow — explicitly out of scope for signup design. When?
- Magic link login — explicitly out of scope. Will it be added?
- Resend webhook integration for bounce/complaint tracking — not implemented. Needed for deliverability?
- Blog/changelog section — out of scope in all designs so far. Plan?
- Analytics integration — mentioned as “add later if needed” in W1 design. Which provider?
Sources
- deploy-webpage.md
- 2026-03-23-w1-landing-page-design.md
- 2026-03-23-w1-landing-page-plan.md
- 2026-03-24-w2-dashboard-design.md
- 2026-03-25-w2-dashboard-plan.md
- 2026-03-29-admin-portal-design.md
- 2026-03-29-admin-portal-plan.md
- 2026-04-01-signup-registration-flow-design.md
- 2026-04-01-signup-registration-flow-plan.md
- 2026-02-28-landing-page-design.md
- 2026-02-28-landing-page-implementation.md
- 2026-02-28-telemyapp-web-plan.md
- 2026-03-01-landing-page-v2-design.md
- 2026-03-01-landing-page-v2-implementation.md