Skip to content

Real-Time Notification System

Stallio includes a fully functional, real-time notification engine that keeps sellers updated on every aspect of their store operations—from new checkout orders to low stock alerts and billing warnings.

Thrive & Empire Feature Gate

The Notification System is a premium feature gated via the notifications feature key. It is fully accessible to sellers on the Thrive (₹599/mo) and Empire (₹999/mo) plans. Sellers on Spark and Rise plans will see a clean prompt to upgrade when accessing these areas.


Architecture Overview

Stallio's notification system is built on a reactive architecture using Supabase PostgreSQL, Row Level Security (RLS), and Supabase Realtime subscriptions.

flowchart TD
    A[Order Created] -->|Trigger| N[Notification Service]
    B[Order Status Updated] -->|Trigger| N
    C[Low Stock Detected] -->|Trigger| N
    D[Plan Expiry/Change] -->|Trigger| N
    E[System Updates] -->|Manual/Admin| N
    N -->|Insert| DB[(notifications table)]
    DB -->|Supabase Realtime| RT[Real-time Subscription]
    RT -->|Push to UI| UI[Bell Icon + Notifications Page]
    DB -->|Query| UI

Notification Categories & Types

Notifications are classified into four main categories. Users can configure toggles for each category in their settings.

Category Event Type (type) Description Default Trigger
Orders order_placed New customer order received Customer checkout checkout-client
order_status_changed Order status changes (e.g., Pending → Confirmed) Vendor updates status in Admin orders
payment_received Successful Razorpay payment Successful checkout payment
Alerts low_stock Product inventory level drops below threshold Stock decrement during checkout
Billing plan_expiry_warning Warning that subscription will expire soon Daily cron/billing check
plan_expired Subscription expired, features limited Grace period expiry
plan_upgraded Success upgrade to Rise/Thrive/Empire Payment captured webhook
plan_downgraded Plan changed to a lower tier Subscription cancellation
System system_update Platform-wide announcements or maintenance Dispatch by system administrator

Interactive Features

1. The Notification Center

Located at /admin/notifications, the Notification Center is the central dashboard for checking alerts.

  • Category Tabs: Dynamically filter alerts by All, Orders, Alerts, Billing, and System.
  • Mark as Read: Clicking any notification card marks it read in the DB, immediately updating the top navbar indicator badge.
  • Quick Action Shortcuts:
    • Orders: "View Orders" button redirects directly to fulfillment dashboard.
    • Alerts: "Manage Inventory" button redirects to product catalog.
    • Billing: "Manage Plan" redirects to billing settings.
  • Soft Deletion: Hovering over any item displays a trash icon to remove it from your history.

2. Live Bell Dropdown

The top navbar houses the real-time Notification Bell.

  • Realtime Badge: Shows a subtle indicator when new unread notifications arrive.
  • Quick Preview: Shows the 5 most recent notifications.
  • Real-time Subscription: Supabase Realtime listens to database inserts and appends new alerts instantly without requiring a page refresh.

3. Preferences Control Panel

Accessible at /admin/settings/notifications, sellers can customize how and when they get notified.

  • Channel Toggles: Turn on/off categories (Orders, Inventory Alerts, Plan Updates, System Updates).
  • Custom Thresholds: Configure the exact stock level (default: 5) that triggers a low-stock alert.

Developer Guide

If you are expanding Stallio or integrating new events, here is how you can use the Notification System.

Use the service functions in @/lib/notification-service to trigger notifications from backend logic.

import { 
  notifyOrderPlaced, 
  checkAndNotifyLowStock, 
  notifyPlanChange 
} from '@/lib/notification-service'

// Example 1: Notify on order placement (happens in createOrder server action)
await notifyOrderPlaced(storeId, order)

// Example 2: Check stock levels and dispatch alert if below user threshold
await checkAndNotifyLowStock(storeId)

// Example 3: Notify user of plan change (happens in updateStorePlan action)
await notifyPlanChange(userId, 'rise', 'thrive', true)

Wrap components in the admin layout with <NotificationProvider> and consume context using useNotificationContext().

import { useNotificationContext } from '@/contexts/notification-context'
import { useFeatureGate } from '@/hooks/use-feature-gate'

export function NotificationBadge() {
  const { allowed } = useFeatureGate('notifications')
  const { unreadCount, notifications, markAsRead } = useNotificationContext()

  if (!allowed || unreadCount === 0) return null

  return (
    <span className="badge">
      {unreadCount}
    </span>
  )
}

The relational tables created in Supabase. Check 06_notifications.sql for RLS policies.

-- Core notifications log
CREATE TABLE notifications (
    id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
    store_id UUID REFERENCES stores(id) ON DELETE CASCADE,
    user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
    type TEXT NOT NULL,
    category TEXT NOT NULL,
    title TEXT NOT NULL,
    message TEXT NOT NULL,
    metadata JSONB DEFAULT '{}'::jsonb,
    is_read BOOLEAN DEFAULT false NOT NULL,
    created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() NOT NULL
);

-- User channel toggles
CREATE TABLE notification_preferences (
    id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
    user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE UNIQUE,
    orders_enabled BOOLEAN DEFAULT true NOT NULL,
    alerts_enabled BOOLEAN DEFAULT true NOT NULL,
    billing_enabled BOOLEAN DEFAULT true NOT NULL,
    system_enabled BOOLEAN DEFAULT true NOT NULL,
    low_stock_threshold INTEGER DEFAULT 5 NOT NULL,
    updated_at TIMESTAMP WITH TIME ZONE DEFAULT NOW() NOT NULL
  );