Skip to main content

Ticker Announcements System

Real-time header announcements with acknowledgment tracking, rich text modals, and per-user/entity alert views.


Overview

The Ticker system provides organization-wide announcements via the admin header bar. Features include:

  1. Sliding Announcements - Animated ticker in header with rotation
  2. Acknowledgment Tracking - Per-user acknowledgment for important messages
  3. Rich Text Modals - Long-form announcements requiring modal interaction
  4. Alert Views - Staff/participant detail pages show targeted alerts
  5. Bootstrap Alert Styling - Color-coded by type (warning, system, announcement)

Architecture

┌─────────────────────────────────────────────────────────┐
│ Admin Header │
│ ┌─────────────────────────────────────────────────┐ │
│ │ RABS: [⚠️ Important Update - Click to Read ACK] │ │
│ └─────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────┐
│ ticker_messages table │
│ - type: announcement | warning | system | success │
│ - target: all | staff | participants │
│ - requires_ack: boolean │
│ - is_rich_text: boolean │
│ - rich_content: HTML (for modals) │
└─────────────────────────────────────────────────────────┘


┌─────────────────────────────────────────────────────────┐
│ ticker_acknowledgments table │
│ - message_id + user_id (unique) │
│ - acknowledged_at timestamp │
└─────────────────────────────────────────────────────────┘

Message Types & Colors

TypeColorUse Case
warning / urgentRed (alert-danger)Critical alerts, safety issues
systemYellow (alert-warning)System maintenance, required actions
announcementBlue (alert-primary)General announcements
successGreen (alert-success)Positive news, achievements

Acknowledgment Flow

Simple Message (requires_ack + no modal)

┌─────────────────────────────────────────────────────────┐
│ ⚠️ Staff meeting tomorrow at 2pm [✓ ACK] │
└─────────────────────────────────────────────────────────┘

▼ Click ACK button

POST /api/v1/ticker/messages/:id/acknowledge


Message removed from ticker

Rich Text Message (requires_ack + is_rich_text)

┌─────────────────────────────────────────────────────────┐
│ ⚠️ New Policy Update [Click to Read & Acknowledge] │
└─────────────────────────────────────────────────────────┘

▼ Click anywhere on alert

┌────────────────────────────────┐
│ Modal Opens (Large) │
│ ┌────────────────────────────┐ │
│ │ New Policy Update (header) │ │
│ ├────────────────────────────┤ │
│ │ │ │
│ │ Rich HTML Content │ │
│ │ - Formatted text │ │
│ │ - Lists, tables │ │
│ │ - Links │ │
│ │ │ │
│ ├────────────────────────────┤ │
│ │ [I have read and acknowledge│ │
│ │ this] │ │
│ └────────────────────────────┘ │
└────────────────────────────────┘

Key Point: Rich text messages with requires_ack=true have NO ACK button in the ticker. Users MUST open the modal and click the acknowledge button to confirm they've read the content.


Database Schema

core_system.ticker_messages

CREATE TABLE core_system.ticker_messages (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
type TEXT NOT NULL DEFAULT 'announcement',
target TEXT NOT NULL DEFAULT 'all', -- 'all', 'staff', 'participants'
text TEXT NOT NULL, -- Ticker display text (or title for rich)
icon TEXT, -- Optional icon class
requires_ack BOOLEAN DEFAULT false,
priority INTEGER DEFAULT 0,
starts_at TIMESTAMP,
expires_at TIMESTAMP,
is_active BOOLEAN DEFAULT true,
is_rich_text BOOLEAN DEFAULT false, -- If true, opens modal
rich_content TEXT, -- HTML content for modal
created_by UUID,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);

core_system.ticker_acknowledgments

CREATE TABLE core_system.ticker_acknowledgments (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
message_id UUID REFERENCES core_system.ticker_messages(id),
user_id UUID NOT NULL,
acknowledged_at TIMESTAMP DEFAULT NOW(),
UNIQUE(message_id, user_id)
);

API Endpoints

Public (Authenticated)

MethodEndpointDescription
GET/api/v1/ticker/messagesGet active announcements for current user
POST/api/v1/ticker/messages/:id/acknowledgeAcknowledge a message

Admin Only

MethodEndpointDescription
GET/api/v1/ticker/messages?all=trueGet all messages (including inactive)
POST/api/v1/ticker/messagesCreate new announcement
PUT/api/v1/ticker/messages/:idUpdate announcement
DELETE/api/v1/ticker/messages/:idDeactivate announcement
GET/api/v1/ticker/messages/:id/acknowledgmentsView who acknowledged

Alerts (Per Entity)

MethodEndpointDescription
GET/api/v1/ticker/alerts/staff/:staffIdAlerts for staff member
GET/api/v1/ticker/alerts/participant/:idAlerts for participant

Frontend Components

admin/src/js/shared/ticker.js

  • initTicker() - Initialize ticker and staff counter
  • renderCurrentMessage() - Render current message with animation
  • showMessageModal() - Open modal for rich text messages
  • acknowledgeMessage() - Send ACK to API
  • rotateNext() - Slide to next message

Admin Settings

Location: App Settings → Ticker section

Features:

  • Create/edit/delete announcements
  • "Requires Modal" checkbox for rich text
  • Summernote rich text editor (loaded from CDN)
  • Preview modal button
  • View acknowledgment counts

Alerts Tab (Staff/Participant Detail)

Both staff and participant detail pages have an "Alerts" tab showing:

  1. Pending Count - Messages requiring acknowledgment
  2. Acknowledged Count - Already acknowledged
  3. Alert List - All targeted announcements with status
┌─────────────────────────────────────────────────────────┐
│ Alerts │
├─────────────────────────────────────────────────────────┤
│ [2 pending] [5 acknowledged] │
│ │
│ ⚠️ announcement | staff Jan 7, 2026 │
│ Important: New safety protocol in effect │
│ ✓ Acknowledged Jan 7, 2026 3:45 PM │
│ │
│ ⚠️ warning | all Jan 6, 2026 │
│ System maintenance tonight 10pm-2am │
│ ⏱️ Awaiting acknowledgment │
└─────────────────────────────────────────────────────────┘

Note: Alerts lookup uses the staff member's linked user_id from core_hr.staff to match acknowledgments.


Animation

Slide Transition

  • Messages slide down when appearing (translateY with opacity)
  • Messages slide up when rotating out
  • 0.25s ease-in/out transitions
  • 6 second rotation interval (configurable)

Pause on Hover

  • Rotation pauses when mouse hovers over ticker
  • Resumes when mouse leaves

Configuration

Environment Variables

None required - uses existing database.

Rotation Timing

// In ticker.js
const state = {
rotationMs: 6000 // 6 seconds between messages
};

Refresh Interval

Messages refresh every 2 minutes to pick up new announcements.


Best Practices

  1. Use rich text for policies - Anything requiring detailed reading
  2. Set expiration dates - Don't leave old announcements lingering
  3. Priority ordering - Higher priority shows first
  4. Target appropriately - Use 'staff' or 'participants' to reduce noise
  5. Check acknowledgment rates - Follow up on low acknowledgment