---
name: ai-backend-automation
description: >
  باك إند مدعوم بالذكاء الاصطناعي للحلول التلقائية.
  استخدم هذا الـ skill عند: تصنيف تلقائي للمستندات/التذاكر، استخراج بيانات ذكي،
  تحليل المشاعر، محرك توصيات، كشف الشذوذ، ملخصات تلقائية، chatbot داخلي،
  RAG (Retrieval Augmented Generation)، أو أي مهمة تتطلب ذكاء اصطناعي في الخلفية.
  يدعم Claude API, OpenAI, Azure AI, والنماذج المحلية عبر Ollama.
---

# AI-Powered Backend Automation
# الباك إند الذكي

## Architecture

```
┌──────────────────────────────────────────────┐
│              AI Gateway / Router              │
│  ┌─────────┐ ┌─────────┐ ┌───────────────┐  │
│  │ Claude  │ │ OpenAI  │ │ Azure AI /    │  │
│  │ API     │ │ API     │ │ Local (Ollama)│  │
│  └────┬────┘ └────┬────┘ └──────┬────────┘  │
│       └───────────┼─────────────┘            │
│                   ▼                          │
│         ┌─────────────────┐                  │
│         │  AI Service     │                  │
│         │  Orchestrator   │                  │
│         └────────┬────────┘                  │
└──────────────────┼───────────────────────────┘
                   │
    ┌──────────────┼──────────────┐
    ▼              ▼              ▼
┌────────┐  ┌──────────┐  ┌──────────┐
│Classify│  │ Extract  │  │ Generate │
│Tickets │  │ Documents│  │ Summaries│
│Docs    │  │ OCR Data │  │ Reports  │
└────────┘  └──────────┘  └──────────┘
```

## Domain Model

```csharp
// === AI Task ===
public class AiTask : BaseAuditableEntity
{
    public long Id { get; set; }
    public Guid TaskKey { get; set; } = Guid.NewGuid();
    public AiTaskType Type { get; set; }
    public AiProvider Provider { get; set; }
    public string ModelName { get; set; } = string.Empty;
    
    // Input/Output
    public string InputJson { get; set; } = string.Empty;
    public string? OutputJson { get; set; }
    public string? ErrorMessage { get; set; }
    
    // Performance
    public AiTaskStatus Status { get; set; }
    public int? InputTokens { get; set; }
    public int? OutputTokens { get; set; }
    public decimal? CostUsd { get; set; }
    public int LatencyMs { get; set; }
    
    // Context
    public string? EntityType { get; set; }
    public int? EntityId { get; set; }
    public int? RequestedByUserId { get; set; }
}

public enum AiTaskType
{
    Classification,         // تصنيف
    Extraction,             // استخراج بيانات
    Summarization,          // تلخيص
    SentimentAnalysis,      // تحليل مشاعر
    Translation,            // ترجمة
    AnomalyDetection,       // كشف شذوذ
    Recommendation,         // توصية
    ChatCompletion,         // محادثة
    Embedding,              // تحويل لـ vector
    RAG                     // استرجاع + توليد
}

public enum AiProvider
{
    Claude,
    OpenAI,
    AzureOpenAI,
    Ollama,
    Custom
}
```

## AI Service Gateway

```csharp
public interface IAiGateway
{
    Task<AiResponse> CompleteAsync(AiRequest request);
    Task<float[]> EmbedAsync(string text);
    Task<AiResponse> CompleteWithToolsAsync(AiRequest request, List<AiTool> tools);
}

public class AiGateway : IAiGateway
{
    private readonly Dictionary<AiProvider, IAiProvider> _providers;

    public async Task<AiResponse> CompleteAsync(AiRequest request)
    {
        var provider = SelectProvider(request);
        var stopwatch = Stopwatch.StartNew();
        
        try
        {
            var response = await provider.CompleteAsync(request);
            stopwatch.Stop();
            
            // Log usage
            await LogAiTaskAsync(new AiTask
            {
                Type = request.TaskType,
                Provider = request.Provider ?? GetDefaultProvider(),
                ModelName = response.Model,
                InputTokens = response.Usage.InputTokens,
                OutputTokens = response.Usage.OutputTokens,
                CostUsd = CalculateCost(response),
                LatencyMs = (int)stopwatch.ElapsedMilliseconds,
                Status = AiTaskStatus.Completed
            });
            
            return response;
        }
        catch (Exception ex)
        {
            // Fallback to secondary provider
            if (request.AllowFallback)
            {
                var fallback = GetFallbackProvider(provider);
                return await fallback.CompleteAsync(request);
            }
            throw;
        }
    }
}

// === Claude Provider ===
public class ClaudeProvider : IAiProvider
{
    public async Task<AiResponse> CompleteAsync(AiRequest request)
    {
        var client = new HttpClient();
        client.DefaultRequestHeaders.Add("x-api-key", _config.ApiKey);
        client.DefaultRequestHeaders.Add("anthropic-version", "2023-06-01");
        
        var body = new
        {
            model = request.Model ?? "claude-sonnet-4-5-20250514",
            max_tokens = request.MaxTokens ?? 4096,
            system = request.SystemPrompt,
            messages = request.Messages.Select(m => new { role = m.Role, content = m.Content })
        };
        
        var response = await client.PostAsJsonAsync(
            "https://api.anthropic.com/v1/messages", body);
        return await ParseResponseAsync(response);
    }
}
```

## Pre-built AI Services

```csharp
// === 1. Smart Ticket Classifier ===
public class TicketClassifierService
{
    public async Task<TicketClassification> ClassifyAsync(string subject, string description)
    {
        var response = await _aiGateway.CompleteAsync(new AiRequest
        {
            TaskType = AiTaskType.Classification,
            SystemPrompt = """
                أنت مصنف تذاكر دعم فني. صنف التذكرة التالية إلى:
                - الفئة: (شبكات، أجهزة، برمجيات، بريد، طابعات، صلاحيات، أخرى)
                - الأولوية: (Critical, High, Medium, Low)
                - النوع: (Incident, ServiceRequest, Problem)
                أجب بصيغة JSON فقط.
                """,
            Messages = [new("user", $"العنوان: {subject}\nالوصف: {description}")]
        });
        
        return JsonSerializer.Deserialize<TicketClassification>(response.Content)!;
    }
}

// === 2. Document Data Extractor ===
public class DocumentExtractorService
{
    public async Task<ExtractedData> ExtractFromDocumentAsync(string ocrText, string documentType)
    {
        var schema = GetExtractionSchema(documentType);
        
        var response = await _aiGateway.CompleteAsync(new AiRequest
        {
            TaskType = AiTaskType.Extraction,
            SystemPrompt = $"""
                أنت محلل وثائق. استخرج البيانات التالية من النص:
                {schema}
                أجب بصيغة JSON. إذا لم تجد قيمة اكتب null.
                """,
            Messages = [new("user", ocrText)]
        });
        
        return JsonSerializer.Deserialize<ExtractedData>(response.Content)!;
    }
}

// === 3. Meeting Summarizer ===
public class MeetingSummarizerService
{
    public async Task<MeetingSummary> SummarizeAsync(string transcript)
    {
        var response = await _aiGateway.CompleteAsync(new AiRequest
        {
            TaskType = AiTaskType.Summarization,
            SystemPrompt = """
                لخص محضر الاجتماع التالي باللغة العربية وأخرج:
                1. ملخص تنفيذي (3-5 أسطر)
                2. القرارات المتخذة
                3. المهام والمسؤوليات (من يفعل ماذا ومتى)
                4. النقاط المعلقة
                """,
            Messages = [new("user", transcript)]
        });
        
        return ParseMeetingSummary(response.Content);
    }
}

// === 4. RAG - Knowledge Base Q&A ===
public class RagService
{
    public async Task<RagResponse> AnswerAsync(string question)
    {
        // 1. Embed the question
        var questionEmbedding = await _aiGateway.EmbedAsync(question);
        
        // 2. Search similar documents
        var relevantDocs = await _vectorStore.SearchSimilarAsync(
            questionEmbedding, topK: 5, minScore: 0.7f);
        
        // 3. Build context
        var context = string.Join("\n---\n", relevantDocs.Select(d => d.Content));
        
        // 4. Generate answer with context
        var response = await _aiGateway.CompleteAsync(new AiRequest
        {
            TaskType = AiTaskType.RAG,
            SystemPrompt = """
                أنت مساعد ذكي للمنصة الموحدة الحكومية. أجب على السؤال بناءً على السياق المقدم فقط.
                إذا لم تجد إجابة في السياق، قل "لا تتوفر لدي معلومات كافية".
                اذكر مصدر المعلومة.
                """,
            Messages = [
                new("user", $"السياق:\n{context}\n\nالسؤال: {question}")
            ]
        });
        
        return new RagResponse
        {
            Answer = response.Content,
            Sources = relevantDocs.Select(d => d.Source).ToList(),
            Confidence = relevantDocs.Average(d => d.Score)
        };
    }
}

// === 5. Anomaly Detection ===
public class AnomalyDetectionService
{
    public async Task<List<Anomaly>> DetectFinancialAnomaliesAsync(int periodId)
    {
        var transactions = await _context.JournalEntries
            .Where(j => j.FiscalPeriodId == periodId)
            .ToListAsync();

        // Statistical anomaly detection
        var amounts = transactions.Select(t => (double)t.TotalDebit).ToArray();
        var mean = amounts.Average();
        var stdDev = Math.Sqrt(amounts.Average(a => Math.Pow(a - mean, 2)));

        var anomalies = transactions
            .Where(t => Math.Abs((double)t.TotalDebit - mean) > 3 * stdDev)
            .Select(t => new Anomaly
            {
                EntityType = "JournalEntry",
                EntityId = t.Id,
                Description = $"قيد بقيمة غير اعتيادية: {t.TotalDebit:N2}",
                Severity = AnomalySeverity.High,
                ZScore = ((double)t.TotalDebit - mean) / stdDev
            })
            .ToList();

        // AI-powered pattern analysis for complex cases
        if (anomalies.Any())
        {
            var aiAnalysis = await _aiGateway.CompleteAsync(new AiRequest
            {
                TaskType = AiTaskType.AnomalyDetection,
                SystemPrompt = "حلل القيود المحاسبية التالية وحدد أي أنماط مشبوهة أو غير اعتيادية.",
                Messages = [new("user", JsonSerializer.Serialize(anomalies))]
            });
            // Enrich anomalies with AI insights
        }

        return anomalies;
    }
}

// === 6. Smart Auto-Responder ===
public class AutoResponderService
{
    public async Task<AutoResponse?> TryAutoRespondAsync(int ticketId)
    {
        var ticket = await _context.Tickets.FindAsync(ticketId);
        
        // Search knowledge base
        var ragResponse = await _ragService.AnswerAsync(
            $"{ticket!.Subject} {ticket.Description}");
        
        if (ragResponse.Confidence >= 0.85)
        {
            return new AutoResponse
            {
                TicketId = ticketId,
                SuggestedAnswer = ragResponse.Answer,
                Confidence = ragResponse.Confidence,
                Sources = ragResponse.Sources,
                RequiresHumanReview = ragResponse.Confidence < 0.95
            };
        }
        
        return null; // Human handling needed
    }
}
```

## SQL Schema

```sql
CREATE SCHEMA [AI];

CREATE TABLE [AI].[Tasks] (
    [Id] BIGINT IDENTITY(1,1) PRIMARY KEY,
    [TaskKey] UNIQUEIDENTIFIER NOT NULL DEFAULT NEWID(),
    [Type] NVARCHAR(30) NOT NULL,
    [Provider] NVARCHAR(20) NOT NULL,
    [ModelName] NVARCHAR(100) NOT NULL,
    [Status] NVARCHAR(20) NOT NULL DEFAULT 'Pending',
    [InputTokens] INT NULL,
    [OutputTokens] INT NULL,
    [CostUsd] DECIMAL(10,6) NULL,
    [LatencyMs] INT NOT NULL DEFAULT 0,
    [EntityType] NVARCHAR(50) NULL,
    [EntityId] INT NULL,
    [CreatedAt] DATETIME2 NOT NULL DEFAULT GETUTCDATE(),
    INDEX IX_Type_Date ([Type], [CreatedAt] DESC)
);

-- Vector Store for RAG
CREATE TABLE [AI].[DocumentEmbeddings] (
    [Id] INT IDENTITY(1,1) PRIMARY KEY,
    [DocumentId] INT NOT NULL,
    [ChunkIndex] INT NOT NULL,
    [Content] NVARCHAR(4000) NOT NULL,
    [Embedding] VARBINARY(MAX) NOT NULL,
    [Source] NVARCHAR(500) NOT NULL,
    [CreatedAt] DATETIME2 NOT NULL DEFAULT GETUTCDATE()
);

-- AI Usage Analytics
CREATE VIEW [AI].[vw_UsageStats] AS
SELECT 
    Provider, Type, ModelName,
    COUNT(*) AS TaskCount,
    AVG(LatencyMs) AS AvgLatencyMs,
    SUM(InputTokens) AS TotalInputTokens,
    SUM(OutputTokens) AS TotalOutputTokens,
    SUM(CostUsd) AS TotalCostUsd,
    CAST(CreatedAt AS DATE) AS TaskDate
FROM [AI].[Tasks]
WHERE Status = 'Completed'
GROUP BY Provider, Type, ModelName, CAST(CreatedAt AS DATE);
```
