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 });
+ });
+ }
}