Admin Cockpit · Surface walkthrough

Cross-product · Telegram channels

A per-surface walkthrough of the Admin Cockpit admin surface: layout, states, interactions, data, and cross-references.

drafted
8sections3 minread

On this page

Context. surface admin · domain cross-product · route /messaging/telegram-channels · auth signed-in (admin) · source apps/oshun/admin/src/app/messaging/telegram-channels/page.tsx

Last walked.

Purpose#

Operator-only registry for public Telegram channels bound to editorial pipelines, takedowns, disclosure copy, and crisis suppression. Cross-product surface: pairs editorial domain content (Veritas / Nyx / Tara / Arete / Nisaba) with the Telegram channel boundary policy from @oshun/messaging-channels.

Entry points#

  • Direct URL — /messaging/telegram-channels (the /messaging parent has no index page)
  • External runbooks / deep links
  • Not in canonical admin IA — no sidebar entry from AdminSidebar

Layout regions#

Page does NOT wrap the body in AdminShell. Renders a plain <main className="adminPage">:

  • adminHeader — eyebrow "Messaging"; h1 "Telegram channels"; copy describing the operator registry; when a telegramChannelBoundary() exists, a <dl className="boundaryStrip"> surfaces Residency, Retention, Consent, Disclosure values from CHANNEL_BOUNDARIES (filtered to channelId === 'telegram-channel')
  • adminTable — six columns: Channel / Domain / Pipeline / Owner role / Crisis suppression / Actions. Rows from SEED_BINDINGS (five hardcoded channels: @oshun_veritas, @oshun_nyx, @oshun_tara, @oshun_arete, @oshun_nisaba)
  • adminSection (bind form) — h2 "Bind a Telegram channel"; form fields Channel handle (pattern @.+), Domain select (5 options), Editorial pipeline select, Owner role input, Locale input, Audited rationale textarea, "Bind channel" submit
  • adminFootnote — explanation of how takedownTelegramChannelPost edits or publishes a correction notice

States#

  • Anonymous → global middleware redirects
  • Boundary present (default true; CHANNEL_BOUNDARIES includes telegram-channel) → boundary strip renders
  • Boundary missing → boundaryStrip omitted (boundary !== undefined guard)
  • Table populated from SEED_BINDINGS constant — always 5 rows
  • Crisis suppression toggle on each row reflects binding.crisisSuppressionEnabled (all true in seed data)
  • Post preview <details> element collapsed by default; opens to show synthesizeTelegramChannelPost output

Interactions#

  • Crisis suppression toggle (per row)
    • Function: <form action={toggleCrisisSuppression}> with hidden handle input; submit dispatches the server action
    • aria-pressed={binding.crisisSuppressionEnabled}
  • Takedown form (per row)
    • Hidden handle input; Rationale input (default Takedown <handle> — audited reason); Takedown submit; calls takedownTelegramChannel server action
  • Post preview (<details> / <summary>)
    • Summary: "Post preview"; pre-formatted body from previewPost(binding) (uses synthesizeTelegramChannelPost)
  • Bind channel form (bottom)
    • Channel handle input — required, pattern @.+, default @oshun_metis
    • Domain select — 5 options (tara / arete / veritas / nyx / nisaba); default tara
    • Editorial pipeline select — 5 options from PIPELINES; default arete-weekly-reflection
    • Owner role input — required; default Editor
    • Locale input — required; default en-US
    • Audited rationale textarea — required; default copy
    • Bind channel (submit) — calls bindTelegramChannel server action

Data & contracts#

  • Reads:
    • CHANNEL_BOUNDARIES from @oshun/messaging-channels (module constant)
    • SEED_BINDINGS — 5 hardcoded channel bindings in the page file
    • PIPELINES — 5 hardcoded pipeline id/label pairs
  • Writes: three server actions from apps/oshun/admin/src/app/messaging/telegram-channels/actions.ts:
    • bindTelegramChannel (form action)
    • takedownTelegramChannel (form action)
    • toggleCrisisSuppression (form action)
  • Helpers used at render:
    • synthesizeTelegramChannelPost(channel, content) produces the preview body
    • takedownTelegramChannelPost(message) produces the action (edit vs correction-notice) — surfaced in the footnote
  • Realtime: None.
  • Auth/role check: only the global middleware (no session fetch in the page; no scope check)

Cross-references#

  • Shell: shell/02-routing-layouts.md
  • Not in canonical IA — /messaging parent has no index page
  • Library: @oshun/messaging-channelsCHANNEL_BOUNDARIES, synthesizeTelegramChannelPost, takedownTelegramChannelPost, EditorialDomain
  • Server actions: apps/oshun/admin/src/app/messaging/telegram-channels/actions.ts
  • Related canonical workspace: ../workspaces/content/editorial.md (editorial pipelines are the upstream source of channel posts)
  • V1 PWA relationship: Telegram bot CTA appears on the V1 PWA home (WALKTHROUGH/customer/02-home-discovery/home.md companion bridge rail); the admin side governs the channel registry

Open questions / known gaps#

  • SEED_BINDINGS is hardcoded in the page file; document where the production registry lives and how it replaces the seed data
  • No session / scope check — the page uses server actions but relies entirely on middleware to gate access. Consider promoting to the canonical workspace pattern
  • Form fields have minimal client-side validation; document the server-action validation contracts (handle pattern, locale format, rationale length)