Commercial Tiers Scoping: Growth / Acquisition / Partner

Status: Draft Owner: @bilal Last Updated: 2026-03-09

ADR: ADR-019 Commercial Motions Architecture


1. Executive Summary

Envo Energy is evolving from a single self-serve SaaS into three distinct commercial motions:

MotionSales ModelPricingTarget Customer
GrowthSelf-serveFixed tiers (Basic/Premium)SME landlords, small HMO operators
AcquisitionAgency/outbound salesPer-enquiry, custom pricingMid-market landlords, letting agents
PartnerEnterprise salesCustom contracts, SOC2, isolated infraLarge enterprises, housing associations

The codebase is structured as a multi-app monorepo:

PackagePurposeDB Access
envo-dashboardTenant-facing SaaS (Growth/Acquisition/Partner customers)Prisma + Pothos GraphQL
envo-adminInternal Envo operations — Acquisition provisioning, pricing, invoicingDirect Supabase client (no Pothos)

Key decisions:

  • envo-dashboard remains the monolith — all tenant-facing features stay here. No decomposition planned yet.
  • envo-admin is a separate Next.js app at admin.envo-energy.com, tightly coupled to Supabase/DB, skipping the Pothos GraphQL layer. Handles Acquisition provisioning, custom pricing, and invoicing.
  • Close CRM handles the Acquisition sales pipeline externally — no in-house CRM.
  • AI-first support: In-app “follow me” guided onboarding + AI help bot + AI helpline (VA/receptionist).
  • Future improvement: Extract envo-common shared types/utils package when duplication between apps justifies it.

2. Current State (What We Have)

2.1 Data Model

  • organisations.plan enum: basic | premium | partner
  • plans config table (feature branch): property_limit, tenant_limit, price, features JSONB
  • Stripe integration on feature/stripe-integration branch (checkout + webhooks)
  • Multi-tenancy via organisation_id + RLS everywhere

2.2 Onboarding

  • Self-serve only: signup 2-step wizard (org details + plan selection) dashboard
  • No invite flow, no team management UI yet

2.3 Infrastructure

  • Cloudflare Workers + Hyperdrive + Supabase (single DB)
  • Terraform IaC for DNS, Workers, Access policies
  • Cloudflare for SaaS custom domains: designed but not implemented
  • BYOAK credential resolver: designed (ADR-014) but not implemented

2.4 Integrations

  • Provider adapters: Twilio, Meta WhatsApp, VAPI/Retell (voice)
  • LLM multi-provider with fallback chain
  • No CRM integrations, no outbound webhook system, no plugin registry

3. The Three Motions — Detailed Scope

3.1 Growth (Self-Serve SaaS) — EXISTS TODAY

What it is: The current product. Landlords sign up, pay, and get started immediately with AI-guided onboarding.

3.1.1 Onboarding Flow (Growth)

Customer visits ehq.tech (marketing site)
  -> Selects plan + clicks "Get Started"
  -> Stripe Checkout (payment first)
  -> Stripe webhook confirms payment
  -> Redirect to app.ehq.tech (auto-logged in via session token)
  -> Set up email & password (account creation)
  -> Receive invoice / payment confirmation via email
  -> AI "Follow Me" guided setup bot appears
    -> Step 1: Create your organisation
    -> Step 2: Add your first property
    -> Step 3: Add tenants
    -> Step 4: Configure your tenant phone line
    -> Step 5: Test an inbound enquiry
  -> Dashboard ready, bot dismisses

3.1.2 Ongoing Support (Growth)

  • AI Help Bot — In-app chat assistant that can answer questions, guide users through features, and troubleshoot issues
  • AI Helpline — Phone number staffed by a VA / AI receptionist for customers who prefer voice support

3.1.3 What’s Needed

  • Merge Stripe integration branch
  • Payment-first flow: Stripe Checkout on ehq.tech auto-login redirect to app.ehq.tech
  • Email/password account creation post-payment
  • Invoice / payment confirmation emails (Stripe + Resend)
  • AI “Follow Me” onboarding bot (step-by-step guided setup)
  • AI Help Bot (in-app chat for ongoing support)
  • AI Helpline (VA/receptionist phone number)
  • Plan upgrade/downgrade UI in dashboard
  • Billing portal (manage payment method, view invoices)
  • Feature gating enforcement beyond property/tenant limits

Pricing model: Fixed monthly tiers (Basic free, Premium ~GBP 29-89/mo, configurable)

Data model changes: None beyond what’s on the feature branch.


3.2 Acquisition (Agency Sales) — NEW

What it is: Envo sales agents outreach to landlords, demo the product, configure custom pricing, and onboard them. The customer never visits app.ehq.tech — they get their own branded domain (e.g., envo.biglandlord.com).

3.2.1 Sales Pipeline (Close CRM)

Close CRM handles the entire Acquisition sales pipeline externally:

  • Prospect tracking, outreach, follow-ups
  • Demo scheduling, call logging
  • Deal stages through to “Closed Won”
  • No in-house CRM — Close is purpose-built for this

Once a deal is Closed Won in Close CRM, the handoff to Envo begins.

3.2.2 Admin Application (envo-admin)

A separate Next.js application at admin.envo-energy.com for Envo internal operations. Talks directly to Supabase (no Pothos/GraphQL overhead — admin queries are bespoke and internal).

Capabilities:

  • Create organisation on behalf of customer (post-sale)
  • Configure custom pricing (per-enquiry basis, not fixed tiers)
  • Set up custom domain (Cloudflare for SaaS provisioning)
  • Generate login credentials for customer
  • Track customer activation/usage
  • Manage invoicing (Stripe or bank-to-bank)

Why a separate app (not a route group in the dashboard):

  • Admin has no tenant-facing auth — uses Envo staff Supabase Auth or CF Access
  • No need for Pothos/GraphQL — direct Supabase client queries are simpler and faster for internal tooling
  • Different deployment target: admin.envo-energy.com with stricter CF Access policies
  • Clean separation makes future decomposition easier

3.2.3 Data Model Changes

-- New: Acquisition-specific pricing
CREATE TABLE custom_pricing (
    id UUID PRIMARY KEY,
    organisation_id UUID REFERENCES organisations(id),
    pricing_model VARCHAR(50) NOT NULL,        -- 'per_enquiry', 'per_unit', 'flat_fee', 'hybrid'
    price_per_enquiry DECIMAL(10,2),           -- e.g., GBP 2.50 per enquiry
    price_per_unit DECIMAL(10,2),              -- e.g., GBP 5/unit/month
    flat_fee DECIMAL(10,2),                    -- e.g., GBP 500/month
    minimum_monthly DECIMAL(10,2),             -- floor
    billing_frequency VARCHAR(20) DEFAULT 'monthly',
    payment_method VARCHAR(30),                -- 'stripe', 'bank_transfer', 'invoice'
    contract_start DATE,
    contract_end DATE,
    notes TEXT,
    configured_by UUID REFERENCES users(id),   -- sales agent
    created_at TIMESTAMPTZ DEFAULT NOW(),
    updated_at TIMESTAMPTZ DEFAULT NOW()
);
 
-- New: Enquiry tracking (for per-enquiry billing)
CREATE TABLE enquiries (
    id UUID PRIMARY KEY,
    organisation_id UUID REFERENCES organisations(id),
    conversation_id UUID REFERENCES conversations(id),
    issue_id UUID REFERENCES issues(id),
    channel VARCHAR(30),
    billable BOOLEAN DEFAULT true,
    billed_at TIMESTAMPTZ,
    billing_period_start DATE,
    billing_period_end DATE,
    created_at TIMESTAMPTZ DEFAULT NOW()
);
 
-- New: Custom domains
CREATE TABLE organisation_domains (
    id UUID PRIMARY KEY,
    organisation_id UUID REFERENCES organisations(id),
    hostname VARCHAR(255) UNIQUE NOT NULL,      -- e.g., 'envo.biglandlord.com'
    cf_custom_hostname_id VARCHAR(255),          -- Cloudflare for SaaS ID
    status VARCHAR(30) DEFAULT 'pending',        -- 'pending', 'active', 'ssl_pending', 'failed'
    ssl_status VARCHAR(30),
    provisioned_by UUID REFERENCES users(id),
    provisioned_at TIMESTAMPTZ,
    created_at TIMESTAMPTZ DEFAULT NOW()
);
 
-- Extend organisations
ALTER TABLE organisations ADD COLUMN commercial_motion VARCHAR(20)
    DEFAULT 'growth'
    CHECK (commercial_motion IN ('growth', 'acquisition', 'partner'));
ALTER TABLE organisations ADD COLUMN onboarded_by UUID REFERENCES users(id);
ALTER TABLE organisations ADD COLUMN sales_agent_id UUID REFERENCES users(id);

3.2.4 Onboarding Flow (Acquisition)

Close CRM: Deal marked "Closed Won"
  |
envo-admin: Envo ops creates org + configures custom pricing
  -> Provisions custom domain (Cloudflare for SaaS)
  -> Generates login credentials
  -> Sends login details to customer (email)
  |
VA (AI account manager) books onboarding call for next day
  |
Onboarding call: VA coaches customer through software
  -> Walks through dashboard
  -> Sets up properties, tenants, phone lines
  -> Answers questions
  |
Customer is live on their branded domain

3.2.5 Billing (Acquisition)

Two paths:

  1. Stripe: For automated per-enquiry or per-unit billing. Requires metered billing via Stripe (usage records).
  2. Bank transfer + invoicing: For customers who prefer traditional invoicing. Requires invoice generation (PDF), invoice tracking table, manual payment reconciliation (or Open Banking API later).

3.2.6 Per-Enquiry Concept

Deep dive: See Enquiry Billing Model for the full analysis — conversation lifecycle gaps, edge cases, billing model options, recommended hybrid approach, and proposed contractual definition.

An “enquiry” = a completed tenant interaction that results in a meaningful outcome (issue created, question answered, escalation to human). Not every message is an enquiry — it’s a conversation that reaches resolution.


3.3 Partner (Enterprise) — NEW

What it is: Large enterprises with strict compliance, data isolation, and integration requirements. Sold via enterprise sales process.

3.3.1 Infrastructure Isolation

Isolation LevelApproachComplexityCost
Shared DB, RLSCurrent modelLowLow
Separate schemaSchema-per-tenant in same DBMediumLow
Separate DBDedicated Supabase project per partnerHigh~GBP 20/mo per partner
Separate everythingOwn Workers, DB, domainVery High~GBP 50+/mo per partner

Recommendation: Start with shared DB + RLS (current model) for all Partner customers. Only provision separate DB when contractually required (SOC2, data residency).

3.3.2 SOC2 & Compliance

Defer SOC2 until a signed contract requires it. Many enterprise customers accept ISO 27001 or a detailed security questionnaire instead.

3.3.3 Integration Adapters

Partner/Acquisition customers may need:

  • CRM sync (Dynamics 365, Salesforce)
  • Outbound webhooks
  • Inbound API
  • SSO/SAML
  • Custom reporting

3.3.4 Data Model Changes (Partner-specific)

CREATE TABLE integration_configs (
    id UUID PRIMARY KEY,
    organisation_id UUID REFERENCES organisations(id),
    integration_type VARCHAR(50) NOT NULL,
    provider VARCHAR(50),
    config JSONB NOT NULL DEFAULT '{}',
    vault_secret_id VARCHAR(255),
    is_active BOOLEAN DEFAULT true,
    last_sync_at TIMESTAMPTZ,
    created_at TIMESTAMPTZ DEFAULT NOW(),
    updated_at TIMESTAMPTZ DEFAULT NOW()
);
 
CREATE TABLE webhook_subscriptions (
    id UUID PRIMARY KEY,
    organisation_id UUID REFERENCES organisations(id),
    url TEXT NOT NULL,
    events TEXT[] NOT NULL,
    secret VARCHAR(255),
    is_active BOOLEAN DEFAULT true,
    last_triggered_at TIMESTAMPTZ,
    failure_count INTEGER DEFAULT 0,
    created_at TIMESTAMPTZ DEFAULT NOW()
);
 
CREATE TABLE webhook_deliveries (
    id UUID PRIMARY KEY,
    subscription_id UUID REFERENCES webhook_subscriptions(id),
    event_type VARCHAR(100),
    payload JSONB,
    response_status INTEGER,
    response_body TEXT,
    delivered_at TIMESTAMPTZ,
    created_at TIMESTAMPTZ DEFAULT NOW()
);

4. Feature Matrix

                              Growth          Acquisition       Partner
                           Basic  Premium   (Custom)          (Custom)
                           -----  -------   --------          --------
CORE FEATURES
  Issue management          x       x          x                 x
  Tenant engine (AI)        x       x          x                 x
  Property management       x       x          x                 x
  Document storage          x       x          x                 x
  Compliance tracking       -       x          x                 x

LIMITS
  Properties               1-5     50         Custom            Unlimited
  Tenants                  20      200        Custom            Custom

BRANDING
  Custom domain             -       -          x                 x
  Custom logo/colours       -       x          x                 x
  Remove "Powered by Envo"  -       -          -                 x

INTEGRATIONS
  Webhook notifications     -       -          Add-on            Add-on
  CRM sync                  -       -          Add-on            Add-on
  SSO/SAML                  -       -          -                 Add-on
  BYOAK (own API keys)      -       x          x                 x
  Custom voice greeting     -       x          x                 x

BILLING
  Self-serve (Stripe)       x       x          -                 -
  Per-enquiry pricing       -       -          x                 -
  Custom contract           -       -          x                 x
  Invoice/bank transfer     -       -          x                 x

SUPPORT
  AI Help Bot (in-app)      x       x          x                 x
  AI Helpline (phone)       x       x          x                 x
  VA onboarding call        -       -          x                 x
  Dedicated account mgr     -       -          x                 x
  SLA guarantees            -       -          -                 x

DATA & COMPLIANCE
  Shared infrastructure     x       x          x                 Default
  Isolated database         -       -          -                 On request
  SOC2 compliance           -       -          -                 On request
  Data export API           -       -          Add-on            Add-on

ADMIN (ENVO INTERNAL -- admin.envo-energy.com)
  Sales pipeline            -       -          Close CRM         Close CRM
  Custom pricing config     -       -          x                 x
  Domain provisioning       -       -          x                 x
  Usage analytics           -       -          x                 x

5. Phased Delivery

Phase 0: Foundation (Pre-requisite)

  • Merge Stripe integration branch
  • Add commercial_motion field to organisations
  • Implement organisation_domains table
  • Scaffold envo-admin Next.js app (direct Supabase client, CF Access auth, admin.envo-energy.com)
  • Build feature gating framework in envo-dashboard (plan + motion + add-ons)
  • Add envo_admin / envo_support role to AccessRole enum
  • Set up Close CRM account + basic pipeline stages

Phase 1: Growth Completion

  • Payment-first flow: Stripe Checkout on ehq.tech auto-login redirect to app.ehq.tech
  • Email/password account creation post-payment
  • Invoice + payment confirmation emails (Stripe + Resend)
  • AI “Follow Me” onboarding bot (step-by-step guided setup, 5 steps)
  • AI Help Bot (in-app chat for ongoing support)
  • AI Helpline setup (VA/receptionist phone number via VAPI)
  • Plan upgrade/downgrade UI
  • Stripe billing portal integration
  • Feature gating enforcement in UI + API

Phase 2: Acquisition MVP

  • envo-admin: organisation creation on behalf of customer
  • envo-admin: custom pricing configuration UI
  • envo-admin: generate login credentials + send to customer
  • envo-admin: invoice generation (PDF) — basic
  • envo-admin: manual payment tracking
  • envo-dashboard: enquiry tracking + billable tagging
  • envo-dashboard: Cloudflare for SaaS domain provisioning (API integration)
  • envo-dashboard: domain resolution in middleware
  • VA onboarding call flow (book next-day call, coach customer through software)
  • Close CRM envo-admin handoff (deal Closed Won triggers provisioning)

Phase 3: Partner MVP

  • Outbound webhook system (event subscriptions + delivery)
  • Webhook management UI in dashboard
  • Integration config framework (JSONB config + Vault secrets)
  • First CRM adapter (likely Dynamics 365 or Salesforce)
  • SSO/SAML integration (via Cloudflare Access or Supabase)
  • Isolated DB provisioning tooling (Terraform + Supabase API)

Phase 4: Maturity — Ongoing

  • SOC2 preparation (if contractually required)
  • Per-enquiry metered billing via Stripe
  • Open Banking for bank-to-bank payments
  • Additional CRM adapters
  • Data export API
  • Customer-facing API (REST + webhooks)

6. Risks & Mitigations

RiskImpactMitigation
Complexity explosion — 3 motions across appsCode unmaintainableSeparate apps, feature flags, Close CRM for pipeline
Premature Partner investmentWasted effort + costOnly build when signed contract requires it
Custom pricing edge casesRevenue leakageClear enquiry definition, audit trail, dispute process
Custom domain SSL issuesCustomer can’t access dashboardMonitoring + fallback to app.ehq.tech subdomain
envo-admin scope creepDistraction from core productClose CRM handles pipeline; admin = provisioning + pricing only

7. Open Questions

  1. Close CRM integration depth — Webhook/API from Close to auto-trigger provisioning, or manual handoff initially?
  2. Invoice tooling — Build PDF generation or use Stripe Invoicing / Xero API?
  3. Bank-to-bank payments — Manual transfers initially, or Open Banking from the start?
  4. Multi-DB strategy — Schema migrations across N databases? Connection routing?
  5. Custom domain auth — Supabase Auth alone on custom domains, or CF Access per customer?
  6. Feature add-on pricing — Fixed monthly per add-on, per-usage, or bundled?
  7. Data migration on upgrade — Growth Acquisition: just flag + pricing config, or infra changes too?
  8. White-label depth — Logo + colours + domain only, or also email templates, SMS sender ID, voice personality?

8. Assumptions

  1. Envo is a two-app monorepo (envo-dashboard + envo-admin). No shared package yet.
  2. Supabase remains the DB. Cloudflare remains the hosting platform.
  3. Growth is the primary motion — Acquisition and Partner are secondary initially.
  4. No mobile app — dashboard is web-only.
  5. Acquisition customers use the same core product (configuration only, no custom features).
  6. Partner isolation is the exception, not the rule.
  7. Integration adapters built for one customer become generic offerings.
  8. Sales pipeline lives in Close CRM — envo-admin is post-sale only.
  9. SOC2 is a future requirement — no Partner customer currently requires it.