version 3

This commit is contained in:
2025-12-17 00:34:41 +03:30
parent 139924db94
commit 74e8480a68
38 changed files with 5399 additions and 70 deletions

View File

@@ -0,0 +1,80 @@
namespace GreenHome.Application;
public sealed class ChecklistDto
{
public int Id { get; set; }
public int DeviceId { get; set; }
public string DeviceName { get; set; } = string.Empty;
public string Title { get; set; } = string.Empty;
public string? Description { get; set; }
public bool IsActive { get; set; }
public List<ChecklistItemDto> Items { get; set; } = new();
public DateTime CreatedAt { get; set; }
public int CreatedByUserId { get; set; }
public string CreatedByUserName { get; set; } = string.Empty;
}
public sealed class ChecklistItemDto
{
public int Id { get; set; }
public string Title { get; set; } = string.Empty;
public string? Description { get; set; }
public int Order { get; set; }
public bool IsRequired { get; set; }
}
public sealed class CreateChecklistRequest
{
public required int DeviceId { get; set; }
public required int CreatedByUserId { get; set; }
public required string Title { get; set; }
public string? Description { get; set; }
public required List<CreateChecklistItemRequest> Items { get; set; }
}
public sealed class CreateChecklistItemRequest
{
public required string Title { get; set; }
public string? Description { get; set; }
public int Order { get; set; }
public bool IsRequired { get; set; }
}
public sealed class ChecklistCompletionDto
{
public int Id { get; set; }
public int ChecklistId { get; set; }
public string ChecklistTitle { get; set; } = string.Empty;
public int CompletedByUserId { get; set; }
public string CompletedByUserName { get; set; } = string.Empty;
public string PersianDate { get; set; } = string.Empty;
public List<ChecklistItemCompletionDto> ItemCompletions { get; set; } = new();
public string? Notes { get; set; }
public DateTime CompletedAt { get; set; }
}
public sealed class ChecklistItemCompletionDto
{
public int Id { get; set; }
public int ChecklistItemId { get; set; }
public string ItemTitle { get; set; } = string.Empty;
public bool IsChecked { get; set; }
public string? Note { get; set; }
}
public sealed class CompleteChecklistRequest
{
public required int ChecklistId { get; set; }
public required int CompletedByUserId { get; set; }
public required string PersianDate { get; set; }
public required List<CompleteChecklistItemRequest> ItemCompletions { get; set; }
public string? Notes { get; set; }
}
public sealed class CompleteChecklistItemRequest
{
public required int ChecklistItemId { get; set; }
public bool IsChecked { get; set; }
public string? Note { get; set; }
}

View File

@@ -0,0 +1,46 @@
namespace GreenHome.Application;
public sealed class DevicePostDto
{
public int Id { get; set; }
public int DeviceId { get; set; }
public int AuthorUserId { get; set; }
public string AuthorName { get; set; } = string.Empty;
public string AuthorFamily { get; set; } = string.Empty;
public string Content { get; set; } = string.Empty;
public List<DevicePostImageDto> Images { get; set; } = new();
public DateTime CreatedAt { get; set; }
public DateTime? UpdatedAt { get; set; }
}
public sealed class DevicePostImageDto
{
public int Id { get; set; }
public string FileName { get; set; } = string.Empty;
public string FilePath { get; set; } = string.Empty;
public string ContentType { get; set; } = string.Empty;
public long FileSize { get; set; }
public DateTime UploadedAt { get; set; }
}
public sealed class CreateDevicePostRequest
{
public required int DeviceId { get; set; }
public required int AuthorUserId { get; set; }
public required string Content { get; set; }
}
public sealed class UpdateDevicePostRequest
{
public required int Id { get; set; }
public required string Content { get; set; }
}
public sealed class DevicePostFilter
{
public required int DeviceId { get; set; }
public int? AuthorUserId { get; set; }
public int Page { get; set; } = 1;
public int PageSize { get; set; } = 20;
}

View File

@@ -123,6 +123,11 @@ public sealed class DeviceSettingsDto
public decimal? Latitude { get; set; }
public decimal? Longitude { get; set; }
public string ProductType { get; set; } = string.Empty;
public int MinimumSmsIntervalMinutes { get; set; } = 15;
public int MinimumCallIntervalMinutes { get; set; } = 60;
public decimal? AreaSquareMeters { get; set; }
public DateTime CreatedAt { get; set; }
public DateTime UpdatedAt { get; set; }
}
@@ -202,4 +207,109 @@ public sealed class DailyReportResponse
public int TotalTokens { get; set; }
public DateTime CreatedAt { get; set; }
public bool FromCache { get; set; }
}
public sealed class WeeklyAnalysisRequest
{
public required int DeviceId { get; set; }
public required string StartDate { get; set; } // yyyy/MM/dd
public required string EndDate { get; set; } // yyyy/MM/dd
}
public sealed class MonthlyAnalysisRequest
{
public required int DeviceId { get; set; }
public required int Year { get; set; }
public required int Month { get; set; }
}
public sealed class AlertLogDto
{
public int Id { get; set; }
public int DeviceId { get; set; }
public string DeviceName { get; set; } = string.Empty;
public int UserId { get; set; }
public string UserName { get; set; } = string.Empty;
public string UserMobile { get; set; } = string.Empty;
public int? AlertConditionId { get; set; }
public Domain.AlertType AlertType { get; set; }
public Domain.AlertNotificationType NotificationType { get; set; }
public string Message { get; set; } = string.Empty;
public Domain.AlertStatus Status { get; set; }
public string? ErrorMessage { get; set; }
public string PhoneNumber { get; set; } = string.Empty;
public DateTime SentAt { get; set; }
public long ProcessingTimeMs { get; set; }
}
public sealed class AlertLogFilter
{
public int? DeviceId { get; set; }
public int? UserId { get; set; }
public Domain.AlertType? AlertType { get; set; }
public Domain.AlertStatus? Status { get; set; }
public DateTime? StartDate { get; set; }
public DateTime? EndDate { get; set; }
public int Page { get; set; } = 1;
public int PageSize { get; set; } = 20;
}
public sealed class UserDailyReportDto
{
public int Id { get; set; }
public int DeviceId { get; set; }
public string DeviceName { get; set; } = string.Empty;
public int UserId { get; set; }
public string UserName { get; set; } = string.Empty;
public string UserFamily { get; set; } = string.Empty;
public string PersianDate { get; set; } = string.Empty;
public string Title { get; set; } = string.Empty;
public string Observations { get; set; } = string.Empty;
public string Operations { get; set; } = string.Empty;
public string? Notes { get; set; }
public List<ReportImageDto> Images { get; set; } = new();
public DateTime CreatedAt { get; set; }
public DateTime UpdatedAt { get; set; }
}
public sealed class ReportImageDto
{
public int Id { get; set; }
public string FileName { get; set; } = string.Empty;
public string FilePath { get; set; } = string.Empty;
public string ContentType { get; set; } = string.Empty;
public long FileSize { get; set; }
public string? Description { get; set; }
public DateTime UploadedAt { get; set; }
}
public sealed class CreateUserDailyReportRequest
{
public required int DeviceId { get; set; }
public required int UserId { get; set; }
public required string PersianDate { get; set; }
public required string Title { get; set; }
public required string Observations { get; set; }
public required string Operations { get; set; }
public string? Notes { get; set; }
}
public sealed class UpdateUserDailyReportRequest
{
public required int Id { get; set; }
public required string Title { get; set; }
public required string Observations { get; set; }
public required string Operations { get; set; }
public string? Notes { get; set; }
}
public sealed class UserDailyReportFilter
{
public int? DeviceId { get; set; }
public int? UserId { get; set; }
public string? PersianDate { get; set; }
public int? Year { get; set; }
public int? Month { get; set; }
public int Page { get; set; } = 1;
public int PageSize { get; set; } = 20;
}

View File

@@ -0,0 +1,9 @@
namespace GreenHome.Application;
public interface IAlertLogService
{
Task<PagedResult<AlertLogDto>> GetAlertLogsAsync(AlertLogFilter filter, CancellationToken cancellationToken);
Task<AlertLogDto?> GetAlertLogByIdAsync(int id, CancellationToken cancellationToken);
Task<int> CreateAlertLogAsync(AlertLogDto dto, CancellationToken cancellationToken);
}

View File

@@ -3,5 +3,6 @@ namespace GreenHome.Application;
public interface IAlertService
{
Task CheckAndSendAlertsAsync(int deviceId, TelemetryDto telemetry, CancellationToken cancellationToken);
Task SendPowerOutageAlertAsync(int deviceId, CancellationToken cancellationToken);
}

View File

@@ -0,0 +1,12 @@
namespace GreenHome.Application;
public interface IChecklistService
{
Task<ChecklistDto?> GetActiveChecklistByDeviceIdAsync(int deviceId, CancellationToken cancellationToken);
Task<List<ChecklistDto>> GetChecklistsByDeviceIdAsync(int deviceId, CancellationToken cancellationToken);
Task<ChecklistDto?> GetChecklistByIdAsync(int id, CancellationToken cancellationToken);
Task<int> CreateChecklistAsync(CreateChecklistRequest request, CancellationToken cancellationToken);
Task<List<ChecklistCompletionDto>> GetCompletionsByChecklistIdAsync(int checklistId, CancellationToken cancellationToken);
Task<int> CompleteChecklistAsync(CompleteChecklistRequest request, CancellationToken cancellationToken);
}

View File

@@ -9,5 +9,9 @@ public interface IDailyReportService
/// <param name="cancellationToken">Cancellation token</param>
/// <returns>Daily report with AI analysis</returns>
Task<DailyReportResponse> GetOrCreateDailyReportAsync(DailyReportRequest request, CancellationToken cancellationToken);
Task<DailyReportResponse> GetWeeklyAnalysisAsync(WeeklyAnalysisRequest request, CancellationToken cancellationToken);
Task<DailyReportResponse> GetMonthlyAnalysisAsync(MonthlyAnalysisRequest request, CancellationToken cancellationToken);
}

View File

@@ -0,0 +1,14 @@
namespace GreenHome.Application;
public interface IDevicePostService
{
Task<PagedResult<DevicePostDto>> GetPostsAsync(DevicePostFilter filter, CancellationToken cancellationToken);
Task<DevicePostDto?> GetPostByIdAsync(int id, CancellationToken cancellationToken);
Task<int> CreatePostAsync(CreateDevicePostRequest request, CancellationToken cancellationToken);
Task UpdatePostAsync(UpdateDevicePostRequest request, CancellationToken cancellationToken);
Task DeletePostAsync(int id, CancellationToken cancellationToken);
Task<int> AddImageToPostAsync(int postId, string fileName, string filePath, string contentType, long fileSize, CancellationToken cancellationToken);
Task DeleteImageAsync(int imageId, CancellationToken cancellationToken);
Task<bool> CanUserAccessDeviceAsync(int userId, int deviceId, CancellationToken cancellationToken);
}

View File

@@ -0,0 +1,45 @@
namespace GreenHome.Application;
public interface IMonthlyReportService
{
Task<MonthlyReportDto> GetMonthlyReportAsync(int deviceId, int year, int month, CancellationToken cancellationToken);
}
public sealed class MonthlyReportDto
{
public int DeviceId { get; set; }
public string DeviceName { get; set; } = string.Empty;
public int Year { get; set; }
public int Month { get; set; }
// Alert Statistics
public int TotalAlerts { get; set; }
public int SmsAlerts { get; set; }
public int CallAlerts { get; set; }
public int SuccessfulAlerts { get; set; }
public int FailedAlerts { get; set; }
public int PowerOutageAlerts { get; set; }
// Telemetry Statistics
public int TotalTelemetryRecords { get; set; }
public decimal AverageTemperature { get; set; }
public decimal MinTemperature { get; set; }
public decimal MaxTemperature { get; set; }
public decimal AverageHumidity { get; set; }
public decimal MinHumidity { get; set; }
public decimal MaxHumidity { get; set; }
public decimal AverageLux { get; set; }
public int AverageGasPPM { get; set; }
public int MaxGasPPM { get; set; }
// User Activity
public int UserDailyReportsCount { get; set; }
public int ChecklistCompletionsCount { get; set; }
public int DailyAnalysesCount { get; set; }
// Performance Summary
public string PerformanceSummary { get; set; } = string.Empty;
public DateTime GeneratedAt { get; set; }
}

View File

@@ -0,0 +1,13 @@
namespace GreenHome.Application;
public interface IUserDailyReportService
{
Task<PagedResult<UserDailyReportDto>> GetReportsAsync(UserDailyReportFilter filter, CancellationToken cancellationToken);
Task<UserDailyReportDto?> GetReportByIdAsync(int id, CancellationToken cancellationToken);
Task<int> CreateReportAsync(CreateUserDailyReportRequest request, CancellationToken cancellationToken);
Task UpdateReportAsync(UpdateUserDailyReportRequest request, CancellationToken cancellationToken);
Task DeleteReportAsync(int id, CancellationToken cancellationToken);
Task<int> AddImageToReportAsync(int reportId, string fileName, string filePath, string contentType, long fileSize, string? description, CancellationToken cancellationToken);
Task DeleteImageAsync(int imageId, CancellationToken cancellationToken);
}

View File

@@ -32,5 +32,40 @@ public sealed class MappingProfile : Profile
CreateMap<CreateAlertRuleRequest, Domain.AlertRule>();
CreateMap<Domain.User, UserDto>().ReverseMap();
CreateMap<Domain.AlertLog, AlertLogDto>()
.ForMember(dest => dest.DeviceName, opt => opt.MapFrom(src => src.Device.DeviceName))
.ForMember(dest => dest.UserName, opt => opt.MapFrom(src => src.User.Name))
.ForMember(dest => dest.UserMobile, opt => opt.MapFrom(src => src.User.Mobile))
.ReverseMap()
.ForMember(dest => dest.Device, opt => opt.Ignore())
.ForMember(dest => dest.User, opt => opt.Ignore())
.ForMember(dest => dest.AlertCondition, opt => opt.Ignore());
CreateMap<Domain.UserDailyReport, UserDailyReportDto>()
.ForMember(dest => dest.DeviceName, opt => opt.MapFrom(src => src.Device.DeviceName))
.ForMember(dest => dest.UserName, opt => opt.MapFrom(src => src.User.Name))
.ForMember(dest => dest.UserFamily, opt => opt.MapFrom(src => src.User.Family));
CreateMap<Domain.ReportImage, ReportImageDto>();
CreateMap<Domain.Checklist, ChecklistDto>()
.ForMember(dest => dest.DeviceName, opt => opt.MapFrom(src => src.Device.DeviceName))
.ForMember(dest => dest.CreatedByUserName, opt => opt.MapFrom(src => src.CreatedByUser.Name + " " + src.CreatedByUser.Family));
CreateMap<Domain.ChecklistItem, ChecklistItemDto>();
CreateMap<Domain.ChecklistCompletion, ChecklistCompletionDto>()
.ForMember(dest => dest.ChecklistTitle, opt => opt.MapFrom(src => src.Checklist.Title))
.ForMember(dest => dest.CompletedByUserName, opt => opt.MapFrom(src => src.CompletedByUser.Name + " " + src.CompletedByUser.Family));
CreateMap<Domain.ChecklistItemCompletion, ChecklistItemCompletionDto>()
.ForMember(dest => dest.ItemTitle, opt => opt.MapFrom(src => src.ChecklistItem.Title));
CreateMap<Domain.DevicePost, DevicePostDto>()
.ForMember(dest => dest.AuthorName, opt => opt.MapFrom(src => src.AuthorUser.Name))
.ForMember(dest => dest.AuthorFamily, opt => opt.MapFrom(src => src.AuthorUser.Family));
CreateMap<Domain.DevicePostImage, DevicePostImageDto>();
}
}