From 7aae87d012661026650c3deb8a91a03b69d07d1f Mon Sep 17 00:00:00 2001 From: "gorbenko.pavel" Date: Wed, 22 Jul 2026 15:05:44 +0500 Subject: [PATCH] =?UTF-8?q?=D1=81=D0=BE=D0=B7=D0=B4=D0=B0=D0=BD=D1=8B=20?= =?UTF-8?q?=D0=BC=D0=BE=D0=B4=D0=B5=D0=BB=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../.idea.Tnsu.ApprovalRoute/.idea/.gitignore | 15 +++++++++ .../.idea.Tnsu.ApprovalRoute/.idea/.name | 1 + .../.idea/encodings.xml | 4 +++ .../.idea/indexLayout.xml | 8 +++++ .../.idea.Tnsu.ApprovalRoute/.idea/vcs.xml | 6 ++++ backend/src/Tnsu.ApprovalRoute.Api/Program.cs | 3 ++ .../Entities/RequestType.cs | 13 ++++++++ .../Entities/Route.cs | 20 +++++++++++ .../Entities/RouteStep.cs | 19 +++++++++++ .../Enums/RouteStepStatus.cs | 12 +++++++ .../Enums/RouteType.cs | 7 ++++ .../Persistence/ApprovalRouteDbContext.cs | 33 +++++++++++++++++++ 12 files changed, 141 insertions(+) create mode 100644 backend/.idea/.idea.Tnsu.ApprovalRoute/.idea/.gitignore create mode 100644 backend/.idea/.idea.Tnsu.ApprovalRoute/.idea/.name create mode 100644 backend/.idea/.idea.Tnsu.ApprovalRoute/.idea/encodings.xml create mode 100644 backend/.idea/.idea.Tnsu.ApprovalRoute/.idea/indexLayout.xml create mode 100644 backend/.idea/.idea.Tnsu.ApprovalRoute/.idea/vcs.xml create mode 100644 backend/src/Tnsu.ApprovalRoute.Domain/Entities/RequestType.cs create mode 100644 backend/src/Tnsu.ApprovalRoute.Domain/Entities/Route.cs create mode 100644 backend/src/Tnsu.ApprovalRoute.Domain/Entities/RouteStep.cs create mode 100644 backend/src/Tnsu.ApprovalRoute.Domain/Enums/RouteStepStatus.cs create mode 100644 backend/src/Tnsu.ApprovalRoute.Domain/Enums/RouteType.cs diff --git a/backend/.idea/.idea.Tnsu.ApprovalRoute/.idea/.gitignore b/backend/.idea/.idea.Tnsu.ApprovalRoute/.idea/.gitignore new file mode 100644 index 0000000..e865c8b --- /dev/null +++ b/backend/.idea/.idea.Tnsu.ApprovalRoute/.idea/.gitignore @@ -0,0 +1,15 @@ +# Default ignored files +/shelf/ +/workspace.xml +# Rider ignored files +/.idea.Tnsu.ApprovalRoute.iml +/modules.xml +/projectSettingsUpdater.xml +/contentModel.xml +# Editor-based HTTP Client requests +/httpRequests/ +# Ignored default folder with query files +/queries/ +# Datasource local storage ignored files +/dataSources/ +/dataSources.local.xml diff --git a/backend/.idea/.idea.Tnsu.ApprovalRoute/.idea/.name b/backend/.idea/.idea.Tnsu.ApprovalRoute/.idea/.name new file mode 100644 index 0000000..b44cf1f --- /dev/null +++ b/backend/.idea/.idea.Tnsu.ApprovalRoute/.idea/.name @@ -0,0 +1 @@ +Tnsu.ApprovalRoute \ No newline at end of file diff --git a/backend/.idea/.idea.Tnsu.ApprovalRoute/.idea/encodings.xml b/backend/.idea/.idea.Tnsu.ApprovalRoute/.idea/encodings.xml new file mode 100644 index 0000000..df87cf9 --- /dev/null +++ b/backend/.idea/.idea.Tnsu.ApprovalRoute/.idea/encodings.xml @@ -0,0 +1,4 @@ + + + + \ No newline at end of file diff --git a/backend/.idea/.idea.Tnsu.ApprovalRoute/.idea/indexLayout.xml b/backend/.idea/.idea.Tnsu.ApprovalRoute/.idea/indexLayout.xml new file mode 100644 index 0000000..7b08163 --- /dev/null +++ b/backend/.idea/.idea.Tnsu.ApprovalRoute/.idea/indexLayout.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/backend/.idea/.idea.Tnsu.ApprovalRoute/.idea/vcs.xml b/backend/.idea/.idea.Tnsu.ApprovalRoute/.idea/vcs.xml new file mode 100644 index 0000000..6c0b863 --- /dev/null +++ b/backend/.idea/.idea.Tnsu.ApprovalRoute/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/backend/src/Tnsu.ApprovalRoute.Api/Program.cs b/backend/src/Tnsu.ApprovalRoute.Api/Program.cs index 6a18908..a1dac74 100644 --- a/backend/src/Tnsu.ApprovalRoute.Api/Program.cs +++ b/backend/src/Tnsu.ApprovalRoute.Api/Program.cs @@ -1,3 +1,6 @@ +using Microsoft.AspNetCore.Builder; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Hosting; using Tnsu.ApprovalRoute.Application; using Tnsu.ApprovalRoute.Infrastructure; diff --git a/backend/src/Tnsu.ApprovalRoute.Domain/Entities/RequestType.cs b/backend/src/Tnsu.ApprovalRoute.Domain/Entities/RequestType.cs new file mode 100644 index 0000000..2cd90e7 --- /dev/null +++ b/backend/src/Tnsu.ApprovalRoute.Domain/Entities/RequestType.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; + +namespace Tnsu.ApprovalRoute.Domain.Entities; + +public class RequestType +{ + public Guid Id { get; set; } = Guid.NewGuid(); + public string Name { get; set; } = string.Empty; + public string PageUrl { get; set; } = string.Empty; + + public ICollection Routes { get; set; } = new List(); +} diff --git a/backend/src/Tnsu.ApprovalRoute.Domain/Entities/Route.cs b/backend/src/Tnsu.ApprovalRoute.Domain/Entities/Route.cs new file mode 100644 index 0000000..8e531aa --- /dev/null +++ b/backend/src/Tnsu.ApprovalRoute.Domain/Entities/Route.cs @@ -0,0 +1,20 @@ +using Tnsu.ApprovalRoute.Domain.Enums; + +namespace Tnsu.ApprovalRoute.Domain.Entities; + +public class Route +{ + public Guid Id { get; set; } = Guid.NewGuid(); + public RouteType RouteType { get; set; } = RouteType.Sequential; + public Guid RequestTypeId { get; set; } + + // Внешние справочники (1С/ZUP) — хранятся как ссылки без FK в этой БД. + public Guid DepartmentId { get; set; } + public Guid CompanyId { get; set; } + public Guid ProjectId { get; set; } + + public bool RequiresControl { get; set; } + + public RequestType? RequestType { get; set; } + public ICollection Steps { get; set; } = new List(); +} diff --git a/backend/src/Tnsu.ApprovalRoute.Domain/Entities/RouteStep.cs b/backend/src/Tnsu.ApprovalRoute.Domain/Entities/RouteStep.cs new file mode 100644 index 0000000..bf01d87 --- /dev/null +++ b/backend/src/Tnsu.ApprovalRoute.Domain/Entities/RouteStep.cs @@ -0,0 +1,19 @@ +using Tnsu.ApprovalRoute.Domain.Enums; + +namespace Tnsu.ApprovalRoute.Domain.Entities; + +public class RouteStep +{ + public Guid Id { get; set; } = Guid.NewGuid(); + public int OrderNo { get; set; } + + // Внешняя ссылка на пользователя (1С/ZUP) — без локальной таблицы Users. + public Guid ExecutorUserId { get; set; } + public string Position { get; set; } = string.Empty; + + public RouteStepStatus Status { get; set; } = RouteStepStatus.Draft; + public Guid RouteId { get; set; } + public bool AllowReassignToOtherApprovers { get; set; } + + public Route? Route { get; set; } +} diff --git a/backend/src/Tnsu.ApprovalRoute.Domain/Enums/RouteStepStatus.cs b/backend/src/Tnsu.ApprovalRoute.Domain/Enums/RouteStepStatus.cs new file mode 100644 index 0000000..147d9d6 --- /dev/null +++ b/backend/src/Tnsu.ApprovalRoute.Domain/Enums/RouteStepStatus.cs @@ -0,0 +1,12 @@ +namespace Tnsu.ApprovalRoute.Domain.Enums; + +public enum RouteStepStatus +{ + Draft, + OnApproval, + Approved, + InExecution, + Completed, + Returned, + Closed +} diff --git a/backend/src/Tnsu.ApprovalRoute.Domain/Enums/RouteType.cs b/backend/src/Tnsu.ApprovalRoute.Domain/Enums/RouteType.cs new file mode 100644 index 0000000..4a042fa --- /dev/null +++ b/backend/src/Tnsu.ApprovalRoute.Domain/Enums/RouteType.cs @@ -0,0 +1,7 @@ +namespace Tnsu.ApprovalRoute.Domain.Enums; + +public enum RouteType +{ + Parallel, + Sequential +} diff --git a/backend/src/Tnsu.ApprovalRoute.Infrastructure/Persistence/ApprovalRouteDbContext.cs b/backend/src/Tnsu.ApprovalRoute.Infrastructure/Persistence/ApprovalRouteDbContext.cs index 6fa2086..c845852 100644 --- a/backend/src/Tnsu.ApprovalRoute.Infrastructure/Persistence/ApprovalRouteDbContext.cs +++ b/backend/src/Tnsu.ApprovalRoute.Infrastructure/Persistence/ApprovalRouteDbContext.cs @@ -1,7 +1,40 @@ using Microsoft.EntityFrameworkCore; +using Tnsu.ApprovalRoute.Domain.Entities; namespace Tnsu.ApprovalRoute.Infrastructure.Persistence; public class ApprovalRouteDbContext(DbContextOptions options) : DbContext(options) { + public DbSet RequestTypes => Set(); + public DbSet Routes => Set(); + public DbSet RouteSteps => Set(); + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.Entity(e => + { + e.ToTable("request_types"); + e.HasKey(x => x.Id); + e.Property(x => x.Name).HasMaxLength(256).IsRequired(); + e.Property(x => x.PageUrl).HasMaxLength(512).IsRequired(); + }); + + modelBuilder.Entity(e => + { + e.ToTable("routes"); + e.HasKey(x => x.Id); + e.Property(x => x.RouteType).HasConversion().HasMaxLength(32).IsRequired(); + e.HasOne(x => x.RequestType).WithMany(x => x.Routes).HasForeignKey(x => x.RequestTypeId); + }); + + modelBuilder.Entity(e => + { + e.ToTable("route_steps"); + e.HasKey(x => x.Id); + e.Property(x => x.Position).HasMaxLength(128).IsRequired(); + e.Property(x => x.Status).HasConversion().HasMaxLength(32).IsRequired(); + e.HasOne(x => x.Route).WithMany(x => x.Steps).HasForeignKey(x => x.RouteId); + e.HasIndex(x => new { x.RouteId, x.OrderNo }); + }); + } }