Add customer communication system
This commit is contained in:
113
LittleShop/DTOs/BotDto.cs
Normal file
113
LittleShop/DTOs/BotDto.cs
Normal file
@@ -0,0 +1,113 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using LittleShop.Enums;
|
||||
|
||||
namespace LittleShop.DTOs;
|
||||
|
||||
public class BotDto
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public string Description { get; set; } = string.Empty;
|
||||
public BotType Type { get; set; }
|
||||
public BotStatus Status { get; set; }
|
||||
public DateTime CreatedAt { get; set; }
|
||||
public DateTime? LastSeenAt { get; set; }
|
||||
public DateTime? LastConfigSyncAt { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
public string Version { get; set; } = string.Empty;
|
||||
public string IpAddress { get; set; } = string.Empty;
|
||||
public string PlatformUsername { get; set; } = string.Empty;
|
||||
public string PlatformDisplayName { get; set; } = string.Empty;
|
||||
public string PlatformId { get; set; } = string.Empty;
|
||||
public string PersonalityName { get; set; } = string.Empty;
|
||||
public Dictionary<string, object> Settings { get; set; } = new();
|
||||
|
||||
// Metrics summary
|
||||
public int TotalSessions { get; set; }
|
||||
public int ActiveSessions { get; set; }
|
||||
public decimal TotalRevenue { get; set; }
|
||||
public int TotalOrders { get; set; }
|
||||
}
|
||||
|
||||
public class BotRegistrationDto
|
||||
{
|
||||
[Required]
|
||||
[StringLength(100)]
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
[StringLength(500)]
|
||||
public string Description { get; set; } = string.Empty;
|
||||
|
||||
public BotType Type { get; set; }
|
||||
|
||||
[StringLength(50)]
|
||||
public string Version { get; set; } = string.Empty;
|
||||
|
||||
[StringLength(50)]
|
||||
public string PersonalityName { get; set; } = string.Empty;
|
||||
|
||||
public Dictionary<string, object> InitialSettings { get; set; } = new();
|
||||
}
|
||||
|
||||
public class BotRegistrationResponseDto
|
||||
{
|
||||
public Guid BotId { get; set; }
|
||||
public string BotKey { get; set; } = string.Empty;
|
||||
public string Name { get; set; } = string.Empty;
|
||||
public Dictionary<string, object> Settings { get; set; } = new();
|
||||
}
|
||||
|
||||
public class BotAuthenticateDto
|
||||
{
|
||||
public string BotKey { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public class BotSettingsDto
|
||||
{
|
||||
public Dictionary<string, object> Telegram { get; set; } = new();
|
||||
public Dictionary<string, object> Privacy { get; set; } = new();
|
||||
public Dictionary<string, object> Features { get; set; } = new();
|
||||
public Dictionary<string, object> Redis { get; set; } = new();
|
||||
public List<string> Cryptocurrencies { get; set; } = new();
|
||||
}
|
||||
|
||||
public class UpdateBotSettingsDto
|
||||
{
|
||||
public Dictionary<string, object> Settings { get; set; } = new();
|
||||
}
|
||||
|
||||
public class BotHeartbeatDto
|
||||
{
|
||||
public string Version { get; set; } = string.Empty;
|
||||
public string IpAddress { get; set; } = string.Empty;
|
||||
public int ActiveSessions { get; set; }
|
||||
public Dictionary<string, object> Status { get; set; } = new();
|
||||
}
|
||||
|
||||
public class UpdatePlatformInfoDto
|
||||
{
|
||||
public string PlatformUsername { get; set; } = string.Empty;
|
||||
public string PlatformDisplayName { get; set; } = string.Empty;
|
||||
public string PlatformId { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public class BotWizardDto
|
||||
{
|
||||
[Required(ErrorMessage = "Bot name is required")]
|
||||
[StringLength(50)]
|
||||
public string BotName { get; set; } = string.Empty;
|
||||
|
||||
[Required(ErrorMessage = "Bot username is required")]
|
||||
[StringLength(100)]
|
||||
public string BotUsername { get; set; } = string.Empty;
|
||||
|
||||
[StringLength(500)]
|
||||
public string Description { get; set; } = string.Empty;
|
||||
|
||||
[StringLength(50)]
|
||||
public string PersonalityName { get; set; } = string.Empty;
|
||||
|
||||
public string BotToken { get; set; } = string.Empty;
|
||||
}
|
||||
62
LittleShop/DTOs/BotMetricDto.cs
Normal file
62
LittleShop/DTOs/BotMetricDto.cs
Normal file
@@ -0,0 +1,62 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using LittleShop.Enums;
|
||||
|
||||
namespace LittleShop.DTOs;
|
||||
|
||||
public class BotMetricDto
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public Guid BotId { get; set; }
|
||||
public MetricType MetricType { get; set; }
|
||||
public decimal Value { get; set; }
|
||||
public string Category { get; set; } = string.Empty;
|
||||
public string Description { get; set; } = string.Empty;
|
||||
public DateTime RecordedAt { get; set; }
|
||||
public Dictionary<string, object> Metadata { get; set; } = new();
|
||||
}
|
||||
|
||||
public class CreateBotMetricDto
|
||||
{
|
||||
public MetricType MetricType { get; set; }
|
||||
public decimal Value { get; set; }
|
||||
public string Category { get; set; } = string.Empty;
|
||||
public string Description { get; set; } = string.Empty;
|
||||
public Dictionary<string, object> Metadata { get; set; } = new();
|
||||
}
|
||||
|
||||
public class BotMetricsBatchDto
|
||||
{
|
||||
public List<CreateBotMetricDto> Metrics { get; set; } = new();
|
||||
}
|
||||
|
||||
public class BotMetricsSummaryDto
|
||||
{
|
||||
public Guid BotId { get; set; }
|
||||
public string BotName { get; set; } = string.Empty;
|
||||
public DateTime PeriodStart { get; set; }
|
||||
public DateTime PeriodEnd { get; set; }
|
||||
|
||||
// Key metrics
|
||||
public int TotalSessions { get; set; }
|
||||
public int UniqueSessions { get; set; }
|
||||
public int TotalOrders { get; set; }
|
||||
public decimal TotalRevenue { get; set; }
|
||||
public int TotalMessages { get; set; }
|
||||
public int TotalErrors { get; set; }
|
||||
public decimal AverageResponseTime { get; set; }
|
||||
public decimal UptimePercentage { get; set; }
|
||||
|
||||
// Breakdown by type
|
||||
public Dictionary<string, decimal> MetricsByType { get; set; } = new();
|
||||
|
||||
// Time series data (for charts)
|
||||
public List<TimeSeriesDataPoint> TimeSeries { get; set; } = new();
|
||||
}
|
||||
|
||||
public class TimeSeriesDataPoint
|
||||
{
|
||||
public DateTime Timestamp { get; set; }
|
||||
public string Label { get; set; } = string.Empty;
|
||||
public decimal Value { get; set; }
|
||||
}
|
||||
54
LittleShop/DTOs/BotSessionDto.cs
Normal file
54
LittleShop/DTOs/BotSessionDto.cs
Normal file
@@ -0,0 +1,54 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace LittleShop.DTOs;
|
||||
|
||||
public class BotSessionDto
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public Guid BotId { get; set; }
|
||||
public string SessionIdentifier { get; set; } = string.Empty;
|
||||
public string Platform { get; set; } = string.Empty;
|
||||
public DateTime StartedAt { get; set; }
|
||||
public DateTime LastActivityAt { get; set; }
|
||||
public DateTime? EndedAt { get; set; }
|
||||
public int OrderCount { get; set; }
|
||||
public int MessageCount { get; set; }
|
||||
public decimal TotalSpent { get; set; }
|
||||
public string Language { get; set; } = string.Empty;
|
||||
public string Country { get; set; } = string.Empty;
|
||||
public bool IsAnonymous { get; set; }
|
||||
public Dictionary<string, object> Metadata { get; set; } = new();
|
||||
}
|
||||
|
||||
public class CreateBotSessionDto
|
||||
{
|
||||
public string SessionIdentifier { get; set; } = string.Empty;
|
||||
public string Platform { get; set; } = string.Empty;
|
||||
public string Language { get; set; } = "en";
|
||||
public string Country { get; set; } = string.Empty;
|
||||
public bool IsAnonymous { get; set; } = true;
|
||||
public Dictionary<string, object> Metadata { get; set; } = new();
|
||||
}
|
||||
|
||||
public class UpdateBotSessionDto
|
||||
{
|
||||
public int? OrderCount { get; set; }
|
||||
public int? MessageCount { get; set; }
|
||||
public decimal? TotalSpent { get; set; }
|
||||
public bool? EndSession { get; set; }
|
||||
public Dictionary<string, object>? Metadata { get; set; }
|
||||
}
|
||||
|
||||
public class BotSessionSummaryDto
|
||||
{
|
||||
public int TotalSessions { get; set; }
|
||||
public int ActiveSessions { get; set; }
|
||||
public int CompletedSessions { get; set; }
|
||||
public decimal AverageSessionDuration { get; set; } // in minutes
|
||||
public decimal AverageOrdersPerSession { get; set; }
|
||||
public decimal AverageSpendPerSession { get; set; }
|
||||
public Dictionary<string, int> SessionsByPlatform { get; set; } = new();
|
||||
public Dictionary<string, int> SessionsByCountry { get; set; } = new();
|
||||
public Dictionary<string, int> SessionsByLanguage { get; set; } = new();
|
||||
}
|
||||
90
LittleShop/DTOs/CustomerDto.cs
Normal file
90
LittleShop/DTOs/CustomerDto.cs
Normal file
@@ -0,0 +1,90 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace LittleShop.DTOs;
|
||||
|
||||
public class CustomerDto
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public long TelegramUserId { get; set; }
|
||||
public string TelegramUsername { get; set; } = string.Empty;
|
||||
public string TelegramDisplayName { get; set; } = string.Empty;
|
||||
public string TelegramFirstName { get; set; } = string.Empty;
|
||||
public string TelegramLastName { get; set; } = string.Empty;
|
||||
public string? Email { get; set; }
|
||||
public string? PhoneNumber { get; set; }
|
||||
public bool AllowMarketing { get; set; }
|
||||
public bool AllowOrderUpdates { get; set; }
|
||||
public string Language { get; set; } = "en";
|
||||
public string Timezone { get; set; } = "UTC";
|
||||
public int TotalOrders { get; set; }
|
||||
public decimal TotalSpent { get; set; }
|
||||
public decimal AverageOrderValue { get; set; }
|
||||
public DateTime FirstOrderDate { get; set; }
|
||||
public DateTime LastOrderDate { get; set; }
|
||||
public string? CustomerNotes { get; set; }
|
||||
public bool IsBlocked { get; set; }
|
||||
public string? BlockReason { get; set; }
|
||||
public int RiskScore { get; set; }
|
||||
public int SuccessfulOrders { get; set; }
|
||||
public int CancelledOrders { get; set; }
|
||||
public int DisputedOrders { get; set; }
|
||||
public DateTime CreatedAt { get; set; }
|
||||
public DateTime UpdatedAt { get; set; }
|
||||
public DateTime LastActiveAt { get; set; }
|
||||
public DateTime? DataRetentionDate { get; set; }
|
||||
public bool IsActive { get; set; }
|
||||
|
||||
// Calculated Properties
|
||||
public string DisplayName { get; set; } = string.Empty;
|
||||
public string CustomerType { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public class CustomerSummaryDto
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string DisplayName { get; set; } = string.Empty;
|
||||
public string TelegramUsername { get; set; } = string.Empty;
|
||||
public int TotalOrders { get; set; }
|
||||
public decimal TotalSpent { get; set; }
|
||||
public string CustomerType { get; set; } = string.Empty;
|
||||
public int RiskScore { get; set; }
|
||||
public DateTime LastActiveAt { get; set; }
|
||||
public bool IsBlocked { get; set; }
|
||||
}
|
||||
|
||||
public class CreateCustomerDto
|
||||
{
|
||||
[Required]
|
||||
public long TelegramUserId { get; set; }
|
||||
|
||||
public string TelegramUsername { get; set; } = string.Empty;
|
||||
|
||||
[Required]
|
||||
public string TelegramDisplayName { get; set; } = string.Empty;
|
||||
|
||||
public string TelegramFirstName { get; set; } = string.Empty;
|
||||
public string TelegramLastName { get; set; } = string.Empty;
|
||||
public string? Email { get; set; }
|
||||
public string? PhoneNumber { get; set; }
|
||||
public bool AllowMarketing { get; set; } = false;
|
||||
public bool AllowOrderUpdates { get; set; } = true;
|
||||
public string Language { get; set; } = "en";
|
||||
public string Timezone { get; set; } = "UTC";
|
||||
}
|
||||
|
||||
public class UpdateCustomerDto
|
||||
{
|
||||
public string TelegramUsername { get; set; } = string.Empty;
|
||||
public string TelegramDisplayName { get; set; } = string.Empty;
|
||||
public string TelegramFirstName { get; set; } = string.Empty;
|
||||
public string TelegramLastName { get; set; } = string.Empty;
|
||||
public string? Email { get; set; }
|
||||
public string? PhoneNumber { get; set; }
|
||||
public bool AllowMarketing { get; set; }
|
||||
public bool AllowOrderUpdates { get; set; }
|
||||
public string Language { get; set; } = "en";
|
||||
public string Timezone { get; set; } = "UTC";
|
||||
public string? CustomerNotes { get; set; }
|
||||
public bool IsBlocked { get; set; }
|
||||
public string? BlockReason { get; set; }
|
||||
}
|
||||
118
LittleShop/DTOs/CustomerMessageDto.cs
Normal file
118
LittleShop/DTOs/CustomerMessageDto.cs
Normal file
@@ -0,0 +1,118 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using LittleShop.Models;
|
||||
|
||||
namespace LittleShop.DTOs;
|
||||
|
||||
public class CustomerMessageDto
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public Guid CustomerId { get; set; }
|
||||
public Guid? OrderId { get; set; }
|
||||
public Guid? AdminUserId { get; set; }
|
||||
public MessageDirection Direction { get; set; }
|
||||
public MessageType Type { get; set; }
|
||||
public string Subject { get; set; } = string.Empty;
|
||||
public string Content { get; set; } = string.Empty;
|
||||
public MessageStatus Status { get; set; }
|
||||
public DateTime CreatedAt { get; set; }
|
||||
public DateTime? SentAt { get; set; }
|
||||
public DateTime? DeliveredAt { get; set; }
|
||||
public DateTime? ReadAt { get; set; }
|
||||
public DateTime? FailedAt { get; set; }
|
||||
public string? FailureReason { get; set; }
|
||||
public int RetryCount { get; set; }
|
||||
public DateTime? NextRetryAt { get; set; }
|
||||
public Guid? ParentMessageId { get; set; }
|
||||
public Guid? ThreadId { get; set; }
|
||||
public string Platform { get; set; } = string.Empty;
|
||||
public string? PlatformMessageId { get; set; }
|
||||
public int Priority { get; set; }
|
||||
public DateTime? ScheduledFor { get; set; }
|
||||
public DateTime? ExpiresAt { get; set; }
|
||||
public bool RequiresResponse { get; set; }
|
||||
public bool IsUrgent { get; set; }
|
||||
public bool IsMarketing { get; set; }
|
||||
public bool IsAutoGenerated { get; set; }
|
||||
public string? AutoGenerationTrigger { get; set; }
|
||||
|
||||
// Navigation properties
|
||||
public CustomerSummaryDto? Customer { get; set; }
|
||||
public string? AdminUsername { get; set; }
|
||||
public string? OrderReference { get; set; }
|
||||
|
||||
// For message delivery
|
||||
public long TelegramUserId { get; set; }
|
||||
|
||||
// Helper properties
|
||||
public string DisplayTitle { get; set; } = string.Empty;
|
||||
public string StatusDisplay { get; set; } = string.Empty;
|
||||
public string DirectionDisplay { get; set; } = string.Empty;
|
||||
public string TypeDisplay { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public class CreateCustomerMessageDto
|
||||
{
|
||||
[Required]
|
||||
public Guid CustomerId { get; set; }
|
||||
|
||||
public Guid? OrderId { get; set; }
|
||||
|
||||
public Guid? AdminUserId { get; set; } // Set by controller from claims
|
||||
|
||||
[Required]
|
||||
public MessageType Type { get; set; }
|
||||
|
||||
[Required]
|
||||
[StringLength(100)]
|
||||
public string Subject { get; set; } = string.Empty;
|
||||
|
||||
[Required]
|
||||
[StringLength(4000)]
|
||||
public string Content { get; set; } = string.Empty;
|
||||
|
||||
public int Priority { get; set; } = 5;
|
||||
|
||||
public DateTime? ScheduledFor { get; set; }
|
||||
|
||||
public DateTime? ExpiresAt { get; set; }
|
||||
|
||||
public bool RequiresResponse { get; set; } = false;
|
||||
|
||||
public bool IsUrgent { get; set; } = false;
|
||||
|
||||
public bool IsMarketing { get; set; } = false;
|
||||
}
|
||||
|
||||
public class CustomerMessageSummaryDto
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public Guid CustomerId { get; set; }
|
||||
public string CustomerName { get; set; } = string.Empty;
|
||||
public Guid? OrderId { get; set; }
|
||||
public string? OrderReference { get; set; }
|
||||
public MessageDirection Direction { get; set; }
|
||||
public MessageType Type { get; set; }
|
||||
public string Subject { get; set; } = string.Empty;
|
||||
public MessageStatus Status { get; set; }
|
||||
public DateTime CreatedAt { get; set; }
|
||||
public DateTime? SentAt { get; set; }
|
||||
public bool IsUrgent { get; set; }
|
||||
public bool RequiresResponse { get; set; }
|
||||
public string DisplayTitle { get; set; } = string.Empty;
|
||||
}
|
||||
|
||||
public class MessageThreadDto
|
||||
{
|
||||
public Guid ThreadId { get; set; }
|
||||
public string Subject { get; set; } = string.Empty;
|
||||
public Guid CustomerId { get; set; }
|
||||
public string CustomerName { get; set; } = string.Empty;
|
||||
public Guid? OrderId { get; set; }
|
||||
public string? OrderReference { get; set; }
|
||||
public DateTime StartedAt { get; set; }
|
||||
public DateTime LastMessageAt { get; set; }
|
||||
public int MessageCount { get; set; }
|
||||
public bool HasUnreadMessages { get; set; }
|
||||
public bool RequiresResponse { get; set; }
|
||||
public List<CustomerMessageDto> Messages { get; set; } = new();
|
||||
}
|
||||
@@ -6,8 +6,12 @@ namespace LittleShop.DTOs;
|
||||
public class OrderDto
|
||||
{
|
||||
public Guid Id { get; set; }
|
||||
public string IdentityReference { get; set; } = string.Empty;
|
||||
public Guid? CustomerId { get; set; }
|
||||
public string? IdentityReference { get; set; }
|
||||
public OrderStatus Status { get; set; }
|
||||
|
||||
// Customer Information (embedded for convenience)
|
||||
public CustomerSummaryDto? Customer { get; set; }
|
||||
public decimal TotalAmount { get; set; }
|
||||
public string Currency { get; set; } = "GBP";
|
||||
public string ShippingName { get; set; } = string.Empty;
|
||||
@@ -37,8 +41,13 @@ public class OrderItemDto
|
||||
|
||||
public class CreateOrderDto
|
||||
{
|
||||
[Required]
|
||||
public string IdentityReference { get; set; } = string.Empty;
|
||||
// Either Customer ID (for registered customers) OR Identity Reference (for anonymous)
|
||||
public Guid? CustomerId { get; set; }
|
||||
|
||||
public string? IdentityReference { get; set; }
|
||||
|
||||
// Customer Information (collected at checkout for anonymous orders)
|
||||
public CreateCustomerDto? CustomerInfo { get; set; }
|
||||
|
||||
[Required]
|
||||
public string ShippingName { get; set; } = string.Empty;
|
||||
|
||||
12
LittleShop/DTOs/PagedResultDto.cs
Normal file
12
LittleShop/DTOs/PagedResultDto.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
namespace LittleShop.DTOs;
|
||||
|
||||
public class PagedResult<T>
|
||||
{
|
||||
public List<T> Items { get; set; } = new();
|
||||
public int TotalCount { get; set; }
|
||||
public int PageNumber { get; set; }
|
||||
public int PageSize { get; set; }
|
||||
public int TotalPages => (int)Math.Ceiling((double)TotalCount / PageSize);
|
||||
public bool HasPrevious => PageNumber > 1;
|
||||
public bool HasNext => PageNumber < TotalPages;
|
||||
}
|
||||
Reference in New Issue
Block a user