Skip to content

Admin Communication Hub ​

The platform-admin mission-control surface for the whole communication channel: accounts, templates, policy, campaigns, delivery, cost, alerts — in one place, instead of Meta configuration scattered across features. This page is the hub's module contract: what each module controls, what Meta's APIs can actually feed it, and what phase it belongs to.

THREE THINGS DO NOT EXIST YET, AND THE HUB SITS BEHIND ALL OF THEM

  1. The admin panel surface is not started — apps/web's admin tier has zero code, and ADR-0011/ADR-0028 place it in Stack 1 behind /admin (a trust boundary that must never share a route group with /org).
  2. is_admin() does not exist (QRS-803) — the platform-admin identity is an open ADR-0006 decision, and every read this hub makes is gated on it.
  3. No Communication Hub screen exists in the design project. The admin-panel section (prototype/admin-panel/, desktop only, 12 live sections) was enumerated on 2026-08-21 and holds no communications screen — so this is a design request, not a design pull, and it goes through the Claude Design process first. The spec/prompt is Communication Hub Spec.

Where it sits in the admin panel ​

The admin design's own conventions (from the design registry, round 30+):

  • A new sidebar section (Communications), one page sharing the admin shell — the same "one surface per job" rule that gave Subscriptions and Affiliates their own sections. It is not a tab of Ad Manager: Campaigns.dc.html in the admin panel is ad campaigns (a redirect to AdManager), and message campaigns are a different job with different policy constraints.
  • The channel kill-switch registers in the platform control registry (platform/controls.js, the 28-control MissionControl registry), so pausing all WhatsApp sends is findable from Mission Control like every other platform-wide switch — the left nav never grows an item per switch.
  • High-risk actions confirm with old value, new value and consequence (the MissionControl pattern): kill-switch, category disable, template delete, campaign cancel.

Modules ​

Phases: P1 ships with the transactional money-path messages · P2 with template/campaign operations · P3 with merchant/enterprise exposure. "Meta feed" says where the data really comes from, so no module is designed around an API that does not exist.

#ModuleControlsMeta feedPhase
1Channel healthWABA + phone-number registry, quality rating, messaging-limit tier, webhook health (event lag, last event at), throughputmirrored from phone_number_quality_update / account_update / business_capability_update webhooks + reconciling readsP1
2Templatesfull lifecycle: author → submit to Meta → review status → paused/disabled alerts; usage/dependency view (which platform flows send which template); category + recategorization tracking; library-template shortcutsBusiness Management API CRUD + message_template_status_update / message_template_quality_update / template_category_update webhooksP2 (a read-only status list is P1)
3Sending policy & consenttransactional vs marketing enablement per category, quiet hours, the consent ledger (opt-in/opt-out, source, history), suppression browsing, the kill-switchours — Meta only enforces (per-user marketing caps, error 131049); consent is QRSETU's ledgerP1 (policy) / P2 (ledger UI)
4Message campaignscreate → audience (consented contacts × filters) → schedule → execute → per-campaign delivered/read/failed foldssend API + status webhooks; per-template template_analytics for clicksP3
5Message log & deliverythe communication_messages ledger explorer: per-message event timeline, failed queue with retry state, suppressed reasons, dead-lettered (uncorrelated) eventsmessages status webhooks, recorded verbatimP1
6Usage & costdaily volume + cost by category/number/workspace, our-count-vs-Meta-count reconciliation, per-merchant usage reportingpricing_analytics (COST + VOLUME — the one real cost endpoint) + our ledger foldsP2
7Billing runbookpayment method, invoices, GST, INR migration — surfaced as documented ops tasks with deep links into Meta Billing Hub, not as UI, because no API exists for any of them (verified — see the assessment)none (UI-only at Meta)P2
8Merchant & enterprise configper-workspace communication settings and per-plan usage limits — configuration against feature_grants.limit_value + on_exceed, which already exists; entitlement-gated merchant campaigns; and (much later) tenant-owned WABAs via Embedded Signup. ⚠ No credit-balance or top-up control until Model A collection exists (ADR-0030)ours for limits · Tech Provider / Embedded Signup for tenant senderslimits P2 · campaigns P3 · tenant senders P3+
9Alertsquality drop, template paused, webhook silence, failure-rate spike, 131049 spike, messaging-limit approachderived from 1/5/6 — plus an out-of-band watchdog workflow, the payments-watchdog.yml pattern applied to the channel that is otherwise its own only witnessP2

The three honest answers this hub's spec must carry ​

"Meta billing/usage visibility where APIs support it" — usage and computed cost: yes, via pricing_analytics. Invoices, payment methods, top-up/recharge: no API exists; module 7 is a runbook by design, and drawing a recharge screen would be designing against a capability Meta does not offer (prepaid balances are a BSP-product concept, not a Meta Cloud API one).

"Customer-specific branding" — in R1 every message is sent by QRSETU's own number and display name. Per-merchant sender branding means per-tenant WABAs/numbers (Tech Provider + Embedded Signup + per-number display-name review), which is real but is a P3+ programme, not a hub setting. What IS available per-merchant from day one: template variables carrying the merchant's name, and per-workspace attribution of every message in the ledger. Full assessment, including why a customer's name may not simply be set as the display name on one of our own numbers, and why own-branding and QRSETU-sold credits are mutually exclusive without Solution Partner status: the tenant model · ADR-0030.

"Retry/error handling" — retry is the dispatcher's job (outbox next_attempt_at, capped backoff); the hub shows it and offers a manual re-drive for terminal failures. A paused template or a 131049 marketing cap is not retried on a timer — it is an alert, because resending into a quality problem deepens it.

What stays out of this hub, deliberately ​

  • Org-admin communication policy (an enterprise customer configuring their messaging) — that is the /org portal's job (ADR-0024 oversight model, ADR-0028 trust boundaries). The platform hub administers the platform; conflating the two admin surfaces is the privilege-escalation class CLAUDE.md names.
  • Merchant self-serve campaign authoring — merchant console scope, entitlement-gated (ADR-0021 entitlement axis: visible-locked when unentitled), consuming the same backend.
  • In-app notification preferences — the existing notifications feature owns the in-app half; this hub governs the WhatsApp channel.