Architecture Concept · v0.1 Draft

HonorPro Hub

A multi-tenant SaaS control plane that licenses brokers and delivers turnkey trading features — MT5 server plugins paired with white-label web frontends — onto broker-owned infrastructure.

2026-08-19 · internal · status: concept for review (OPS-7)

1Product vision

Brokers who run their own MetaTrader 5 servers want modern client-facing functionality — a web terminal, copy trading, social trading, risk tooling — without building or operating any of it. The Hub is the product that sells them exactly that: a subscription service where a broker signs up, receives a license, and switches individual features on from a self-service console. Each feature arrives as a matched pair: a server-side component (an MT5 plugin or a gateway service that talks to the broker's MT5 server) plus a white-label web frontend branded for that broker.

The provider owns the Hub — the control plane, the licensing authority, the feature catalog, and the frontends. The broker owns their trading infrastructure — the MT5 server, the accounts, the market data, the money. That split is the core selling point: the broker's trading data never leaves the broker's infrastructure; the Hub only orchestrates.

One control plane, many brokersEvery broker is a tenant. Licensing, provisioning, configuration and monitoring all flow through the Hub.
Features are productsA feature is a versioned, self-describing unit: server component + web frontend + config schema + license flag. Enable it, and it works.
Broker infra stays broker'sMT5 servers, plugins and gateways run on the broker's machines. The Hub reaches them only through an outbound agent connection.
License is enforceableEvery layer — plugin, gateway, frontend — independently verifies a signed license. Expiry and kill-switch take effect without touching the broker's box.

2Terminology

TermMeaning
ProviderThe SaaS operator (us). Owns the Hub, the catalog, the licenses, the frontend hosting.
HubThe multi-tenant control plane: broker registry, licensing service, feature catalog, provisioning orchestrator, telemetry, and the two consoles.
BrokerA tenant. A brokerage company with its own MT5 server(s) that subscribes to Hub features.
FeatureA sellable capability (Web Terminal, Copy Trading, Price Alerts…). Described by a manifest; composed of components.
ComponentA deployable part of a feature: mt5-plugin (native DLL on the MT5 server), gateway-service (module inside the broker's Gateway), or web-frontend (SPA hosted by the provider).
GatewayThe broker-side API service (evolution of today's manager-api): logs into the broker's MT5 server as a manager, exposes the API that feature frontends consume, hosts gateway-type feature modules.
AgentThe broker-side daemon that maintains a single outbound connection to the Hub: installs/updates components, delivers config and licenses, reports health.
EntitlementOne line inside a license: “feature X, tier Y, limits Z, until date D”.

3System topology

Two planes. The control plane (provider cloud) holds no trading data. The data plane (one per broker) holds all of it.

Provider ops Broker admin Traders web · mobile PROVIDER CLOUD — CONTROL PLANE Provider Console back office Broker Console tenant self-service · feature store Hub Core Broker registry & lifecycle · Licensing authority (Ed25519) Feature catalog & versions · Provisioning orchestrator Telemetry & fleet health · Audit log Feature Frontends white-label SPAs · per-broker domains · branding & license from Hub Web Terminal Copy Trading Social Cabinet Price Alerts Artifact Registry signed plugin & frontend builds Notification Service Telegram · email routing Telegram broker ops chats stall alerts · expiry · deploy results BROKER PREMISES — DATA PLANE …brokers B, C Hub Agent Windows service outbound-only · verifies signatures Gateway manager-api core + feature modules serves trader APIs MT5 Server broker-owned feature plugins copy engine · … modules · config license fan-out installs plugins (staged restarts) Manager API = independent license check (plugin · gateway · frontend) outbound WSS only deploy plans · licenses health · alert events trader traffic (HTTPS/WSS) Hub not in the path
Fig. 1 — One control plane licenses and provisions many broker-owned data planes; the Agent dials out, trader traffic never touches the Hub.

Traffic rules, in order of importance:

4Tenancy & data boundary

The Hub database is multi-tenant with a broker_id discriminator on every row and row-level enforcement in the API layer (single schema; per-tenant schemas are not warranted at this data volume — the Hub stores configuration, not trading history). Broker Console sessions are scoped to exactly one broker_id; provider operators carry an explicit cross-tenant role.

What the Hub stores vs. what it never stores Stores: broker profiles, licenses, feature configs, branding assets, deployment state, health telemetry, alert history, audit log. Never stores: trader accounts, balances, orders, deals, quotes (beyond transient alert evaluation), or broker end-client PII. This line is contractual as much as technical — it goes in the sales pitch and the DPA.

5Broker lifecycle

A broker record moves through a small, explicit state machine. Licensing (§6) is layered on top of an active broker; deactivating the broker overrides every license.

stateDiagram-v2
  [*] --> Draft: create broker
  Draft --> Provisioning: issue license + agent token
  Provisioning --> Active: agent connected,
first feature deployed Active --> Suspended: manual suspend /
license expired + grace over Suspended --> Active: reactivate / renew Suspended --> Terminated: offboard Terminated --> [*]
OperationWhereNotes
Create brokerProvider ConsoleCompany profile, contacts, contract refs; generates broker_id, agent enrollment token, initial license.
Edit brokerProvider ConsoleProfile, license terms, entitlements, limits. Every change audited.
Suspend / reactivateProvider ConsoleSuspend = frontends show a neutral “service unavailable” page, gateways stop serving feature APIs, plugins go dormant. Reversible in minutes.
TerminateProvider ConsoleAgent uninstalls components on command (or broker removes manually); license revoked; config retained 90 days, then purged.
Self-service editsBroker ConsoleBranding, feature config, notification channels, own staff accounts — never license terms.

6Licensing

The license is a signed document, not a database flag — because it must be enforceable on machines we do not control, including ones temporarily offline.

License document

{
  "license_id": "lic_01J9…",
  "broker_id": "brk_honorpro",
  "status": "active",              // active | suspended
  "issued_at": "2026-08-19T00:00:00Z",
  "valid_until": "2027-08-19T00:00:00Z",   // “active until” — the expiry the sales side manages
  "grace_hours": 72,               // offline tolerance
  "entitlements": [
    { "feature": "web-terminal",  "tier": "standard", "limits": { "concurrent_sessions": 500 } },
    { "feature": "copy-trading",  "tier": "pro",      "limits": { "masters": 50, "followers": 2000 } },
    { "feature": "price-alerts",  "tier": "standard", "limits": { "watched_symbols": 200 } }
  ],
  "signature": "ed25519:…"         // signed by the Hub licensing key
}

Issuance and refresh

Enforcement points

LayerCheckOn failure
MT5 pluginVerifies signature + expiry + its own feature flag at start and on each refreshFeature logic goes dormant; plugin stays loaded but inert (no server restart needed)
GatewaySame verification; also enforces entitlement limits (session counts, follower counts)Serves 403 license_expired per feature; health endpoint reports the reason
Feature frontendHub-side tenant resolution checks license before serving the app shellRenders the broker-branded “subscription expired — contact provider” page

Statuses shown to operators: active expiring ≤ 30d grace expired suspended terminated. “Is this broker active, and until when” is a first-class column in the Provider Console, not a report.

7White-label

Branding is a per-broker document applied uniformly by every feature frontend:

Implementation: the frontend fleet is one deployment, many tenants. A request hits the frontend host, tenant is resolved from the domain, the branding document and license are fetched from the Hub (edge-cached, minutes-level TTL), theme tokens are injected as CSS variables. No per-broker builds; a rebrand is a config change.

8Feature model

A feature is defined by a manifest in the catalog. The manifest is what makes “broker clicks Enable, everything else happens” possible.

feature: copy-trading
version: 2.4.1
components:
  - kind: mt5-plugin          # native, runs inside the broker's MT5 server
    artifact: copyengine-2.4.1-mt5build4620.zip   # signed
    mt5_min_build: 4560
  - kind: gateway-service     # Python module loaded by the broker's Gateway
    artifact: gw-copytrading-2.4.1.whl
  - kind: web-frontend        # provider-hosted SPA route(s)
    routes: [ "/copy", "/copy/admin" ]
config_schema: ./config.schema.json   # drives the auto-generated settings UI
license_flag: copy-trading
depends_on: [ web-terminal-core ]
health: [ "plugin:copyengine:heartbeat", "gw:copytrading:ping" ]

Enable flow

sequenceDiagram
  participant B as Broker admin
  participant H as Hub
  participant A as Agent (broker box)
  participant G as Gateway
  participant M as MT5 server
  B->>H: Enable "copy-trading"
  H->>H: check entitlement, resolve deps & version
  H->>A: deploy plan (artifacts, config, license)
  A->>A: download signed artifacts, verify signatures
  A->>M: install plugin (staged, server-safe window)
  A->>G: install gateway module, hot-reload
  A->>H: deployed OK + component health
  H->>B: feature live — link to its admin panel
  

MT5 plugin installation is the one step that may require a server restart (MetaQuotes constraint). The deploy plan marks such steps staged: the Agent prepares everything and either restarts within a broker-approved maintenance window or waits for the broker admin to confirm the restart from the console.

9Broker-side runtime

Three things run on broker infrastructure, all installed from one signed installer:

ComponentRuns onResponsibilities
Hub AgentWindows service on (or beside) the MT5 hostOutbound WSS to Hub; artifact download + signature verification; plugin/module install & upgrade; license fan-out; health & metrics reporting; remote log bundle on request.
GatewayWindows or Linux box in the broker's networkManager-API login to the broker's MT5; serves the feature APIs (REST + WS hubs) that frontends consume; loads gateway-type feature modules; enforces license limits; terminates trader TLS (or sits behind the broker's proxy).
MT5 pluginsInside the broker's MT5 server processFeature-specific server logic (copy engine, etc.). Each verifies the license independently.

Enrollment: the Provider Console issues a one-time token; the broker (or our onboarding engineer) runs the installer, pastes the token, and the Agent appears in the Hub with a persistent identity (mTLS client cert issued on enrollment). Everything after that is remote.

Design ruleThe Agent is deliberately dumb: it executes signed deploy plans and reports state. All decision logic lives in the Hub, so fixing orchestration bugs never requires touching broker machines.

10Consoles

Broker Console (tenant self-service — the Hub's own frontend)

Because the web terminal is itself a feature, the Broker Console is the natural home of what is today the terminal's admin area: one login, terminal administration under it. The current admin console (operators, dealing) continues to run gateway-side — it administers trading data that must stay broker-side — and is surfaced inside the Broker Console via SSO-embedded panel.

Provider Console (back office)

11Initial feature catalog

FeatureComponentsSource today
Web Terminalweb-frontend (HonorPro UI) + gateway coreweb/src/honorpro + manager-api — exists, single-tenant
Terminal Admingateway-service + embedded paneladmin_page.py console — exists (split into static assets first, per OPS backlog)
Copy Tradingmt5-plugin (copy engine) + gateway-service + web-frontendCopy engine — exists; needs the TicketMap scaling fix before large fleets
Social Tradinggateway-service + web-frontendPatterns from ZT4 social — port, not rebuild
Trader Cabinetgateway-service + web-frontendPatterns from ZT4 trader cabinet
Price Alertsgateway-service + Hub notification serviceNew — small; the pilot feature for the whole pipeline (§12)
Mobile appwhite-label build pipeline (MAUI)Exists single-brand; per-broker builds are a later phase

12Price Alert feature

The first fully Hub-native feature, and deliberately the pilot: it exercises the manifest, config schema, gateway module deployment, licensing and notification pipeline end-to-end while being small enough to ship early.

What it does: watches the broker's quote stream and notifies the broker's team in Telegram when quotes stop flowing during hours when the market should be trading — the classic “feed died at 3 a.m. Sunday? no — feed died mid-session and nobody noticed” insurance.

Detection (gateway module — broker side, at the feed)

Notification (Hub side)

sequenceDiagram
  participant G as Gateway module
  participant H as Hub notification service
  participant T as Telegram
  G->>G: stall detected (market open, threshold passed)
  G->>H: alert event {symbols, since, severity}
  H->>T: message to broker's configured chat(s)
  Note over G,H: repeat/escalate every N min while stalled
  G->>H: recovery event
  H->>T: "feed recovered, gap 4m 12s"
  

Config (schema-driven form in the Broker Console)

{
  "symbol_groups": [
    { "match": "*.z", "threshold_s": 30 },
    { "match": "XAU*", "threshold_s": 60 }
  ],
  "calendar_overrides": [ { "date": "2026-12-25", "closed": true } ],
  "telegram_chats": [ "-100123456789" ],
  "repeat_min": 10,
  "escalate_after_min": 30,
  "open_close_quiet_multiplier": 3
}

13Data model (Hub core)

brokers          id, name, status, contacts, created_at
licenses         id, broker_id, status, valid_until, grace_hours, signed_doc, issued_at
entitlements     license_id, feature, tier, limits(json)
features         key, name, description, config_schema_ref
feature_versions feature, version, channel, components(json), mt5_min_build
deployments      id, broker_id, feature, version, state, plan(json), started_at, finished_at
agents           id, broker_id, cert_fp, last_seen, agent_version, host_meta
branding         broker_id, tokens(json), domains(json), locales(json), assets…
notif_channels   broker_id, kind(telegram|email), address, verified
alert_events     id, broker_id, feature, severity, payload, raised_at, resolved_at
audit_log        id, actor, broker_id, action, before, after, at
users            id, email, role, broker_id nullable (null ⇒ provider staff)

14API surface (sketch)

APIConsumersShape
Hub Admin APIProvider ConsoleREST: /brokers, /brokers/{id}/license, /catalog/features, /fleet
Hub Tenant APIBroker Console, feature frontends (tenant resolution)REST: /me/license, /me/features, /me/features/{f}/config, /me/branding, /me/channels
Agent channelHub ⇄ AgentWSS, JSON messages: deploy.plan, deploy.result, license.push, health.report, alert.event, logs.request
Gateway feature APIsTrader browsers / mobilePer-feature REST + WS (today's manager-api API, namespaced per feature)

Auth: Hub sessions are JWT with broker_id + role claims; agent channel is mTLS; frontends resolve tenants via signed, short-TTL tenant descriptors so a compromised edge cache cannot grant an expired broker service.

15Security

16Mapping to existing assets

The Hub is not a green-field rewrite; it is a control plane wrapped around software that already runs in production for one broker.

Exists today (mt5-terminal repo)BecomesWork
HonorPro web terminal (web/)Web Terminal feature frontendTenant resolution + branding tokens (theming groundwork exists — light-theme work)
manager-api (Python FastAPI)Gateway coreModularize: core (MT5 session, pumps, auth) vs. feature modules; config from Hub instead of env-only
Copy engine (Windows, loopback)Copy Trading mt5-plugin componentPackage + license check + fix TicketMap scaling debt before multi-broker fleets
Admin console (admin_page.py)Terminal Admin embedded panelSplit the 2000-line HTML string into static assets (already planned), add Hub SSO
Saphyte auth integrationPer-broker pluggable CRM auth providerGeneralize: “CRM connector” becomes a per-broker Gateway config, Saphyte is connector #1
ZT4 social / trader cabinetSocial Trading & Cabinet featuresPort against the Gateway API
Current single-broker deploymentTenant #1The migration test: HonorPro must move onto the Hub with zero trader-visible change

17Roadmap

PhaseDeliversProves
0 — ConceptThis document; catalog + license format reviewShared vocabulary
1 — Hub coreBroker registry + CRUD, licensing service (issue/sign/verify/expiry), Provider Console MVP, Broker Console shell with license visibility“Active / inactive / until when” managed in one place
2 — Agent + pilot featureAgent (enroll, WSS, deploy, health), Gateway modularization, Price Alerts shipped end-to-end (deploy → config → detect → Telegram)The whole delivery pipeline, on the smallest feature
3 — Terminal as a featureTenant resolution + white-label in the terminal frontend; HonorPro migrated as tenant #1; Terminal Admin embedded via SSOMulti-tenant frontends; zero-regression migration
4 — Big featuresCopy Trading (with plugin deploy + staged restart flow), then Social Trading, CabinetPlugin lifecycle on broker-owned MT5 servers
5 — Scale & sellSecond real broker onboarded; billing hooks; mobile white-label pipelineThe business model

18Open questions

  1. Frontend hosting for regulated brokers: some will demand frontends on their own domain and their own infrastructure. Support a “self-hosted frontend” deployment mode (Agent deploys the SPA bundle to the broker's web server), or provider-hosted only at launch?
  2. Billing: manual invoicing against license terms at launch, or billing integration (usage counters exist in telemetry) in phase 5?
  3. Gateway placement: recommend a Linux VM beside the MT5 Windows host (today's proven layout) or support Windows-only single-box installs for small brokers?
  4. MT5 version matrix: plugins are build-sensitive (mt5_min_build). How many concurrent MT5 server builds do we commit to supporting per plugin release?
  5. Naming: “HonorPro Hub” is the working title; if the SaaS is sold beyond the HonorPro brand, the control plane needs a brand-neutral name (the white-label system itself never shows it to traders).
  6. Existing Brokeree coexistence: for brokers running third-party plugins (as tenant #1 does — Ignore Rival Engines), define the compatibility checklist the onboarding flow must verify.

Draft v0.1 — for review. Next step after sign-off: phase 1 technical spec (Hub core data model + licensing service API, detailed).