feat: Add monitoring alerts skeleton and enhance worker with notifications
This commit is contained in:
732
docs/monitoring-alerts-consolidated-report.md
Normal file
732
docs/monitoring-alerts-consolidated-report.md
Normal file
@@ -0,0 +1,732 @@
|
||||
# 📊 Monitoring & Alerts System - Consolidated Implementation Report
|
||||
|
||||
**Date**: 2025-11-30
|
||||
**Status**: ✅ Skeleton Implemented (30% Complete)
|
||||
**Build**: ✅ Success
|
||||
|
||||
---
|
||||
|
||||
## 📋 Executive Summary
|
||||
|
||||
اسکلت کامل سیستم Monitoring & Alerts پیادهسازی شد. این سیستم شامل دو بخش اصلی است:
|
||||
1. **Alert System**: اعلانهای مدیریتی (Critical/Warning/Success) برای Admin
|
||||
2. **User Notification System**: اعلانهای کاربری (SMS/Email/Push) برای Users
|
||||
|
||||
فعلاً فقط Logging فعال است. Integration های اصلی (Sentry, Slack, SMS) آماده پیادهسازی هستند.
|
||||
|
||||
---
|
||||
|
||||
## 🏗️ Architecture Overview
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ Application Layer │
|
||||
│ ┌─────────────────────┐ ┌─────────────────────────┐ │
|
||||
│ │ IAlertService │ │ IUserNotificationService│ │
|
||||
│ │ - Critical │ │ - Commission Received │ │
|
||||
│ │ - Warning │ │ - Club Activation │ │
|
||||
│ │ - Success │ │ - Payout Error │ │
|
||||
│ └─────────────────────┘ └─────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────┘
|
||||
↓ implements
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ Infrastructure Layer │
|
||||
│ ┌─────────────────────┐ ┌─────────────────────────┐ │
|
||||
│ │ AlertService │ │ UserNotificationService │ │
|
||||
│ │ ✅ Logging │ │ ✅ Logging │ │
|
||||
│ │ ⏳ Sentry │ │ ⏳ SMS Gateway │ │
|
||||
│ │ ⏳ Slack │ │ ⏳ Email Service │ │
|
||||
│ │ ⏳ Email │ │ ⏳ Push Notification │ │
|
||||
│ └─────────────────────┘ └─────────────────────────┘ │
|
||||
│ │
|
||||
│ ┌──────────────────────────────────────────────────┐ │
|
||||
│ │ MonitoringSettings (Configuration) │ │
|
||||
│ │ - SentryEnabled, SentryDsn │ │
|
||||
│ │ - SlackEnabled, SlackWebhookUrl │ │
|
||||
│ │ - EmailAlertsEnabled, AdminEmails │ │
|
||||
│ │ - SmsNotificationsEnabled, SmsApiKey │ │
|
||||
│ └──────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────┘
|
||||
↓ used by
|
||||
┌─────────────────────────────────────────────────────────┐
|
||||
│ Background Workers / Handlers │
|
||||
│ ┌──────────────────────────────────────────────────┐ │
|
||||
│ │ WeeklyNetworkCommissionWorker │ │
|
||||
│ │ - On Success: SendSuccessNotificationAsync() │ │
|
||||
│ │ - On Error: SendCriticalAlertAsync() │ │
|
||||
│ └──────────────────────────────────────────────────┘ │
|
||||
│ ┌──────────────────────────────────────────────────┐ │
|
||||
│ │ ProcessUserPayoutsCommandHandler │ │
|
||||
│ │ - On Payout: SendCommissionReceivedNotification│ │
|
||||
│ └──────────────────────────────────────────────────┘ │
|
||||
└─────────────────────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📦 Implementation Details
|
||||
|
||||
### 1️⃣ Alert Service (Admin Notifications)
|
||||
|
||||
**Interface**: `CMSMicroservice.Application/Common/Interfaces/IAlertService.cs`
|
||||
|
||||
```csharp
|
||||
public interface IAlertService
|
||||
{
|
||||
Task SendCriticalAlertAsync(string title, string message, Exception? exception, CancellationToken ct);
|
||||
Task SendWarningAlertAsync(string title, string message, CancellationToken ct);
|
||||
Task SendSuccessNotificationAsync(string title, string message, CancellationToken ct);
|
||||
}
|
||||
```
|
||||
|
||||
**Implementation**: `CMSMicroservice.Infrastructure/Services/Monitoring/AlertService.cs`
|
||||
|
||||
**Current Behavior**:
|
||||
```
|
||||
🚨 CRITICAL ALERT: {Title} - {Message}
|
||||
⚠️ WARNING ALERT: {Title} - {Message}
|
||||
✅ SUCCESS: {Title} - {Message}
|
||||
```
|
||||
|
||||
**Pending Integrations**:
|
||||
- **Sentry**: Exception tracking & aggregation (TODO: `SentrySdk.CaptureException()`)
|
||||
- **Slack**: Real-time alerts to channel (TODO: HTTP POST to webhook)
|
||||
- **Email**: Alert emails to admin list (TODO: SMTP integration)
|
||||
|
||||
---
|
||||
|
||||
### 2️⃣ User Notification Service
|
||||
|
||||
**Interface**: `CMSMicroservice.Application/Common/Interfaces/IAlertService.cs` (same file)
|
||||
|
||||
```csharp
|
||||
public interface IUserNotificationService
|
||||
{
|
||||
Task SendCommissionReceivedNotificationAsync(long userId, decimal amount, int weekNumber, CancellationToken ct);
|
||||
Task SendClubActivationNotificationAsync(long userId, CancellationToken ct);
|
||||
Task SendPayoutErrorNotificationAsync(long userId, string errorMessage, CancellationToken ct);
|
||||
}
|
||||
```
|
||||
|
||||
**Implementation**: `CMSMicroservice.Infrastructure/Services/Monitoring/UserNotificationService.cs`
|
||||
|
||||
**Current Behavior**:
|
||||
```
|
||||
📧 Sending commission notification: User={UserId}, Amount={Amount}, Week={WeekNumber}
|
||||
🎉 Sending club activation notification: User={UserId}
|
||||
⚠️ Sending payout error notification: User={UserId}, Error={Error}
|
||||
```
|
||||
|
||||
**Pending Integrations**:
|
||||
- **SMS Gateway**: Kavenegar/Ghasedak integration (TODO: HTTP API call)
|
||||
- **Email Service**: SMTP/SendGrid integration (TODO: template-based emails)
|
||||
- **Push Notification**: FCM/OneSignal integration (TODO: mobile app notifications)
|
||||
|
||||
---
|
||||
|
||||
### 3️⃣ Configuration Model
|
||||
|
||||
**File**: `CMSMicroservice.Infrastructure/Services/Monitoring/MonitoringSettings.cs`
|
||||
|
||||
```csharp
|
||||
public class MonitoringSettings
|
||||
{
|
||||
public const string SectionName = "Monitoring";
|
||||
|
||||
// Sentry
|
||||
public bool SentryEnabled { get; set; }
|
||||
public string? SentryDsn { get; set; }
|
||||
|
||||
// Slack
|
||||
public bool SlackEnabled { get; set; }
|
||||
public string? SlackWebhookUrl { get; set; }
|
||||
|
||||
// Email Alerts (Admin)
|
||||
public bool EmailAlertsEnabled { get; set; }
|
||||
public List<string> AdminEmails { get; set; }
|
||||
|
||||
// SMS (User Notifications)
|
||||
public bool SmsNotificationsEnabled { get; set; }
|
||||
public string? SmsApiKey { get; set; }
|
||||
public string? SmsGatewayUrl { get; set; }
|
||||
}
|
||||
```
|
||||
|
||||
**Config File**: `CMSMicroservice.WebApi/appsettings.json`
|
||||
|
||||
```json
|
||||
{
|
||||
"Monitoring": {
|
||||
"SentryEnabled": false,
|
||||
"SentryDsn": "",
|
||||
"SlackEnabled": false,
|
||||
"SlackWebhookUrl": "",
|
||||
"EmailAlertsEnabled": false,
|
||||
"AdminEmails": ["admin@example.com"],
|
||||
"SmsNotificationsEnabled": false,
|
||||
"SmsApiKey": "",
|
||||
"SmsGatewayUrl": ""
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4️⃣ Dependency Injection
|
||||
|
||||
**File**: `CMSMicroservice.Infrastructure/ConfigureServices.cs`
|
||||
|
||||
```csharp
|
||||
services.AddScoped<IAlertService, AlertService>();
|
||||
services.AddScoped<IUserNotificationService, UserNotificationService>();
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 5️⃣ Worker Integration
|
||||
|
||||
**File**: `CMSMicroservice.Infrastructure/BackgroundJobs/WeeklyNetworkCommissionWorker.cs`
|
||||
|
||||
**On Success**:
|
||||
```csharp
|
||||
await alertService.SendSuccessNotificationAsync(
|
||||
"Weekly Commission Completed",
|
||||
$"Week {previousWeekNumber}: {payoutsProcessed} payouts, {balancesToExpire.Count} balances expired");
|
||||
```
|
||||
|
||||
**On Error**:
|
||||
```csharp
|
||||
await alertService.SendCriticalAlertAsync(
|
||||
"Weekly Commission Worker Failed",
|
||||
$"Worker execution {executionId} failed for week {GetPreviousWeekNumber()}",
|
||||
ex,
|
||||
cancellationToken);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔌 Integration Roadmap
|
||||
|
||||
### Priority 1: Sentry (High - 1 hour)
|
||||
|
||||
**Why**: Critical error tracking & aggregation برای Production
|
||||
|
||||
**Steps**:
|
||||
1. Install NuGet:
|
||||
```bash
|
||||
dotnet add package Sentry.AspNetCore
|
||||
```
|
||||
|
||||
2. Configure in `Program.cs`:
|
||||
```csharp
|
||||
builder.WebHost.UseSentry(options =>
|
||||
{
|
||||
options.Dsn = builder.Configuration["Monitoring:SentryDsn"];
|
||||
options.Environment = builder.Environment.EnvironmentName;
|
||||
options.TracesSampleRate = 1.0;
|
||||
});
|
||||
```
|
||||
|
||||
3. Update `AlertService.SendCriticalAlertAsync()`:
|
||||
```csharp
|
||||
if (_settings.SentryEnabled && exception != null)
|
||||
{
|
||||
SentrySdk.CaptureException(exception, scope =>
|
||||
{
|
||||
scope.SetTag("alert.title", title);
|
||||
scope.SetExtra("message", message);
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
4. Set DSN in `appsettings.Production.json`:
|
||||
```json
|
||||
{
|
||||
"Monitoring": {
|
||||
"SentryEnabled": true,
|
||||
"SentryDsn": "https://xxxxx@sentry.io/12345"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Priority 2: Slack Webhook (Medium - 2 hours)
|
||||
|
||||
**Why**: Real-time alerts به تیم Development/DevOps
|
||||
|
||||
**Steps**:
|
||||
1. Create Incoming Webhook در Slack:
|
||||
- Go to: `https://api.slack.com/apps`
|
||||
- Create app → Incoming Webhooks → Add to channel
|
||||
- Copy Webhook URL
|
||||
|
||||
2. Update `AlertService`:
|
||||
```csharp
|
||||
private readonly HttpClient _httpClient;
|
||||
|
||||
public async Task SendCriticalAlertAsync(...)
|
||||
{
|
||||
_logger.LogCritical(exception, "🚨 {Title} - {Message}", title, message);
|
||||
|
||||
if (_settings.SlackEnabled)
|
||||
{
|
||||
var payload = new
|
||||
{
|
||||
text = $"🚨 *{title}*",
|
||||
attachments = new[]
|
||||
{
|
||||
new
|
||||
{
|
||||
color = "danger",
|
||||
text = message,
|
||||
fields = exception != null ? new[]
|
||||
{
|
||||
new { title = "Exception", value = exception.Message, @short = false }
|
||||
} : null
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
await _httpClient.PostAsJsonAsync(_settings.SlackWebhookUrl, payload);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
3. Set Webhook URL in config:
|
||||
```json
|
||||
{
|
||||
"Monitoring": {
|
||||
"SlackEnabled": true,
|
||||
"SlackWebhookUrl": "https://hooks.slack.com/services/T00/B00/XXX"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Priority 3: SMS Gateway - Kavenegar (Medium - 3 hours)
|
||||
|
||||
**Why**: اطلاعرسانی کمیسیون به کاربران
|
||||
|
||||
**Steps**:
|
||||
1. Get API Key from Kavenegar:
|
||||
- Sign up: `https://panel.kavenegar.com`
|
||||
- API Key: Settings → API Key
|
||||
|
||||
2. Create `ISmsGatewayService`:
|
||||
```csharp
|
||||
public interface ISmsGatewayService
|
||||
{
|
||||
Task SendAsync(string mobile, string message, CancellationToken ct = default);
|
||||
}
|
||||
```
|
||||
|
||||
3. Implement `KavenegarSmsService`:
|
||||
```csharp
|
||||
public class KavenegarSmsService : ISmsGatewayService
|
||||
{
|
||||
private readonly HttpClient _httpClient;
|
||||
private readonly string _apiKey;
|
||||
|
||||
public async Task SendAsync(string mobile, string message, CancellationToken ct)
|
||||
{
|
||||
var url = $"https://api.kavenegar.com/v1/{_apiKey}/sms/send.json";
|
||||
var payload = new
|
||||
{
|
||||
receptor = mobile,
|
||||
message = message
|
||||
};
|
||||
|
||||
var response = await _httpClient.PostAsJsonAsync(url, payload, ct);
|
||||
response.EnsureSuccessStatusCode();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
4. Update `UserNotificationService.SendCommissionReceivedNotificationAsync()`:
|
||||
```csharp
|
||||
var user = await _context.Users.FindAsync(userId, ct);
|
||||
|
||||
if (user.SmsNotifications && _settings.SmsNotificationsEnabled)
|
||||
{
|
||||
var message = $"کمیسیون شما: {amount:N0} ریال برای هفته {weekNumber} واریز شد.";
|
||||
await _smsGateway.SendAsync(user.Mobile, message, ct);
|
||||
}
|
||||
```
|
||||
|
||||
5. Configure:
|
||||
```json
|
||||
{
|
||||
"Monitoring": {
|
||||
"SmsNotificationsEnabled": true,
|
||||
"SmsApiKey": "your-kavenegar-api-key"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Priority 4: Email Alerts for Admins (Low - 2 hours)
|
||||
|
||||
**Why**: Backup notification channel
|
||||
|
||||
**Options**:
|
||||
- **A) MailKit (SMTP)**:
|
||||
```csharp
|
||||
using var client = new SmtpClient();
|
||||
await client.ConnectAsync("smtp.gmail.com", 587, SecureSocketOptions.StartTls);
|
||||
await client.AuthenticateAsync("user@example.com", "password");
|
||||
|
||||
var message = new MimeMessage();
|
||||
message.From.Add(new MailboxAddress("CMS Alerts", "noreply@foursat.ir"));
|
||||
message.To.Add(new MailboxAddress("Admin", adminEmail));
|
||||
message.Subject = $"[ALERT] {title}";
|
||||
message.Body = new TextPart("html") { Text = htmlMessage };
|
||||
|
||||
await client.SendAsync(message);
|
||||
```
|
||||
|
||||
- **B) SendGrid API**:
|
||||
```csharp
|
||||
var client = new SendGridClient(_settings.SendGridApiKey);
|
||||
var msg = MailHelper.CreateSingleEmail(
|
||||
from: new EmailAddress("noreply@foursat.ir", "CMS Alerts"),
|
||||
to: new EmailAddress(adminEmail),
|
||||
subject: $"[ALERT] {title}",
|
||||
plainTextContent: message,
|
||||
htmlContent: htmlMessage
|
||||
);
|
||||
await client.SendEmailAsync(msg);
|
||||
```
|
||||
|
||||
**Config**:
|
||||
```json
|
||||
{
|
||||
"Monitoring": {
|
||||
"EmailAlertsEnabled": true,
|
||||
"AdminEmails": ["admin@foursat.ir", "devops@foursat.ir"],
|
||||
"SmtpServer": "smtp.gmail.com",
|
||||
"SmtpPort": 587,
|
||||
"SmtpUsername": "user@example.com",
|
||||
"SmtpPassword": "password"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Priority 5: Retry Logic با Exponential Backoff (Low - 1 hour)
|
||||
|
||||
**Why**: بهبود Reliability در صورت خطاهای Transient
|
||||
|
||||
**Implementation در Worker**:
|
||||
```csharp
|
||||
private async Task<T> RetryWithExponentialBackoffAsync<T>(
|
||||
Func<Task<T>> operation,
|
||||
int maxRetries = 3,
|
||||
CancellationToken ct = default)
|
||||
{
|
||||
for (int attempt = 0; attempt <= maxRetries; attempt++)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await operation();
|
||||
}
|
||||
catch (Exception ex) when (attempt < maxRetries && IsTransientError(ex))
|
||||
{
|
||||
var delay = TimeSpan.FromSeconds(Math.Pow(2, attempt)); // 2^n: 1s, 2s, 4s
|
||||
|
||||
_logger.LogWarning(ex,
|
||||
"Attempt {Attempt}/{MaxRetries} failed. Retrying in {Delay}s...",
|
||||
attempt + 1, maxRetries, delay.TotalSeconds);
|
||||
|
||||
await Task.Delay(delay, ct);
|
||||
}
|
||||
}
|
||||
|
||||
throw new InvalidOperationException($"Operation failed after {maxRetries} retries");
|
||||
}
|
||||
|
||||
private bool IsTransientError(Exception ex)
|
||||
{
|
||||
return ex is TimeoutException
|
||||
|| ex is HttpRequestException
|
||||
|| (ex is SqlException sqlEx && sqlEx.IsTransient);
|
||||
}
|
||||
```
|
||||
|
||||
**Usage**:
|
||||
```csharp
|
||||
// در ExecuteWeeklyCalculationAsync():
|
||||
var balancesCalculated = await RetryWithExponentialBackoffAsync(async () =>
|
||||
{
|
||||
return await mediator.Send(new CalculateWeeklyBalancesCommand
|
||||
{
|
||||
WeekNumber = previousWeekNumber
|
||||
}, cancellationToken);
|
||||
}, maxRetries: 3, ct: cancellationToken);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🧪 Testing Guide
|
||||
|
||||
### Test 1: Alert Service (Console Logging)
|
||||
```csharp
|
||||
// در Controller یا Handler:
|
||||
var alertService = _serviceProvider.GetRequiredService<IAlertService>();
|
||||
|
||||
await alertService.SendCriticalAlertAsync(
|
||||
"Test Critical Alert",
|
||||
"این یک تست برای Alert Service است",
|
||||
new Exception("Sample exception"));
|
||||
|
||||
await alertService.SendSuccessNotificationAsync(
|
||||
"Test Success",
|
||||
"عملیات با موفقیت انجام شد");
|
||||
```
|
||||
|
||||
**Expected Output**:
|
||||
```
|
||||
🚨 CRITICAL ALERT: Test Critical Alert - این یک تست برای Alert Service است
|
||||
✅ SUCCESS: Test Success - عملیات با موفقیت انجام شد
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Test 2: User Notification Service
|
||||
```csharp
|
||||
var notificationService = _serviceProvider.GetRequiredService<IUserNotificationService>();
|
||||
|
||||
await notificationService.SendCommissionReceivedNotificationAsync(
|
||||
userId: 123,
|
||||
amount: 500_000,
|
||||
weekNumber: 48);
|
||||
```
|
||||
|
||||
**Expected Output**:
|
||||
```
|
||||
📧 Sending commission notification: User=123, Amount=500000, Week=48
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### Test 3: Worker Integration
|
||||
```bash
|
||||
# Run Worker manually (for testing)
|
||||
# تغییر زمان اجرا به 1 دقیقه بعد برای تست:
|
||||
# در Worker: var delay = TimeSpan.FromMinutes(1);
|
||||
dotnet run --project CMSMicroservice.WebApi
|
||||
```
|
||||
|
||||
**Expected**:
|
||||
- Worker starts
|
||||
- After 1 minute → Executes calculation
|
||||
- On success → Logs: `✅ SUCCESS: Weekly Commission Completed`
|
||||
- On error → Logs: `🚨 CRITICAL ALERT: Weekly Commission Worker Failed`
|
||||
|
||||
---
|
||||
|
||||
### Test 4: Sentry Integration (بعد از پیادهسازی)
|
||||
```csharp
|
||||
// Throw یک exception برای تست:
|
||||
throw new InvalidOperationException("Test Sentry integration");
|
||||
```
|
||||
|
||||
**Check**: Sentry dashboard → Issues → باید exception جدید نمایش داده شود
|
||||
|
||||
---
|
||||
|
||||
### Test 5: Slack Integration (بعد از پیادهسازی)
|
||||
```csharp
|
||||
await alertService.SendCriticalAlertAsync("Test Slack", "Testing webhook integration", null);
|
||||
```
|
||||
|
||||
**Check**: Slack channel → باید پیام جدید نمایش داده شود
|
||||
|
||||
---
|
||||
|
||||
### Test 6: SMS Integration (بعد از پیادهسازی)
|
||||
```csharp
|
||||
await notificationService.SendCommissionReceivedNotificationAsync(
|
||||
userId: YOUR_USER_ID, // با شماره موبایل معتبر
|
||||
amount: 100_000,
|
||||
weekNumber: 48);
|
||||
```
|
||||
|
||||
**Check**: موبایل کاربر → باید SMS دریافت شود
|
||||
|
||||
---
|
||||
|
||||
## 📊 Current Status & Progress
|
||||
|
||||
| Component | Status | Completion | Notes |
|
||||
|-----------|--------|------------|-------|
|
||||
| **Interfaces** | ✅ Done | 100% | `IAlertService`, `IUserNotificationService` |
|
||||
| **Skeleton Implementations** | ✅ Done | 100% | Logging only |
|
||||
| **Configuration Model** | ✅ Done | 100% | `MonitoringSettings` |
|
||||
| **DI Registration** | ✅ Done | 100% | In `ConfigureServices.cs` |
|
||||
| **Worker Integration** | ✅ Done | 100% | Success + Error alerts |
|
||||
| **appsettings Structure** | ✅ Done | 100% | Monitoring section added |
|
||||
| **Sentry Integration** | ⏳ Pending | 0% | Install package + configure DSN |
|
||||
| **Slack Webhook** | ⏳ Pending | 0% | Create webhook + implement POST |
|
||||
| **SMS Gateway** | ⏳ Pending | 0% | Choose provider + get API key |
|
||||
| **Email Alerts** | ⏳ Pending | 0% | SMTP/SendGrid integration |
|
||||
| **Retry Logic** | ⏳ Pending | 0% | Exponential backoff implementation |
|
||||
| **Testing** | ⏳ Pending | 0% | Unit + Integration tests |
|
||||
|
||||
**Overall Progress**: 30% ✅ | 70% ⏳
|
||||
|
||||
---
|
||||
|
||||
## 📝 Important Notes
|
||||
|
||||
### 1. Production Readiness
|
||||
- ⚠️ **فعلاً فقط Logging فعال است**
|
||||
- ⚠️ برای Production **حداقل Sentry** باید فعال شود
|
||||
- ⚠️ برای Critical systems حتماً Slack هم اضافه شود
|
||||
|
||||
### 2. User Preferences
|
||||
- SMS/Email/Push باید بر اساس تنظیمات کاربر (`User.SmsNotifications`, etc.) ارسال شود
|
||||
- در `UserNotificationService` باید ابتدا preferences چک شود
|
||||
|
||||
### 3. Rate Limiting
|
||||
- برای SMS Gateway باید Rate Limiting در نظر گرفته شود
|
||||
- پیشنهاد: استفاده از Queue (Hangfire/RabbitMQ) برای ارسال تعداد زیاد SMS
|
||||
|
||||
### 4. Cost Management
|
||||
- SMS و Email هزینه دارند
|
||||
- پیشنهاد: Batching برای ارسال گروهی
|
||||
- پیشنهاد: Template-based messaging برای کاهش هزینه
|
||||
|
||||
### 5. Security
|
||||
- API Keys در `appsettings.json` نباید commit شوند
|
||||
- استفاده از Environment Variables یا Azure Key Vault
|
||||
- مثال: `SmsApiKey: ${SMS_API_KEY}` در appsettings
|
||||
|
||||
### 6. Monitoring the Monitor
|
||||
- خود Alert System هم باید Monitor شود
|
||||
- اگر Slack/SMS fail شد، باید Fallback به Email یا Log باشد
|
||||
- پیشنهاد: Dead Letter Queue برای failed notifications
|
||||
|
||||
---
|
||||
|
||||
## 🔗 File Reference Map
|
||||
|
||||
```
|
||||
CMS/
|
||||
├── src/
|
||||
│ ├── CMSMicroservice.Application/
|
||||
│ │ └── Common/
|
||||
│ │ └── Interfaces/
|
||||
│ │ └── IAlertService.cs ⭐
|
||||
│ │
|
||||
│ ├── CMSMicroservice.Infrastructure/
|
||||
│ │ ├── Services/
|
||||
│ │ │ └── Monitoring/
|
||||
│ │ │ ├── AlertService.cs ⭐
|
||||
│ │ │ ├── UserNotificationService.cs ⭐
|
||||
│ │ │ └── MonitoringSettings.cs ⭐
|
||||
│ │ │
|
||||
│ │ ├── BackgroundJobs/
|
||||
│ │ │ └── WeeklyNetworkCommissionWorker.cs ✏️ (Modified)
|
||||
│ │ │
|
||||
│ │ └── ConfigureServices.cs ✏️ (Modified)
|
||||
│ │
|
||||
│ └── CMSMicroservice.WebApi/
|
||||
│ └── appsettings.json ✏️ (Modified)
|
||||
│
|
||||
└── docs/
|
||||
└── monitoring-alerts-implementation-report.md 📄 (This file)
|
||||
```
|
||||
|
||||
**Legend**:
|
||||
- ⭐ = New file created
|
||||
- ✏️ = Existing file modified
|
||||
- 📄 = Documentation
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Next Action Items
|
||||
|
||||
### Immediate (این هفته):
|
||||
1. ✅ Review this document
|
||||
2. ⏳ Decision: کدام Integration اول؟ (پیشنهاد: Sentry)
|
||||
3. ⏳ Get credentials:
|
||||
- Sentry DSN
|
||||
- Slack Webhook URL
|
||||
- SMS Gateway API Key
|
||||
|
||||
### Short-term (هفته آینده):
|
||||
4. ⏳ Implement Sentry integration
|
||||
5. ⏳ Implement Slack webhook
|
||||
6. ⏳ Test in Staging environment
|
||||
|
||||
### Long-term (ماه آینده):
|
||||
7. ⏳ Implement SMS Gateway (Kavenegar)
|
||||
8. ⏳ Add Email alerts
|
||||
9. ⏳ Implement Retry logic
|
||||
10. ⏳ Write Unit/Integration tests
|
||||
11. ⏳ Deploy to Production
|
||||
|
||||
---
|
||||
|
||||
## 📞 Contact & Support
|
||||
|
||||
**Implementation Questions**:
|
||||
- Developer: GitHub Copilot (این گزارش)
|
||||
- Review: Development Team
|
||||
|
||||
**Service Providers**:
|
||||
- **Sentry**: https://sentry.io (Error tracking)
|
||||
- **Slack**: https://api.slack.com/messaging/webhooks (Webhooks)
|
||||
- **Kavenegar**: https://kavenegar.com (SMS Gateway - Iran)
|
||||
- **Ghasedak**: https://ghasedak.me (SMS Gateway Alternative)
|
||||
- **SendGrid**: https://sendgrid.com (Email service)
|
||||
|
||||
---
|
||||
|
||||
**Last Updated**: 2025-11-30
|
||||
**Build Status**: ✅ Success
|
||||
**Ready for**: Integration implementation
|
||||
|
||||
---
|
||||
|
||||
## 🎯 TL;DR (خلاصه برای رجوع سریع)
|
||||
|
||||
### چی ساخته شد:
|
||||
- ✅ `IAlertService` + `AlertService` (Admin alerts)
|
||||
- ✅ `IUserNotificationService` + `UserNotificationService` (User notifications)
|
||||
- ✅ `MonitoringSettings` (Configuration model)
|
||||
- ✅ Worker integration (Success/Error alerts)
|
||||
- ✅ DI registration
|
||||
- ✅ appsettings structure
|
||||
|
||||
### فعلاً چی کار میکنه:
|
||||
- Logging به Console (🚨 Critical, ⚠️ Warning, ✅ Success)
|
||||
|
||||
### چی باید اضافه بشه:
|
||||
1. **Sentry** - Error tracking (Priority: High)
|
||||
2. **Slack** - Real-time alerts (Priority: Medium)
|
||||
3. **SMS Gateway** - User notifications (Priority: Medium)
|
||||
4. **Email** - Backup channel (Priority: Low)
|
||||
5. **Retry Logic** - Reliability (Priority: Low)
|
||||
|
||||
### کجا باید نگاه کنی:
|
||||
- Interfaces: `CMSMicroservice.Application/Common/Interfaces/IAlertService.cs`
|
||||
- Implementations: `CMSMicroservice.Infrastructure/Services/Monitoring/`
|
||||
- Worker: `CMSMicroservice.Infrastructure/BackgroundJobs/WeeklyNetworkCommissionWorker.cs`
|
||||
- Config: `CMSMicroservice.WebApi/appsettings.json`
|
||||
|
||||
### چطوری تست کنی:
|
||||
```csharp
|
||||
await alertService.SendCriticalAlertAsync("Test", "Message", null);
|
||||
// Output: 🚨 CRITICAL ALERT: Test - Message
|
||||
```
|
||||
|
||||
### بعدش چیکار کنم:
|
||||
1. Get Sentry DSN → Update appsettings.Production.json
|
||||
2. Install `Sentry.AspNetCore` → Configure in Program.cs
|
||||
3. Update `AlertService.SendCriticalAlertAsync()` → Add `SentrySdk.CaptureException()`
|
||||
4. Test → Deploy
|
||||
Reference in New Issue
Block a user