Правки по результатам ревью - 3

This commit is contained in:
Оля Бизюкова 2025-02-18 17:21:30 +05:00
parent baba1a05c0
commit 14893e9bf6
10 changed files with 87 additions and 144 deletions

View File

@ -46,15 +46,6 @@ public class ChangeLogClient : BaseClient, IChangeLogClient
return result!; return result!;
} }
/// <inheritdoc/>
public async Task<int> Add(Guid idDiscriminator, ChangeLogValuesDto dto, string comment, CancellationToken token)
{
var result = await ExecutePostResponse(
async () => await refitChangeLogClient.Add(idDiscriminator, dto, comment, token), token);
return result;
}
/// <inheritdoc/> /// <inheritdoc/>
public async Task<int> AddRange(Guid idDiscriminator, IEnumerable<ChangeLogValuesDto> dtos, string comment, CancellationToken token) public async Task<int> AddRange(Guid idDiscriminator, IEnumerable<ChangeLogValuesDto> dtos, string comment, CancellationToken token)
{ {
@ -64,15 +55,6 @@ public class ChangeLogClient : BaseClient, IChangeLogClient
return result; return result;
} }
/// <inheritdoc/>
public async Task<int> Update(ChangeLogValuesDto dto, string comment, CancellationToken token)
{
var result = await ExecutePostResponse(
async () => await refitChangeLogClient.Update(dto, comment, token), token);
return result;
}
/// <inheritdoc/> /// <inheritdoc/>
public async Task<int> UpdateRange(IEnumerable<ChangeLogValuesDto> dtos, string comment, CancellationToken token) public async Task<int> UpdateRange(IEnumerable<ChangeLogValuesDto> dtos, string comment, CancellationToken token)
{ {
@ -82,15 +64,6 @@ public class ChangeLogClient : BaseClient, IChangeLogClient
return result; return result;
} }
/// <inheritdoc/>
public async Task<int> Delete(Guid id, string comment, CancellationToken token)
{
var result = await ExecutePostResponse(
async () => await refitChangeLogClient.Delete(id, comment, token), token);
return result;
}
/// <inheritdoc/> /// <inheritdoc/>
public async Task<int> DeleteRange(IEnumerable<Guid> ids, string comment, CancellationToken token) public async Task<int> DeleteRange(IEnumerable<Guid> ids, string comment, CancellationToken token)
{ {

View File

@ -9,16 +9,6 @@ namespace DD.Persistence.Client.Clients.Interfaces;
/// </summary> /// </summary>
public interface IChangeLogClient : IDisposable public interface IChangeLogClient : IDisposable
{ {
/// <summary>
/// Добавить одну запись
/// </summary>
/// <param name="idDiscriminator"></param>
/// <param name="dto"></param>
/// <param name="comment"></param>
/// <param name="token"></param>
/// <returns></returns>
Task<int> Add(Guid idDiscriminator, ChangeLogValuesDto dto, string comment, CancellationToken token);
/// <summary> /// <summary>
/// Добавить несколько записей /// Добавить несколько записей
/// </summary> /// </summary>
@ -39,15 +29,6 @@ public interface IChangeLogClient : IDisposable
/// <returns></returns> /// <returns></returns>
Task<int> ClearAndAddRange(Guid idDiscriminator, IEnumerable<ChangeLogValuesDto> dtos, string comment, CancellationToken token); Task<int> ClearAndAddRange(Guid idDiscriminator, IEnumerable<ChangeLogValuesDto> dtos, string comment, CancellationToken token);
/// <summary>
/// Удалить одну запись
/// </summary>
/// <param name="id"></param>
/// <param name="comment"></param>
/// <param name="token"></param>
/// <returns></returns>
Task<int> Delete(Guid id, string comment, CancellationToken token);
/// <summary> /// <summary>
/// Удалить несколько записей /// Удалить несколько записей
/// </summary> /// </summary>
@ -85,15 +66,6 @@ public interface IChangeLogClient : IDisposable
/// <returns></returns> /// <returns></returns>
Task<DatesRangeDto?> GetDatesRange(Guid idDiscriminator, CancellationToken token); Task<DatesRangeDto?> GetDatesRange(Guid idDiscriminator, CancellationToken token);
/// <summary>
/// Обновить одну запись
/// </summary>
/// <param name="dto"></param>
/// <param name="comment"></param>
/// <param name="token"></param>
/// <returns></returns>
Task<int> Update(ChangeLogValuesDto dto, string comment, CancellationToken token);
/// <summary> /// <summary>
/// Обновить несколько записей /// Обновить несколько записей
/// </summary> /// </summary>

View File

@ -34,40 +34,22 @@ public interface IRefitChangeLogClient : IRefitClient, IDisposable
[Get($"{BaseRoute}/history/{{idDiscriminator}}")] [Get($"{BaseRoute}/history/{{idDiscriminator}}")]
Task<IApiResponse<IEnumerable<ChangeLogDto>>> GetChangeLogForInterval(Guid idDiscriminator, DateTimeOffset dateBegin, DateTimeOffset dateEnd, CancellationToken token); Task<IApiResponse<IEnumerable<ChangeLogDto>>> GetChangeLogForInterval(Guid idDiscriminator, DateTimeOffset dateBegin, DateTimeOffset dateEnd, CancellationToken token);
/// <summary>
/// Добавить одну запись
/// </summary>
[Post($"{BaseRoute}/{{idDiscriminator}}")]
Task<IApiResponse<int>> Add(Guid idDiscriminator, ChangeLogValuesDto dto, string comment, CancellationToken token);
/// <summary> /// <summary>
/// Добавить несколько записей /// Добавить несколько записей
/// </summary> /// </summary>
[Post($"{BaseRoute}/range/{{idDiscriminator}}")] [Post($"{BaseRoute}/{{idDiscriminator}}")]
Task<IApiResponse<int>> AddRange(Guid idDiscriminator, IEnumerable<ChangeLogValuesDto> dtos, string comment, CancellationToken token); Task<IApiResponse<int>> AddRange(Guid idDiscriminator, IEnumerable<ChangeLogValuesDto> dtos, string comment, CancellationToken token);
/// <summary>
/// Обновить одну запись
/// </summary>
[Put($"{BaseRoute}")]
Task<IApiResponse<int>> Update(ChangeLogValuesDto dto, string comment, CancellationToken token);
/// <summary> /// <summary>
/// Обновить несколько записей /// Обновить несколько записей
/// </summary> /// </summary>
[Put($"{BaseRoute}/range")] [Put($"{BaseRoute}")]
Task<IApiResponse<int>> UpdateRange(IEnumerable<ChangeLogValuesDto> dtos, string comment, CancellationToken token); Task<IApiResponse<int>> UpdateRange(IEnumerable<ChangeLogValuesDto> dtos, string comment, CancellationToken token);
/// <summary>
/// Удалить одну запись
/// </summary>
[Delete($"{BaseRoute}")]
Task<IApiResponse<int>> Delete(Guid id, string comment, CancellationToken token);
/// <summary> /// <summary>
/// Удалить несколько записей /// Удалить несколько записей
/// </summary> /// </summary>
[Delete($"{BaseRoute}/range")] [Delete($"{BaseRoute}")]
Task<IApiResponse<int>> DeleteRange([Body] IEnumerable<Guid> ids, string comment, CancellationToken token); Task<IApiResponse<int>> DeleteRange([Body] IEnumerable<Guid> ids, string comment, CancellationToken token);
/// <summary> /// <summary>

View File

@ -13,7 +13,7 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
namespace DD.Persistence.Database.Postgres.Migrations namespace DD.Persistence.Database.Postgres.Migrations
{ {
[DbContext(typeof(PersistencePostgresContext))] [DbContext(typeof(PersistencePostgresContext))]
[Migration("20250218060716_Init")] [Migration("20250218121851_Init")]
partial class Init partial class Init
{ {
/// <inheritdoc /> /// <inheritdoc />
@ -45,14 +45,18 @@ namespace DD.Persistence.Database.Postgres.Migrations
.HasColumnType("uuid") .HasColumnType("uuid")
.HasComment("Автор изменения"); .HasComment("Автор изменения");
b.Property<Guid>("IdCommit") b.Property<Guid>("IdCreatedCommit")
.HasColumnType("uuid") .HasColumnType("uuid")
.HasComment("Id коммита"); .HasComment("Id коммита на создание записи");
b.Property<Guid?>("IdNext") b.Property<Guid?>("IdNext")
.HasColumnType("uuid") .HasColumnType("uuid")
.HasComment("Id заменяющей записи"); .HasComment("Id заменяющей записи");
b.Property<Guid?>("IdObsoletedCommit")
.HasColumnType("uuid")
.HasComment("Id коммита на устаревание записи");
b.Property<DateTimeOffset?>("Obsolete") b.Property<DateTimeOffset?>("Obsolete")
.HasColumnType("timestamp with time zone") .HasColumnType("timestamp with time zone")
.HasComment("Дата устаревания (например при удалении)"); .HasComment("Дата устаревания (например при удалении)");
@ -64,7 +68,9 @@ namespace DD.Persistence.Database.Postgres.Migrations
b.HasKey("Id"); b.HasKey("Id");
b.HasIndex("IdCommit"); b.HasIndex("IdCreatedCommit");
b.HasIndex("IdObsoletedCommit");
b.ToTable("change_log"); b.ToTable("change_log");
}); });
@ -243,13 +249,19 @@ namespace DD.Persistence.Database.Postgres.Migrations
modelBuilder.Entity("DD.Persistence.Database.Entity.ChangeLog", b => modelBuilder.Entity("DD.Persistence.Database.Entity.ChangeLog", b =>
{ {
b.HasOne("DD.Persistence.Database.Entity.ChangeLogCommit", "Commit") b.HasOne("DD.Persistence.Database.Entity.ChangeLogCommit", "CreatedCommit")
.WithMany("ChangeLogItems") .WithMany("ChangeLogCreatedItems")
.HasForeignKey("IdCommit") .HasForeignKey("IdCreatedCommit")
.OnDelete(DeleteBehavior.Cascade) .OnDelete(DeleteBehavior.Cascade)
.IsRequired(); .IsRequired();
b.Navigation("Commit"); b.HasOne("DD.Persistence.Database.Entity.ChangeLogCommit", "ObsoletedCommit")
.WithMany("ChangeLogObsoletedItems")
.HasForeignKey("IdObsoletedCommit");
b.Navigation("CreatedCommit");
b.Navigation("ObsoletedCommit");
}); });
modelBuilder.Entity("DD.Persistence.Database.Entity.TechMessage", b => modelBuilder.Entity("DD.Persistence.Database.Entity.TechMessage", b =>
@ -265,7 +277,9 @@ namespace DD.Persistence.Database.Postgres.Migrations
modelBuilder.Entity("DD.Persistence.Database.Entity.ChangeLogCommit", b => modelBuilder.Entity("DD.Persistence.Database.Entity.ChangeLogCommit", b =>
{ {
b.Navigation("ChangeLogItems"); b.Navigation("ChangeLogCreatedItems");
b.Navigation("ChangeLogObsoletedItems");
}); });
#pragma warning restore 612, 618 #pragma warning restore 612, 618
} }

View File

@ -105,17 +105,23 @@ namespace DD.Persistence.Database.Postgres.Migrations
Obsolete = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true, comment: "Дата устаревания (например при удалении)"), Obsolete = table.Column<DateTimeOffset>(type: "timestamp with time zone", nullable: true, comment: "Дата устаревания (например при удалении)"),
IdNext = table.Column<Guid>(type: "uuid", nullable: true, comment: "Id заменяющей записи"), IdNext = table.Column<Guid>(type: "uuid", nullable: true, comment: "Id заменяющей записи"),
Value = table.Column<string>(type: "jsonb", nullable: false, comment: "Значение"), Value = table.Column<string>(type: "jsonb", nullable: false, comment: "Значение"),
IdCommit = table.Column<Guid>(type: "uuid", nullable: false, comment: "Id коммита") IdCreatedCommit = table.Column<Guid>(type: "uuid", nullable: false, comment: "Id коммита на создание записи"),
IdObsoletedCommit = table.Column<Guid>(type: "uuid", nullable: true, comment: "Id коммита на устаревание записи")
}, },
constraints: table => constraints: table =>
{ {
table.PrimaryKey("PK_change_log", x => x.Id); table.PrimaryKey("PK_change_log", x => x.Id);
table.ForeignKey( table.ForeignKey(
name: "FK_change_log_change_log_commit_IdCommit", name: "FK_change_log_change_log_commit_IdCreatedCommit",
column: x => x.IdCommit, column: x => x.IdCreatedCommit,
principalTable: "change_log_commit", principalTable: "change_log_commit",
principalColumn: "Id", principalColumn: "Id",
onDelete: ReferentialAction.Cascade); onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_change_log_change_log_commit_IdObsoletedCommit",
column: x => x.IdObsoletedCommit,
principalTable: "change_log_commit",
principalColumn: "Id");
}); });
migrationBuilder.CreateTable( migrationBuilder.CreateTable(
@ -141,9 +147,14 @@ namespace DD.Persistence.Database.Postgres.Migrations
}); });
migrationBuilder.CreateIndex( migrationBuilder.CreateIndex(
name: "IX_change_log_IdCommit", name: "IX_change_log_IdCreatedCommit",
table: "change_log", table: "change_log",
column: "IdCommit"); column: "IdCreatedCommit");
migrationBuilder.CreateIndex(
name: "IX_change_log_IdObsoletedCommit",
table: "change_log",
column: "IdObsoletedCommit");
migrationBuilder.CreateIndex( migrationBuilder.CreateIndex(
name: "IX_tech_message_SystemId", name: "IX_tech_message_SystemId",

View File

@ -42,14 +42,18 @@ namespace DD.Persistence.Database.Postgres.Migrations
.HasColumnType("uuid") .HasColumnType("uuid")
.HasComment("Автор изменения"); .HasComment("Автор изменения");
b.Property<Guid>("IdCommit") b.Property<Guid>("IdCreatedCommit")
.HasColumnType("uuid") .HasColumnType("uuid")
.HasComment("Id коммита"); .HasComment("Id коммита на создание записи");
b.Property<Guid?>("IdNext") b.Property<Guid?>("IdNext")
.HasColumnType("uuid") .HasColumnType("uuid")
.HasComment("Id заменяющей записи"); .HasComment("Id заменяющей записи");
b.Property<Guid?>("IdObsoletedCommit")
.HasColumnType("uuid")
.HasComment("Id коммита на устаревание записи");
b.Property<DateTimeOffset?>("Obsolete") b.Property<DateTimeOffset?>("Obsolete")
.HasColumnType("timestamp with time zone") .HasColumnType("timestamp with time zone")
.HasComment("Дата устаревания (например при удалении)"); .HasComment("Дата устаревания (например при удалении)");
@ -61,7 +65,9 @@ namespace DD.Persistence.Database.Postgres.Migrations
b.HasKey("Id"); b.HasKey("Id");
b.HasIndex("IdCommit"); b.HasIndex("IdCreatedCommit");
b.HasIndex("IdObsoletedCommit");
b.ToTable("change_log"); b.ToTable("change_log");
}); });
@ -240,13 +246,19 @@ namespace DD.Persistence.Database.Postgres.Migrations
modelBuilder.Entity("DD.Persistence.Database.Entity.ChangeLog", b => modelBuilder.Entity("DD.Persistence.Database.Entity.ChangeLog", b =>
{ {
b.HasOne("DD.Persistence.Database.Entity.ChangeLogCommit", "Commit") b.HasOne("DD.Persistence.Database.Entity.ChangeLogCommit", "CreatedCommit")
.WithMany("ChangeLogItems") .WithMany("ChangeLogCreatedItems")
.HasForeignKey("IdCommit") .HasForeignKey("IdCreatedCommit")
.OnDelete(DeleteBehavior.Cascade) .OnDelete(DeleteBehavior.Cascade)
.IsRequired(); .IsRequired();
b.Navigation("Commit"); b.HasOne("DD.Persistence.Database.Entity.ChangeLogCommit", "ObsoletedCommit")
.WithMany("ChangeLogObsoletedItems")
.HasForeignKey("IdObsoletedCommit");
b.Navigation("CreatedCommit");
b.Navigation("ObsoletedCommit");
}); });
modelBuilder.Entity("DD.Persistence.Database.Entity.TechMessage", b => modelBuilder.Entity("DD.Persistence.Database.Entity.TechMessage", b =>
@ -262,7 +274,9 @@ namespace DD.Persistence.Database.Postgres.Migrations
modelBuilder.Entity("DD.Persistence.Database.Entity.ChangeLogCommit", b => modelBuilder.Entity("DD.Persistence.Database.Entity.ChangeLogCommit", b =>
{ {
b.Navigation("ChangeLogItems"); b.Navigation("ChangeLogCreatedItems");
b.Navigation("ChangeLogObsoletedItems");
}); });
#pragma warning restore 612, 618 #pragma warning restore 612, 618
} }

View File

@ -34,9 +34,15 @@ public class ChangeLog : IDiscriminatorItem, IChangeLog
[Column(TypeName = "jsonb"), Comment("Значение")] [Column(TypeName = "jsonb"), Comment("Значение")]
public required IDictionary<string, object> Value { get; set; } public required IDictionary<string, object> Value { get; set; }
[Required, Comment("Id коммита")] [Required, Comment("Id коммита на создание записи")]
public Guid IdCommit { get; set; } public Guid IdCreatedCommit { get; set; }
[Required, ForeignKey(nameof(IdCommit)), Comment("Коммит пользователя")] [Comment("Id коммита на устаревание записи")]
public virtual ChangeLogCommit Commit { get; set; } = null!; public Guid? IdObsoletedCommit { get; set; }
[Required, ForeignKey(nameof(IdCreatedCommit)), Comment("Коммит пользователя на создание записи")]
public virtual ChangeLogCommit CreatedCommit { get; set; } = null!;
[ForeignKey(nameof(IdObsoletedCommit)), Comment("Коммит пользователя на устаревание записи")]
public virtual ChangeLogCommit? ObsoletedCommit { get; set; }
} }

View File

@ -27,6 +27,9 @@ public class ChangeLogCommit
[Comment("Комментарий к коммиту")] [Comment("Комментарий к коммиту")]
public required string Comment { get; set; } public required string Comment { get; set; }
[Required, InverseProperty(nameof(ChangeLog.Commit)), Comment("Журнал изменений")] [Required, InverseProperty(nameof(ChangeLog.CreatedCommit)), Comment("Записи, добавленные в журнал изменений")]
public virtual ICollection<ChangeLog> ChangeLogItems { get; set; } = null!; public virtual ICollection<ChangeLog> ChangeLogCreatedItems { get; set; } = null!;
[InverseProperty(nameof(ChangeLog.ObsoletedCommit)), Comment("Устаревшие записи в журнале изменений")]
public virtual ICollection<ChangeLog>? ChangeLogObsoletedItems { get; set; } = null!;
} }

View File

@ -31,7 +31,7 @@ public class ChangeLogRepository : IChangeLogRepository
IdAuthor = commitDto.IdAuthor, IdAuthor = commitDto.IdAuthor,
DiscriminatorId = idDiscriminator, DiscriminatorId = idDiscriminator,
Value = values.Value, Value = values.Value,
IdCommit = commitDto.Id, IdCreatedCommit = commitDto.Id,
}; };
entities.Add(entity); entities.Add(entity);
@ -59,7 +59,7 @@ public class ChangeLogRepository : IChangeLogRepository
foreach (var entity in entities) foreach (var entity in entities)
{ {
entity.Obsolete = updateTime; entity.Obsolete = updateTime;
entity.IdCommit = idCommit; entity.IdObsoletedCommit = idCommit;
} }
return await db.SaveChangesAsync(token); return await db.SaveChangesAsync(token);
@ -126,12 +126,13 @@ public class ChangeLogRepository : IChangeLogRepository
IdAuthor = commitDto.IdAuthor, IdAuthor = commitDto.IdAuthor,
DiscriminatorId = updatedEntity.DiscriminatorId, DiscriminatorId = updatedEntity.DiscriminatorId,
Value = dto.Value, Value = dto.Value,
IdCommit = commitDto.Id, IdCreatedCommit = commitDto.Id,
}; };
dbSet.Add(newEntity); dbSet.Add(newEntity);
updatedEntity.IdNext = newEntity.Id; updatedEntity.IdNext = newEntity.Id;
updatedEntity.Obsolete = commitDto.Creation; updatedEntity.Obsolete = commitDto.Creation;
updatedEntity.IdObsoletedCommit = commitDto.Id;
} }
var result = await db.SaveChangesAsync(token); var result = await db.SaveChangesAsync(token);

View File

@ -51,23 +51,6 @@ public class ChangeLogControllerTest : BaseIntegrationTest
Assert.Equal(insertedCount * 2, result); Assert.Equal(insertedCount * 2, result);
} }
[Fact]
public async Task Add_returns_success()
{
// arrange
var count = 1;
var idDiscriminator = Guid.NewGuid();
var dtos = Generate(count);
var dto = dtos.FirstOrDefault()!;
var comment = "Создаю 1 элемент";
// act
var result = await client.Add(idDiscriminator, dto, comment, CancellationToken.None);
// assert
Assert.Equal(count, result);
}
[Fact] [Fact]
public async Task AddRange_returns_success() public async Task AddRange_returns_success()
{ {
@ -87,14 +70,14 @@ public class ChangeLogControllerTest : BaseIntegrationTest
[Fact] [Fact]
public async Task Update_returns_success() public async Task Update_returns_success()
{ {
// arrange //arrange
dbContext.CleanupDbSet<ChangeLog>(); dbContext.CleanupDbSet<ChangeLog>();
var idDiscriminator = Guid.NewGuid(); var idDiscriminator = Guid.NewGuid();
var dtos = Generate(1); var dtos = Generate(1);
var dto = dtos.FirstOrDefault()!; var dto = dtos.FirstOrDefault()!;
var comment = "Создаю 1 элемент"; var comment = "Создаю 1 элемент";
var result = await client.Add(idDiscriminator, dto, comment, CancellationToken.None); var result = await client.AddRange(idDiscriminator, [dto], comment, CancellationToken.None);
var entity = dbContext.ChangeLog var entity = dbContext.ChangeLog
.Where(x => x.DiscriminatorId == idDiscriminator) .Where(x => x.DiscriminatorId == idDiscriminator)
@ -103,7 +86,7 @@ public class ChangeLogControllerTest : BaseIntegrationTest
// act // act
comment = "Обновляю 1 элемент"; comment = "Обновляю 1 элемент";
result = await client.Update(dto, comment, CancellationToken.None); result = await client.UpdateRange([dto], comment, CancellationToken.None);
// assert // assert
Assert.Equal(2, result); Assert.Equal(2, result);
@ -151,22 +134,6 @@ public class ChangeLogControllerTest : BaseIntegrationTest
Assert.Equal(count * 2, result); Assert.Equal(count * 2, result);
} }
[Fact]
public async Task Delete_returns_success()
{
// arrange
var insertedCount = 1;
var newEntitiesData = await CreateAndReturnNewDtos(insertedCount, (-15, -1));
var idDiscriminator = newEntitiesData.Item1;
var dto = newEntitiesData.Item2.FirstOrDefault();
// act
var result = await client.Delete(dto!.Id, "Удаление одной записи", CancellationToken.None);
// assert
Assert.Equal(1, result);
}
[Fact] [Fact]
public async Task DeleteRange_returns_success() public async Task DeleteRange_returns_success()
{ {
@ -335,7 +302,7 @@ public class ChangeLogControllerTest : BaseIntegrationTest
var entity = d.Adapt<ChangeLog>(); var entity = d.Adapt<ChangeLog>();
entity.DiscriminatorId = idDiscriminator; entity.DiscriminatorId = idDiscriminator;
entity.Creation = DateTimeOffset.UtcNow.AddDays(generatorRandomDigits.Next(minDayCount, maxDayCount)); entity.Creation = DateTimeOffset.UtcNow.AddDays(generatorRandomDigits.Next(minDayCount, maxDayCount));
entity.IdCommit = commit.Id; entity.IdCreatedCommit = commit.Id;
return entity; return entity;
}).ToArray(); }).ToArray();