Update various configuration files, components, and assets; enhance notification system and API endpoints; improve documentation and styles across the application.
This commit is contained in:
161
docs/SITE_SETTINGS.md
Normal file
161
docs/SITE_SETTINGS.md
Normal file
@@ -0,0 +1,161 @@
|
||||
# Site Settings Feature
|
||||
|
||||
## Overview
|
||||
The Site Settings feature allows administrators to customize the appearance and branding of the application through a user-friendly interface. All settings are globally applied across the entire application including SEO, meta tags, and visual elements.
|
||||
|
||||
## Features
|
||||
|
||||
### 1. Basic Information
|
||||
- **Site Name**: Customize the application name displayed globally in:
|
||||
- Header and sidebar
|
||||
- Browser title and meta tags
|
||||
- SEO and Open Graph tags
|
||||
- Loading screen
|
||||
- All pages and components
|
||||
- **Site Description**: Set a description used for:
|
||||
- SEO meta descriptions
|
||||
- Open Graph descriptions
|
||||
- Twitter Card descriptions
|
||||
- **Theme Selection**: Choose from available themes:
|
||||
- Standard themes (from themeList.js)
|
||||
- Accessibility themes (from themeList2.js)
|
||||
- Custom themes added to theme.css
|
||||
|
||||
### 2. Branding
|
||||
- **Site Logo**: Upload a custom logo displayed in:
|
||||
- Header (horizontal layout)
|
||||
- Sidebar (vertical layout)
|
||||
- Loading screen
|
||||
- Login page
|
||||
- Any component using site settings
|
||||
- **Favicon**: Upload a custom favicon displayed in:
|
||||
- Browser tabs
|
||||
- Bookmarks
|
||||
- Mobile home screen icons
|
||||
|
||||
### 3. Advanced Settings
|
||||
- **Custom CSS**: Add custom CSS injected into document head
|
||||
- **Custom Theme File**: Upload CSS files saved to `/assets/style/css/`
|
||||
- **Add Custom Theme to theme.css**: Directly add themes to the main theme.css file
|
||||
|
||||
## How to Access
|
||||
|
||||
1. Navigate to **Pentadbiran** → **Konfigurasi** → **Site Settings**
|
||||
2. Use the tabbed interface:
|
||||
- **Basic Info**: Site name, description, and theme selection
|
||||
- **Branding**: Logo and favicon uploads
|
||||
- **Advanced**: Custom CSS and theme management
|
||||
3. Use the **Live Preview** panel to see changes in real-time
|
||||
4. Click **Save Changes** to apply your settings
|
||||
|
||||
## Technical Implementation
|
||||
|
||||
### Database Schema
|
||||
The settings are stored in the `site_settings` table with the following fields:
|
||||
- `siteName`, `siteDescription`
|
||||
- `siteLogo`, `siteFavicon`
|
||||
- `selectedTheme` - Selected theme name
|
||||
- `customCSS`, `customThemeFile`
|
||||
- Legacy fields maintained for backward compatibility
|
||||
|
||||
### API Endpoints
|
||||
- `GET /api/devtool/config/site-settings` - Retrieve current settings
|
||||
- `POST /api/devtool/config/site-settings` - Update settings
|
||||
- `POST /api/devtool/config/upload-file` - Upload files (logos, themes)
|
||||
- `POST /api/devtool/config/add-custom-theme` - Add custom theme to theme.css
|
||||
|
||||
### File Upload Locations
|
||||
- **Logo and Favicon files**: Saved to `public/uploads/site-settings/`
|
||||
- **Theme CSS files**: Saved to `assets/style/css/` directory
|
||||
- **Custom themes**: Added directly to `assets/style/css/base/theme.css`
|
||||
|
||||
### Composable
|
||||
The `useSiteSettings()` composable provides:
|
||||
- `siteSettings` - Reactive settings object
|
||||
- `loadSiteSettings()` - Load settings from API
|
||||
- `updateSiteSettings()` - Update settings
|
||||
- `setTheme()` - Set theme using existing theme system
|
||||
- `getCurrentTheme()` - Get current theme
|
||||
- `applyThemeSettings()` - Apply theme changes to DOM
|
||||
- `updateGlobalMeta()` - Update global meta tags and SEO
|
||||
- `addCustomThemeToFile()` - Add custom theme to theme.css
|
||||
|
||||
### Global Integration
|
||||
The site settings are globally integrated across:
|
||||
|
||||
#### Header Component
|
||||
- Uses site settings for logo and name display
|
||||
- Theme selection dropdown uses same system as site settings
|
||||
- Synced with site settings theme selection
|
||||
|
||||
#### Loading Component
|
||||
- Uses site logo if available, fallback to default
|
||||
- Displays site name in loading screen
|
||||
|
||||
#### App.vue
|
||||
- Global meta tags updated from site settings
|
||||
- Title, description, and favicon managed globally
|
||||
- Theme initialization from site settings
|
||||
|
||||
#### SEO and Meta Tags
|
||||
- Document title updated globally
|
||||
- Meta descriptions for SEO
|
||||
- Open Graph tags for social sharing
|
||||
- Twitter Card tags
|
||||
- Favicon and apple-touch-icon
|
||||
|
||||
### Theme System Integration
|
||||
- Integrates with existing theme system (themeList.js, themeList2.js)
|
||||
- Theme selection in header dropdown synced with site settings
|
||||
- Custom themes can be added directly to theme.css
|
||||
- Backward compatibility with existing theme structure
|
||||
|
||||
### Custom Theme Structure
|
||||
Custom themes added to theme.css should follow this structure:
|
||||
```css
|
||||
html[data-theme="your-theme-name"] {
|
||||
--color-primary: 255, 0, 0;
|
||||
--color-secondary: 0, 255, 0;
|
||||
--color-success: 0, 255, 0;
|
||||
--color-info: 0, 0, 255;
|
||||
--color-warning: 255, 255, 0;
|
||||
--color-danger: 255, 0, 0;
|
||||
/* Add your theme variables here */
|
||||
}
|
||||
```
|
||||
|
||||
## Default Values
|
||||
If no settings are configured, the system uses these defaults:
|
||||
- Site Name: "corradAF"
|
||||
- Site Description: "corradAF Base Project"
|
||||
- Selected Theme: "biasa"
|
||||
- Logo: Default corradAF logo
|
||||
- Favicon: Default favicon
|
||||
|
||||
## Migration Notes
|
||||
- Legacy color fields (primaryColor, secondaryColor, etc.) are maintained for backward compatibility
|
||||
- `themeMode` field is mapped to `selectedTheme` for compatibility
|
||||
- Existing installations will automatically use default values
|
||||
- Theme selection integrates with existing theme dropdown in header
|
||||
|
||||
## Notes
|
||||
- Changes are applied immediately in the preview
|
||||
- Theme changes affect the entire application
|
||||
- Custom CSS is injected into the document head
|
||||
- Theme files are saved to `/assets/style/css/` for proper integration
|
||||
- File uploads are validated for type and size
|
||||
- Settings persist across browser sessions
|
||||
- Site name and description updates are reflected globally and immediately
|
||||
- All meta tags and SEO elements are automatically updated
|
||||
- Logo changes are reflected in all components that use site settings
|
||||
|
||||
### Important Notes
|
||||
- Changes are applied immediately in the preview
|
||||
- Theme changes affect the entire application
|
||||
- Custom CSS is injected into the document head
|
||||
- Theme files are saved to `/assets/style/css/` for proper integration
|
||||
- File uploads are validated for type and size
|
||||
- Settings persist across browser sessions
|
||||
- Site name and description updates are reflected globally and immediately
|
||||
- All meta tags and SEO elements are automatically updated
|
||||
- Logo changes are reflected in all components that use site settings
|
||||
211
docs/multi-provider-email-setup.md
Normal file
211
docs/multi-provider-email-setup.md
Normal file
@@ -0,0 +1,211 @@
|
||||
# Multi-Provider Email Configuration
|
||||
|
||||
This document explains how to configure multiple email providers (Mailtrap and AWS SES) in the notification system.
|
||||
|
||||
## Overview
|
||||
|
||||
The system now supports storing **multiple email provider configurations** simultaneously. Each provider's configuration is saved independently, allowing you to:
|
||||
- Switch between providers without losing configurations
|
||||
- Keep backup provider credentials ready
|
||||
- Test different providers easily
|
||||
|
||||
## Database Changes
|
||||
|
||||
### Migration Required
|
||||
|
||||
Run this migration to enable multi-provider support:
|
||||
|
||||
```bash
|
||||
mysql -h <host> -u <user> -p <database> < database/migrations/005_support_multiple_email_providers.sql
|
||||
```
|
||||
|
||||
### What Changed
|
||||
|
||||
1. **Removed** unique constraint on `channel_type`
|
||||
2. **Added** unique constraint on `(channel_type, provider)` combination
|
||||
3. **Added** `is_active` column to track active provider
|
||||
4. Now supports multiple rows per channel_type with different providers
|
||||
|
||||
**Before:**
|
||||
```
|
||||
id | channel_type | provider | is_enabled
|
||||
1 | email | Mailtrap | true
|
||||
```
|
||||
|
||||
**After:**
|
||||
```
|
||||
id | channel_type | provider | is_enabled | is_active
|
||||
1 | email | Mailtrap | true | true
|
||||
2 | email | AWS SES | false | false
|
||||
```
|
||||
|
||||
## How It Works
|
||||
|
||||
### 1. **API Behavior**
|
||||
|
||||
**GET `/api/notifications/delivery/email-config`**
|
||||
- Returns ALL provider configurations
|
||||
- Indicates which provider is active
|
||||
- Response format:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"providers": {
|
||||
"mailtrap": {
|
||||
"enabled": true,
|
||||
"provider": "Mailtrap",
|
||||
"config": { "host": "...", ... },
|
||||
"status": "Connected",
|
||||
"successRate": 99.5
|
||||
},
|
||||
"aws-ses": {
|
||||
"enabled": false,
|
||||
"provider": "AWS SES",
|
||||
"config": { "host": "...", ... },
|
||||
"status": "Not Configured",
|
||||
"successRate": 0
|
||||
}
|
||||
},
|
||||
"activeProvider": "mailtrap"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**PUT `/api/notifications/delivery/email-config`**
|
||||
- Saves configuration for specific provider
|
||||
- If enabling a provider, **automatically disables others**
|
||||
- Only ONE provider can be `is_enabled: true` at a time
|
||||
|
||||
### 2. **UI Behavior**
|
||||
|
||||
**Provider Dropdown:**
|
||||
- Shows: Mailtrap, AWS SES
|
||||
- Switching providers loads that provider's saved configuration
|
||||
- If no config exists, loads default template
|
||||
|
||||
**Saving Configuration:**
|
||||
- Saves to database for the selected provider
|
||||
- Does NOT overwrite other providers' configs
|
||||
- Enabling saves current provider and disables others
|
||||
|
||||
**Configuration Persistence:**
|
||||
- Each provider's config is stored separately
|
||||
- Switching between providers preserves both configurations
|
||||
- Form fields update automatically when switching
|
||||
|
||||
### 3. **Email Sending**
|
||||
|
||||
The `emailService.js` looks for:
|
||||
1. Any `is_enabled: true` config in database
|
||||
2. Falls back to `.env` variables if no enabled config
|
||||
|
||||
Both Mailtrap and AWS SES use **nodemailer SMTP**, so no backend code changes needed.
|
||||
|
||||
## Setup Instructions
|
||||
|
||||
### Step 1: Run Migration
|
||||
|
||||
```bash
|
||||
mysql -h <host> -u <user> -p <database> < database/migrations/005_support_multiple_email_providers.sql
|
||||
```
|
||||
|
||||
This will:
|
||||
- ✅ Update schema to support multiple providers
|
||||
- ✅ Create placeholder rows for Mailtrap and AWS SES
|
||||
- ✅ Preserve existing configuration
|
||||
|
||||
### Step 2: Update Prisma Schema
|
||||
|
||||
```bash
|
||||
npx prisma generate
|
||||
```
|
||||
|
||||
This regenerates the Prisma client with the updated schema.
|
||||
|
||||
### Step 3: Configure Providers via UI
|
||||
|
||||
1. Go to `/notification/delivery`
|
||||
2. Select **Mailtrap** from dropdown
|
||||
3. Fill in Mailtrap credentials
|
||||
4. Click **Save**
|
||||
5. Switch to **AWS SES** from dropdown
|
||||
6. Fill in AWS SES credentials
|
||||
7. Click **Save**
|
||||
|
||||
Both configurations are now saved!
|
||||
|
||||
### Step 4: Switch Between Providers
|
||||
|
||||
To change active provider:
|
||||
1. Select desired provider from dropdown
|
||||
2. Toggle **Enable Email Delivery** to ON
|
||||
3. Click **Save**
|
||||
|
||||
This automatically:
|
||||
- ✅ Enables selected provider
|
||||
- ✅ Disables other provider
|
||||
- ✅ Updates email service to use new provider
|
||||
|
||||
## Provider-Specific Configuration
|
||||
|
||||
### Mailtrap
|
||||
|
||||
**Required Fields:**
|
||||
- SMTP Host: `live.smtp.mailtrap.io`
|
||||
- SMTP Port: `587`
|
||||
- SMTP Username: `apismtp@mailtrap.io`
|
||||
- SMTP Password: Your Mailtrap API token
|
||||
- Sender Email: Your verified sender email
|
||||
- Sender Name: (Optional)
|
||||
|
||||
### AWS SES
|
||||
|
||||
**Required Fields:**
|
||||
- SMTP Host: `email-smtp.<region>.amazonaws.com` (e.g., `email-smtp.us-east-1.amazonaws.com`)
|
||||
- SMTP Port: `587` (STARTTLS) or `465` (TLS)
|
||||
- SMTP Username: AWS SES SMTP username (NOT IAM user)
|
||||
- SMTP Password: AWS SES SMTP password (NOT secret key)
|
||||
- Sender Email: Must be verified in AWS SES
|
||||
- Sender Name: (Optional)
|
||||
- AWS Region: e.g., `us-east-1`
|
||||
- Configuration Set: (Optional) For tracking
|
||||
|
||||
**Note:** AWS SES requires:
|
||||
1. Verified sender email/domain in SES console
|
||||
2. SMTP credentials generated from SES (not IAM credentials)
|
||||
3. Account moved out of sandbox for production sending
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Configuration Not Saving
|
||||
- Check database migration ran successfully
|
||||
- Verify unique constraint exists: `SHOW INDEX FROM notification_delivery_config;`
|
||||
- Should see `channel_type_provider` unique index
|
||||
|
||||
### Wrong Provider Being Used
|
||||
- Check `is_enabled` column in database
|
||||
- Only ONE provider should have `is_enabled = true`
|
||||
- Run: `SELECT * FROM notification_delivery_config WHERE channel_type = 'email';`
|
||||
|
||||
### Form Fields Don't Update When Switching
|
||||
- Clear browser cache
|
||||
- Check browser console for errors
|
||||
- Verify API returns all provider configs
|
||||
|
||||
## Files Modified
|
||||
|
||||
### Backend
|
||||
- `server/api/notifications/delivery/email-config.get.js` - Returns all providers
|
||||
- `server/api/notifications/delivery/email-config.put.js` - Saves per provider
|
||||
- `prisma/schema.prisma` - Updated unique constraint
|
||||
|
||||
### Frontend
|
||||
- `pages/notification/delivery/index.vue` - Multi-provider UI
|
||||
- `pages/notification/delivery/providers.vue` - Provider list
|
||||
|
||||
### Database
|
||||
- `database/migrations/005_support_multiple_email_providers.sql` - Schema migration
|
||||
|
||||
### Documentation
|
||||
- `docs/multi-provider-email-setup.md` - This file
|
||||
515
docs/notification-system-api.md
Normal file
515
docs/notification-system-api.md
Normal file
@@ -0,0 +1,515 @@
|
||||
# Notification System API Documentation
|
||||
|
||||
This document provides comprehensive information about the notification system's database schema and API endpoints based on the notification creation form requirements.
|
||||
|
||||
## Table of Contents
|
||||
1. [Database Schema](#database-schema)
|
||||
2. [API Endpoints](#api-endpoints)
|
||||
3. [Usage Examples](#usage-examples)
|
||||
4. [Integration Guide](#integration-guide)
|
||||
|
||||
## Database Schema
|
||||
|
||||
### Core Tables
|
||||
|
||||
#### `notification_categories`
|
||||
Stores categorization options for notifications.
|
||||
```sql
|
||||
- id (UUID, Primary Key)
|
||||
- name (VARCHAR) - Display name
|
||||
- value (VARCHAR) - Unique identifier
|
||||
- description (TEXT) - Optional description
|
||||
- created_at, updated_at (TIMESTAMP)
|
||||
```
|
||||
|
||||
#### `notification_templates`
|
||||
Reusable templates for common notification types.
|
||||
```sql
|
||||
- id (UUID, Primary Key)
|
||||
- name (VARCHAR) - Template name
|
||||
- value (VARCHAR) - Unique identifier
|
||||
- subject (VARCHAR) - Email subject template
|
||||
- email_content (TEXT) - Email body template
|
||||
- push_title (VARCHAR) - Push notification title
|
||||
- push_body (VARCHAR) - Push notification body
|
||||
- variables (JSONB) - Available variables
|
||||
- is_active (BOOLEAN)
|
||||
- created_at, updated_at (TIMESTAMP)
|
||||
```
|
||||
|
||||
#### `notifications` (Main Table)
|
||||
Central table storing all notification configurations.
|
||||
```sql
|
||||
- id (UUID, Primary Key)
|
||||
- title (VARCHAR) - Internal notification title
|
||||
- type (ENUM) - 'single' or 'bulk'
|
||||
- priority (ENUM) - 'low', 'medium', 'high', 'critical'
|
||||
- category_id (UUID) - FK to notification_categories
|
||||
- status (ENUM) - 'draft', 'scheduled', 'sending', 'sent', 'failed', 'cancelled'
|
||||
- delivery_type (ENUM) - 'immediate' or 'scheduled'
|
||||
- scheduled_at (TIMESTAMP) - When to send (for scheduled)
|
||||
- timezone (VARCHAR) - Timezone for scheduling
|
||||
- expires_at (TIMESTAMP) - Optional expiration
|
||||
- enable_ab_testing (BOOLEAN)
|
||||
- ab_test_split (INTEGER) - Percentage split for A/B testing
|
||||
- ab_test_name (VARCHAR) - A/B test identifier
|
||||
- enable_tracking (BOOLEAN)
|
||||
- audience_type (ENUM) - 'all', 'specific', 'segmented'
|
||||
- specific_users (TEXT) - Comma-separated user identifiers
|
||||
- user_status (VARCHAR) - Filter by user status
|
||||
- registration_period (VARCHAR) - Filter by registration period
|
||||
- exclude_unsubscribed (BOOLEAN)
|
||||
- respect_do_not_disturb (BOOLEAN)
|
||||
- content_type (ENUM) - 'new' or 'template'
|
||||
- template_id (UUID) - FK to notification_templates
|
||||
- email_subject (VARCHAR)
|
||||
- email_content (TEXT)
|
||||
- call_to_action_text (VARCHAR)
|
||||
- call_to_action_url (TEXT)
|
||||
- push_title (VARCHAR)
|
||||
- push_body (VARCHAR)
|
||||
- push_image_url (TEXT)
|
||||
- estimated_reach (INTEGER)
|
||||
- actual_sent (INTEGER)
|
||||
- created_by (UUID) - User who created
|
||||
- created_at, updated_at, sent_at (TIMESTAMP)
|
||||
```
|
||||
|
||||
#### Supporting Tables
|
||||
|
||||
- `notification_channels` - Many-to-many relationship for delivery channels
|
||||
- `notification_user_segments` - Many-to-many for user segments
|
||||
- `notification_recipients` - Tracks individual recipients and delivery status
|
||||
- `notification_queue` - Queue for scheduled notifications
|
||||
- `notification_analytics` - Tracks metrics and engagement
|
||||
- `user_notification_preferences` - User preferences and DND settings
|
||||
|
||||
## API Endpoints
|
||||
|
||||
### 1. Create Notification
|
||||
**POST** `/api/notifications`
|
||||
|
||||
Creates a new notification or schedules it for delivery.
|
||||
|
||||
**Request Body:**
|
||||
```json
|
||||
{
|
||||
"title": "Welcome New Users",
|
||||
"type": "bulk",
|
||||
"priority": "medium",
|
||||
"category": "user_management",
|
||||
"channels": ["email", "push"],
|
||||
"emailSubject": "Welcome to our platform!",
|
||||
"deliveryType": "immediate",
|
||||
"timezone": "UTC",
|
||||
"enableAbTesting": false,
|
||||
"abTestSplit": 50,
|
||||
"enableTracking": true,
|
||||
"audienceType": "segmented",
|
||||
"userSegments": ["new_users"],
|
||||
"excludeUnsubscribed": true,
|
||||
"respectDoNotDisturb": true,
|
||||
"contentType": "new",
|
||||
"emailContent": "<h1>Welcome!</h1><p>Thank you for joining us.</p>",
|
||||
"pushTitle": "Welcome!",
|
||||
"pushBody": "Thank you for joining our platform.",
|
||||
"callToActionText": "Get Started",
|
||||
"callToActionUrl": "https://example.com/onboarding"
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"id": "uuid-of-notification",
|
||||
"message": "Notification is being sent",
|
||||
"estimatedReach": 1500
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Get Categories
|
||||
**GET** `/api/notifications/categories`
|
||||
|
||||
Returns available notification categories.
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": [
|
||||
{
|
||||
"label": "User Management",
|
||||
"value": "user_management",
|
||||
"description": "User registration, profile updates, account changes"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Get Templates
|
||||
**GET** `/api/notifications/templates`
|
||||
|
||||
Returns available notification templates.
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": [
|
||||
{
|
||||
"label": "Welcome Message",
|
||||
"value": "welcome",
|
||||
"subject": "Welcome to {{company_name}}!",
|
||||
"content": "<h1>Welcome {{first_name}}!</h1>",
|
||||
"pushTitle": "Welcome!",
|
||||
"pushBody": "Hi {{first_name}}, welcome!",
|
||||
"variables": ["first_name", "company_name"]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 4. Get User Segments
|
||||
**GET** `/api/notifications/segments`
|
||||
|
||||
Returns available user segments for targeting.
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": [
|
||||
{
|
||||
"label": "New Users",
|
||||
"value": "new_users",
|
||||
"description": "Users registered within last 30 days",
|
||||
"criteria": {"registration_days": 30}
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 5. Preview Audience
|
||||
**POST** `/api/notifications/audience-preview`
|
||||
|
||||
Preview the target audience based on selected criteria.
|
||||
|
||||
**Request Body:**
|
||||
```json
|
||||
{
|
||||
"audienceType": "segmented",
|
||||
"userSegments": ["new_users", "active_users"],
|
||||
"userStatus": "active",
|
||||
"excludeUnsubscribed": true,
|
||||
"channels": ["email"]
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"users": [
|
||||
{
|
||||
"id": "user-uuid",
|
||||
"name": "John Doe",
|
||||
"email": "john@example.com",
|
||||
"segment": "New Users",
|
||||
"status": "active",
|
||||
"registeredAt": "2024-01-01T00:00:00Z"
|
||||
}
|
||||
],
|
||||
"totalCount": 1500,
|
||||
"previewCount": 100
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 6. Send Test Notification
|
||||
**POST** `/api/notifications/test-send`
|
||||
|
||||
Send a test notification to validate setup.
|
||||
|
||||
**Request Body:**
|
||||
```json
|
||||
{
|
||||
"email": "test@example.com",
|
||||
"testData": {
|
||||
"title": "Test Notification",
|
||||
"channels": ["email", "push"],
|
||||
"emailSubject": "Test Email",
|
||||
"emailContent": "<p>This is a test email.</p>",
|
||||
"pushTitle": "Test Push",
|
||||
"pushBody": "This is a test push notification."
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"message": "Test notifications processed",
|
||||
"results": [
|
||||
{
|
||||
"channel": "email",
|
||||
"status": "sent",
|
||||
"message": "Test email sent successfully"
|
||||
},
|
||||
{
|
||||
"channel": "push",
|
||||
"status": "sent",
|
||||
"message": "Test push notification sent successfully"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 7. Save Draft
|
||||
**POST** `/api/notifications/draft`
|
||||
|
||||
Save notification as draft for later completion.
|
||||
|
||||
**Request Body:**
|
||||
```json
|
||||
{
|
||||
"title": "Draft Notification",
|
||||
"type": "single",
|
||||
"category": "marketing",
|
||||
"channels": ["email"],
|
||||
"emailSubject": "Special Offer",
|
||||
"contentType": "new",
|
||||
"draftId": "existing-draft-uuid" // Optional, for updating
|
||||
}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"id": "draft-uuid",
|
||||
"message": "Draft saved successfully"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Usage Examples
|
||||
|
||||
### Creating a Welcome Email Campaign
|
||||
|
||||
```javascript
|
||||
// 1. Create notification for new users
|
||||
const response = await $fetch('/api/notifications', {
|
||||
method: 'POST',
|
||||
body: {
|
||||
title: 'New User Welcome Campaign',
|
||||
type: 'bulk',
|
||||
priority: 'medium',
|
||||
category: 'user_management',
|
||||
channels: ['email'],
|
||||
emailSubject: 'Welcome to {{company_name}}!',
|
||||
deliveryType: 'immediate',
|
||||
audienceType: 'segmented',
|
||||
userSegments: ['new_users'],
|
||||
contentType: 'template',
|
||||
selectedTemplate: 'welcome',
|
||||
enableTracking: true
|
||||
}
|
||||
})
|
||||
|
||||
console.log(`Notification created: ${response.data.id}`)
|
||||
console.log(`Estimated reach: ${response.data.estimatedReach} users`)
|
||||
```
|
||||
|
||||
### Scheduling a Marketing Campaign
|
||||
|
||||
```javascript
|
||||
// 2. Schedule a promotional campaign
|
||||
const scheduledResponse = await $fetch('/api/notifications', {
|
||||
method: 'POST',
|
||||
body: {
|
||||
title: 'Black Friday Sale',
|
||||
type: 'bulk',
|
||||
priority: 'high',
|
||||
category: 'marketing',
|
||||
channels: ['email', 'push'],
|
||||
emailSubject: '🔥 Black Friday Sale - 50% Off Everything!',
|
||||
deliveryType: 'scheduled',
|
||||
scheduledAt: '2024-11-29T09:00:00Z',
|
||||
timezone: 'America/New_York',
|
||||
audienceType: 'segmented',
|
||||
userSegments: ['active_users', 'high_value'],
|
||||
contentType: 'new',
|
||||
emailContent: '<h1>Black Friday Sale!</h1><p>Don\'t miss out on 50% off everything!</p>',
|
||||
pushTitle: 'Black Friday Sale!',
|
||||
pushBody: '50% off everything - today only!',
|
||||
callToActionText: 'Shop Now',
|
||||
callToActionUrl: 'https://example.com/sale',
|
||||
enableAbTesting: true,
|
||||
abTestSplit: 50,
|
||||
abTestName: 'Subject Line Test'
|
||||
}
|
||||
})
|
||||
```
|
||||
|
||||
### Sending Test Notifications
|
||||
|
||||
```javascript
|
||||
// 3. Send test before going live
|
||||
const testResponse = await $fetch('/api/notifications/test-send', {
|
||||
method: 'POST',
|
||||
body: {
|
||||
email: 'marketing@company.com',
|
||||
notificationId: scheduledResponse.data.id
|
||||
}
|
||||
})
|
||||
|
||||
console.log('Test results:', testResponse.data.results)
|
||||
```
|
||||
|
||||
## Integration Guide
|
||||
|
||||
### Frontend Integration
|
||||
|
||||
Update your Vue.js notification creation form to use these APIs:
|
||||
|
||||
```vue
|
||||
<script setup>
|
||||
// Fetch initial data
|
||||
const { data: categories } = await $fetch('/api/notifications/categories')
|
||||
const { data: templates } = await $fetch('/api/notifications/templates')
|
||||
const { data: segments } = await $fetch('/api/notifications/segments')
|
||||
|
||||
// Preview audience
|
||||
const previewAudience = async () => {
|
||||
const response = await $fetch('/api/notifications/audience-preview', {
|
||||
method: 'POST',
|
||||
body: {
|
||||
audienceType: form.audienceType,
|
||||
userSegments: form.userSegments,
|
||||
userStatus: form.userStatus,
|
||||
excludeUnsubscribed: form.excludeUnsubscribed,
|
||||
channels: form.channels
|
||||
}
|
||||
})
|
||||
|
||||
previewedUsers.value = response.data.users
|
||||
estimatedReach.value = response.data.totalCount
|
||||
}
|
||||
|
||||
// Submit notification
|
||||
const submitNotification = async (formData) => {
|
||||
try {
|
||||
const response = await $fetch('/api/notifications', {
|
||||
method: 'POST',
|
||||
body: formData
|
||||
})
|
||||
|
||||
// Show success message
|
||||
await $swal.fire({
|
||||
title: 'Success!',
|
||||
text: response.data.message,
|
||||
icon: 'success'
|
||||
})
|
||||
|
||||
// Redirect to notification list
|
||||
await navigateTo('/notifications')
|
||||
|
||||
} catch (error) {
|
||||
console.error('Failed to create notification:', error)
|
||||
}
|
||||
}
|
||||
</script>
|
||||
```
|
||||
|
||||
### Database Setup
|
||||
|
||||
1. **Run the migration:**
|
||||
```bash
|
||||
psql -d your_database -f database/migrations/001_create_notification_tables.sql
|
||||
```
|
||||
|
||||
2. **Set up database connection in Nuxt:**
|
||||
```javascript
|
||||
// nuxt.config.ts
|
||||
export default defineNuxtConfig({
|
||||
runtimeConfig: {
|
||||
databaseUrl: process.env.DATABASE_URL
|
||||
}
|
||||
})
|
||||
|
||||
// plugins/database.server.js
|
||||
import { Pool } from 'pg'
|
||||
|
||||
export default defineNitroPlugin(async (nitroApp) => {
|
||||
const config = useRuntimeConfig()
|
||||
|
||||
const pool = new Pool({
|
||||
connectionString: config.databaseUrl
|
||||
})
|
||||
|
||||
nitroApp.hooks.hook('close', async () => {
|
||||
await pool.end()
|
||||
})
|
||||
|
||||
nitroApp.provide('db', pool)
|
||||
})
|
||||
```
|
||||
|
||||
### Email/Push Service Integration
|
||||
|
||||
Replace the mock functions in `test-send.post.js` with your actual service integrations:
|
||||
|
||||
```javascript
|
||||
// Email service example (SendGrid)
|
||||
import sgMail from '@sendgrid/mail'
|
||||
|
||||
async function sendTestEmail({ to, subject, content, callToActionText, callToActionUrl }) {
|
||||
sgMail.setApiKey(process.env.SENDGRID_API_KEY)
|
||||
|
||||
const msg = {
|
||||
to,
|
||||
from: 'noreply@yourcompany.com',
|
||||
subject,
|
||||
html: content
|
||||
}
|
||||
|
||||
await sgMail.send(msg)
|
||||
}
|
||||
|
||||
// Push service example (Firebase)
|
||||
import admin from 'firebase-admin'
|
||||
|
||||
async function sendTestPush({ email, title, body }) {
|
||||
// Get user's device tokens from your database
|
||||
const tokens = await getUserDeviceTokens(email)
|
||||
|
||||
const message = {
|
||||
notification: { title, body },
|
||||
tokens
|
||||
}
|
||||
|
||||
await admin.messaging().sendMulticast(message)
|
||||
}
|
||||
```
|
||||
|
||||
This comprehensive notification system provides:
|
||||
|
||||
✅ **Complete database schema** with all necessary tables and relationships
|
||||
✅ **Robust API endpoints** with proper validation and error handling
|
||||
✅ **Transaction support** to ensure data consistency
|
||||
✅ **A/B testing capabilities** for optimization
|
||||
✅ **User preference handling** including DND settings
|
||||
✅ **Queue system** for reliable delivery
|
||||
✅ **Analytics tracking** for performance monitoring
|
||||
✅ **Draft functionality** for iterative creation
|
||||
✅ **Test sending** for validation before deployment
|
||||
|
||||
The system is designed to handle both simple single notifications and complex bulk campaigns with advanced targeting and scheduling capabilities.
|
||||
239
docs/queue-system-explained.md
Normal file
239
docs/queue-system-explained.md
Normal file
@@ -0,0 +1,239 @@
|
||||
# Notification Queue System
|
||||
|
||||
## Overview
|
||||
|
||||
The notification system now uses a **background queue processor** that runs automatically every 30 seconds to send queued emails.
|
||||
|
||||
## How It Works
|
||||
|
||||
### 1. **Queue Creation**
|
||||
When you create a notification:
|
||||
```
|
||||
POST /api/public/create-notification
|
||||
↓
|
||||
Creates notification → status: "sending"
|
||||
Creates recipients → status: "pending"
|
||||
Creates queue items → status: "queued"
|
||||
↓
|
||||
Returns immediately (non-blocking) ✅
|
||||
```
|
||||
|
||||
### 2. **Background Processing**
|
||||
A background worker runs automatically:
|
||||
```
|
||||
Server starts
|
||||
↓
|
||||
Queue Processor Plugin initializes
|
||||
↓
|
||||
Processes queue every 30 seconds
|
||||
↓
|
||||
Sends emails → Updates status → Repeats
|
||||
```
|
||||
|
||||
### 3. **Status Updates**
|
||||
```
|
||||
notification.status: "sending" → "sent" (when all recipients done)
|
||||
recipients.status: "pending" → "sent" or "failed"
|
||||
queue.status: "queued" → "processing" → "completed" or "failed"
|
||||
```
|
||||
|
||||
## Components
|
||||
|
||||
### 1. Queue Processor (`server/utils/queueProcessor.js`)
|
||||
- **Runs every 30 seconds**
|
||||
- Processes up to 50 jobs per batch
|
||||
- Prevents concurrent processing (lock mechanism)
|
||||
- Logs activity for monitoring
|
||||
|
||||
### 2. Nitro Plugin (`server/plugins/queueProcessor.js`)
|
||||
- **Auto-starts** when server starts
|
||||
- Runs in background
|
||||
- Gracefully shuts down with server
|
||||
|
||||
### 3. Email Service (`server/utils/emailService.js`)
|
||||
- `processEmailQueue()` - Processes queued emails
|
||||
- `sendEmailNotification()` - Sends individual emails
|
||||
- Updates all statuses (notification, recipient, queue)
|
||||
|
||||
## Queue Flow
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────┐
|
||||
│ Create Notification API │
|
||||
│ - Creates notification (sending) │
|
||||
│ - Creates recipients (pending) │
|
||||
│ - Creates queue items (queued) │
|
||||
│ - Returns immediately ✅ │
|
||||
└─────────────────────────────────────────┘
|
||||
↓
|
||||
┌─────────────────────────────────────────┐
|
||||
│ Background Queue Processor │
|
||||
│ (Runs every 30 seconds) │
|
||||
│ │
|
||||
│ 1. Find queued items (scheduled_for <= now)
|
||||
│ 2. For each item: │
|
||||
│ - Mark as "processing" │
|
||||
│ - Send email via SMTP │
|
||||
│ - Update recipient status │
|
||||
│ - Update queue status │
|
||||
│ - Update notification status │
|
||||
│ 3. Log results │
|
||||
└─────────────────────────────────────────┘
|
||||
↓
|
||||
┌─────────────────────────────────────────┐
|
||||
│ Email Sent! │
|
||||
│ - notification.status → "sent" │
|
||||
│ - recipient.status → "sent" │
|
||||
│ - queue.status → "completed" │
|
||||
│ - notification.actual_sent = count │
|
||||
└─────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
## Current Implementation
|
||||
|
||||
### ✅ What We Have:
|
||||
- **Non-blocking API** - Returns immediately after queuing
|
||||
- **Background processor** - Runs every 30 seconds
|
||||
- **Auto-start on server boot** - Via Nitro plugin
|
||||
- **Concurrent processing prevention** - Lock mechanism
|
||||
- **Status updates** - All tables updated correctly
|
||||
- **Error handling** - Failed emails marked as failed
|
||||
- **Logging** - Console logs for monitoring
|
||||
|
||||
### ❌ What We Don't Have (Yet):
|
||||
- **BullMQ** - Not using a production queue system
|
||||
- **Redis** - No distributed queue
|
||||
- **Worker pools** - Single-threaded processing
|
||||
- **Job retries** - No automatic retry on failure
|
||||
- **Priority queues** - All jobs equal priority
|
||||
- **Rate limiting** - No per-provider rate limits
|
||||
|
||||
## Manual Queue Processing
|
||||
|
||||
You can manually trigger queue processing via API:
|
||||
|
||||
```bash
|
||||
POST /api/notifications/queue/process
|
||||
```
|
||||
|
||||
This is useful for:
|
||||
- Testing
|
||||
- Debugging
|
||||
- Force processing without waiting
|
||||
|
||||
## Monitoring
|
||||
|
||||
### Console Logs:
|
||||
```
|
||||
🚀 Starting background queue processor...
|
||||
✅ Queue processor started (runs every 30 seconds)
|
||||
⚙️ Processing notification queue...
|
||||
✅ Queue processed: 5 sent, 0 failed, 5 total
|
||||
```
|
||||
|
||||
### Check Queue Status:
|
||||
```sql
|
||||
-- See queued items
|
||||
SELECT * FROM notification_queue WHERE status = 'queued';
|
||||
|
||||
-- See processing status
|
||||
SELECT
|
||||
n.id,
|
||||
n.title,
|
||||
n.status,
|
||||
COUNT(nr.id) as total_recipients,
|
||||
SUM(CASE WHEN nr.status = 'sent' THEN 1 ELSE 0 END) as sent,
|
||||
SUM(CASE WHEN nr.status = 'failed' THEN 1 ELSE 0 END) as failed,
|
||||
SUM(CASE WHEN nr.status = 'pending' THEN 1 ELSE 0 END) as pending
|
||||
FROM notifications n
|
||||
LEFT JOIN notification_recipients nr ON n.id = nr.notification_id
|
||||
GROUP BY n.id, n.title, n.status;
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
### Queue Processing Interval:
|
||||
Change in `server/utils/queueProcessor.js`:
|
||||
```javascript
|
||||
// Current: 30 seconds
|
||||
processorInterval = setInterval(processQueue, 30000);
|
||||
|
||||
// Faster: 10 seconds
|
||||
processorInterval = setInterval(processQueue, 10000);
|
||||
|
||||
// Slower: 1 minute
|
||||
processorInterval = setInterval(processQueue, 60000);
|
||||
```
|
||||
|
||||
### Batch Size:
|
||||
Change in `server/utils/emailService.js`:
|
||||
```javascript
|
||||
// Current: 50 jobs per batch
|
||||
take: 50
|
||||
|
||||
// Larger batch: 100 jobs
|
||||
take: 100
|
||||
|
||||
// Smaller batch: 10 jobs
|
||||
take: 10
|
||||
```
|
||||
|
||||
## Future: Upgrading to BullMQ
|
||||
|
||||
If you want a production-grade queue system:
|
||||
|
||||
### Install BullMQ:
|
||||
```bash
|
||||
npm install bullmq ioredis
|
||||
```
|
||||
|
||||
### Benefits:
|
||||
- ✅ Persistent queue (survives server restart)
|
||||
- ✅ Automatic retries with exponential backoff
|
||||
- ✅ Priority queues
|
||||
- ✅ Concurrent workers
|
||||
- ✅ Rate limiting per provider
|
||||
- ✅ Job scheduling
|
||||
- ✅ Web UI for monitoring
|
||||
- ✅ Distributed processing
|
||||
|
||||
### When to Upgrade:
|
||||
- High volume (>1000 emails/day)
|
||||
- Multiple servers
|
||||
- Need guaranteed delivery
|
||||
- Need advanced retry logic
|
||||
- Need monitoring dashboard
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Queue not processing?
|
||||
1. Check server logs for errors
|
||||
2. Check if plugin is loaded: `grep "queue processor" logs`
|
||||
3. Manually trigger: `POST /api/notifications/queue/process`
|
||||
|
||||
### Emails not sending?
|
||||
1. Check SMTP credentials in delivery settings
|
||||
2. Check notification_queue table for errors
|
||||
3. Check notification_recipients for failed status
|
||||
4. Review email service logs
|
||||
|
||||
### Status stuck on "sending"?
|
||||
1. Check if recipients are still "pending"
|
||||
2. Manually trigger queue processing
|
||||
3. Check for errors in notification_queue table
|
||||
|
||||
## Summary
|
||||
|
||||
**Current System:**
|
||||
- Simple, lightweight queue using database + setInterval
|
||||
- Runs every 30 seconds automatically
|
||||
- Non-blocking API responses
|
||||
- Suitable for low-medium volume
|
||||
|
||||
**When to upgrade:**
|
||||
- Need higher reliability
|
||||
- Higher volume
|
||||
- Multiple servers
|
||||
- Advanced features
|
||||
|
||||
The current system works well for most use cases and can handle thousands of notifications per day!
|
||||
232
docs/template-version-history.md
Normal file
232
docs/template-version-history.md
Normal file
@@ -0,0 +1,232 @@
|
||||
# Template Version History
|
||||
|
||||
## Overview
|
||||
|
||||
The Template Version History feature allows you to track, manage, and restore previous versions of your notification templates. This provides a complete audit trail and the ability to revert changes when needed.
|
||||
|
||||
## Features
|
||||
|
||||
### 1. Automatic Version Creation
|
||||
- Every time you update a template, a new version is automatically created
|
||||
- Version numbers follow a semantic versioning pattern (e.g., 1.0, 1.1, 1.2)
|
||||
- Each version includes a complete snapshot of the template at that point in time
|
||||
|
||||
### 2. Version History View
|
||||
- Access version history by clicking the "Version History" icon in the template list
|
||||
- View all versions of a template in chronological order
|
||||
- See version numbers, change descriptions, and timestamps
|
||||
- Current version is clearly highlighted
|
||||
|
||||
### 3. Version Restoration
|
||||
- Restore any previous version of a template
|
||||
- Restoration creates a new version (doesn't overwrite history)
|
||||
- Automatic backup of current state before restoration
|
||||
|
||||
### 4. Version Deletion
|
||||
- Delete old versions that are no longer needed
|
||||
- Protection against deleting the current version
|
||||
- Protection against deleting the only version
|
||||
|
||||
## Database Schema
|
||||
|
||||
### notification_template_versions Table
|
||||
|
||||
| Field | Type | Description |
|
||||
|-------|------|-------------|
|
||||
| id | varchar(36) | Primary key (UUID) |
|
||||
| template_id | varchar(36) | Reference to the main template |
|
||||
| version | varchar(20) | Version number (e.g., "1.0", "1.1") |
|
||||
| name | varchar(100) | Template name at this version |
|
||||
| description | text | Template description |
|
||||
| subject | varchar(255) | Email subject line |
|
||||
| email_content | text | Email content/body |
|
||||
| push_title | varchar(100) | Push notification title |
|
||||
| push_body | varchar(300) | Push notification body |
|
||||
| category | varchar(50) | Template category |
|
||||
| channels | json | Supported channels array |
|
||||
| status | varchar(20) | Template status (Draft, Active, Archived) |
|
||||
| change_description | text | Description of what changed |
|
||||
| is_current | boolean | Whether this is the current version |
|
||||
| created_by | varchar(36) | User who created this version |
|
||||
| created_at | timestamp | When this version was created |
|
||||
|
||||
## API Endpoints
|
||||
|
||||
### Get Version History
|
||||
```
|
||||
GET /api/notifications/templates/{id}/versions
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"templateId": "template-uuid",
|
||||
"templateName": "Template Name",
|
||||
"versions": [
|
||||
{
|
||||
"id": "version-uuid",
|
||||
"version": "1.2",
|
||||
"name": "Template Name",
|
||||
"changeDescription": "Updated welcome message",
|
||||
"isCurrent": false,
|
||||
"status": "Active",
|
||||
"formattedCreatedAt": "03/20/2024, 02:30 PM"
|
||||
}
|
||||
],
|
||||
"totalCount": 3
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Restore Version
|
||||
```
|
||||
POST /api/notifications/templates/{id}/versions/{versionId}/restore
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"message": "Version 1.1 has been restored successfully as version 1.3",
|
||||
"templateId": "template-uuid",
|
||||
"restoredVersion": "1.1",
|
||||
"newVersion": "1.3"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Delete Version
|
||||
```
|
||||
DELETE /api/notifications/templates/{id}/versions/{versionId}
|
||||
```
|
||||
|
||||
**Response:**
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"message": "Version 1.1 has been deleted successfully",
|
||||
"templateId": "template-uuid",
|
||||
"deletedVersion": "1.1"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## How to Use
|
||||
|
||||
### 1. Setup Database
|
||||
Run the migration to create the version history table:
|
||||
|
||||
```bash
|
||||
node scripts/run-migration.js
|
||||
```
|
||||
|
||||
Or manually run the SQL migration file:
|
||||
```bash
|
||||
mysql -u your_username -p your_database < database/migrations/003_create_template_version_history.sql
|
||||
```
|
||||
|
||||
### 2. Update Prisma Schema
|
||||
After running the migration, update your Prisma client:
|
||||
|
||||
```bash
|
||||
npx prisma generate
|
||||
```
|
||||
|
||||
### 3. Using the Frontend
|
||||
|
||||
#### View Version History
|
||||
1. Go to the notification templates page
|
||||
2. Find the template you want to view history for
|
||||
3. Click the "Version History" icon in the actions column
|
||||
4. The version history modal will open showing all versions
|
||||
|
||||
#### Restore a Version
|
||||
1. Open the version history modal
|
||||
2. Find the version you want to restore
|
||||
3. Click the "Restore" button for that version
|
||||
4. Confirm the restoration in the popup dialog
|
||||
5. The version will be restored as a new version
|
||||
|
||||
#### Delete a Version
|
||||
1. Open the version history modal
|
||||
2. Find the version you want to delete
|
||||
3. Click the "Delete" button for that version
|
||||
4. Confirm the deletion in the popup dialog
|
||||
5. The version will be permanently deleted
|
||||
|
||||
## Best Practices
|
||||
|
||||
### 1. Version Naming
|
||||
- Use semantic versioning (major.minor format)
|
||||
- Increment minor version for small changes
|
||||
- Increment major version for significant changes
|
||||
|
||||
### 2. Change Descriptions
|
||||
- Always provide meaningful change descriptions
|
||||
- Include what was changed and why
|
||||
- Be specific about the modifications made
|
||||
|
||||
### 3. Version Management
|
||||
- Regularly clean up old versions that are no longer needed
|
||||
- Keep important milestone versions
|
||||
- Don't delete versions that might be needed for compliance or audit
|
||||
|
||||
### 4. Testing
|
||||
- Test templates thoroughly before making them active
|
||||
- Use draft status for work-in-progress templates
|
||||
- Restore previous versions if issues are found
|
||||
|
||||
## Security Considerations
|
||||
|
||||
### 1. Access Control
|
||||
- Only authenticated users can access version history
|
||||
- Users can only manage versions of templates they have access to
|
||||
- Audit logs track all version operations
|
||||
|
||||
### 2. Data Protection
|
||||
- All version data is stored securely in the database
|
||||
- Sensitive information in templates is handled according to your data protection policies
|
||||
- Regular backups include version history data
|
||||
|
||||
### 3. Validation
|
||||
- All version operations are validated before execution
|
||||
- Protection against malicious version manipulation
|
||||
- Proper error handling for failed operations
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
1. **Version History Not Loading**
|
||||
- Check database connection
|
||||
- Verify the template exists
|
||||
- Check API endpoint responses
|
||||
|
||||
2. **Restore Failing**
|
||||
- Ensure you have proper permissions
|
||||
- Check if the version exists
|
||||
- Verify template is not locked
|
||||
|
||||
3. **Delete Failing**
|
||||
- Cannot delete current version
|
||||
- Cannot delete if it's the only version
|
||||
- Check user permissions
|
||||
|
||||
### Debug Steps
|
||||
1. Check browser console for errors
|
||||
2. Verify API responses
|
||||
3. Check database logs
|
||||
4. Confirm user authentication
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
- Version comparison view
|
||||
- Bulk version operations
|
||||
- Version export/import
|
||||
- Advanced filtering and search
|
||||
- Version approval workflows
|
||||
- Automated version cleanup policies
|
||||
Reference in New Issue
Block a user