diff --git a/AutobusApi.Api/AutobusApi.Api.csproj b/AutobusApi.Api/AutobusApi.Api.csproj
index b633f78..29337ba 100644
--- a/AutobusApi.Api/AutobusApi.Api.csproj
+++ b/AutobusApi.Api/AutobusApi.Api.csproj
@@ -9,6 +9,10 @@
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
diff --git a/AutobusApi.Api/Program.cs b/AutobusApi.Api/Program.cs
index 1760df1..979fc04 100644
--- a/AutobusApi.Api/Program.cs
+++ b/AutobusApi.Api/Program.cs
@@ -1,6 +1,16 @@
+using AutoubsApi.Persistence.Contexts;
+using Microsoft.EntityFrameworkCore;
+
var builder = WebApplication.CreateBuilder(args);
+
+builder.Services.AddDbContext(options =>
+ options.UseNpgsql(
+ builder.Configuration.GetConnectionString("DefaultConnection"),
+ npgsqOptions => npgsqOptions.UseNetTopologySuite()
+ ));
+
var app = builder.Build();
-app.MapGet("/", () => "Hello World!");
+
app.Run();
diff --git a/AutobusApi.Api/appsettings.Development.json b/AutobusApi.Api/appsettings.Development.json
index 0c208ae..4b6d56e 100644
--- a/AutobusApi.Api/appsettings.Development.json
+++ b/AutobusApi.Api/appsettings.Development.json
@@ -1,8 +1,5 @@
{
- "Logging": {
- "LogLevel": {
- "Default": "Information",
- "Microsoft.AspNetCore": "Warning"
- }
+ "ConnectionStrings": {
+ "DefaultConnection": "Host=10.0.0.20:5432;Database=autobus;Username=postgres;Password=12345678"
}
}
diff --git a/AutobusApi.Persistence/AutobusApi.Persistence.csproj b/AutobusApi.Persistence/AutobusApi.Persistence.csproj
index fec8c31..f837419 100644
--- a/AutobusApi.Persistence/AutobusApi.Persistence.csproj
+++ b/AutobusApi.Persistence/AutobusApi.Persistence.csproj
@@ -7,7 +7,11 @@
-
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
diff --git a/AutobusApi.Persistence/Contexts/Configurations/AddressConfiguration.cs b/AutobusApi.Persistence/Contexts/Configurations/AddressConfiguration.cs
new file mode 100644
index 0000000..059d5e6
--- /dev/null
+++ b/AutobusApi.Persistence/Contexts/Configurations/AddressConfiguration.cs
@@ -0,0 +1,63 @@
+using AutobusApi.Domain.Entities;
+using AutobusApi.Domain.Enums;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+using NetTopologySuite.Geometries;
+
+namespace AutobusApi.Persistence.Contexts.Configurations;
+
+public class AddressConfiguration : EntityBaseConfiguration
+{
+ public override void Configure(EntityTypeBuilder builder)
+ {
+ base.Configure(builder);
+
+ builder
+ .ToTable("addresses")
+ .HasKey(e => e.Id);
+
+ builder
+ .Property(a => a.Name)
+ .HasColumnName("name")
+ .HasColumnType("varchar(64)")
+ .IsRequired();
+
+ builder
+ .Property(a => a.VehicleType)
+ .HasColumnName("vehicle_type")
+ .HasColumnType("varchar(16)")
+ .HasConversion(
+ t => t.ToString(),
+ s => (VehicleType) Enum.Parse(typeof(VehicleType), s)
+ )
+ .IsRequired();
+
+ builder
+ .Property(a => a.Location)
+ .HasColumnName("location")
+ .HasColumnType("geography(point)")
+ .HasConversion(
+ l => new Point(l.Latitude, l.Longitude),
+ p => new Entities.Coordinates(p.X, p.Y)
+ )
+ .IsRequired();
+
+ builder
+ .Property(a => a.CityId)
+ .HasColumnName("city_id")
+ .HasColumnType("int")
+ .IsRequired();
+
+ builder
+ .HasOne(a => a.City)
+ .WithMany(c => c.Addresses)
+ .HasForeignKey(a => a.CityId)
+ .HasConstraintName("fk_addresses_city_id")
+ .OnDelete(DeleteBehavior.Cascade);
+
+ builder
+ .HasMany(a => a.RouteAddresses)
+ .WithOne(ra => ra.Address)
+ .OnDelete(DeleteBehavior.Cascade);
+ }
+}
diff --git a/AutobusApi.Persistence/Contexts/Configurations/AircraftConfiguration.cs b/AutobusApi.Persistence/Contexts/Configurations/AircraftConfiguration.cs
new file mode 100644
index 0000000..03a8958
--- /dev/null
+++ b/AutobusApi.Persistence/Contexts/Configurations/AircraftConfiguration.cs
@@ -0,0 +1,57 @@
+using AutobusApi.Domain.Entities;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+
+namespace AutobusApi.Persistence.Contexts.Configurations;
+
+public class AircraftConfiguration : EntityBaseConfiguration
+{
+ public override void Configure(EntityTypeBuilder builder)
+ {
+ builder
+ .ToTable("aircrafts");
+
+ builder
+ .Property(b => b.Number)
+ .HasColumnName("number")
+ .HasColumnType("varchar(8)")
+ .IsRequired();
+
+ builder
+ .Property(b => b.Model)
+ .HasColumnName("model")
+ .HasColumnType("varchar(64)")
+ .IsRequired();
+
+ builder
+ .Property(b => b.Capacity)
+ .HasColumnName("capacity")
+ .HasColumnType("int")
+ .IsRequired();
+
+ builder
+ .Property(b => b.HasWiFi)
+ .HasColumnName("has_wifi")
+ .HasColumnType("boolean")
+ .IsRequired();
+
+ builder
+ .Property(b => b.HasMultimedia)
+ .HasColumnName("has_multimedia")
+ .HasColumnType("boolean")
+ .IsRequired();
+
+ builder
+ .Property(b => b.Id)
+ .HasColumnName("id")
+ .HasColumnType("int")
+ .IsRequired();
+
+ builder
+ .HasOne(b => b.Vehicle)
+ .WithOne()
+ .HasForeignKey(b => b.Id)
+ .HasConstraintName("fk_aircrafts_vehicles_id")
+ .OnDelete(DeleteBehavior.Cascade);
+ }
+}
diff --git a/AutobusApi.Persistence/Contexts/Configurations/BusConfiguration.cs b/AutobusApi.Persistence/Contexts/Configurations/BusConfiguration.cs
new file mode 100644
index 0000000..ed831b5
--- /dev/null
+++ b/AutobusApi.Persistence/Contexts/Configurations/BusConfiguration.cs
@@ -0,0 +1,75 @@
+using AutobusApi.Domain.Entities;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+
+namespace AutobusApi.Persistence.Contexts.Configurations;
+
+public class BusConfiguration : EntityBaseConfiguration
+{
+ public override void Configure(EntityTypeBuilder builder)
+ {
+ builder
+ .ToTable("buses");
+
+ builder
+ .Property(b => b.Number)
+ .HasColumnName("number")
+ .HasColumnType("varchar(8)")
+ .IsRequired();
+
+ builder
+ .Property(b => b.Model)
+ .HasColumnName("model")
+ .HasColumnType("varchar(64)")
+ .IsRequired();
+
+ builder
+ .Property(b => b.Capacity)
+ .HasColumnName("capacity")
+ .HasColumnType("int")
+ .IsRequired();
+
+ builder
+ .Property(b => b.HasClimateControl)
+ .HasColumnName("has_climate_control")
+ .HasColumnType("boolean")
+ .IsRequired();
+
+ builder
+ .Property(b => b.HasWC)
+ .HasColumnName("has_wc")
+ .HasColumnType("boolean")
+ .IsRequired();
+
+ builder
+ .Property(b => b.HasWiFi)
+ .HasColumnName("has_wifi")
+ .HasColumnType("boolean")
+ .IsRequired();
+
+ builder
+ .Property(b => b.HasMultimedia)
+ .HasColumnName("has_multimedia")
+ .HasColumnType("boolean")
+ .IsRequired();
+
+ builder
+ .Property(b => b.HasOutlets)
+ .HasColumnName("has_outlets")
+ .HasColumnType("boolean")
+ .IsRequired();
+
+ builder
+ .Property(b => b.Id)
+ .HasColumnName("id")
+ .HasColumnType("int")
+ .IsRequired();
+
+ builder
+ .HasOne(b => b.Vehicle)
+ .WithOne()
+ .HasForeignKey(b => b.Id)
+ .HasConstraintName("fk_buses_vehicles_id")
+ .OnDelete(DeleteBehavior.Cascade);
+ }
+}
diff --git a/AutobusApi.Persistence/Contexts/Configurations/CarriageConfiguration.cs b/AutobusApi.Persistence/Contexts/Configurations/CarriageConfiguration.cs
new file mode 100644
index 0000000..2952857
--- /dev/null
+++ b/AutobusApi.Persistence/Contexts/Configurations/CarriageConfiguration.cs
@@ -0,0 +1,57 @@
+using AutobusApi.Domain.Entities;
+using AutobusApi.Domain.Enums;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+
+namespace AutobusApi.Persistence.Contexts.Configurations;
+
+public class CarriageConfiguration : EntityBaseConfiguration
+{
+ public override void Configure(EntityTypeBuilder builder)
+ {
+ base.Configure(builder);
+
+ builder
+ .ToTable("carriages")
+ .HasKey(e => e.Id);
+
+ builder
+ .Property(b => b.Type)
+ .HasColumnName("type")
+ .HasColumnType("varchar(16)")
+ .HasConversion(
+ e => e.ToString(),
+ s => (CarriageType)Enum.Parse(typeof(CarriageType), s)
+ )
+ .IsRequired();
+
+ builder
+ .Property(b => b.Capacity)
+ .HasColumnName("capacity")
+ .HasColumnType("int")
+ .IsRequired();
+
+ builder
+ .Property(b => b.Number)
+ .HasColumnName("number")
+ .HasColumnType("int")
+ .IsRequired();
+
+ builder
+ .Property(b => b.HasWiFi)
+ .HasColumnName("has_wifi")
+ .HasColumnType("boolean")
+ .IsRequired();
+
+ builder
+ .Property(b => b.HasOutlets)
+ .HasColumnName("has_outlets")
+ .HasColumnType("boolean")
+ .IsRequired();
+
+ builder
+ .HasMany(c => c.TrainCarriage)
+ .WithOne(tc => tc.Carriage)
+ .OnDelete(DeleteBehavior.Cascade);
+ }
+}
diff --git a/AutobusApi.Persistence/Contexts/Configurations/CityConfiguration.cs b/AutobusApi.Persistence/Contexts/Configurations/CityConfiguration.cs
new file mode 100644
index 0000000..ff55a52
--- /dev/null
+++ b/AutobusApi.Persistence/Contexts/Configurations/CityConfiguration.cs
@@ -0,0 +1,41 @@
+using AutobusApi.Domain.Entities;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+
+namespace AutobusApi.Persistence.Contexts.Configurations;
+
+public class CityConfiguration : EntityBaseConfiguration
+{
+ public override void Configure(EntityTypeBuilder builder)
+ {
+ base.Configure(builder);
+
+ builder
+ .ToTable("cities")
+ .HasKey(e => e.Id);
+
+ builder
+ .Property(c => c.Name)
+ .HasColumnName("name")
+ .HasColumnType("varchar(64)")
+ .IsRequired();
+
+ builder
+ .Property(r => r.RegionId)
+ .HasColumnName("region_id")
+ .HasColumnType("int")
+ .IsRequired();
+
+ builder
+ .HasOne(c => c.Region)
+ .WithMany(r => r.Cities)
+ .HasForeignKey(c => c.RegionId)
+ .HasConstraintName("fk_cities_regions_regionId")
+ .OnDelete(DeleteBehavior.Cascade);
+
+ builder
+ .HasMany(c => c.Addresses)
+ .WithOne(a => a.City)
+ .OnDelete(DeleteBehavior.Cascade);
+ }
+}
diff --git a/AutobusApi.Persistence/Contexts/Configurations/CompanyConfiguration.cs b/AutobusApi.Persistence/Contexts/Configurations/CompanyConfiguration.cs
new file mode 100644
index 0000000..f560fde
--- /dev/null
+++ b/AutobusApi.Persistence/Contexts/Configurations/CompanyConfiguration.cs
@@ -0,0 +1,51 @@
+using AutobusApi.Domain.Entities;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+
+namespace AutobusApi.Persistence.Contexts.Configurations;
+
+public class CompanyConfiguration : EntityBaseConfiguration
+{
+ public override void Configure(EntityTypeBuilder builder)
+ {
+ base.Configure(builder);
+
+ builder
+ .ToTable("companies")
+ .HasKey(e => e.Id);
+
+ builder
+ .Property(c => c.Name)
+ .HasColumnName("name")
+ .HasColumnType("varchar(64)")
+ .IsRequired();
+
+ builder
+ .Property(c => c.LegalAddress)
+ .HasColumnName("legal_address")
+ .HasColumnType("varchar(256)")
+ .IsRequired();
+
+ builder
+ .Property(c => c.ContactEmail)
+ .HasColumnName("contact_email")
+ .HasColumnType("varchar(256)")
+ .IsRequired();
+
+ builder
+ .Property(c => c.ContactPhoneNumber)
+ .HasColumnName("contact_phone_number")
+ .HasColumnType("varchar(16)")
+ .IsRequired();
+
+ builder
+ .HasMany(c => c.Employees)
+ .WithOne(e => e.EmployerCompany)
+ .OnDelete(DeleteBehavior.Cascade);
+
+ builder
+ .HasMany(c => c.Vehicles)
+ .WithOne(v => v.Company)
+ .OnDelete(DeleteBehavior.Cascade);
+ }
+}
diff --git a/AutobusApi.Persistence/Contexts/Configurations/CountryConfiguration.cs b/AutobusApi.Persistence/Contexts/Configurations/CountryConfiguration.cs
new file mode 100644
index 0000000..9fcc5a0
--- /dev/null
+++ b/AutobusApi.Persistence/Contexts/Configurations/CountryConfiguration.cs
@@ -0,0 +1,28 @@
+using AutobusApi.Domain.Entities;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+
+namespace AutobusApi.Persistence.Contexts.Configurations;
+
+public class CountryConfiguration : EntityBaseConfiguration
+{
+ public override void Configure(EntityTypeBuilder builder)
+ {
+ base.Configure(builder);
+
+ builder
+ .ToTable("countries")
+ .HasKey(e => e.Id);
+
+ builder
+ .Property(c => c.Name)
+ .HasColumnName("name")
+ .HasColumnType("varchar(64)")
+ .IsRequired();
+
+ builder
+ .HasMany(c => c.Regions)
+ .WithOne(r => r.Country)
+ .OnDelete(DeleteBehavior.Cascade);
+ }
+}
diff --git a/AutobusApi.Persistence/Contexts/Configurations/EmployeeConfiguration.cs b/AutobusApi.Persistence/Contexts/Configurations/EmployeeConfiguration.cs
new file mode 100644
index 0000000..6c47f4d
--- /dev/null
+++ b/AutobusApi.Persistence/Contexts/Configurations/EmployeeConfiguration.cs
@@ -0,0 +1,75 @@
+using AutobusApi.Domain.Entities;
+using AutobusApi.Domain.Enums;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+
+namespace AutobusApi.Persistence.Contexts.Configurations;
+
+public class EmployeeConfiguration : EntityBaseConfiguration
+{
+ public override void Configure(EntityTypeBuilder builder)
+ {
+ base.Configure(builder);
+
+ builder
+ .ToTable("employees")
+ .HasKey(e => e.Id);
+
+ builder
+ .Property(e => e.FisrtName)
+ .HasColumnName("first_name")
+ .HasColumnType("varchar(32)")
+ .IsRequired();
+
+ builder
+ .Property(e => e.LastName)
+ .HasColumnName("last_name")
+ .HasColumnType("varchar(32)")
+ .IsRequired();
+
+ builder
+ .Property(e => e.Patronymic)
+ .HasColumnName("patronymic")
+ .HasColumnType("varchar(32)")
+ .IsRequired();
+
+ builder
+ .Property(e => e.Sex)
+ .HasColumnName("sex")
+ .HasColumnType("varchar(16)")
+ .HasConversion(
+ e => e.ToString(),
+ s => (Sex)Enum.Parse(typeof(Sex), s)
+ )
+ .IsRequired();
+
+ builder
+ .Property(e => e.BirthDate)
+ .HasColumnName("birth_date")
+ .HasColumnType("date")
+ .IsRequired();
+
+ builder
+ .Property(e => e.EmployerCompanyId)
+ .HasColumnName("employer_company_id")
+ .HasColumnType("int")
+ .IsRequired();
+
+ builder
+ .HasOne(e => e.EmployerCompany)
+ .WithMany(c => c.Employees)
+ .HasForeignKey(e => e.EmployerCompanyId)
+ .HasConstraintName("fk_employees_companies_employerCompanyId")
+ .OnDelete(DeleteBehavior.Cascade);
+
+ builder
+ .HasMany(e => e.Documents)
+ .WithOne(d => d.Employee)
+ .OnDelete(DeleteBehavior.Cascade);
+
+ builder
+ .HasMany(e => e.Shifts)
+ .WithOne(s => s.Employee)
+ .OnDelete(DeleteBehavior.Cascade);
+ }
+}
diff --git a/AutobusApi.Persistence/Contexts/Configurations/EmployeeDocumentConfiguration.cs b/AutobusApi.Persistence/Contexts/Configurations/EmployeeDocumentConfiguration.cs
new file mode 100644
index 0000000..db5b34b
--- /dev/null
+++ b/AutobusApi.Persistence/Contexts/Configurations/EmployeeDocumentConfiguration.cs
@@ -0,0 +1,47 @@
+using AutobusApi.Domain.Entities;
+using AutobusApi.Domain.Enums;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+
+namespace AutobusApi.Persistence.Contexts.Configurations;
+
+public class EmployeeDocumentConfiguration : EntityBaseConfiguration
+{
+ public override void Configure(EntityTypeBuilder builder)
+ {
+ base.Configure(builder);
+
+ builder
+ .ToTable("employee_documents")
+ .HasKey(e => e.Id);
+
+ builder
+ .Property(ed => ed.Type)
+ .HasColumnName("type")
+ .HasColumnType("varchar(32)")
+ .HasConversion(
+ e => e.ToString(),
+ s => (EmployeeDocumentType)Enum.Parse(typeof(EmployeeDocumentType), s)
+ )
+ .IsRequired();
+
+ builder
+ .Property(ed => ed.Information)
+ .HasColumnName("information")
+ .HasColumnType("varchar(256)")
+ .IsRequired();
+
+ builder
+ .Property(ed => ed.EmployeeId)
+ .HasColumnName("employee_id")
+ .HasColumnType("int")
+ .IsRequired();
+
+ builder
+ .HasOne(ed => ed.Employee)
+ .WithMany(e => e.Documents)
+ .HasForeignKey(ed => ed.EmployeeId)
+ .HasConstraintName("fk_employeeDocuments_employees_employeeId")
+ .OnDelete(DeleteBehavior.Cascade);
+ }
+}
diff --git a/AutobusApi.Persistence/Contexts/Configurations/EntityBaseConfiguration.cs b/AutobusApi.Persistence/Contexts/Configurations/EntityBaseConfiguration.cs
new file mode 100644
index 0000000..cc86b1d
--- /dev/null
+++ b/AutobusApi.Persistence/Contexts/Configurations/EntityBaseConfiguration.cs
@@ -0,0 +1,27 @@
+using AutobusApi.Domain.Common;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+
+namespace AutobusApi.Persistence.Contexts.Configurations;
+
+public class EntityBaseConfiguration : IEntityTypeConfiguration
+ where TEntity : EntityBase
+{
+ public virtual void Configure(EntityTypeBuilder builder)
+ {
+ builder
+ .HasKey(e => e.Id);
+
+ builder
+ .Property(e => e.Id)
+ .HasColumnName("id")
+ .HasColumnType("int")
+ .IsRequired();
+
+ builder
+ .Property(e => e.IsDeleted)
+ .HasColumnName("is_deleted")
+ .HasColumnType("boolean")
+ .IsRequired();
+ }
+}
diff --git a/AutobusApi.Persistence/Contexts/Configurations/RegionConfiguration.cs b/AutobusApi.Persistence/Contexts/Configurations/RegionConfiguration.cs
new file mode 100644
index 0000000..9f9deee
--- /dev/null
+++ b/AutobusApi.Persistence/Contexts/Configurations/RegionConfiguration.cs
@@ -0,0 +1,41 @@
+using AutobusApi.Domain.Entities;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+
+namespace AutobusApi.Persistence.Contexts.Configurations;
+
+public class RegionConfiguration : EntityBaseConfiguration
+{
+ public override void Configure(EntityTypeBuilder builder)
+ {
+ base.Configure(builder);
+
+ builder
+ .ToTable("regions")
+ .HasKey(e => e.Id);
+
+ builder
+ .Property(r => r.Name)
+ .HasColumnName("name")
+ .HasColumnType("varchar(64)")
+ .IsRequired();
+
+ builder
+ .Property(r => r.CountryId)
+ .HasColumnName("country_id")
+ .HasColumnType("int")
+ .IsRequired();
+
+ builder
+ .HasOne(r => r.Country)
+ .WithMany(c => c.Regions)
+ .HasForeignKey(r => r.CountryId)
+ .HasConstraintName("fk_regions_coutries_countryId")
+ .OnDelete(DeleteBehavior.Cascade);
+
+ builder
+ .HasMany(r => r.Cities)
+ .WithOne(c => c.Region)
+ .OnDelete(DeleteBehavior.Cascade);
+ }
+}
diff --git a/AutobusApi.Persistence/Contexts/Configurations/ReviewConfiguration.cs b/AutobusApi.Persistence/Contexts/Configurations/ReviewConfiguration.cs
new file mode 100644
index 0000000..0986db1
--- /dev/null
+++ b/AutobusApi.Persistence/Contexts/Configurations/ReviewConfiguration.cs
@@ -0,0 +1,61 @@
+using AutobusApi.Domain.Entities;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+
+namespace AutobusApi.Persistence.Contexts.Configurations;
+
+public class ReviewConfiguration : EntityBaseConfiguration
+{
+ public override void Configure(EntityTypeBuilder builder)
+ {
+ base.Configure(builder);
+
+ builder
+ .ToTable("reviews")
+ .HasKey(e => e.Id);
+
+ builder
+ .Property(r => r.Rating)
+ .HasColumnName("rating")
+ .HasColumnType("numeric(1,0)")
+ .IsRequired();
+
+ builder
+ .Property(r => r.Comment)
+ .HasColumnName("comment")
+ .HasColumnType("varchar(128)")
+ .IsRequired();
+
+ builder
+ .Property(r => r.PostDateTimeUtc)
+ .HasColumnName("post_timestamp_utc")
+ .HasColumnType("timestamp")
+ .IsRequired();
+
+ builder
+ .Property(r => r.UserId)
+ .HasColumnName("user_id")
+ .HasColumnType("int")
+ .IsRequired();
+
+ builder
+ .HasOne(r => r.User)
+ .WithMany(u => u.Reviews)
+ .HasForeignKey(r => r.UserId)
+ .HasConstraintName("fk_reviews_users_userId")
+ .OnDelete(DeleteBehavior.Cascade);
+
+ builder
+ .Property(r => r.VehicleEnrollmentId)
+ .HasColumnName("vehicle_enrollment_id")
+ .HasColumnType("int")
+ .IsRequired();
+
+ builder
+ .HasOne(r => r.VehicleEnrollment)
+ .WithMany(ve => ve.Reviews)
+ .HasForeignKey(r => r.VehicleEnrollmentId)
+ .HasConstraintName("fk_reviews_vehicleEnrollments_vehicleEnrollmentId")
+ .OnDelete(DeleteBehavior.Cascade);
+ }
+}
diff --git a/AutobusApi.Persistence/Contexts/Configurations/RouteAddressConfiguration.cs b/AutobusApi.Persistence/Contexts/Configurations/RouteAddressConfiguration.cs
new file mode 100644
index 0000000..d7e1491
--- /dev/null
+++ b/AutobusApi.Persistence/Contexts/Configurations/RouteAddressConfiguration.cs
@@ -0,0 +1,49 @@
+using AutobusApi.Domain.Entities;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+
+namespace AutobusApi.Persistence.Contexts.Configurations;
+
+public class RouteAddressConfiguration : EntityBaseConfiguration
+{
+ public override void Configure(EntityTypeBuilder builder)
+ {
+ base.Configure(builder);
+
+ builder
+ .ToTable("route_addresses")
+ .HasKey(e => e.Id);
+
+ builder
+ .Property(ra => ra.Order)
+ .HasColumnName("order")
+ .HasColumnType("int")
+ .IsRequired();
+
+ builder
+ .Property(ra => ra.AddressId)
+ .HasColumnName("address_id")
+ .HasColumnType("int")
+ .IsRequired();
+
+ builder
+ .HasOne(ra => ra.Address)
+ .WithMany(a => a.RouteAddresses)
+ .HasForeignKey(ra => ra.AddressId)
+ .HasConstraintName("fk_routeAddresses_addresses_addressId")
+ .OnDelete(DeleteBehavior.Cascade);
+
+ builder
+ .Property(ra => ra.RouteId)
+ .HasColumnName("route_id")
+ .HasColumnType("int")
+ .IsRequired();
+
+ builder
+ .HasOne(ra => ra.Route)
+ .WithMany(r => r.RouteAddresses)
+ .HasForeignKey(ra => ra.RouteId)
+ .HasConstraintName("fk_routeAddresses_routes_routeId")
+ .OnDelete(DeleteBehavior.Cascade);
+ }
+}
diff --git a/AutobusApi.Persistence/Contexts/Configurations/RouteAddressDetailsConfiguration.cs b/AutobusApi.Persistence/Contexts/Configurations/RouteAddressDetailsConfiguration.cs
new file mode 100644
index 0000000..7f4d8fb
--- /dev/null
+++ b/AutobusApi.Persistence/Contexts/Configurations/RouteAddressDetailsConfiguration.cs
@@ -0,0 +1,61 @@
+using AutobusApi.Domain.Entities;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+
+namespace AutobusApi.Persistence.Contexts.Configurations;
+
+public class RouteAddressDeatilsConfiguration : EntityBaseConfiguration
+{
+ public override void Configure(EntityTypeBuilder builder)
+ {
+ base.Configure(builder);
+
+ builder
+ .ToTable("route_address_details")
+ .HasKey(e => e.Id);
+
+ builder
+ .Property(rad => rad.TimeToNextAddress)
+ .HasColumnName("time_to_next_address")
+ .HasColumnType("interval")
+ .IsRequired();
+
+ builder
+ .Property(rad => rad.CurrentAddressStopTime)
+ .HasColumnName("current_address_stop_time")
+ .HasColumnType("interval")
+ .IsRequired();
+
+ builder
+ .Property(rad => rad.CostToNextAddress)
+ .HasColumnName("cost_to_next_address")
+ .HasColumnType("numeric(16,4)")
+ .IsRequired();
+
+ builder
+ .Property(rad => rad.RouteAddressId)
+ .HasColumnName("route_address_id")
+ .HasColumnType("int")
+ .IsRequired();
+
+ builder
+ .HasOne(rad => rad.RouteAddress)
+ .WithMany(ra => ra.RouteAddressDetails)
+ .HasForeignKey(rad => rad.RouteAddressId)
+ .HasConstraintName("fk_routeAddressDetails_routeAddress_routeAddressId")
+ .OnDelete(DeleteBehavior.Cascade);
+
+ builder
+ .Property(rad => rad.VehicleEnrollmentId)
+ .HasColumnName("vehicle_enrollment_id")
+ .HasColumnType("int")
+ .IsRequired();
+
+ builder
+ .HasOne(rad => rad.VehicleEnrollment)
+ .WithMany(ve => ve.RouteAddressDetails)
+ .HasForeignKey(rad => rad.VehicleEnrollmentId)
+ .HasConstraintName("fk_routeAddressDetails_vehicleEnrollments_vehicleEnrollmentId")
+ .OnDelete(DeleteBehavior.Cascade);
+ }
+}
diff --git a/AutobusApi.Persistence/Contexts/Configurations/RouteConfiguration.cs b/AutobusApi.Persistence/Contexts/Configurations/RouteConfiguration.cs
new file mode 100644
index 0000000..73d2505
--- /dev/null
+++ b/AutobusApi.Persistence/Contexts/Configurations/RouteConfiguration.cs
@@ -0,0 +1,27 @@
+using AutobusApi.Domain.Entities;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+
+namespace AutobusApi.Persistence.Contexts.Configurations;
+
+public class RouteConfiguration : EntityBaseConfiguration
+{
+ public override void Configure(EntityTypeBuilder builder)
+ {
+ base.Configure(builder);
+
+ builder
+ .ToTable("routes")
+ .HasKey(e => e.Id);
+
+ builder
+ .HasMany(r => r.VehicleEnrollments)
+ .WithOne(ve => ve.Route)
+ .OnDelete(DeleteBehavior.Cascade);
+
+ builder
+ .HasMany(r => r.RouteAddresses)
+ .WithOne(ra => ra.Route)
+ .OnDelete(DeleteBehavior.Cascade);
+ }
+}
diff --git a/AutobusApi.Persistence/Contexts/Configurations/TicketConfiguration.cs b/AutobusApi.Persistence/Contexts/Configurations/TicketConfiguration.cs
new file mode 100644
index 0000000..9e0002a
--- /dev/null
+++ b/AutobusApi.Persistence/Contexts/Configurations/TicketConfiguration.cs
@@ -0,0 +1,43 @@
+using AutobusApi.Domain.Entities;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+
+namespace AutobusApi.Persistence.Contexts.Configurations;
+
+public class TicketConfiguration : EntityBaseConfiguration
+{
+ public override void Configure(EntityTypeBuilder builder)
+ {
+ base.Configure(builder);
+
+ builder
+ .ToTable("tickets")
+ .HasKey(e => e.Id);
+
+ builder
+ .Property(t => t.VehicleEnrollmentId)
+ .HasColumnName("vehicle_enrollment_id")
+ .HasColumnType("int")
+ .IsRequired();
+
+ builder
+ .HasOne(t => t.VehicleEnrollment)
+ .WithMany(ve => ve.Tickets)
+ .HasForeignKey(t => t.VehicleEnrollmentId)
+ .HasConstraintName("fk_tickets_vehicleEnrollments_vehicleEnrollmentId")
+ .OnDelete(DeleteBehavior.Cascade);
+
+ builder
+ .Property(t => t.TicketGroupId)
+ .HasColumnName("ticket_group_id")
+ .HasColumnType("int")
+ .IsRequired();
+
+ builder
+ .HasOne(t => t.TicketGroup)
+ .WithMany(ve => ve.Tickets)
+ .HasForeignKey(t => t.TicketGroupId)
+ .HasConstraintName("fk_tickets_ticketGroups_ticketGroupId")
+ .OnDelete(DeleteBehavior.Cascade);
+ }
+}
diff --git a/AutobusApi.Persistence/Contexts/Configurations/TicketDocumentConfiguration.cs b/AutobusApi.Persistence/Contexts/Configurations/TicketDocumentConfiguration.cs
new file mode 100644
index 0000000..36ea420
--- /dev/null
+++ b/AutobusApi.Persistence/Contexts/Configurations/TicketDocumentConfiguration.cs
@@ -0,0 +1,47 @@
+using AutobusApi.Domain.Entities;
+using AutobusApi.Domain.Enums;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+
+namespace AutobusApi.Persistence.Contexts.Configurations;
+
+public class TicketDocumentConfiguration : EntityBaseConfiguration
+{
+ public override void Configure(EntityTypeBuilder builder)
+ {
+ base.Configure(builder);
+
+ builder
+ .ToTable("ticket_documents")
+ .HasKey(e => e.Id);
+
+ builder
+ .Property(td => td.Type)
+ .HasColumnName("type")
+ .HasColumnType("varchar(32)")
+ .HasConversion(
+ e => e.ToString(),
+ s => (TicketDocumentType)Enum.Parse(typeof(TicketDocumentType), s)
+ )
+ .IsRequired();
+
+ builder
+ .Property(td => td.Information)
+ .HasColumnName("information")
+ .HasColumnType("varchar(256)")
+ .IsRequired();
+
+ builder
+ .Property(td => td.TicketGroupId)
+ .HasColumnName("ticket_group_id")
+ .HasColumnType("int")
+ .IsRequired();
+
+ builder
+ .HasOne(td => td.TicketGroup)
+ .WithOne(tg => tg.TicketDocument)
+ .HasForeignKey(td => td.TicketDocumentId)
+ .HasConstraintName("fk_ticketDocuments_ticketGroups_ticketDocumentId")
+ .OnDelete(DeleteBehavior.Cascade);
+ }
+}
diff --git a/AutobusApi.Persistence/Contexts/Configurations/TicketGroupConfiguraions.cs b/AutobusApi.Persistence/Contexts/Configurations/TicketGroupConfiguraions.cs
new file mode 100644
index 0000000..7f1bb9b
--- /dev/null
+++ b/AutobusApi.Persistence/Contexts/Configurations/TicketGroupConfiguraions.cs
@@ -0,0 +1,119 @@
+using AutobusApi.Domain.Entities;
+using AutobusApi.Domain.Enums;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+
+namespace AutobusApi.Persistence.Contexts.Configurations;
+
+public class TicketGroupConfiguration : EntityBaseConfiguration
+{
+ public override void Configure(EntityTypeBuilder builder)
+ {
+ base.Configure(builder);
+
+ builder
+ .ToTable("ticket_groups")
+ .HasKey(e => e.Id);
+
+ builder
+ .Property(tg => tg.BuyerFirstName)
+ .HasColumnName("buyer_first_name")
+ .HasColumnType("varchar(32)")
+ .IsRequired();
+
+ builder
+ .Property(tg => tg.BuyerLastName)
+ .HasColumnName("buyer_last_name")
+ .HasColumnType("varchar(32)")
+ .IsRequired();
+
+ builder
+ .Property(tg => tg.BuyerPhoneNumber)
+ .HasColumnName("buyer_phone_number")
+ .HasColumnType("varchar(16)")
+ .IsRequired();
+
+ builder
+ .Property(tg => tg.BuyerEmailAddress)
+ .HasColumnName("buyer_email")
+ .HasColumnType("varchar(256)")
+ .IsRequired();
+
+ builder
+ .Property(tg => tg.PassengerFirstName)
+ .HasColumnName("passenger_first_name")
+ .HasColumnType("varchar(32)")
+ .IsRequired();
+
+ builder
+ .Property(tg => tg.PassengerLastName)
+ .HasColumnName("passenger_last_name")
+ .HasColumnType("varchar(32)")
+ .IsRequired();
+
+ builder
+ .Property(tg => tg.PassengerPatronymic)
+ .HasColumnName("passenger_patronymic")
+ .HasColumnType("varchar(32)")
+ .IsRequired();
+
+ builder
+ .Property(tg => tg.PassengerSex)
+ .HasColumnName("passenger_sex")
+ .HasColumnType("varchar(16)")
+ .HasConversion(
+ e => e.ToString(),
+ s => (Sex)Enum.Parse(typeof(Sex), s)
+ )
+ .IsRequired();
+
+ builder
+ .Property(tg => tg.PassengerBirthDate)
+ .HasColumnName("passenger_birth_date")
+ .HasColumnType("date")
+ .IsRequired();
+
+ builder
+ .Property(tg => tg.PurchaseDateTimeUtc)
+ .HasColumnName("purchase_timestamp_utc")
+ .HasColumnType("timestamp")
+ .IsRequired();
+
+ builder
+ .Property(tg => tg.IsReturned)
+ .HasColumnName("is_returned")
+ .HasColumnType("boolean")
+ .IsRequired();
+
+ builder
+ .Property(tg => tg.BuyerEmailAddress)
+ .HasColumnName("buyer_email")
+ .HasColumnType("varchar(256)")
+ .IsRequired();
+
+ builder
+ .Property(tg => tg.UserId)
+ .HasColumnName("user_id")
+ .HasColumnType("int")
+ .IsRequired(false);
+
+ builder
+ .HasOne(tg => tg.User)
+ .WithMany(u => u.TicketGroups)
+ .HasForeignKey(tg => tg.UserId)
+ .HasConstraintName("fk_ticketGroups_users_userId")
+ .OnDelete(DeleteBehavior.Cascade);
+
+ builder
+ .HasMany(tg => tg.Tickets)
+ .WithOne(t => t.TicketGroup)
+ .OnDelete(DeleteBehavior.Cascade);
+
+ builder
+ .HasOne(tg => tg.TicketDocument)
+ .WithOne(td => td.TicketGroup)
+ .HasForeignKey(tg => tg.TicketDocumentId)
+ .HasConstraintName("fk_ticketGroups_ticketDocuments_ticketDocumentId")
+ .OnDelete(DeleteBehavior.Cascade);
+ }
+}
diff --git a/AutobusApi.Persistence/Contexts/Configurations/TrainCarriageConfiguration.cs b/AutobusApi.Persistence/Contexts/Configurations/TrainCarriageConfiguration.cs
new file mode 100644
index 0000000..38922ca
--- /dev/null
+++ b/AutobusApi.Persistence/Contexts/Configurations/TrainCarriageConfiguration.cs
@@ -0,0 +1,43 @@
+using AutobusApi.Domain.Entities;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+
+namespace AutobusApi.Persistence.Contexts.Configurations;
+
+public class TrainCarriageConfiguration : EntityBaseConfiguration
+{
+ public override void Configure(EntityTypeBuilder builder)
+ {
+ base.Configure(builder);
+
+ builder
+ .ToTable("train_carriages")
+ .HasKey(e => e.Id);
+
+ builder
+ .Property(b => b.TrainId)
+ .HasColumnName("train_id")
+ .HasColumnType("int")
+ .IsRequired();
+
+ builder
+ .HasOne(tc => tc.Train)
+ .WithMany(t => t.TrainCarriage)
+ .HasForeignKey(tc => tc.TrainId)
+ .HasConstraintName("fk_trainCarriages_trains_trainId")
+ .OnDelete(DeleteBehavior.Cascade);
+
+ builder
+ .Property(b => b.CarriageId)
+ .HasColumnName("carriage_id")
+ .HasColumnType("int")
+ .IsRequired();
+
+ builder
+ .HasOne(tc => tc.Carriage)
+ .WithMany(c => c.TrainCarriage)
+ .HasForeignKey(tc => tc.TrainId)
+ .HasConstraintName("fk_trainCarriages_trains_carriageId")
+ .OnDelete(DeleteBehavior.Cascade);
+ }
+}
diff --git a/AutobusApi.Persistence/Contexts/Configurations/TrainConfiguration.cs b/AutobusApi.Persistence/Contexts/Configurations/TrainConfiguration.cs
new file mode 100644
index 0000000..830dce2
--- /dev/null
+++ b/AutobusApi.Persistence/Contexts/Configurations/TrainConfiguration.cs
@@ -0,0 +1,38 @@
+using AutobusApi.Domain.Entities;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+
+namespace AutobusApi.Persistence.Contexts.Configurations;
+
+public class TrainConfiguration : EntityBaseConfiguration
+{
+ public override void Configure(EntityTypeBuilder builder)
+ {
+ builder
+ .ToTable("trains");
+
+ builder
+ .Property(b => b.Number)
+ .HasColumnName("number")
+ .HasColumnType("varchar(8)")
+ .IsRequired();
+
+ builder
+ .HasMany(t => t.TrainCarriage)
+ .WithOne(tc => tc.Train)
+ .OnDelete(DeleteBehavior.Cascade);
+
+ builder
+ .Property(b => b.Id)
+ .HasColumnName("id")
+ .HasColumnType("int")
+ .IsRequired();
+
+ builder
+ .HasOne(b => b.Vehicle)
+ .WithOne()
+ .HasForeignKey(b => b.Id)
+ .HasConstraintName("fk_trains_vehicles_id")
+ .OnDelete(DeleteBehavior.Cascade);
+ }
+}
diff --git a/AutobusApi.Persistence/Contexts/Configurations/UserConfiguration.cs b/AutobusApi.Persistence/Contexts/Configurations/UserConfiguration.cs
new file mode 100644
index 0000000..573697d
--- /dev/null
+++ b/AutobusApi.Persistence/Contexts/Configurations/UserConfiguration.cs
@@ -0,0 +1,27 @@
+using AutobusApi.Domain.Entities;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+
+namespace AutobusApi.Persistence.Contexts.Configurations;
+
+public class UserConfiguration : EntityBaseConfiguration
+{
+ public override void Configure(EntityTypeBuilder builder)
+ {
+ base.Configure(builder);
+
+ builder
+ .ToTable("users")
+ .HasKey(e => e.Id);
+
+ builder
+ .HasMany(u => u.Reviews)
+ .WithOne(r => r.User)
+ .OnDelete(DeleteBehavior.Cascade);
+
+ builder
+ .HasMany(u => u.TicketGroups)
+ .WithOne(tg => tg.User)
+ .OnDelete(DeleteBehavior.Cascade);
+ }
+}
diff --git a/AutobusApi.Persistence/Contexts/Configurations/VehicleConfiguration.cs b/AutobusApi.Persistence/Contexts/Configurations/VehicleConfiguration.cs
new file mode 100644
index 0000000..cf2ca53
--- /dev/null
+++ b/AutobusApi.Persistence/Contexts/Configurations/VehicleConfiguration.cs
@@ -0,0 +1,38 @@
+using AutobusApi.Domain.Entities;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+
+namespace AutobusApi.Persistence.Contexts.Configurations;
+
+public class VehicleConfiguration : EntityBaseConfiguration
+{
+ public override void Configure(EntityTypeBuilder builder)
+ {
+ base.Configure(builder);
+
+ builder
+ .UseTptMappingStrategy()
+ .ToTable("vehicles")
+ .HasKey(e => e.Id);
+
+ builder
+ .Property(v => v.CompanyId)
+ .HasColumnName("company_id")
+ .HasColumnType("int")
+ .IsRequired();
+
+ builder
+ .HasOne(v => v.Company)
+ .WithMany(c => c.Vehicles)
+ .HasForeignKey(v => v.CompanyId)
+ .HasConstraintName("fk_vehicles_companies_companyId")
+ .OnDelete(DeleteBehavior.Cascade);
+
+ builder
+ .HasMany(v => v.Enrollments)
+ .WithOne(ve => ve.Vehicle)
+ .OnDelete(DeleteBehavior.Cascade);
+
+
+ }
+}
diff --git a/AutobusApi.Persistence/Contexts/Configurations/VehicleEnrollmentConfiguration.cs b/AutobusApi.Persistence/Contexts/Configurations/VehicleEnrollmentConfiguration.cs
new file mode 100644
index 0000000..934775a
--- /dev/null
+++ b/AutobusApi.Persistence/Contexts/Configurations/VehicleEnrollmentConfiguration.cs
@@ -0,0 +1,69 @@
+using AutobusApi.Domain.Entities;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+
+namespace AutobusApi.Persistence.Contexts.Configurations;
+
+public class VehicleEnrollmentConfiguration : EntityBaseConfiguration
+{
+ public override void Configure(EntityTypeBuilder builder)
+ {
+ base.Configure(builder);
+
+ builder
+ .ToTable("vehicle_enrollments")
+ .HasKey(e => e.Id);
+
+ builder
+ .Property(ve => ve.DepartureDateTimeUtc)
+ .HasColumnName("departure_timestamp_utc")
+ .HasColumnType("timestamp")
+ .IsRequired();
+
+ builder
+ .Property(ve => ve.RouteId)
+ .HasColumnName("route_id")
+ .HasColumnType("int")
+ .IsRequired();
+
+ builder
+ .HasOne(ve => ve.Route)
+ .WithMany(r => r.VehicleEnrollments)
+ .HasForeignKey(ve => ve.RouteId)
+ .HasConstraintName("fk_vehicleEnrollments_routes_routeId")
+ .OnDelete(DeleteBehavior.Cascade);
+
+ builder
+ .Property(ve => ve.VehicleId)
+ .HasColumnName("vehicle_id")
+ .HasColumnType("int")
+ .IsRequired();
+
+ builder
+ .HasOne(ve => ve.Vehicle)
+ .WithMany(v => v.Enrollments)
+ .HasForeignKey(ve => ve.VehicleId)
+ .HasConstraintName("fk_vehicleEnrollments_vehicles_vehicleId")
+ .OnDelete(DeleteBehavior.Cascade);
+
+ builder
+ .HasMany(ve => ve.RouteAddressDetails)
+ .WithOne(rad => rad.VehicleEnrollment)
+ .OnDelete(DeleteBehavior.Cascade);
+
+ builder
+ .HasMany(ve => ve.Tickets)
+ .WithOne(t => t.VehicleEnrollment)
+ .OnDelete(DeleteBehavior.Cascade);
+
+ builder
+ .HasMany(ve => ve.Crew)
+ .WithOne(c => c.VehicleEnrollment)
+ .OnDelete(DeleteBehavior.Cascade);
+
+ builder
+ .HasMany(ve => ve.Reviews)
+ .WithOne(r => r.VehicleEnrollment)
+ .OnDelete(DeleteBehavior.Cascade);
+ }
+}
diff --git a/AutobusApi.Persistence/Contexts/Configurations/VehicleEnrollmentEmployeeConfiguration.cs b/AutobusApi.Persistence/Contexts/Configurations/VehicleEnrollmentEmployeeConfiguration.cs
new file mode 100644
index 0000000..0c4693b
--- /dev/null
+++ b/AutobusApi.Persistence/Contexts/Configurations/VehicleEnrollmentEmployeeConfiguration.cs
@@ -0,0 +1,43 @@
+using AutobusApi.Domain.Entities;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+
+namespace AutobusApi.Persistence.Contexts.Configurations;
+
+public class VehicleEnrollmentEmployeeConfiguration : EntityBaseConfiguration
+{
+ public override void Configure(EntityTypeBuilder builder)
+ {
+ base.Configure(builder);
+
+ builder
+ .ToTable("vehicle_enrollment_employees")
+ .HasKey(e => e.Id);
+
+ builder
+ .Property(vee => vee.EmployeeId)
+ .HasColumnName("employee_id")
+ .HasColumnType("int")
+ .IsRequired();
+
+ builder
+ .HasOne(vee => vee.Employee)
+ .WithMany(e => e.Shifts)
+ .HasForeignKey(vee => vee.EmployeeId)
+ .HasConstraintName("fk_vehicleEnrollmentEmployees_employees_employeeId")
+ .OnDelete(DeleteBehavior.Cascade);
+
+ builder
+ .Property(vee => vee.VehicleEnrollmentId)
+ .HasColumnName("vehicle_enrollment_id")
+ .HasColumnType("int")
+ .IsRequired();
+
+ builder
+ .HasOne(vee => vee.VehicleEnrollment)
+ .WithMany(ve => ve.Crew)
+ .HasForeignKey(vee => vee.VehicleEnrollmentId)
+ .HasConstraintName("fk_vehicleEnrollmentEmployees_vehicleEnrollments_vehicleEnrollmentId")
+ .OnDelete(DeleteBehavior.Cascade);
+ }
+}
diff --git a/AutobusApi.Persistence/Contexts/PostgresContext.cs b/AutobusApi.Persistence/Contexts/PostgresContext.cs
new file mode 100644
index 0000000..3241391
--- /dev/null
+++ b/AutobusApi.Persistence/Contexts/PostgresContext.cs
@@ -0,0 +1,64 @@
+using System.Reflection;
+using AutobusApi.Domain.Entities;
+using Microsoft.EntityFrameworkCore;
+
+namespace AutoubsApi.Persistence.Contexts;
+
+public class PostgresContext : DbContext
+{
+ public PostgresContext(DbContextOptions options)
+ : base(options) { }
+
+ public DbSet Countries { get; set; }
+
+ public DbSet Regions { get; set; }
+
+ public DbSet Cities { get; set; }
+
+ public DbSet Addresses { get; set; }
+
+ public DbSet RouteAddresses { get; set; }
+
+ public DbSet Routes { get; set; }
+
+ public DbSet RouteAddressDetails { get; set; }
+
+ public DbSet VehicleEnrollments { get; set; }
+
+ public DbSet Vehicles { get; set; }
+
+ public DbSet Buses { get; set; }
+
+ public DbSet Aircraft { get; set; }
+
+ public DbSet Trains { get; set; }
+
+ public DbSet TrainCarriages { get; set; }
+
+ public DbSet Carriages { get; set; }
+
+ public DbSet Companies { get; set; }
+
+ public DbSet Employees { get; set; }
+
+ public DbSet EmployeeDocuments { get; set; }
+
+ public DbSet vehicleEnrollmentEmployees { get; set; }
+
+ public DbSet Users { get; set; }
+
+ public DbSet TicketGroups { get; set; }
+
+ public DbSet Tickets { get; set; }
+
+ public DbSet TicketDocuments { get; set; }
+
+ public DbSet Reviews { get; set; }
+
+ protected override void OnModelCreating(ModelBuilder modelBuilder)
+ {
+ modelBuilder.HasPostgresExtension("postgis");
+
+ modelBuilder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly());
+ }
+}
diff --git a/AutobusApi.Persistence/Entities/Coordinates.cs b/AutobusApi.Persistence/Entities/Coordinates.cs
new file mode 100644
index 0000000..f649088
--- /dev/null
+++ b/AutobusApi.Persistence/Entities/Coordinates.cs
@@ -0,0 +1,17 @@
+using AutobusApi.Domain.IEntities;
+using NetTopologySuite.Geometries;
+
+namespace AutobusApi.Persistence.Entities;
+
+public class Coordinates : ICoordinates
+{
+ private readonly Point point;
+
+ public Coordinates(double latitude, double longitude)
+ {
+ point = new Point(latitude, longitude);
+ }
+
+ public double Latitude { get => point.X; }
+ public double Longitude { get => point.Y; }
+}
diff --git a/AutobusApi.Persistence/Migrations/20231101122211_initial_create.Designer.cs b/AutobusApi.Persistence/Migrations/20231101122211_initial_create.Designer.cs
new file mode 100644
index 0000000..7ba0a4f
--- /dev/null
+++ b/AutobusApi.Persistence/Migrations/20231101122211_initial_create.Designer.cs
@@ -0,0 +1,1175 @@
+//
+using System;
+using AutoubsApi.Persistence.Contexts;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using NetTopologySuite.Geometries;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+
+#nullable disable
+
+namespace AutobusApi.Persistence.Migrations
+{
+ [DbContext(typeof(PostgresContext))]
+ [Migration("20231101122211_initial_create")]
+ partial class initial_create
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasAnnotation("ProductVersion", "7.0.13")
+ .HasAnnotation("Relational:MaxIdentifierLength", 63);
+
+ NpgsqlModelBuilderExtensions.HasPostgresExtension(modelBuilder, "postgis");
+ NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.Address", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int")
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("CityId")
+ .HasColumnType("int")
+ .HasColumnName("city_id");
+
+ b.Property("IsDeleted")
+ .HasColumnType("boolean")
+ .HasColumnName("is_deleted");
+
+ b.Property("Location")
+ .IsRequired()
+ .HasColumnType("geography(point)")
+ .HasColumnName("location");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("varchar(64)")
+ .HasColumnName("name");
+
+ b.Property("VehicleType")
+ .IsRequired()
+ .HasColumnType("varchar(16)")
+ .HasColumnName("vehicle_type");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CityId");
+
+ b.ToTable("addresses", (string)null);
+ });
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.Carriage", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int")
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("Capacity")
+ .HasColumnType("int")
+ .HasColumnName("capacity");
+
+ b.Property("HasOutlets")
+ .HasColumnType("boolean")
+ .HasColumnName("has_outlets");
+
+ b.Property("HasWiFi")
+ .HasColumnType("boolean")
+ .HasColumnName("has_wifi");
+
+ b.Property("IsDeleted")
+ .HasColumnType("boolean")
+ .HasColumnName("is_deleted");
+
+ b.Property("Number")
+ .HasColumnType("int")
+ .HasColumnName("number");
+
+ b.Property("Type")
+ .IsRequired()
+ .HasColumnType("varchar(16)")
+ .HasColumnName("type");
+
+ b.HasKey("Id");
+
+ b.ToTable("carriages", (string)null);
+ });
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.City", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int")
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("IsDeleted")
+ .HasColumnType("boolean")
+ .HasColumnName("is_deleted");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("varchar(64)")
+ .HasColumnName("name");
+
+ b.Property("RegionId")
+ .HasColumnType("int")
+ .HasColumnName("region_id");
+
+ b.HasKey("Id");
+
+ b.HasIndex("RegionId");
+
+ b.ToTable("cities", (string)null);
+ });
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.Company", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int")
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("ContactEmail")
+ .IsRequired()
+ .HasColumnType("varchar(256)")
+ .HasColumnName("contact_email");
+
+ b.Property("ContactPhoneNumber")
+ .IsRequired()
+ .HasColumnType("varchar(16)")
+ .HasColumnName("contact_phone_number");
+
+ b.Property("IsDeleted")
+ .HasColumnType("boolean")
+ .HasColumnName("is_deleted");
+
+ b.Property("LegalAddress")
+ .IsRequired()
+ .HasColumnType("varchar(256)")
+ .HasColumnName("legal_address");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("varchar(64)")
+ .HasColumnName("name");
+
+ b.HasKey("Id");
+
+ b.ToTable("companies", (string)null);
+ });
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.Country", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int")
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("IsDeleted")
+ .HasColumnType("boolean")
+ .HasColumnName("is_deleted");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("varchar(64)")
+ .HasColumnName("name");
+
+ b.HasKey("Id");
+
+ b.ToTable("countries", (string)null);
+ });
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.Employee", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int")
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("BirthDate")
+ .HasColumnType("date")
+ .HasColumnName("birth_date");
+
+ b.Property("EmployerCompanyId")
+ .HasColumnType("int")
+ .HasColumnName("employer_company_id");
+
+ b.Property("FisrtName")
+ .IsRequired()
+ .HasColumnType("varchar(32)")
+ .HasColumnName("first_name");
+
+ b.Property("IsDeleted")
+ .HasColumnType("boolean")
+ .HasColumnName("is_deleted");
+
+ b.Property("LastName")
+ .IsRequired()
+ .HasColumnType("varchar(32)")
+ .HasColumnName("last_name");
+
+ b.Property("Patronymic")
+ .IsRequired()
+ .HasColumnType("varchar(32)")
+ .HasColumnName("patronymic");
+
+ b.Property("Sex")
+ .IsRequired()
+ .HasColumnType("varchar(16)")
+ .HasColumnName("sex");
+
+ b.HasKey("Id");
+
+ b.HasIndex("EmployerCompanyId");
+
+ b.ToTable("employees", (string)null);
+ });
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.EmployeeDocument", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int")
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("EmployeeId")
+ .HasColumnType("int")
+ .HasColumnName("employee_id");
+
+ b.Property("Information")
+ .IsRequired()
+ .HasColumnType("varchar(256)")
+ .HasColumnName("information");
+
+ b.Property("IsDeleted")
+ .HasColumnType("boolean")
+ .HasColumnName("is_deleted");
+
+ b.Property("Type")
+ .IsRequired()
+ .HasColumnType("varchar(32)")
+ .HasColumnName("type");
+
+ b.HasKey("Id");
+
+ b.HasIndex("EmployeeId");
+
+ b.ToTable("employee_documents", (string)null);
+ });
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.Region", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int")
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("CountryId")
+ .HasColumnType("int")
+ .HasColumnName("country_id");
+
+ b.Property("IsDeleted")
+ .HasColumnType("boolean")
+ .HasColumnName("is_deleted");
+
+ b.Property("Name")
+ .IsRequired()
+ .HasColumnType("varchar(64)")
+ .HasColumnName("name");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CountryId");
+
+ b.ToTable("regions", (string)null);
+ });
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.Review", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int")
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("Comment")
+ .IsRequired()
+ .HasColumnType("varchar(128)")
+ .HasColumnName("comment");
+
+ b.Property("IsDeleted")
+ .HasColumnType("boolean")
+ .HasColumnName("is_deleted");
+
+ b.Property("PostDateTimeUtc")
+ .HasColumnType("timestamp")
+ .HasColumnName("post_timestamp_utc");
+
+ b.Property("Rating")
+ .HasColumnType("numeric(1,0)")
+ .HasColumnName("rating");
+
+ b.Property("UserId")
+ .HasColumnType("int")
+ .HasColumnName("user_id");
+
+ b.Property("VehicleEnrollmentId")
+ .HasColumnType("int")
+ .HasColumnName("vehicle_enrollment_id");
+
+ b.HasKey("Id");
+
+ b.HasIndex("UserId");
+
+ b.HasIndex("VehicleEnrollmentId");
+
+ b.ToTable("reviews", (string)null);
+ });
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.Route", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int")
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("IsDeleted")
+ .HasColumnType("boolean")
+ .HasColumnName("is_deleted");
+
+ b.HasKey("Id");
+
+ b.ToTable("routes", (string)null);
+ });
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.RouteAddress", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int")
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("AddressId")
+ .HasColumnType("int")
+ .HasColumnName("address_id");
+
+ b.Property("IsDeleted")
+ .HasColumnType("boolean")
+ .HasColumnName("is_deleted");
+
+ b.Property("Order")
+ .HasColumnType("int")
+ .HasColumnName("order");
+
+ b.Property("RouteId")
+ .HasColumnType("int")
+ .HasColumnName("route_id");
+
+ b.HasKey("Id");
+
+ b.HasIndex("AddressId");
+
+ b.HasIndex("RouteId");
+
+ b.ToTable("route_addresses", (string)null);
+ });
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.RouteAddressDetails", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int")
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("CostToNextAddress")
+ .HasColumnType("numeric(16,4)")
+ .HasColumnName("cost_to_next_address");
+
+ b.Property("CurrentAddressStopTime")
+ .HasColumnType("interval")
+ .HasColumnName("current_address_stop_time");
+
+ b.Property("IsDeleted")
+ .HasColumnType("boolean")
+ .HasColumnName("is_deleted");
+
+ b.Property("RouteAddressId")
+ .HasColumnType("int")
+ .HasColumnName("route_address_id");
+
+ b.Property("TimeToNextAddress")
+ .HasColumnType("interval")
+ .HasColumnName("time_to_next_address");
+
+ b.Property("VehicleEnrollmentId")
+ .HasColumnType("int")
+ .HasColumnName("vehicle_enrollment_id");
+
+ b.HasKey("Id");
+
+ b.HasIndex("RouteAddressId");
+
+ b.HasIndex("VehicleEnrollmentId");
+
+ b.ToTable("route_address_details", (string)null);
+ });
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.Ticket", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int")
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("IsDeleted")
+ .HasColumnType("boolean")
+ .HasColumnName("is_deleted");
+
+ b.Property("TicketGroupId")
+ .HasColumnType("int")
+ .HasColumnName("ticket_group_id");
+
+ b.Property("VehicleEnrollmentId")
+ .HasColumnType("int")
+ .HasColumnName("vehicle_enrollment_id");
+
+ b.HasKey("Id");
+
+ b.HasIndex("TicketGroupId");
+
+ b.HasIndex("VehicleEnrollmentId");
+
+ b.ToTable("tickets", (string)null);
+ });
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.TicketDocument", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int")
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("Information")
+ .IsRequired()
+ .HasColumnType("varchar(256)")
+ .HasColumnName("information");
+
+ b.Property("IsDeleted")
+ .HasColumnType("boolean")
+ .HasColumnName("is_deleted");
+
+ b.Property("TicketGroupId")
+ .HasColumnType("int")
+ .HasColumnName("ticket_group_id");
+
+ b.Property("Type")
+ .IsRequired()
+ .HasColumnType("varchar(32)")
+ .HasColumnName("type");
+
+ b.HasKey("Id");
+
+ b.ToTable("ticket_documents", (string)null);
+ });
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.TicketGroup", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int")
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("BuyerEmailAddress")
+ .IsRequired()
+ .HasColumnType("varchar(256)")
+ .HasColumnName("buyer_email");
+
+ b.Property("BuyerFirstName")
+ .IsRequired()
+ .HasColumnType("varchar(32)")
+ .HasColumnName("buyer_first_name");
+
+ b.Property("BuyerLastName")
+ .IsRequired()
+ .HasColumnType("varchar(32)")
+ .HasColumnName("buyer_last_name");
+
+ b.Property("BuyerPhoneNumber")
+ .IsRequired()
+ .HasColumnType("varchar(16)")
+ .HasColumnName("buyer_phone_number");
+
+ b.Property("IsDeleted")
+ .HasColumnType("boolean")
+ .HasColumnName("is_deleted");
+
+ b.Property("IsReturned")
+ .HasColumnType("boolean")
+ .HasColumnName("is_returned");
+
+ b.Property("PassengerBirthDate")
+ .HasColumnType("date")
+ .HasColumnName("passenger_birth_date");
+
+ b.Property("PassengerFirstName")
+ .IsRequired()
+ .HasColumnType("varchar(32)")
+ .HasColumnName("passenger_first_name");
+
+ b.Property("PassengerLastName")
+ .IsRequired()
+ .HasColumnType("varchar(32)")
+ .HasColumnName("passenger_last_name");
+
+ b.Property("PassengerPatronymic")
+ .IsRequired()
+ .HasColumnType("varchar(32)")
+ .HasColumnName("passenger_patronymic");
+
+ b.Property("PassengerSex")
+ .IsRequired()
+ .HasColumnType("varchar(16)")
+ .HasColumnName("passenger_sex");
+
+ b.Property("PurchaseDateTimeUtc")
+ .HasColumnType("timestamp")
+ .HasColumnName("purchase_timestamp_utc");
+
+ b.Property("TicketDocumentId")
+ .HasColumnType("int");
+
+ b.Property("UserId")
+ .HasColumnType("int")
+ .HasColumnName("user_id");
+
+ b.HasKey("Id");
+
+ b.HasIndex("TicketDocumentId")
+ .IsUnique();
+
+ b.HasIndex("UserId");
+
+ b.ToTable("ticket_groups", (string)null);
+ });
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.TrainCarriage", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int")
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("CarriageId")
+ .HasColumnType("int")
+ .HasColumnName("carriage_id");
+
+ b.Property("IsDeleted")
+ .HasColumnType("boolean")
+ .HasColumnName("is_deleted");
+
+ b.Property("TrainId")
+ .HasColumnType("int")
+ .HasColumnName("train_id");
+
+ b.HasKey("Id");
+
+ b.HasIndex("TrainId");
+
+ b.ToTable("train_carriages", (string)null);
+ });
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.User", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int")
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("IsDeleted")
+ .HasColumnType("boolean")
+ .HasColumnName("is_deleted");
+
+ b.HasKey("Id");
+
+ b.ToTable("users", (string)null);
+ });
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.Vehicle", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int")
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("CompanyId")
+ .HasColumnType("int")
+ .HasColumnName("company_id");
+
+ b.Property("IsDeleted")
+ .HasColumnType("boolean")
+ .HasColumnName("is_deleted");
+
+ b.HasKey("Id");
+
+ b.HasIndex("CompanyId");
+
+ b.ToTable("vehicles", (string)null);
+
+ b.UseTptMappingStrategy();
+ });
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.VehicleEnrollment", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int")
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("DepartureDateTimeUtc")
+ .HasColumnType("timestamp")
+ .HasColumnName("departure_timestamp_utc");
+
+ b.Property("IsDeleted")
+ .HasColumnType("boolean")
+ .HasColumnName("is_deleted");
+
+ b.Property("RouteId")
+ .HasColumnType("int")
+ .HasColumnName("route_id");
+
+ b.Property("VehicleId")
+ .HasColumnType("int")
+ .HasColumnName("vehicle_id");
+
+ b.HasKey("Id");
+
+ b.HasIndex("RouteId");
+
+ b.HasIndex("VehicleId");
+
+ b.ToTable("vehicle_enrollments", (string)null);
+ });
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.VehicleEnrollmentEmployee", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("int")
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("EmployeeId")
+ .HasColumnType("int")
+ .HasColumnName("employee_id");
+
+ b.Property("IsDeleted")
+ .HasColumnType("boolean")
+ .HasColumnName("is_deleted");
+
+ b.Property("VehicleEnrollmentId")
+ .HasColumnType("int")
+ .HasColumnName("vehicle_enrollment_id");
+
+ b.HasKey("Id");
+
+ b.HasIndex("EmployeeId");
+
+ b.HasIndex("VehicleEnrollmentId");
+
+ b.ToTable("vehicle_enrollment_employees", (string)null);
+ });
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.Aircraft", b =>
+ {
+ b.HasBaseType("AutobusApi.Domain.Entities.Vehicle");
+
+ b.Property("Capacity")
+ .HasColumnType("int")
+ .HasColumnName("capacity");
+
+ b.Property("HasMultimedia")
+ .HasColumnType("boolean")
+ .HasColumnName("has_multimedia");
+
+ b.Property("HasWiFi")
+ .HasColumnType("boolean")
+ .HasColumnName("has_wifi");
+
+ b.Property("Model")
+ .IsRequired()
+ .HasColumnType("varchar(64)")
+ .HasColumnName("model");
+
+ b.Property("Number")
+ .IsRequired()
+ .HasColumnType("varchar(8)")
+ .HasColumnName("number");
+
+ b.ToTable("aircrafts", (string)null);
+ });
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.Bus", b =>
+ {
+ b.HasBaseType("AutobusApi.Domain.Entities.Vehicle");
+
+ b.Property("Capacity")
+ .HasColumnType("int")
+ .HasColumnName("capacity");
+
+ b.Property("HasClimateControl")
+ .HasColumnType("boolean")
+ .HasColumnName("has_climate_control");
+
+ b.Property("HasMultimedia")
+ .HasColumnType("boolean")
+ .HasColumnName("has_multimedia");
+
+ b.Property("HasOutlets")
+ .HasColumnType("boolean")
+ .HasColumnName("has_outlets");
+
+ b.Property("HasWC")
+ .HasColumnType("boolean")
+ .HasColumnName("has_wc");
+
+ b.Property("HasWiFi")
+ .HasColumnType("boolean")
+ .HasColumnName("has_wifi");
+
+ b.Property("Model")
+ .IsRequired()
+ .HasColumnType("varchar(64)")
+ .HasColumnName("model");
+
+ b.Property("Number")
+ .IsRequired()
+ .HasColumnType("varchar(8)")
+ .HasColumnName("number");
+
+ b.ToTable("buses", (string)null);
+ });
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.Train", b =>
+ {
+ b.HasBaseType("AutobusApi.Domain.Entities.Vehicle");
+
+ b.Property("Number")
+ .IsRequired()
+ .HasColumnType("varchar(8)")
+ .HasColumnName("number");
+
+ b.ToTable("trains", (string)null);
+ });
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.Address", b =>
+ {
+ b.HasOne("AutobusApi.Domain.Entities.City", "City")
+ .WithMany("Addresses")
+ .HasForeignKey("CityId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_addresses_city_id");
+
+ b.Navigation("City");
+ });
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.City", b =>
+ {
+ b.HasOne("AutobusApi.Domain.Entities.Region", "Region")
+ .WithMany("Cities")
+ .HasForeignKey("RegionId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_cities_regions_regionId");
+
+ b.Navigation("Region");
+ });
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.Employee", b =>
+ {
+ b.HasOne("AutobusApi.Domain.Entities.Company", "EmployerCompany")
+ .WithMany("Employees")
+ .HasForeignKey("EmployerCompanyId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_employees_companies_employerCompanyId");
+
+ b.Navigation("EmployerCompany");
+ });
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.EmployeeDocument", b =>
+ {
+ b.HasOne("AutobusApi.Domain.Entities.Employee", "Employee")
+ .WithMany("Documents")
+ .HasForeignKey("EmployeeId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_employeeDocuments_employees_employeeId");
+
+ b.Navigation("Employee");
+ });
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.Region", b =>
+ {
+ b.HasOne("AutobusApi.Domain.Entities.Country", "Country")
+ .WithMany("Regions")
+ .HasForeignKey("CountryId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_regions_coutries_countryId");
+
+ b.Navigation("Country");
+ });
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.Review", b =>
+ {
+ b.HasOne("AutobusApi.Domain.Entities.User", "User")
+ .WithMany("Reviews")
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_reviews_users_userId");
+
+ b.HasOne("AutobusApi.Domain.Entities.VehicleEnrollment", "VehicleEnrollment")
+ .WithMany("Reviews")
+ .HasForeignKey("VehicleEnrollmentId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_reviews_vehicleEnrollments_vehicleEnrollmentId");
+
+ b.Navigation("User");
+
+ b.Navigation("VehicleEnrollment");
+ });
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.RouteAddress", b =>
+ {
+ b.HasOne("AutobusApi.Domain.Entities.Address", "Address")
+ .WithMany("RouteAddresses")
+ .HasForeignKey("AddressId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_routeAddresses_addresses_addressId");
+
+ b.HasOne("AutobusApi.Domain.Entities.Route", "Route")
+ .WithMany("RouteAddresses")
+ .HasForeignKey("RouteId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_routeAddresses_routes_routeId");
+
+ b.Navigation("Address");
+
+ b.Navigation("Route");
+ });
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.RouteAddressDetails", b =>
+ {
+ b.HasOne("AutobusApi.Domain.Entities.RouteAddress", "RouteAddress")
+ .WithMany("RouteAddressDetails")
+ .HasForeignKey("RouteAddressId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_routeAddressDetails_routeAddress_routeAddressId");
+
+ b.HasOne("AutobusApi.Domain.Entities.VehicleEnrollment", "VehicleEnrollment")
+ .WithMany("RouteAddressDetails")
+ .HasForeignKey("VehicleEnrollmentId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_routeAddressDetails_vehicleEnrollments_vehicleEnrollmentId");
+
+ b.Navigation("RouteAddress");
+
+ b.Navigation("VehicleEnrollment");
+ });
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.Ticket", b =>
+ {
+ b.HasOne("AutobusApi.Domain.Entities.TicketGroup", "TicketGroup")
+ .WithMany("Tickets")
+ .HasForeignKey("TicketGroupId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_tickets_ticketGroups_ticketGroupId");
+
+ b.HasOne("AutobusApi.Domain.Entities.VehicleEnrollment", "VehicleEnrollment")
+ .WithMany("Tickets")
+ .HasForeignKey("VehicleEnrollmentId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_tickets_vehicleEnrollments_vehicleEnrollmentId");
+
+ b.Navigation("TicketGroup");
+
+ b.Navigation("VehicleEnrollment");
+ });
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.TicketGroup", b =>
+ {
+ b.HasOne("AutobusApi.Domain.Entities.TicketDocument", "TicketDocument")
+ .WithOne("TicketGroup")
+ .HasForeignKey("AutobusApi.Domain.Entities.TicketGroup", "TicketDocumentId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_ticketGroups_ticketDocuments_ticketDocumentId");
+
+ b.HasOne("AutobusApi.Domain.Entities.User", "User")
+ .WithMany("TicketGroups")
+ .HasForeignKey("UserId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .HasConstraintName("fk_ticketGroups_users_userId");
+
+ b.Navigation("TicketDocument");
+
+ b.Navigation("User");
+ });
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.TrainCarriage", b =>
+ {
+ b.HasOne("AutobusApi.Domain.Entities.Carriage", "Carriage")
+ .WithMany("TrainCarriage")
+ .HasForeignKey("TrainId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_trainCarriages_trains_carriageId");
+
+ b.HasOne("AutobusApi.Domain.Entities.Train", "Train")
+ .WithMany("TrainCarriage")
+ .HasForeignKey("TrainId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_trainCarriages_trains_trainId");
+
+ b.Navigation("Carriage");
+
+ b.Navigation("Train");
+ });
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.Vehicle", b =>
+ {
+ b.HasOne("AutobusApi.Domain.Entities.Company", "Company")
+ .WithMany("Vehicles")
+ .HasForeignKey("CompanyId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_vehicles_companies_companyId");
+
+ b.Navigation("Company");
+ });
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.VehicleEnrollment", b =>
+ {
+ b.HasOne("AutobusApi.Domain.Entities.Route", "Route")
+ .WithMany("VehicleEnrollments")
+ .HasForeignKey("RouteId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_vehicleEnrollments_routes_routeId");
+
+ b.HasOne("AutobusApi.Domain.Entities.Vehicle", "Vehicle")
+ .WithMany("Enrollments")
+ .HasForeignKey("VehicleId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_vehicleEnrollments_vehicles_vehicleId");
+
+ b.Navigation("Route");
+
+ b.Navigation("Vehicle");
+ });
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.VehicleEnrollmentEmployee", b =>
+ {
+ b.HasOne("AutobusApi.Domain.Entities.Employee", "Employee")
+ .WithMany("Shifts")
+ .HasForeignKey("EmployeeId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_vehicleEnrollmentEmployees_employees_employeeId");
+
+ b.HasOne("AutobusApi.Domain.Entities.VehicleEnrollment", "VehicleEnrollment")
+ .WithMany("Crew")
+ .HasForeignKey("VehicleEnrollmentId")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_vehicleEnrollmentEmployees_vehicleEnrollments_vehicleEnrollmentId");
+
+ b.Navigation("Employee");
+
+ b.Navigation("VehicleEnrollment");
+ });
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.Aircraft", b =>
+ {
+ b.HasOne("AutobusApi.Domain.Entities.Vehicle", "Vehicle")
+ .WithOne()
+ .HasForeignKey("AutobusApi.Domain.Entities.Aircraft", "Id")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_aircrafts_vehicles_id");
+
+ b.Navigation("Vehicle");
+ });
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.Bus", b =>
+ {
+ b.HasOne("AutobusApi.Domain.Entities.Vehicle", "Vehicle")
+ .WithOne()
+ .HasForeignKey("AutobusApi.Domain.Entities.Bus", "Id")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_buses_vehicles_id");
+
+ b.Navigation("Vehicle");
+ });
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.Train", b =>
+ {
+ b.HasOne("AutobusApi.Domain.Entities.Vehicle", "Vehicle")
+ .WithOne()
+ .HasForeignKey("AutobusApi.Domain.Entities.Train", "Id")
+ .OnDelete(DeleteBehavior.Cascade)
+ .IsRequired()
+ .HasConstraintName("fk_trains_vehicles_id");
+
+ b.Navigation("Vehicle");
+ });
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.Address", b =>
+ {
+ b.Navigation("RouteAddresses");
+ });
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.Carriage", b =>
+ {
+ b.Navigation("TrainCarriage");
+ });
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.City", b =>
+ {
+ b.Navigation("Addresses");
+ });
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.Company", b =>
+ {
+ b.Navigation("Employees");
+
+ b.Navigation("Vehicles");
+ });
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.Country", b =>
+ {
+ b.Navigation("Regions");
+ });
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.Employee", b =>
+ {
+ b.Navigation("Documents");
+
+ b.Navigation("Shifts");
+ });
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.Region", b =>
+ {
+ b.Navigation("Cities");
+ });
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.Route", b =>
+ {
+ b.Navigation("RouteAddresses");
+
+ b.Navigation("VehicleEnrollments");
+ });
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.RouteAddress", b =>
+ {
+ b.Navigation("RouteAddressDetails");
+ });
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.TicketDocument", b =>
+ {
+ b.Navigation("TicketGroup")
+ .IsRequired();
+ });
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.TicketGroup", b =>
+ {
+ b.Navigation("Tickets");
+ });
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.User", b =>
+ {
+ b.Navigation("Reviews");
+
+ b.Navigation("TicketGroups");
+ });
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.Vehicle", b =>
+ {
+ b.Navigation("Enrollments");
+ });
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.VehicleEnrollment", b =>
+ {
+ b.Navigation("Crew");
+
+ b.Navigation("Reviews");
+
+ b.Navigation("RouteAddressDetails");
+
+ b.Navigation("Tickets");
+ });
+
+ modelBuilder.Entity("AutobusApi.Domain.Entities.Train", b =>
+ {
+ b.Navigation("TrainCarriage");
+ });
+#pragma warning restore 612, 618
+ }
+ }
+}
diff --git a/AutobusApi.Persistence/Migrations/20231101122211_initial_create.cs b/AutobusApi.Persistence/Migrations/20231101122211_initial_create.cs
new file mode 100644
index 0000000..2b98317
--- /dev/null
+++ b/AutobusApi.Persistence/Migrations/20231101122211_initial_create.cs
@@ -0,0 +1,722 @@
+using System;
+using Microsoft.EntityFrameworkCore.Migrations;
+using NetTopologySuite.Geometries;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+
+#nullable disable
+
+namespace AutobusApi.Persistence.Migrations
+{
+ ///
+ public partial class initial_create : Migration
+ {
+ ///
+ protected override void Up(MigrationBuilder migrationBuilder)
+ {
+ migrationBuilder.AlterDatabase()
+ .Annotation("Npgsql:PostgresExtension:postgis", ",,");
+
+ migrationBuilder.CreateTable(
+ name: "carriages",
+ columns: table => new
+ {
+ id = table.Column(type: "int", nullable: false)
+ .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
+ type = table.Column(type: "varchar(16)", nullable: false),
+ capacity = table.Column(type: "int", nullable: false),
+ number = table.Column(type: "int", nullable: false),
+ has_wifi = table.Column(type: "boolean", nullable: false),
+ has_outlets = table.Column(type: "boolean", nullable: false),
+ is_deleted = table.Column(type: "boolean", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_carriages", x => x.id);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "companies",
+ columns: table => new
+ {
+ id = table.Column(type: "int", nullable: false)
+ .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
+ name = table.Column(type: "varchar(64)", nullable: false),
+ legal_address = table.Column(type: "varchar(256)", nullable: false),
+ contact_email = table.Column(type: "varchar(256)", nullable: false),
+ contact_phone_number = table.Column(type: "varchar(16)", nullable: false),
+ is_deleted = table.Column(type: "boolean", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_companies", x => x.id);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "countries",
+ columns: table => new
+ {
+ id = table.Column(type: "int", nullable: false)
+ .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
+ name = table.Column(type: "varchar(64)", nullable: false),
+ is_deleted = table.Column(type: "boolean", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_countries", x => x.id);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "routes",
+ columns: table => new
+ {
+ id = table.Column(type: "int", nullable: false)
+ .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
+ is_deleted = table.Column(type: "boolean", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_routes", x => x.id);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "ticket_documents",
+ columns: table => new
+ {
+ id = table.Column(type: "int", nullable: false)
+ .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
+ type = table.Column(type: "varchar(32)", nullable: false),
+ information = table.Column(type: "varchar(256)", nullable: false),
+ ticket_group_id = table.Column(type: "int", nullable: false),
+ is_deleted = table.Column(type: "boolean", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_ticket_documents", x => x.id);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "users",
+ columns: table => new
+ {
+ id = table.Column(type: "int", nullable: false)
+ .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
+ is_deleted = table.Column(type: "boolean", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_users", x => x.id);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "employees",
+ columns: table => new
+ {
+ id = table.Column(type: "int", nullable: false)
+ .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
+ first_name = table.Column(type: "varchar(32)", nullable: false),
+ last_name = table.Column(type: "varchar(32)", nullable: false),
+ patronymic = table.Column(type: "varchar(32)", nullable: false),
+ sex = table.Column(type: "varchar(16)", nullable: false),
+ birth_date = table.Column(type: "date", nullable: false),
+ employer_company_id = table.Column(type: "int", nullable: false),
+ is_deleted = table.Column(type: "boolean", nullable: false)
+ },
+ constraints: table =>
+ {
+ table.PrimaryKey("PK_employees", x => x.id);
+ table.ForeignKey(
+ name: "fk_employees_companies_employerCompanyId",
+ column: x => x.employer_company_id,
+ principalTable: "companies",
+ principalColumn: "id",
+ onDelete: ReferentialAction.Cascade);
+ });
+
+ migrationBuilder.CreateTable(
+ name: "vehicles",
+ columns: table => new
+ {
+ id = table.Column(type: "int", nullable: false)
+ .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
+ company_id = table.Column