Внести исправления после ревью

This commit is contained in:
Roman Efremov 2024-11-28 08:55:50 +05:00
parent dc66522c0f
commit 1e87523ab9
15 changed files with 355 additions and 142 deletions

View File

@ -11,7 +11,7 @@ namespace Persistence.API.Controllers;
[ApiController]
[Authorize]
[Route("api/[controller]")]
public class TechMessagesController : ControllerBase, ITechMessages
public class TechMessagesController : ControllerBase
{
private readonly ITechMessagesRepository techMessagesRepository;
@ -41,8 +41,8 @@ public class TechMessagesController : ControllerBase, ITechMessages
/// <param name="autoDrillingSystem"></param>
/// <param name="token"></param>
/// <returns></returns>
[HttpGet("statistics")]
public async Task<ActionResult<int>> GetStatistics(int importantId, string autoDrillingSystem, CancellationToken token)
[HttpGet("statistics/{autoDrillingSystem}")]
public async Task<ActionResult<int>> GetStatistics([FromRoute] string? autoDrillingSystem, int? importantId, CancellationToken token)
{
var result = await techMessagesRepository.GetStatistics(importantId, autoDrillingSystem, token);

View File

@ -1,9 +1,12 @@
using System.Reflection;
using System.Text.Json.Nodes;
using Mapster;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.IdentityModel.Tokens;
using Microsoft.OpenApi.Any;
using Microsoft.OpenApi.Models;
using Persistence.Database.Entity;
using Persistence.Models;
using Persistence.Models.Configurations;
using Swashbuckle.AspNetCore.SwaggerGen;
@ -11,6 +14,12 @@ namespace Persistence.API;
public static class DependencyInjection
{
public static void MapsterSetup()
{
TypeAdapterConfig.GlobalSettings.Default.Config
.ForType<TechMessageDto, TechMessage>()
.Ignore(dest => dest.System, dest => dest.SystemId);
}
public static void AddSwagger(this IServiceCollection services, IConfiguration configuration)
{
services.AddSwaggerGen(c =>

View File

@ -23,6 +23,9 @@ public class Startup
services.AddInfrastructure();
services.AddPersistenceDbContext(Configuration);
services.AddJWTAuthentication(Configuration);
services.AddMemoryCache();
DependencyInjection.MapsterSetup();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)

View File

@ -1,59 +0,0 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Persistence.Database.Postgres.Migrations
{
/// <inheritdoc />
public partial class TechMessageMigration : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AlterColumn<DateTimeOffset>(
name: "Created",
table: "Setpoint",
type: "timestamp with time zone",
nullable: false,
comment: "Дата создания уставки",
oldClrType: typeof(DateTimeOffset),
oldType: "timestamp with time zone",
oldComment: "Дата изменения уставки");
migrationBuilder.CreateTable(
name: "TechMessage",
columns: table => new
{
EventId = table.Column<Guid>(type: "uuid", nullable: false, comment: "Id события"),
ImportantId = table.Column<int>(type: "integer", nullable: false, comment: "Id Категории важности"),
OccurrenceDate = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, comment: "Дата возникновения"),
Depth = table.Column<double>(type: "double precision", nullable: true, comment: "Глубина забоя"),
MessageText = table.Column<string>(type: "varchar(512)", nullable: true, comment: "Текст сообщения"),
AutoDrillingSystem = table.Column<string>(type: "varchar(256)", nullable: true, comment: "Система автобурения, к которой относится сообщение"),
UserId = table.Column<Guid>(type: "uuid", nullable: false, comment: "Id пользователя за пультом бурильщика")
},
constraints: table =>
{
table.PrimaryKey("PK_TechMessage", x => x.EventId);
});
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "TechMessage");
migrationBuilder.AlterColumn<DateTimeOffset>(
name: "Created",
table: "Setpoint",
type: "timestamp with time zone",
nullable: false,
comment: "Дата изменения уставки",
oldClrType: typeof(DateTimeOffset),
oldType: "timestamp with time zone",
oldComment: "Дата создания уставки");
}
}
}

View File

@ -12,7 +12,7 @@ using Persistence.Database.Model;
namespace Persistence.Database.Postgres.Migrations
{
[DbContext(typeof(PersistenceDbContext))]
[Migration("20241126044756_TechMessageMigration")]
[Migration("20241127123045_TechMessageMigration")]
partial class TechMessageMigration
{
/// <inheritdoc />
@ -27,6 +27,27 @@ namespace Persistence.Database.Postgres.Migrations
NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "adminpack");
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("Persistence.Database.Entity.ADSystem", b =>
{
b.Property<Guid>("SystemId")
.ValueGeneratedOnAdd()
.HasColumnType("uuid")
.HasComment("Id системы автобурения");
b.Property<string>("Description")
.HasColumnType("text")
.HasComment("Описание системы автобурения");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("varchar(256)")
.HasComment("Наименование системы автобурения");
b.HasKey("SystemId");
b.ToTable("ADSystem");
});
modelBuilder.Entity("Persistence.Database.Entity.TechMessage", b =>
{
b.Property<Guid>("EventId")
@ -34,10 +55,6 @@ namespace Persistence.Database.Postgres.Migrations
.HasColumnType("uuid")
.HasComment("Id события");
b.Property<string>("AutoDrillingSystem")
.HasColumnType("varchar(256)")
.HasComment("Система автобурения, к которой относится сообщение");
b.Property<double?>("Depth")
.HasColumnType("double precision")
.HasComment("Глубина забоя");
@ -47,6 +64,7 @@ namespace Persistence.Database.Postgres.Migrations
.HasComment("Id Категории важности");
b.Property<string>("MessageText")
.IsRequired()
.HasColumnType("varchar(512)")
.HasComment("Текст сообщения");
@ -54,15 +72,44 @@ namespace Persistence.Database.Postgres.Migrations
.HasColumnType("timestamp with time zone")
.HasComment("Дата возникновения");
b.Property<Guid>("SystemId")
.HasColumnType("uuid")
.HasComment("Id системы автобурения, к которой относится сообщение");
b.Property<Guid>("UserId")
.HasColumnType("uuid")
.HasComment("Id пользователя за пультом бурильщика");
b.HasKey("EventId");
b.HasIndex("SystemId");
b.ToTable("TechMessage");
});
modelBuilder.Entity("Persistence.Database.Entity.TimestampedSet", b =>
{
b.Property<Guid>("IdDiscriminator")
.HasColumnType("uuid")
.HasComment("Дискриминатор ссылка на тип сохраняемых данных");
b.Property<DateTimeOffset>("Timestamp")
.HasColumnType("timestamp with time zone")
.HasComment("Отметка времени, строго в UTC");
b.Property<string>("Set")
.IsRequired()
.HasColumnType("jsonb")
.HasComment("Набор сохраняемых данных");
b.HasKey("IdDiscriminator", "Timestamp");
b.ToTable("TimestampedSets", t =>
{
t.HasComment("Общая таблица данных временных рядов");
});
});
modelBuilder.Entity("Persistence.Database.Model.DataSaub", b =>
{
b.Property<DateTimeOffset>("Date")
@ -169,6 +216,17 @@ namespace Persistence.Database.Postgres.Migrations
b.ToTable("Setpoint");
});
modelBuilder.Entity("Persistence.Database.Entity.TechMessage", b =>
{
b.HasOne("Persistence.Database.Entity.ADSystem", "System")
.WithMany()
.HasForeignKey("SystemId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("System");
});
#pragma warning restore 612, 618
}
}

View File

@ -0,0 +1,83 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Persistence.Database.Postgres.Migrations
{
/// <inheritdoc />
public partial class TechMessageMigration : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "ADSystem",
columns: table => new
{
SystemId = table.Column<Guid>(type: "uuid", nullable: false, comment: "Id системы автобурения"),
Name = table.Column<string>(type: "varchar(256)", nullable: false, comment: "Наименование системы автобурения"),
Description = table.Column<string>(type: "text", nullable: true, comment: "Описание системы автобурения")
},
constraints: table =>
{
table.PrimaryKey("PK_ADSystem", x => x.SystemId);
});
migrationBuilder.CreateTable(
name: "TimestampedSets",
columns: table => new
{
IdDiscriminator = table.Column<Guid>(type: "uuid", nullable: false, comment: "Дискриминатор ссылка на тип сохраняемых данных"),
Timestamp = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, comment: "Отметка времени, строго в UTC"),
Set = table.Column<string>(type: "jsonb", nullable: false, comment: "Набор сохраняемых данных")
},
constraints: table =>
{
table.PrimaryKey("PK_TimestampedSets", x => new { x.IdDiscriminator, x.Timestamp });
},
comment: "Общая таблица данных временных рядов");
migrationBuilder.CreateTable(
name: "TechMessage",
columns: table => new
{
EventId = table.Column<Guid>(type: "uuid", nullable: false, comment: "Id события"),
ImportantId = table.Column<int>(type: "integer", nullable: false, comment: "Id Категории важности"),
OccurrenceDate = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: false, comment: "Дата возникновения"),
Depth = table.Column<double>(type: "double precision", nullable: true, comment: "Глубина забоя"),
MessageText = table.Column<string>(type: "varchar(512)", nullable: false, comment: "Текст сообщения"),
SystemId = table.Column<Guid>(type: "uuid", nullable: false, comment: "Id системы автобурения, к которой относится сообщение"),
UserId = table.Column<Guid>(type: "uuid", nullable: false, comment: "Id пользователя за пультом бурильщика")
},
constraints: table =>
{
table.PrimaryKey("PK_TechMessage", x => x.EventId);
table.ForeignKey(
name: "FK_TechMessage_ADSystem_SystemId",
column: x => x.SystemId,
principalTable: "ADSystem",
principalColumn: "SystemId",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_TechMessage_SystemId",
table: "TechMessage",
column: "SystemId");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "TechMessage");
migrationBuilder.DropTable(
name: "TimestampedSets");
migrationBuilder.DropTable(
name: "ADSystem");
}
}
}

View File

@ -24,6 +24,27 @@ namespace Persistence.Database.Postgres.Migrations
NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "adminpack");
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("Persistence.Database.Entity.ADSystem", b =>
{
b.Property<Guid>("SystemId")
.ValueGeneratedOnAdd()
.HasColumnType("uuid")
.HasComment("Id системы автобурения");
b.Property<string>("Description")
.HasColumnType("text")
.HasComment("Описание системы автобурения");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("varchar(256)")
.HasComment("Наименование системы автобурения");
b.HasKey("SystemId");
b.ToTable("ADSystem");
});
modelBuilder.Entity("Persistence.Database.Entity.TechMessage", b =>
{
b.Property<Guid>("EventId")
@ -31,10 +52,6 @@ namespace Persistence.Database.Postgres.Migrations
.HasColumnType("uuid")
.HasComment("Id события");
b.Property<string>("AutoDrillingSystem")
.HasColumnType("varchar(256)")
.HasComment("Система автобурения, к которой относится сообщение");
b.Property<double?>("Depth")
.HasColumnType("double precision")
.HasComment("Глубина забоя");
@ -44,6 +61,7 @@ namespace Persistence.Database.Postgres.Migrations
.HasComment("Id Категории важности");
b.Property<string>("MessageText")
.IsRequired()
.HasColumnType("varchar(512)")
.HasComment("Текст сообщения");
@ -51,15 +69,44 @@ namespace Persistence.Database.Postgres.Migrations
.HasColumnType("timestamp with time zone")
.HasComment("Дата возникновения");
b.Property<Guid>("SystemId")
.HasColumnType("uuid")
.HasComment("Id системы автобурения, к которой относится сообщение");
b.Property<Guid>("UserId")
.HasColumnType("uuid")
.HasComment("Id пользователя за пультом бурильщика");
b.HasKey("EventId");
b.HasIndex("SystemId");
b.ToTable("TechMessage");
});
modelBuilder.Entity("Persistence.Database.Entity.TimestampedSet", b =>
{
b.Property<Guid>("IdDiscriminator")
.HasColumnType("uuid")
.HasComment("Дискриминатор ссылка на тип сохраняемых данных");
b.Property<DateTimeOffset>("Timestamp")
.HasColumnType("timestamp with time zone")
.HasComment("Отметка времени, строго в UTC");
b.Property<string>("Set")
.IsRequired()
.HasColumnType("jsonb")
.HasComment("Набор сохраняемых данных");
b.HasKey("IdDiscriminator", "Timestamp");
b.ToTable("TimestampedSets", t =>
{
t.HasComment("Общая таблица данных временных рядов");
});
});
modelBuilder.Entity("Persistence.Database.Model.DataSaub", b =>
{
b.Property<DateTimeOffset>("Date")
@ -166,6 +213,17 @@ namespace Persistence.Database.Postgres.Migrations
b.ToTable("Setpoint");
});
modelBuilder.Entity("Persistence.Database.Entity.TechMessage", b =>
{
b.HasOne("Persistence.Database.Entity.ADSystem", "System")
.WithMany()
.HasForeignKey("SystemId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("System");
});
#pragma warning restore 612, 618
}
}

View File

@ -0,0 +1,16 @@
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using Microsoft.EntityFrameworkCore;
namespace Persistence.Database.Entity;
public class ADSystem
{
[Key, Comment("Id системы автобурения")]
public Guid SystemId { get; set; }
[Required, Column(TypeName = "varchar(256)"), Comment("Наименование системы автобурения")]
public required string Name { get; set; }
[Comment("Описание системы автобурения")]
public string? Description { get; set; }
}

View File

@ -19,10 +19,13 @@ namespace Persistence.Database.Entity
public double? Depth { get; set; }
[Column(TypeName = "varchar(512)"), Comment("Текст сообщения")]
public string? MessageText { get; set; }
public required string MessageText { get; set; }
[Column(TypeName = "varchar(256)"), Comment("Система автобурения, к которой относится сообщение")]
public string? AutoDrillingSystem { get; set; }
[Required, Comment("Id системы автобурения, к которой относится сообщение")]
public required Guid SystemId { get; set; }
[Required, ForeignKey(nameof(SystemId)), Comment("Система автобурения, к которой относится сообщение")]
public virtual required ADSystem System { get; set; }
[Comment("Id пользователя за пультом бурильщика")]
public Guid UserId { get; set; }

View File

@ -29,7 +29,7 @@ namespace Persistence.IntegrationTests.Controllers
{
Skip = 1,
Take = 2,
SortSettings = nameof(TechMessageDto.ImportantId)
SortSettings = nameof(TechMessageDto.CategoryId)
};
//act
@ -53,7 +53,7 @@ namespace Persistence.IntegrationTests.Controllers
{
Skip = 0,
Take = 2,
SortSettings = nameof(TechMessageDto.ImportantId)
SortSettings = nameof(TechMessageDto.CategoryId)
};
//act
@ -90,7 +90,7 @@ namespace Persistence.IntegrationTests.Controllers
//arrange
var dtos = await InsertRange();
var systems = dtos
.Select(e => e.AutoDrillingSystem)
.Select(e => e.System)
.Distinct()
.ToArray();
@ -110,7 +110,7 @@ namespace Persistence.IntegrationTests.Controllers
//arrange
dbContext.CleanupDbSet<TechMessage>();
var imortantId = 1;
var autoDrillingSystem = nameof(TechMessageDto.AutoDrillingSystem);
var autoDrillingSystem = nameof(TechMessageDto.System);
//act
var response = await techMessagesClient.GetStatistics(imortantId, autoDrillingSystem, new CancellationToken());
@ -125,9 +125,9 @@ namespace Persistence.IntegrationTests.Controllers
{
//arrange
var imortantId = 1;
var autoDrillingSystem = nameof(TechMessageDto.AutoDrillingSystem);
var autoDrillingSystem = nameof(TechMessageDto.System);
var dtos = await InsertRange();
var filteredDtos = dtos.Where(e => e.ImportantId == imortantId && e.AutoDrillingSystem == e.AutoDrillingSystem);
var filteredDtos = dtos.Where(e => e.CategoryId == imortantId && e.System == e.System);
//act
var response = await techMessagesClient.GetStatistics(imortantId, autoDrillingSystem, new CancellationToken());
@ -145,21 +145,21 @@ namespace Persistence.IntegrationTests.Controllers
new TechMessageDto()
{
EventId = Guid.NewGuid(),
ImportantId = 1,
OccurrenceDate = DateTimeOffset.UtcNow,
CategoryId = 1,
Timestamp = DateTimeOffset.UtcNow,
Depth = 1.11,
MessageText = nameof(TechMessageDto.MessageText),
AutoDrillingSystem = nameof(TechMessageDto.AutoDrillingSystem),
System = nameof(TechMessageDto.System),
UserId = Guid.NewGuid()
},
new TechMessageDto()
{
EventId = Guid.NewGuid(),
ImportantId = 2,
OccurrenceDate = DateTimeOffset.UtcNow,
CategoryId = 2,
Timestamp = DateTimeOffset.UtcNow,
Depth = 2.22,
MessageText = nameof(TechMessageDto.MessageText),
AutoDrillingSystem = nameof(TechMessageDto.AutoDrillingSystem),
System = nameof(TechMessageDto.System),
UserId = Guid.NewGuid()
}
};

View File

@ -1,5 +1,7 @@
using Mapster;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Memory;
using Newtonsoft.Json.Linq;
using Persistence.Database.Entity;
using Persistence.Models;
using Persistence.Repositories;
@ -9,9 +11,13 @@ namespace Persistence.Repository.Repositories
{
public class TechMessagesRepository : ITechMessagesRepository
{
private static readonly string SystemCacheKey = $"{typeof(ADSystem).FullName}CacheKey";
private readonly IMemoryCache memoryCache;
private DbContext db;
public TechMessagesRepository(DbContext db)
public TechMessagesRepository(DbContext db, IMemoryCache memoryCache)
{
this.memoryCache = memoryCache;
this.db = db;
}
@ -36,36 +42,75 @@ namespace Persistence.Repository.Repositories
return dto;
}
public async Task<int> GetStatistics(int importantId, string autoDrillingSystem, CancellationToken token)
public async Task<Dictionary<string, int>> GetStatistics(int? importantId, string? autoDrillingSystem, CancellationToken token)
{
var query = GetQueryReadOnly();
var count = await query
.Where(e => e.ImportantId == importantId && e.AutoDrillingSystem == autoDrillingSystem)
.CountAsync();
.Where(e => importantId == null || e.ImportantId == importantId)
.Where(e => autoDrillingSystem == null || e.System.Name == autoDrillingSystem)
.GroupBy(e => e.System.Name)
.ToDictionaryAsync(e => e.Key, v => v.Count());
return count;
}
public async Task<IEnumerable<string>> GetSystems(CancellationToken token)
public async Task<IEnumerable<ADSystemDto>> GetSystems(CancellationToken token)
{
var query = GetQueryReadOnly();
var entities = await query
.Select(e => e.AutoDrillingSystem ?? string.Empty)
.Distinct()
.ToArrayAsync(token);
var dtos = entities.Order();
var systems = await memoryCache.GetOrCreateAsync(SystemCacheKey, async f =>
{
f.AbsoluteExpirationRelativeToNow = TimeSpan.FromMinutes(60);
return dtos;
var query = db.Set<ADSystem>();
var entities = await query.ToListAsync();
var dtos = entities.Select(e => e.Adapt<ADSystemDto>());
return dtos;
});
return systems ?? [];
}
public async Task<int> InsertRange(IEnumerable<TechMessageDto> dtos, CancellationToken token)
{
var entities = dtos.Select(d => d.Adapt<TechMessage>());
var entities = dtos.Select(dto =>
{
var task = Task.Run(async () =>
{
var entity = dto.Adapt<TechMessage>();
var systems = await GetSystems(token);
var systemId = systems.FirstOrDefault(e => e.Name == dto.System)?.SystemId
?? await CreateSystem(dto.System);
entity.SystemId = systemId;
return entity;
});
task.Wait();
return task.Result;
});
await db.Set<TechMessage>().AddRangeAsync(entities, token);
var result = await db.SaveChangesAsync(token);
return result;
}
private async Task<Guid> CreateSystem(string name)
{
memoryCache.Remove(SystemCacheKey);
var systemId = Guid.NewGuid();
var entity = new ADSystem()
{
SystemId = systemId,
Name = name
};
await db.Set<ADSystem>().AddAsync(entity);
await db.SaveChangesAsync();
return Guid.NewGuid();
}
}
}

View File

@ -1,35 +0,0 @@
using Microsoft.AspNetCore.Mvc;
using Persistence.Models;
namespace Persistence.API
{
/// <summary>
/// Интерфейс для API сообщений о состояниях работы систем автобурения (АБ)
/// </summary>
public interface ITechMessages : ITableDataApi<TechMessageDto, RequestDto>
{
/// <summary>
/// Добавление новых сообщений
/// </summary>
/// <param name="dtos"></param>
/// <param name="token"></param>
/// <returns></returns>
Task<ActionResult<int>> InsertRange(IEnumerable<TechMessageDto> dtos, CancellationToken token);
/// <summary>
/// Получение списка систем АБ
/// </summary>
/// <param name="token"></param>
/// <returns></returns>
Task<ActionResult<IEnumerable<string>>> GetSystems(CancellationToken token);
/// <summary>
/// Получение статистики
/// </summary>
/// <param name="importantId">Id Категории важности</param>
/// <param name="autoDrillingSystem">Система АБ</param>
/// <param name="token"></param>
/// <returns></returns>
Task<ActionResult<int>> GetStatistics(int importantId, string autoDrillingSystem, CancellationToken token);
}
}

View File

@ -0,0 +1,22 @@
namespace Persistence.Models;
/// <summary>
/// Модель системы автобурения
/// </summary>
public class ADSystemDto
{
/// <summary>
/// Ключ
/// </summary>
public Guid SystemId { get; set; }
/// <summary>
/// Наименование
/// </summary>
public required string Name { get; set; }
/// <summary>
/// Описание
/// </summary>
public string? Description { get; set; }
}

View File

@ -1,4 +1,6 @@
namespace Persistence.Models
using System.ComponentModel.DataAnnotations;
namespace Persistence.Models
{
/// <summary>
/// Модель технологического сообщения
@ -8,32 +10,39 @@
/// <summary>
/// Id события
/// </summary>
[Required]
public Guid EventId { get; set; }
/// <summary>
/// Id Категории важности
/// </summary>
public int ImportantId { get; set; }
[Range(0, int.MaxValue, ErrorMessage = "Id Категории важности не может быть меньше 0")]
public int CategoryId { get; set; }
/// <summary>
/// Дата возникновения
/// </summary>
public DateTimeOffset OccurrenceDate { get; set; }
public DateTimeOffset Timestamp { get; set; }
/// <summary>
/// Глубина забоя
/// </summary>
[Range(0, double.MaxValue, ErrorMessage = "Глубина забоя не может быть меньше 0")]
public double? Depth { get; set; }
/// <summary>
/// Текст сообщения
/// </summary>
public string? MessageText { get; set; }
[Required]
[StringLength(512, MinimumLength = 1, ErrorMessage = "Допустимая длина текста сообщения от 1 до 512 символов")]
public required string MessageText { get; set; }
/// <summary>
/// Система автобурения, к которой относится сообщение
/// </summary>
public string? AutoDrillingSystem { get; set; }
[Required]
[StringLength(256, MinimumLength = 1, ErrorMessage = "Допустимая длина наименования системы АБ от 1 до 256 символов")]
public required string System { get; set; }
/// <summary>
/// Id пользователя за пультом бурильщика

View File

@ -1,4 +1,5 @@
using Persistence.Models;
using System.Threading.Tasks;
using Persistence.Models;
namespace Persistence.Repositories
{
@ -28,7 +29,7 @@ namespace Persistence.Repositories
/// </summary>
/// <param name="token"></param>
/// <returns></returns>
Task<IEnumerable<string>> GetSystems(CancellationToken token);
Task<IEnumerable<ADSystemDto>> GetSystems(CancellationToken token);
/// <summary>
/// Получение количества сообщений по категориям и системам автобурения
@ -37,6 +38,6 @@ namespace Persistence.Repositories
/// <param name="autoDrillingSystem">Система автобурения</param>
/// <param name="token"></param>
/// <returns></returns>
Task<int> GetStatistics(int importantId, string autoDrillingSystem, CancellationToken token);
Task<Dictionary<string, int>> GetStatistics(int? importantId, string? autoDrillingSystem, CancellationToken token);
}
}