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
);