StackTrading Docs

SRS: UC_6.2.2 — Flow 24: Notification Matrix

BA in ChargeDate CreatedVersionDocument References
BA Team2026-09-06v1Zapier Integration V7.pdf; UC_4.1.3 BR_4.1.3.2–BR_4.1.3.5; UC_6.1.2 BR_6.1.2.6

UC_6.2.2 — Flow 24: Notification Matrix

This UC owns Flow 24's 4-channel broadcast engine: receiving the Alert_Level/Widget_State/Widget_Short_Text/Notification_Severity/Message_Text payload from the Middleware Hub (constructed by UC_6.1.2 BR_6.1.2.6 at each overnight milestone) and fanning it out to Discord, Slack #risk-ops, the Dashboard NOTIFICATION WebSocket event, and the Dashboard MARKET_STATUS_UPDATE WebSocket event — including server-side [Asset_Class]/[Symbol] placeholder replacement in Message_Text before dispatch. The Alert Level → Widget State/Text/Severity mapping table, the tie-breaking rule for simultaneous webhooks, the motion/severity visual mapping, and the DST handling are already fully specified in UC_4.1.3 BR_4.1.3.2–BR_4.1.3.5 and are cross-referenced here, not duplicated — this UC owns the broadcast/dispatch mechanism (the 4 channels + placeholder replacement), UC_4.1.3 owns the resulting widget's consumption of that broadcast. This UC is unaffected by CHR_67 — Flow 24's trigger is the Node.js Dynamic Timekeeper (UC_6.1.1), a separate provider/mechanism from Flow 23's Finnhub news feed, per CHR_67's explicit "Not Affected" note.

1. Overview

FieldContent
IDUC_6.2.2
Use CaseFlow 24 — Overnight Margin & Swap Monitor (Broadcast): 4-channel notification fan-out + placeholder replacement
DescriptionOn receiving a webhook from the Middleware Hub's Dynamic Timekeeper — payload:Asset_Class, Symbol (nullable), Alert_Level, Widget_State, Widget_Short_Text, Notification_Severity, Message_Text — Flow 24 replaces any [Asset_Class]/[Symbol] tokens in Message_Text server-side, then dispatches to 4 channels in parallel: (1) Discord Global Alert using Message_Text, (2) Slack #risk-ops Internal Alert using Message_Text, (3) Dashboard NOTIFICATION WebSocket event using Notification_Severity + Message_Text to populate the Notification Center, (4) Dashboard MARKET_STATUS_UPDATE WebSocket event using Widget_State + Widget_Short_Text to populate the Market Status Widget. The Node.js middleware is the timeline authority: because asset classes/symbols close or halt at different times (holiday shifts, market-specific structure), webhooks fire independently per asset-class/symbol configuration as each approaches its window — this UC does not batch or coalesce them.
Zapier FlowFlow 24 — Overnight Margin & Swap Monitor (Broadcast)
Zapier Table—(consumes the payload constructed by UC_6.1.2 BR_6.1.2.6; does not read Table A/B/C directly)
3rd PartyDiscord · Slack (#risk-ops) · Dashboard WebSocket (NOTIFICATION, MARKET_STATUS_UPDATE events — consumed by UC_4.1.3 Market Status Widget and UC_4.7.1 Notification Center)

No wireframe of its own — this UC is the broadcast mechanism. The consuming UIs are UC_4.1.3 (Market Status Widget) and UC_4.7.1 (Notification Center), both already fully specified.


2. Trigger

Event-driven — a webhook from the Middleware Hub's Node.js Dynamic Timekeeper arrives at this flow whenever UC_6.1.2 constructs a payload for one of the 8 designated Alert_Level milestones (Warning_60, Warning_30, Warning_10, Lockout_Active, Enforcement_Complete, Halt_Active, Halt_Cleared, Session_Open) for a specific asset class/symbol configuration. Each asset class/symbol's milestones fire independently on their own timeline — this UC has no batching window and reacts to each webhook individually.


3. Pre-conditions

IDCondition
P-1UC_6.1.2 has constructed and dispatched a valid Flow 24 payload for the asset class/symbol in question — this UC has nothing to broadcast otherwise.
P-2The payload'sAlert_Level is one of the 8 values mapped by UC_4.1.3 BR_4.1.3.2 — this UC does not define behavior for an unrecognized Alert_Level value (see Exceptional Flow Exc-1).
P-3Discord, Slack, and the Dashboard WebSocket gateway are reachable for the 4-channel dispatch.

4. Post-conditions

All 4 channels — successful dispatch

  • Discord receives the Global Alert with fully-resolved Message_Text (no unresolved [Asset_Class]/[Symbol] tokens).
  • Slack #risk-ops receives the Internal Alert with the same resolved Message_Text.
  • The Dashboard Notification Center (UC_4.7.1) receives a NOTIFICATION WebSocket event carrying Notification_Severity + Message_Text.
  • The Dashboard Market Status Widget (UC_4.1.3) receives a MARKET_STATUS_UPDATE WebSocket event carrying Widget_State + Widget_Short_Text.

5. Basic Flow

  1. Receive webhook. Flow 24 receives a payload from the Middleware Hub: Asset_Class, Symbol (nullable), Alert_Level, Widget_State, Widget_Short_Text, Notification_Severity, Message_Text. See BR_6.2.2.1.
  2. Resolve placeholders. Any [Asset_Class] or [Symbol] token inside Message_Text is replaced server-side with the payload's actual Asset_Class/Symbol values before any channel dispatch. See BR_6.2.2.2.
  3. Dispatch — Discord. Send a Global Alert to Discord using the resolved Message_Text.
  4. Dispatch — Slack. Send an Internal Alert to Slack #risk-ops using the resolved Message_Text.
  5. Dispatch — Dashboard NOTIFICATION event. Push a NOTIFICATION WebSocket event to the Dashboard, carrying Notification_Severity and the resolved Message_Text, to populate the Notification Center (UC_4.7.1).
  6. Dispatch — Dashboard MARKET_STATUS_UPDATE event. Push a MARKET_STATUS_UPDATE WebSocket event to the Dashboard, carrying Widget_State and Widget_Short_Text, to populate the Market Status Widget (UC_4.1.3 BR_4.1.3.2). See BR_6.2.2.3.
  7. Independent per-asset-class/symbol firing. Because each asset class/symbol has its own timeline (per UC_6.1.1's independent timeline threads), steps 1-6 repeat independently whenever any configuration's milestone is reached — there is no cross-asset-class batching or coalescing. If two webhooks arrive at effectively the same time, UC_4.1.3 BR_4.1.3.3's tie-breaking rule governs display prioritization on the consuming widget — this UC dispatches both regardless of arrival order. See BR_6.2.2.4.

6. Alternative Flows

  • Alt-1 — Symbol is null (asset-class-level milestone, not symbol-specific).

    • Context: some milestones (e.g. Session_Open for an entire asset class) do not target one specific symbol.
    • [Symbol] tokens simply do not appear in that Message_Text template; step 2's replacement has nothing to substitute for Symbol and proceeds normally using only [Asset_Class].

7. Exceptional Flows

  • Exc-1 — Payload's Alert_Level does not match any of the 8 values UC_4.1.3 BR_4.1.3.2 maps.

    • The malformed/unrecognized payload is logged as an error; this UC does not continue with dispatch to any of the 4 channels.

8. Business Rules

BR_6.2.2.1: Flow 24 payload structure

The Middleware Hub webhook payload consumed by this UC has the following structure:

FieldTypeNotes
Asset_ClassString—
SymbolString, NullableNull for asset-class-level milestones (seeAlternative Flow Alt-1)
Alert_LevelStringOne of:Warning_60, Warning_30, Warning_10, Lockout_Active, Enforcement_Complete, Halt_Active, Halt_Cleared, Session_Open
Widget_StateStringOne of:Open, Lockout, Closed, Halted — mapping per UC_4.1.3 BR_4.1.3.2
Widget_Short_TextString, max 15 charse.g."Close in 10m" — mapping per BR_4.1.3.2
Notification_SeverityStringOne of:INFO, WARN, CRITICAL — mapping per BR_4.1.3.2; visual/motion mapping per BR_4.1.3.4
Message_TextStringFull copy text, may contain[Asset_Class]/[Symbol] tokens (see BR_6.2.2.2)

This UC does not itself define the Alert_Level → Widget_State/Widget_Short_Text/Notification_Severity mapping — that table, the tie-breaking rule for simultaneous webhooks, the motion/severity visual mapping, and the DST handling that produces the correct milestone timestamps are all owned by UC_4.1.3 BR_4.1.3.2–BR_4.1.3.5 and are consumed here as given, not restated.

(Source: Zapier Integration V7.pdf §Flow 24, lines 2241-2255)


BR_6.2.2.2: Server-side placeholder replacement

Message_Text may contain [Asset_Class] and/or [Symbol] tokens (e.g. "[Symbol] has entered its scheduled intraday maintenance pause"). These tokens are replaced server-side, using the payload's own Asset_Class/Symbol values, before dispatch to any of the 4 channels (BR_6.2.2.3). No channel — Discord, Slack, or either Dashboard WebSocket event — ever receives an unresolved token; the frontend performs no placeholder substitution of its own (consistent with UC_4.1.3 BR_4.1.3.2's note that the widget only consumes Widget_State/Widget_Short_Text, not the full copy text — the copy text substitution is entirely this UC's responsibility).

(Source: Zapier Integration V7.pdf §Flow 24, lines 2263-2268 — "Message text tokens such as [Symbol] are replaced server-side before execution")


BR_6.2.2.3: 4-channel parallel dispatch

On receiving a valid payload, this UC dispatches to all 4 channels: (1) Discord Global Alert using Message_Text, (2) Slack #risk-ops Internal Alert using Message_Text, (3) Dashboard NOTIFICATION WebSocket event using Notification_Severity + Message_Text, (4) Dashboard MARKET_STATUS_UPDATE WebSocket event using Widget_State + Widget_Short_Text. These 4 dispatches are independent of one another (see Exceptional Flow Exc-2) — this UC does not require all 4 to succeed before considering the webhook processed.

(Source: Zapier Integration V7.pdf §Flow 24, lines 2256-2262 — "Action 1" through "Action 4")


BR_6.2.2.4: Independent per-asset-class/symbol timeline — no batching

The Node.js middleware acts as the core timeline authority, calculating dynamic, asset-specific market milestones from the master reference schedule database (UC_6.1.1). Because asset classes or individual symbols close or halt at different times — due to holiday calendar shifts or market-specific structures — webhooks are triggered independently for each specific configuration as it approaches its window. This UC does not coalesce or batch multiple asset classes' milestones into a single dispatch, even if their timestamps happen to coincide; each fires and is broadcast on its own. Display-side prioritization when two updates land at the same widget slot is UC_4.1.3 BR_4.1.3.3's concern, not this UC's.

(Source: Zapier Integration V7.pdf §Flow 24, lines 2263-2269 — "Operational Control Logic")


9. Update History

DateVersionSectionChange FromChange ToSource
2026-09-06v1All (new)UC_6.2.2 not yet writtenInitial SRS for UC_6.2.2, covering Flow 24's 4-channel broadcast engine and server-side placeholder replacement, cross-referencing (not duplicating) UC_4.1.3's Alert Level mapping table/tie-break/motion/DST rulesZapier Integration V7.pdf lines 2241-2269; UC_4.1.3 BR_4.1.3.2–BR_4.1.3.5; UC_6.1.2 BR_6.1.2.6
2026-09-15v1Exceptional Flows (Exc-1, Exc-2); §9-10 removedExc-1 was flagged⚠️ [ASSUMPTION — pending client confirmation], describing an unrecognized Alert_Level as logged + a Sev-1 alert fired to Slack #risk-ops, still broadcasting an error signal; Exc-2 (channel unreachable) was also flagged as an open assumption; NFRs (old §9) and Acceptance Criteria (old §10) sections presentExc-1 simplified: an unrecognizedAlert_Level is logged as an error and dispatch does not continue to any of the 4 channels — no Sev-1/Slack alert branch. Exc-2 kept as a confirmed assumption (not rewritten) — each of the 4 channel dispatches remains independent/non-blocking, per-channel failure does not block the other 3. NFRs and Acceptance Criteria sections removed; Update History renumbered to §9User instruction (BA session), 2026-09-15

On this page