Appearance
Communication Hub Spec (admin panel)
The specification for the platform Admin Panel's Communications section — written BEFORE any design exists, per the screen-origination rule. Verified 2026-08-21 by enumerating prototype/admin-panel/ in the design project: 12 live sections, none of them communications, so this is a design REQUEST. The backend contract it draws is ADR-0029 + the module contract + the data model.
Purpose
One mission-control surface for the WhatsApp channel: account/number health, template lifecycle, sending policy and consent, message campaigns, the delivery ledger, usage and cost, and alerts — so Meta configuration never scatters across the application.
User categories served
Platform admin (QRSETU staff) only. Explicitly NOT the org admin (a customer's employee — their communication policy belongs to the future /org portal, a different trust boundary per ADR-0028) and NOT merchants (their campaign authoring is a later merchant-console feature consuming the same backend, entitlement-gated per ADR-0021).
Entry points
Admin sidebar item Communications (new section, one page, sharing the admin shell like Subscriptions/Affiliates); the channel kill-switch also registers in the MissionControl control registry (platform/controls.js) so it is findable from Mission Control and the ⌘K palette; alert deep-links land on the relevant tab.
States
Default · loading · empty (channel not yet configured: setup checklist, not a blank) · error · read-only / permission-denied (the access tweak pattern Curation already uses) · dark. Every list state includes a positive empty state.
Data contract (summary — full contract in the portal pages linked above)
- Health: WABA + numbers with quality rating (GREEN/YELLOW/RED), messaging-limit tier, webhook lag, last-event-at.
- Templates: registry rows keyed name + language; category MARKETING/UTILITY/AUTHENTICATION; Meta status enum (PENDING, APPROVED, REJECTED, PAUSED, DISABLED, IN_APPEAL, …) with rejection reason verbatim; per-template quality;
used_byflow dependencies; recategorization history. Statuses are MIRRORED from Meta — the UI never offers "approve", only "submit to Meta". - Policy & consent: per-category enablement, quiet hours, kill-switch; consent ledger (phone-keyed, source, granted/revoked timeline); suppression browser with reasons.
- Campaigns (message campaigns): draft → scheduled → running → completed/cancelled/failed, audience = consented contacts × filters, counts are folds (delivered/read/failed), per-campaign detail with failure breakdown (incl. per-user-cap error 131049 as its own visible slice).
- Log: per-message timeline (queued → sent → delivered → read, or failed/suppressed with reason), correlation to order/payment/campaign, manual re-drive for terminal failures (high-risk confirm).
- Usage & cost: day × category × workspace volume + Meta-reported cost (
pricing_analytics), our-count-vs-Meta-count reconciliation tiles, and a billing runbook card — deep links into Meta Billing Hub with the INR-migration deadline surfaced. There is no recharge/top-up UI anywhere: no Meta API exists for it. - Alerts: quality drop, template paused, webhook silence, failure spike, limit approach.
Permissions
Everything behind platform-admin identity — which is the open is_admin() decision (QRS-803). High-risk actions (kill-switch, category disable, template delete, campaign cancel, re-drive) use the MissionControl confirm pattern: old value, new value, consequence.
Proactive-value answer
This surface is what keeps the platform's proactive channel trustworthy: it makes quality degradation, template pauses and consent posture visible before they burn the channel (a paused template or a red-quality number silently kills every dependent flow). The intelligence comes from the event ledger and Meta's own webhook signals — no fabricated insight.
Prompt to Claude Design (send-ready)
Upload target: prototype/admin-panel/communications.prompt.md in the prototype project; generate prototype/admin-panel/Communications.dc.html.
Create Communications.dc.html in
prototype/admin-panel/— a new admin-panel section ("Communications") sharing the same sidebar shell as the other admin pages, desktop only. Add the nav item to every admin page, as Subscriptions and Affiliates did. DO NOT use em dashes anywhere in any generated copy, labels, or examples.It is the mission control for the platform's WhatsApp channel (Meta Cloud API, direct). Seven tabs: Health (WhatsApp Business Account and phone numbers: quality rating GREEN or YELLOW or RED, messaging limit tier 250 / 2,000 / 10,000 / 100,000 / Unlimited, webhook freshness with a last-event-at timestamp and a lag alarm) · Templates (registry keyed by name + language; category MARKETING or UTILITY or AUTHENTICATION; Meta-mirrored status chips PENDING, APPROVED, REJECTED with the verbatim reason, PAUSED with a countdown, DISABLED, IN_APPEAL; per-template quality; a "used by" column listing the platform flows that send it; a create/edit drawer that submits to Meta for review, never approves locally; a recategorization notice banner when Meta changed a category) · Policy & Consent (per-category enable switches, quiet hours, the channel kill switch, and a consent ledger browser: phone, category, granted or revoked, source, history; plus a suppression list with reasons) · Campaigns (message campaigns, NOT ad campaigns: draft, scheduled, running, completed, cancelled; audience is consented contacts with filters; detail view shows delivered, read, failed folds and a failure breakdown where the per-user marketing cap error 131049 is its own labelled slice) · Log (the message ledger: per-message timeline queued, sent, delivered, read, or failed or suppressed with reason; correlation chips linking to order, payment, or campaign; a manual re-drive action for terminal failures) · Usage & Cost (daily volume and cost by category and by workspace, an "our count vs Meta count" reconciliation tile pair, and a billing runbook card that deep-links to Meta Billing Hub and surfaces the INR migration deadline; there is deliberately NO recharge or top-up control because Meta has no API for it) · Alerts (quality drop, template paused, webhook silence, failure spike, limit approach; each row deep-links to its tab).
Register the kill switch as a row in
../platform/controls.jsso Mission Control lists it. High-risk actions (kill switch, category disable, template delete, campaign cancel, re-drive) confirm with old value, new value, and consequence, the Mission Control pattern. Status chips are DERIVED from stored data, never set by hand (the Curation pattern). Include default, loading, empty (an unconfigured-channel setup checklist), error, permission-denied (accesstweak), and dark states, with ademoStatetweak. Persist state underqrsetu_comm_*. Charts viacreateElementlike Subscriptions Insights.Out of scope, deliberately: org-admin communication policy (a different portal and trust boundary), merchant self-serve campaign authoring (merchant console, later), tenant-owned WhatsApp account onboarding (a later programme; at most a single "coming later" note), and any prepaid balance or recharge concept.
Registration checklist (the four-part rule)
- [x] Page at
design-system/communication-hub-spec.md - [x] Sidebar entry in
.vitepress/config.mjs - [x] Cross-linked in
screen-coverage-mandate.mdandfoundational-screens.md - [x]
check:portal-navgreen