SoConnective

Architecture

ADR 0008 — Multi-tier platform, module marketplace & AI onboarding

  • Status: Accepted
  • Date: 2026-06-13
  • Supersedes: the flat single-tenant assumption in earlier ADRs (the agency→client intent from the original brief is now made explicit).

Context

Feedback OS is evolving from a single-tenant CRM into a multi-tier SaaS platform sold GHL-style: Feedback Studios runs the platform, sells it to agencies, and each agency serves its own clients (sub-accounts).

Requirements that emerged:

  1. A master/platform account (Feedback Studios) that can see and manage every account in the system.
  2. Agency accounts that configure things once and deploy to their sub-accounts (all or some).
  3. A marketplace of installable modules (AI, Channels, Payments, Calendar, …) — "the batches of extra modules we keep building".
  4. Configuration is per account, not per user.
  5. An AI onboarding concierge: the first thing a new account sees is an AI that offers to set everything up, installing + configuring each entitled module conversationally until 100% live.
  6. The whole thing must be easier to use than GHL.

Decision

1. Three-tier tenancy

The tenants collection becomes hierarchical:

FieldMeaning
typeplatform | agency | subaccount
parentrelationship → tenants (an agency's parent is the platform; a sub-account's parent is its agency)
statusactive | suspended
  • Platform (Master) — one tenant (Feedback Studios). Super-admin: sees all accounts, curates the marketplace catalog, owns platform billing, can impersonate any account for support (audited).
  • Agency — a customer. Owns its users, branding, billing, installed modules, and its sub-accounts.
  • Sub-account — an agency's client. Fully isolated data (contacts, inbox, pipelines, appointments…).

2. Access, RLS & account switcher

  • A user belongs to a home tenant with a role. Roles per tier: platform_admin, agency_admin, agency_member, subaccount_admin, subaccount_member.
  • RLS: a request is scoped to the active tenant. A user may switch the active tenant to any descendant they're allowed into (master → any; agency → its sub-accounts). Queries filter by tenant = active OR tenant IN descendants(active) per the user's grant.
  • Account switcher: a breadcrumb in the top bar — Platform › Agency › Sub-account — sets the active tenant (a cookie + server-validated against the user's grants). This single switcher replaces GHL's nested menus.

3. Marketplace & modules

  • Catalog lives in code (apps/crm/lib/marketplace.ts): each module declares its metadata + install requirements (a field schema) + whether it's configurable. Example: the AI module declares it needs an apiKey; the WhatsApp channel declares phoneNumberId, accessToken, …
  • Install state + credentials live per account in the tenant-scoped integrations collection (secrets write-only to the browser).
  • AI agent contexts live per account in the tenant-scoped agents collection (name, system prompt, model, scope, isDefault) — one or many.
  • The same server actions (saveIntegration, saveAgent, …) are used by both the manual marketplace UI and the AI onboarding agent — built once, driven two ways.

4. Entitlements

What an account "paid for / enabled" = its entitlements (the set of module slugs it may install). Owned by billing / set by the agency-or-platform. Stored on the account (tenant) as entitlements: string[] (or a future subscriptions collection). The marketplace shows entitled modules as installable; non-entitled as upsell.

5. Hybrid sub-account deployment (agency-decided)

Per module, the agency chooses at deploy time (stored in integrations.deployment, already a forward-compatible JSON field):

  • deployTo: account | all | selected (+ subAccounts: number[])
  • credentialMode: shared (sub-accounts use the agency's credential/config) | byo (each sub-account connects its own)
  • allowCustomize: boolean — may the sub-account override model/agents?

"Configure once → deploy to many in one click" is the agency superpower GHL makes painful.

6. AI onboarding concierge

On first run (and re-runnable later), an AI tool-using agent offers: "Want me to set everything up, or do it yourself?" If AI:

  1. listEntitlements() → the modules this account paid for / enabled.
  2. For each not-yet-Connected module, in order:
    • explain it in one line,
    • read its declared install requirements and ask the user for exactly those values,
    • installModule(slug, creds)configureModule(slug, config) (for AI: pick model + create agent context(s)),
    • checkModuleStatus(slug) → confirm it's live; surface + retry on error,
  3. continue until every entitled module is 100% live, then hand off to the workspace.

Why it scales ("block by block"): because every module declares its own requirements, the agent is generic — any future module is auto-onboardable with zero agent changes. The agent simply walks the entitled modules; each one tells it what it needs.

Tooling: a constrained Claude agent (function-calling) whose tools are the same install/configure/verify actions the UI uses, scoped to the active account.

Consequences

  • Tenancy is the critical-path foundation — everything sits on it; getting it wrong means rework. It is Phase A and must land first.
  • The marketplace's declarative catalog + shared actions are what make both the manual UI and the AI concierge cheap to extend.
  • More to build, but it is the platform's moat: an AI-native, self-installing, multi-tier CRM that an agency can white-label and deploy to clients.
  • Migrations: tenants gains type/parent/status/entitlements; new integrations + agents collections (some already built); RLS policies updated for descendant scoping.

Phased roadmap

PhaseScope
A — Platform tenancytenant type/parent/status, roles, RLS descendant scoping, account switcher, master "all accounts" view, impersonation (audited)
B — Marketplace (account level)catalog, install (gather declared creds), configure (AI: model + agent contexts). AI engine already built — it plugs in here.
C — Sub-account deploymententitlements, hybrid credential mode, per-module allow-customize, "deploy to all/some"
D — AI onboarding conciergetool-using agent that installs+configures entitled modules conversationally until 100% live
E — Premium inbox360° context panel, power workflow (slash/snooze/notes/assign), visual redesign (AI assistant already built)

"Easier than GHL" — the design principles this enables

  1. One clear account switcher, not nested menus.
  2. AI does the setup (the concierge) instead of manual clicking.
  3. Unified marketplace vs scattered settings.
  4. Configure once → deploy to many in one click.
  5. Modern, fast, opinionated UI with smart defaults.
Previous
ADR 0007 — Backend schema via migrations (not push)