Skip to content

Latest commit

 

History

History
424 lines (333 loc) · 13.6 KB

File metadata and controls

424 lines (333 loc) · 13.6 KB

Notification Subscription Feature - Complete Implementation

Overview

Complete end-to-end implementation of the notification subscription feature for the Tikka raffle platform. Users can subscribe to receive notifications when a raffle ends or when they win.

Feature Summary

Frontend UI Components

  • Subscribe/unsubscribe buttons on raffle detail pages
  • Compact bell icon for raffle cards
  • Settings page with notification preferences
  • Real-time subscription status updates

Backend API

  • RESTful endpoints for subscription management
  • JWT authentication integration
  • Supabase database storage
  • Efficient querying with indexes

Database

  • Notifications table with proper constraints
  • Indexed for performance
  • RLS enabled for security

Architecture

┌─────────────────────────────────────────────────────────────┐
│                         Frontend                             │
│  ┌──────────────────────────────────────────────────────┐  │
│  │  Components                                           │  │
│  │  - NotificationSubscribeButton                        │  │
│  │  - NotificationBellIcon                               │  │
│  │  - NotificationPreferences                            │  │
│  │  - Settings Page                                      │  │
│  └──────────────────────────────────────────────────────┘  │
│  ┌──────────────────────────────────────────────────────┐  │
│  │  Hooks & Services                                     │  │
│  │  - useNotifications (React Hook)                      │  │
│  │  - notificationService (API Client)                   │  │
│  └──────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────┘
                            │
                            │ HTTPS/JWT
                            ▼
┌─────────────────────────────────────────────────────────────┐
│                         Backend                              │
│  ┌──────────────────────────────────────────────────────┐  │
│  │  REST API (NestJS)                                    │  │
│  │  - POST /notifications/subscribe                      │  │
│  │  - DELETE /notifications/subscribe/:raffleId          │  │
│  │  - GET /notifications/subscriptions                   │  │
│  └──────────────────────────────────────────────────────┘  │
│  ┌──────────────────────────────────────────────────────┐  │
│  │  Services                                             │  │
│  │  - NotificationsService (Business Logic)              │  │
│  │  - NotificationService (Supabase Integration)         │  │
│  └──────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────┘
                            │
                            │ Supabase Client
                            ▼
┌─────────────────────────────────────────────────────────────┐
│                       Database                               │
│  ┌──────────────────────────────────────────────────────┐  │
│  │  notifications table                                  │  │
│  │  - id (UUID)                                          │  │
│  │  - raffle_id (INTEGER)                                │  │
│  │  - user_address (VARCHAR)                             │  │
│  │  - channel (VARCHAR)                                  │  │
│  │  - created_at (TIMESTAMP)                             │  │
│  │  UNIQUE(raffle_id, user_address)                      │  │
│  └──────────────────────────────────────────────────────┘  │
└─────────────────────────────────────────────────────────────┘

User Flow

1. Subscribe to Raffle Notifications

User visits raffle detail page
    ↓
Sees "Stay Updated" section with "Notify Me" button
    ↓
Clicks button (if not signed in, prompted to authenticate)
    ↓
Frontend calls POST /notifications/subscribe with JWT
    ↓
Backend validates JWT and creates subscription
    ↓
Subscription stored in database
    ↓
Frontend updates button to show "Unsubscribe"
    ↓
Success message displayed

2. Manage Subscriptions in Settings

User navigates to /settings
    ↓
Clicks "Notifications" tab
    ↓
Frontend calls GET /notifications/subscriptions
    ↓
Backend returns all user subscriptions
    ↓
User sees list of active subscriptions
    ↓
User clicks unsubscribe on a raffle
    ↓
Frontend calls DELETE /notifications/subscribe/:raffleId
    ↓
Backend removes subscription
    ↓
Frontend updates list

Implementation Details

Frontend (Client)

Location: client/

Key Files:

  • src/services/notificationService.ts - API client
  • src/hooks/useNotifications.ts - React hook
  • src/components/NotificationSubscribeButton.tsx - Main button
  • src/components/NotificationBellIcon.tsx - Compact icon
  • src/components/NotificationPreferences.tsx - Settings panel
  • src/pages/Settings.tsx - Settings page
  • src/config/api.ts - API endpoints
  • src/types/types.ts - TypeScript types

Documentation: client/docs/NOTIFICATIONS.md

Backend (Server)

Location: backend/

Key Files:

  • src/api/rest/notifications/notifications.controller.ts - HTTP endpoints
  • src/api/rest/notifications/notifications.service.ts - Business logic
  • src/api/rest/notifications/notifications.module.ts - Module config
  • src/services/notification.service.ts - Supabase integration
  • src/api/rest/notifications/dto/subscribe.dto.ts - Request validation
  • database/migrations/002_notifications.sql - Database schema

Documentation: backend/NOTIFICATION_IMPLEMENTATION.md

Setup Instructions

1. Database Setup

Run the migration in Supabase SQL Editor:

# Navigate to Supabase dashboard
# Go to SQL Editor
# Copy contents of backend/database/migrations/002_notifications.sql
# Execute the SQL

2. Backend Setup

cd backend

# Install dependencies (if not already installed)
npm install

# Ensure environment variables are set
# SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY, JWT_SECRET

# Start the server
npm run dev

Backend will be available at http://localhost:3001

3. Frontend Setup

cd client

# Install dependencies (if not already installed)
npm install

# Ensure environment variables are set
# VITE_API_BASE_URL=http://localhost:3001

# Start the development server
npm run dev

Frontend will be available at http://localhost:5173

Testing

End-to-End Test Flow

  1. Start both servers (backend and frontend)

  2. Sign in with wallet

    • Connect Stellar wallet
    • Complete SIWS authentication
    • Verify JWT token is stored
  3. Subscribe to raffle

    • Navigate to a raffle detail page
    • Click "Notify Me" button
    • Verify button changes to "Unsubscribe"
    • Check success message appears
  4. View subscriptions

    • Navigate to /settings
    • Click "Notifications" tab
    • Verify subscription appears in list
  5. Unsubscribe

    • Click unsubscribe button
    • Verify subscription is removed from list
  6. Test without auth

    • Sign out
    • Try to subscribe
    • Verify authentication prompt appears

API Testing with cURL

See backend/NOTIFICATION_IMPLEMENTATION.md for detailed cURL examples.

API Reference

POST /notifications/subscribe

Subscribe to raffle notifications.

Authentication: Required (JWT)

Request:

{
  "raffleId": 123,
  "channel": "email"
}

Response (201):

{
  "id": "uuid",
  "raffle_id": 123,
  "user_address": "GXXX...",
  "channel": "email",
  "created_at": "2024-02-25T10:30:00Z"
}

DELETE /notifications/subscribe/:raffleId

Unsubscribe from raffle notifications.

Authentication: Required (JWT)

Response: 204 No Content

GET /notifications/subscriptions

Get all user subscriptions.

Authentication: Required (JWT)

Response (200):

[
  {
    "id": "uuid",
    "raffle_id": 123,
    "user_address": "GXXX...",
    "channel": "email",
    "created_at": "2024-02-25T10:30:00Z"
  }
]

Database Schema

CREATE TABLE notifications (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  raffle_id INTEGER NOT NULL,
  user_address VARCHAR(56) NOT NULL,
  channel VARCHAR(20) NOT NULL DEFAULT 'email',
  created_at TIMESTAMP WITH TIME ZONE DEFAULT NOW(),
  CONSTRAINT unique_raffle_user UNIQUE (raffle_id, user_address)
);

-- Indexes for performance
CREATE INDEX idx_notifications_raffle_id ON notifications(raffle_id);
CREATE INDEX idx_notifications_user_address ON notifications(user_address);
CREATE INDEX idx_notifications_created_at ON notifications(created_at DESC);

Security

  • ✅ JWT authentication required for all endpoints
  • ✅ Users can only manage their own subscriptions
  • ✅ Rate limiting via global throttler guard
  • ✅ Input validation with DTOs
  • ✅ SQL injection protection via Supabase
  • ✅ Unique constraint prevents duplicates
  • ✅ RLS enabled for future policies

Performance

  • ✅ Database indexes for fast queries
  • ✅ Efficient Supabase connection pooling
  • ✅ Optimized React hooks with proper dependencies
  • ✅ Minimal re-renders with state management
  • ✅ Lazy loading of subscription data

Future Enhancements

Phase 1: Notification Delivery

  • Email service integration (SendGrid/AWS SES)
  • Push notification service (Firebase/OneSignal)
  • Event listeners for raffle end/win
  • Notification templates

Phase 2: Advanced Features

  • SMS notifications (Twilio)
  • Discord/Telegram webhooks
  • Notification preferences (frequency, types)
  • Notification history/log
  • Batch operations

Phase 3: Analytics

  • Subscription metrics dashboard
  • Delivery success tracking
  • User engagement analytics
  • A/B testing for notifications

Troubleshooting

Frontend Issues

Subscription button not working

  • Check if user is authenticated
  • Verify JWT token in sessionStorage
  • Check browser console for errors
  • Verify API_BASE_URL is correct

Subscriptions not loading

  • Check network tab for API calls
  • Verify backend is running
  • Check JWT token is valid
  • Review backend logs

Backend Issues

Cannot create subscription

  • Verify database migration ran
  • Check Supabase connection
  • Review server logs
  • Verify JWT secret matches

Duplicate subscription error

  • This is expected behavior
  • Frontend should handle gracefully
  • Returns existing subscription

Documentation

  • Frontend: client/docs/NOTIFICATIONS.md
  • Frontend Implementation: client/NOTIFICATION_IMPLEMENTATION.md
  • Backend Implementation: backend/NOTIFICATION_IMPLEMENTATION.md
  • This Document: Complete feature overview

Issue Resolution

This implementation resolves GitHub Issue #27:

✅ Users can subscribe to raffle notifications ✅ Backend supports POST /notifications/subscribe ✅ Client offers clear subscription flow ✅ Settings page for notification preferences ✅ JWT authentication integrated ✅ Database table created ✅ API endpoints implemented ✅ UI components created ✅ Documentation complete

Next Steps

  1. Deploy to staging

    • Run database migration on staging
    • Deploy backend with new endpoints
    • Deploy frontend with new components
    • Test end-to-end flow
  2. Implement notification delivery

    • Choose email service provider
    • Set up event listeners
    • Create notification templates
    • Test delivery flow
  3. Monitor and optimize

    • Track subscription metrics
    • Monitor API performance
    • Gather user feedback
    • Iterate on UX

Support

For questions or issues:

  • Review documentation in client/docs/ and backend/
  • Check server logs for errors
  • Verify database schema in Supabase
  • Test API endpoints with cURL
  • Review browser console for frontend errors