WeWrite's notification system provides real-time updates to users about important events and interactions. The system is designed to be scalable, user-friendly, and aligned with WeWrite's actual functionality.
The canonical type union lives in app/types/database.ts (NotificationType). Current in-app notification types:
follow— user started following youlink— your page was linked from another pageappend— your page was added/embedded into another pagesystem_announcement— platform-wide announcementemail_verification— prompt to verify emailallocation_threshold— you’ve used ≥90% of this month’s subscription fundspayment_failed|payment_failed_warning|payment_failed_final— subscription charge issuespayout_initiated|payout_processing|payout_completed|payout_failed|payout_retry_scheduled|payout_cancelled|payout_processed— payout lifecycle eventspayout_setup_reminder|payout_setup_final_notice— reminders to finish payout setup when earnings existpayout_unclaimed_warning— approaching unclaimed property deadlines
All types above are present in NotificationType. allocation_threshold currently fires from UsdBalanceContext when allocations reach 90% of the monthly fund; it records once per month per user (keyed by uid + month) and includes usage metrics in metadata.
- Trigger: When a user follows another user
- Message: "{username} started following you"
- Criticality:
normal - Note: Users can only follow other users, not pages
- Trigger: When a user links to your page from their page
- Message: "{username} linked to your page '{page_title}'"
- Criticality:
normal - Implementation: Created automatically when backlinks are updated
- Trigger: When a user adds your page to their page content
- Message: "{username} added your page '{source_page}' to '{target_page}'"
- Criticality:
normal
- Trigger: Creator has earnings in storage but payout setup is incomplete (missing bank/Stripe or unverified email). Admin tools can also trigger an immediate reminder for a user with available earnings and no payouts configured.
- Cadence: Weekly reminders for the first month, then monthly until resolved; stop when payouts are enabled. Admin-triggered reminders respect the same safeguards (e.g., last reminder timestamp).
- Message: "You have funds waiting. Connect payouts and verify your email to receive them." with deep-links to payout setup + email verification.
- User controls: Users can toggle
payout_setup_reminderandpayout_setup_final_noticein Settings → Notifications (push + in-app). - Admin visibility: Admin user detail view shows recently sent payout reminders (title/body/timestamp/available amount) and provides a “Send payout reminder” action when a user has available earnings and no payout setup.
- Unclaimed/Escheat: Track first-accrual date for unpaid funds. Send
payout_unclaimed_warningas the statutory dormancy window approaches. After the legal deadline, funds are locked for escheat and cannot be paid out; record the transfer to the state.
- Trigger: When user needs to verify their email address
- Message: "Please verify your email address to access all features"
- Criticality:
device(highest priority) - Action: Links to settings page
- Trigger: Platform-wide announcements from administrators
- Message: Custom message content
- Criticality:
device
- Trigger: When subscription payment fails
- Message: "Your subscription payment of ${amount} failed. Please update your payment method."
- Criticality:
device - Variants:
payment_failed_warning- First failurepayment_failed_final- Final notice before cancellation
- Trigger: When a user allocates 90% or more of their monthly subscription funds
- Message: "You have used 90% of your monthly funds. Top off or adjust allocations."
- Criticality:
normal - Notes: Fired once per month per user; reset on a new billing month.
- Trigger: When payout is successfully processed
- Message: "Your payout of ${amount} has been processed"
- Criticality:
normal
- Trigger: When payout processing fails
- Message: "There was an issue processing your payout of ${amount}"
- Criticality:
device
payout_initiated- Payout startedpayout_processing- Payout in progress (hidden by default)payout_retry_scheduled- Retry scheduledpayout_cancelled- Payout cancelled
- Highest priority
- Sends push notifications if enabled
- Used for critical account and payment issues
- Examples: Email verification, payment failures, system announcements
- Standard priority
- Shows in notifications tab
- Used for user interactions and completed events
- Examples: New followers, page mentions, completed payouts
Hidden (hidden)
- Lowest priority
- Can be hidden by user preference
- Used for intermediate states
- Examples: Payout processing status
GET /api/notifications- List notificationsPOST /api/notifications- Create notificationPUT /api/notifications- Mark as read/unreadDELETE /api/notifications- Delete notification
users/{userId}/notifications/{notificationId}
{
id: string,
userId: string,
type: NotificationType,
title: string,
message: string,
sourceUserId?: string,
targetPageId?: string,
targetPageTitle?: string,
actionUrl?: string,
metadata?: object,
read: boolean,
readAt?: timestamp,
criticality: 'device' | 'normal' | 'hidden',
createdAt: timestamp
}
- Page Links: Created in
updateBacklinksIndex()when pages link to other pages - Payment Events: Created via Stripe webhooks
- Payout Events: Created by payout processing system
- Email Verification: Created by authentication system
import { createNotification } from '../services/notificationsApi';
await createNotification({
userId: 'target-user-id',
type: 'link',
title: 'Page Mention',
message: 'Someone linked to your page',
sourceUserId: 'source-user-id',
targetPageId: 'page-id',
targetPageTitle: 'Page Title',
metadata: { category: 'engagement' }
});- Shows unread count badge
- Click to open notifications dropdown
- Real-time updates via optimized polling
- Chronological order (newest first)
- Visual distinction for read/unread
- Click to mark as read and navigate to action URL
- Bulk "mark all as read" functionality
- Per-type notification preferences
- Push notification toggles
- In-app notification controls
- Located at
/settings/notifications
The following notification types have been removed as they reference non-existent functionality:
- ❌
like- Page likes don't exist - ❌
comment- Comments don't exist - ❌
page_mention- Replaced withlink - ❌
page_follow- Page following doesn't exist
- Notifications use subcollection structure for scalability
- Unread counts are cached on user documents
- Optimized polling reduces database reads by 90%
- All notifications are user-scoped (no cross-user access)
- Source user validation prevents spoofing
- Rate limiting prevents notification spam
- Test notifications available via
createTestNotification() - Email verification notifications can be force-created for testing
- Comprehensive notification preferences testing in settings
When updating existing code:
- Remove references to
like,comment, andpage_follownotifications - Update
follownotifications to reference users, not pages - Use
linktype for page mentions instead ofpage_mention - Ensure all notification creation goes through the API service
- Current Architecture - System overview
- Analytics Events - Event tracking
- Firebase Optimization Guide - Real-time listener optimization