Skip to content
English - United Kingdom
  • There are no suggestions because the search field is empty.

Ops Hub Architecture Overview

The technical map of Ops Hub for anyone who needs to know how it works.

What is Ops Hub?

BTT Ops Hub (ops.bristechtonic.co.uk) is BrisTechTonic's internal operations dashboard. It is the central place where the team monitors clients, generates SEO reports, runs prospecting campaigns, tracks business metrics, and accesses AI tooling. Built and maintained by Chris McDowell with Claude Code as the primary build tool.

Tech stack

  • Framework: Next.js 14 (App Router, server components, API routes)
  • Hosting: Vercel (Pro plan)
  • Database: Supabase (single project pphqguceuhrytszaykgd, no dev/live split)
  • Auth: next-auth with Google OAuth. JWT strategy, 12-hour session, role stored on the JWT.
  • Version control: GitHub (BrisTechTonic/btt-ops-hub)

File structure

app/
  (hub)/          All authenticated hub pages go here
  (public)/       Unauthenticated pages (magic-link reports, policies)
  api/            API routes at app/api/[route-name]/route.js
components/       Shared UI components
lib/              Shared utilities (hubspot.js, xero.js, reports/, etc.)
tools/            VPS-side services (sf-vps-service/)
docs/             Backlog, specs, SOPs, architecture notes
supabase/
  migrations/     Every schema change is a timestamped SQL migration file

Authentication and role model

All authenticated pages live under app/(hub)/. middleware.js (next-auth middleware) protects every route except an explicit exclusion list covering: /login, /api/auth, all MCP routes (/api/*-mcp), webhook routes, cron routes, public magic-link routes (/r/*, /msp-r/*), and the audit prospect pages. Adding a new public route without listing it in middleware.js causes 307 redirect loops.

Session management uses next-auth exclusively. Never call supabase.auth.getSession() directly. The role hierarchy is: admin > exec > management > team. An additional isBryley flag controls access to the Bryley Group personal finance section.

Environments

  • Production: ops.bristechtonic.co.uk (main branch)
  • Staging: staging.ops.bristechtonic.co.uk (staging branch)

All features are committed to the staging branch first, tested, then merged to main. Direct pushes to main are blocked by a pre-push git hook. HUBSPOT_WEBHOOK_ENABLED is always false on staging so CRM writes never pollute production HubSpot from staging. Every Supabase schema change requires a timestamped migration file -- never alter tables directly.

Key design patterns

  • Supabase access: all API routes use the service-role key (bypasses Row Level Security). RLS is enabled with empty policies on every table as a defence-in-depth measure against accidental anon-key access.
  • Token encryption: sensitive tokens at rest (Aircall Google calendar tokens, Xero tokens, Google Data Account reporting tokens) are AES-256-GCM encrypted via lib/crypto.js.
  • MCP routes: all hosted MCPs use Streamable HTTP transport (protocol 2025-03-26), stateless POST, ?token=VALUE URL auth.
  • Cron auth: Vercel auto-injects Authorization: Bearer $CRON_SECRET on every cron call. Routes check this header in lib/cron-auth.js.