diff --git a/AutobusApi.Api/AutobusApi.Api.csproj b/AutobusApi.Api/AutobusApi.Api.csproj
index 29337ba..c67fb11 100644
--- a/AutobusApi.Api/AutobusApi.Api.csproj
+++ b/AutobusApi.Api/AutobusApi.Api.csproj
@@ -7,21 +7,20 @@
-
-
+
runtime; build; native; contentfiles; analyzers; buildtransitive
all
+
-
diff --git a/AutobusApi.Api/Controllers/BaseController.cs b/AutobusApi.Api/Controllers/BaseController.cs
new file mode 100644
index 0000000..39137b3
--- /dev/null
+++ b/AutobusApi.Api/Controllers/BaseController.cs
@@ -0,0 +1,12 @@
+using MediatR;
+using Microsoft.AspNetCore.Mvc;
+
+namespace AutobusApi.Api.Controllers;
+
+[ApiController]
+[Route("[controller]")]
+public class BaseController : ControllerBase
+{
+ private IMediator _mediator;
+ protected IMediator Mediator => _mediator ??= HttpContext.RequestServices.GetService();
+}
diff --git a/AutobusApi.Api/Controllers/IdentityController.cs b/AutobusApi.Api/Controllers/IdentityController.cs
new file mode 100644
index 0000000..efb2864
--- /dev/null
+++ b/AutobusApi.Api/Controllers/IdentityController.cs
@@ -0,0 +1,35 @@
+using AutobusApi.Application.Common.Models.Identity;
+using AutobusApi.Application.Identity.Commands.Register;
+using AutobusApi.Application.Identity.Commands.RenewAccessToken;
+using AutobusApi.Application.Identity.Commands.RevokeRefreshToken;
+using AutobusApi.Application.Identity.Queries.Login;
+using Microsoft.AspNetCore.Mvc;
+
+namespace AutobusApi.Api.Controllers;
+
+public class IdentityController : BaseController
+{
+ [HttpPost("register")]
+ public async Task Register([FromBody] RegisterCommand command, CancellationToken cancellationToken)
+ {
+ await Mediator.Send(command, cancellationToken);
+ }
+
+ [HttpPost("login")]
+ public async Task Login([FromBody] LoginQuery query, CancellationToken cancellationToken)
+ {
+ return await Mediator.Send(query, cancellationToken);
+ }
+
+ [HttpPost("renewAccessToken")]
+ public async Task RenewAccessToken([FromBody] RenewAccessTokenCommand command, CancellationToken cancellationToken)
+ {
+ return await Mediator.Send(command, cancellationToken);
+ }
+
+ [HttpPost("revokeRefreshToken")]
+ public async Task RevokeRefreshToken([FromBody] RevokeRefreshTokenCommand command, CancellationToken cancellationToken)
+ {
+ await Mediator.Send(command, cancellationToken);
+ }
+}
diff --git a/AutobusApi.Api/Middlewares/GlobalExceptionHandlerMiddleware.cs b/AutobusApi.Api/Middlewares/GlobalExceptionHandlerMiddleware.cs
new file mode 100644
index 0000000..9e67ff6
--- /dev/null
+++ b/AutobusApi.Api/Middlewares/GlobalExceptionHandlerMiddleware.cs
@@ -0,0 +1,129 @@
+using AutobusApi.Application.Common.Exceptions;
+using Microsoft.AspNetCore.Mvc;
+
+namespace AutobusApi.Api.Middlewares;
+
+public class GlobalExceptionHandlerMiddleware : IMiddleware
+{
+ private readonly Dictionary> _exceptionHandlers;
+
+ public GlobalExceptionHandlerMiddleware()
+ {
+ // Register known exception types and handlers.
+ _exceptionHandlers = new()
+ {
+ { typeof(ValidationException), HandleValidationException },
+ { typeof(RegistrationException), HandleRegistrationException },
+ { typeof(LoginException), HandleLoginException },
+ { typeof(RenewAccessTokenException), HandleRenewAccessTokenException },
+ { typeof(RevokeRefreshTokenException), HandleRevokeRefreshTokenException },
+ };
+ }
+
+ public async Task InvokeAsync(HttpContext context, RequestDelegate next)
+ {
+ try
+ {
+ await next(context);
+ }
+ catch (Exception exception)
+ {
+ var exceptionType = exception.GetType();
+
+ if (_exceptionHandlers.ContainsKey(exceptionType))
+ {
+ await _exceptionHandlers[exceptionType].Invoke(context, exception);
+ return;
+ }
+
+ await HandleUnhandledExceptionException(context, exception);
+ }
+ }
+
+ private async Task HandleValidationException(HttpContext context, Exception exception)
+ {
+ var ex = (ValidationException) exception;
+
+ context.Response.StatusCode = StatusCodes.Status400BadRequest;
+ context.Response.ContentType = "application/problem+json";
+
+ await context.Response.WriteAsJsonAsync(new HttpValidationProblemDetails(ex.Errors)
+ {
+ Status = StatusCodes.Status400BadRequest,
+ Type = "https://datatracker.ietf.org/doc/html/rfc7231#section-6.5.1",
+ Detail = "Check provided information."
+ });
+ }
+
+ private async Task HandleRegistrationException(HttpContext context, Exception exception)
+ {
+ context.Response.StatusCode = StatusCodes.Status400BadRequest;
+ context.Response.ContentType = "application/problem+json";
+
+ await context.Response.WriteAsJsonAsync(new ProblemDetails()
+ {
+ Status = StatusCodes.Status400BadRequest,
+ Type = "https://datatracker.ietf.org/doc/html/rfc7231#section-6.5.1",
+ Title = "Registration failed.",
+ Detail = "Check your credentials."
+ });
+ }
+
+ private async Task HandleLoginException(HttpContext context, Exception exception)
+ {
+ context.Response.StatusCode = StatusCodes.Status400BadRequest;
+ context.Response.ContentType = "application/problem+json";
+
+ await context.Response.WriteAsJsonAsync(new ProblemDetails()
+ {
+ Status = StatusCodes.Status400BadRequest,
+ Type = "https://datatracker.ietf.org/doc/html/rfc7231#section-6.5.1",
+ Title = "Login failed.",
+ Detail = "Provided email and/or password are invalid."
+ });
+ }
+
+ private async Task HandleRenewAccessTokenException(HttpContext context, Exception exception)
+ {
+ context.Response.StatusCode = StatusCodes.Status400BadRequest;
+ context.Response.ContentType = "application/problem+json";
+
+ await context.Response.WriteAsJsonAsync(new ProblemDetails()
+ {
+ Status = StatusCodes.Status400BadRequest,
+ Type = "https://datatracker.ietf.org/doc/html/rfc7231#section-6.5.1",
+ Title = "Access token renewal failed.",
+ Detail = "Check validity of your refresh token."
+ });
+ }
+
+ private async Task HandleRevokeRefreshTokenException(HttpContext context, Exception exception)
+ {
+ context.Response.StatusCode = StatusCodes.Status400BadRequest;
+ context.Response.ContentType = "application/problem+json";
+
+ await context.Response.WriteAsJsonAsync(new ProblemDetails()
+ {
+ Status = StatusCodes.Status400BadRequest,
+ Type = "https://datatracker.ietf.org/doc/html/rfc7231#section-6.5.1",
+ Title = "Refresh token revocation failed.",
+ Detail = "Check validity of your refresh token."
+ });
+ }
+
+ private async Task HandleUnhandledExceptionException(HttpContext context, Exception exception)
+ {
+ context.Response.StatusCode = StatusCodes.Status500InternalServerError;
+ context.Response.ContentType = "application/problem+json";
+
+ await context.Response.WriteAsJsonAsync(new ProblemDetails()
+ {
+ Status = StatusCodes.Status500InternalServerError,
+ Type = "https://datatracker.ietf.org/doc/html/rfc7231#section-6.6.1",
+ Title = "One or more internal server errors occured.",
+ Detail = "Report this error to service's support team.",
+ });
+
+ await Console.Error.WriteLineAsync(exception.StackTrace);
+ }
+}
diff --git a/AutobusApi.Api/Program.cs b/AutobusApi.Api/Program.cs
index 979fc04..7a14efe 100644
--- a/AutobusApi.Api/Program.cs
+++ b/AutobusApi.Api/Program.cs
@@ -1,16 +1,37 @@
-using AutoubsApi.Persistence.Contexts;
-using Microsoft.EntityFrameworkCore;
+using AutobusApi.Infrastructure;
+using AutobusApi.Application;
+using AutobusApi.Api.Middlewares;
+using AutoubsApi.Infrastructure.Data;
+using AutobusApi.Infrastructure.Identity;
var builder = WebApplication.CreateBuilder(args);
-builder.Services.AddDbContext(options =>
- options.UseNpgsql(
- builder.Configuration.GetConnectionString("DefaultConnection"),
- npgsqOptions => npgsqOptions.UseNetTopologySuite()
- ));
+builder.Services.AddInfrastructure(builder.Configuration);
+builder.Services.AddApplication();
+
+builder.Services.AddControllers();
+
+builder.Services.AddSwaggerGen();
+
+builder.Services.AddTransient();
var app = builder.Build();
+// Initialize database
+var scope = app.Services.CreateScope();
+var dbContext = scope.ServiceProvider.GetRequiredService();
+var identityDbContext = scope.ServiceProvider.GetRequiredService();
+DbInitializer.Initialize(dbContext, identityDbContext);
+app.UseAuthentication();
+
+app.MapControllers();
+
+app.UseSwagger();
+app.UseSwaggerUI();
+
+app.UseMiddleware();
app.Run();
+
+public partial class Program { }
diff --git a/AutobusApi.Api/appsettings.Development.json b/AutobusApi.Api/appsettings.Development.json
index 4b6d56e..7075fba 100644
--- a/AutobusApi.Api/appsettings.Development.json
+++ b/AutobusApi.Api/appsettings.Development.json
@@ -1,5 +1,12 @@
{
"ConnectionStrings": {
"DefaultConnection": "Host=10.0.0.20:5432;Database=autobus;Username=postgres;Password=12345678"
+ },
+ "Jwt": {
+ "Issuer": "",
+ "Audience": "",
+ "IssuerSigningKey": "a2c98dec80787a4e85ffb5bcbc24f7e4cc014d8a4fe43e9520480a50759164bc",
+ "AccessTokenValidityInMinutes": "5",
+ "RefreshTokenValidityInDays": "15",
}
}
diff --git a/AutobusApi.Application/AutobusApi.Application.csproj b/AutobusApi.Application/AutobusApi.Application.csproj
index 6db0075..b821f29 100644
--- a/AutobusApi.Application/AutobusApi.Application.csproj
+++ b/AutobusApi.Application/AutobusApi.Application.csproj
@@ -8,6 +8,16 @@
+
+ 12.0.1
+
+
+ 11.8.0
+
+
+
+ 7.0.13
+
diff --git a/AutobusApi.Application/Common/Behaviours/ValidationBehaviour.cs b/AutobusApi.Application/Common/Behaviours/ValidationBehaviour.cs
new file mode 100644
index 0000000..67f676c
--- /dev/null
+++ b/AutobusApi.Application/Common/Behaviours/ValidationBehaviour.cs
@@ -0,0 +1,43 @@
+using FluentValidation;
+using MediatR;
+using ValidationException = AutobusApi.Application.Common.Exceptions.ValidationException;
+
+namespace AutobusApi.Application.Common.Behaviours;
+
+public class ValidationBehaviour : IPipelineBehavior
+ where TRequest : notnull
+{
+ private readonly IEnumerable> _validators;
+
+ public ValidationBehaviour(IEnumerable> validators)
+ {
+ _validators = validators;
+ }
+
+ public async Task Handle(
+ TRequest request,
+ RequestHandlerDelegate next,
+ CancellationToken cancellationToken)
+ {
+ if (_validators.Any())
+ {
+ var context = new ValidationContext(request);
+
+ var validationResults = await Task.WhenAll(
+ _validators.Select(v =>
+ v.ValidateAsync(context, cancellationToken)));
+
+ var failures = validationResults
+ .Where(r => r.Errors.Any())
+ .SelectMany(r => r.Errors)
+ .ToList();
+
+ if (failures.Any())
+ {
+ throw new ValidationException(failures);
+ }
+ }
+
+ return await next();
+ }
+}
diff --git a/AutobusApi.Application/Common/Exceptions/LoginException.cs b/AutobusApi.Application/Common/Exceptions/LoginException.cs
new file mode 100644
index 0000000..af414c0
--- /dev/null
+++ b/AutobusApi.Application/Common/Exceptions/LoginException.cs
@@ -0,0 +1,7 @@
+namespace AutobusApi.Application.Common.Exceptions;
+
+public class LoginException : Exception
+{
+ public LoginException(string? message)
+ : base(message) { }
+}
diff --git a/AutobusApi.Application/Common/Exceptions/RegistrationException.cs b/AutobusApi.Application/Common/Exceptions/RegistrationException.cs
new file mode 100644
index 0000000..b3c1ab7
--- /dev/null
+++ b/AutobusApi.Application/Common/Exceptions/RegistrationException.cs
@@ -0,0 +1,7 @@
+namespace AutobusApi.Application.Common.Exceptions;
+
+public class RegistrationException : Exception
+{
+ public RegistrationException(string? message)
+ : base(message) { }
+}
diff --git a/AutobusApi.Application/Common/Exceptions/RenewAccessTokenException.cs b/AutobusApi.Application/Common/Exceptions/RenewAccessTokenException.cs
new file mode 100644
index 0000000..9721212
--- /dev/null
+++ b/AutobusApi.Application/Common/Exceptions/RenewAccessTokenException.cs
@@ -0,0 +1,7 @@
+namespace AutobusApi.Application.Common.Exceptions;
+
+public class RenewAccessTokenException : Exception
+{
+ public RenewAccessTokenException(string? errorMessage)
+ : base(errorMessage) { }
+}
diff --git a/AutobusApi.Application/Common/Exceptions/RevokeRefreshTokenException.cs b/AutobusApi.Application/Common/Exceptions/RevokeRefreshTokenException.cs
new file mode 100644
index 0000000..397cc3e
--- /dev/null
+++ b/AutobusApi.Application/Common/Exceptions/RevokeRefreshTokenException.cs
@@ -0,0 +1,7 @@
+namespace AutobusApi.Application.Common.Exceptions;
+
+public class RevokeRefreshTokenException : Exception
+{
+ public RevokeRefreshTokenException(string? errorMessage)
+ : base(errorMessage) { }
+}
diff --git a/AutobusApi.Application/Common/Exceptions/ValidationException.cs b/AutobusApi.Application/Common/Exceptions/ValidationException.cs
new file mode 100644
index 0000000..3332b93
--- /dev/null
+++ b/AutobusApi.Application/Common/Exceptions/ValidationException.cs
@@ -0,0 +1,22 @@
+using FluentValidation.Results;
+
+namespace AutobusApi.Application.Common.Exceptions;
+
+public class ValidationException : Exception
+{
+ public ValidationException()
+ : base("One or more validation failures have occurred.")
+ {
+ Errors = new Dictionary();
+ }
+
+ public ValidationException(IEnumerable failures)
+ : this()
+ {
+ Errors = failures
+ .GroupBy(f => f.PropertyName, f => f.ErrorMessage)
+ .ToDictionary(fg => fg.Key, fg => fg.ToArray());
+ }
+
+ public IDictionary Errors { get; }
+}
diff --git a/AutobusApi.Application/Common/Interfaces/IApplicationDbContext.cs b/AutobusApi.Application/Common/Interfaces/IApplicationDbContext.cs
new file mode 100644
index 0000000..fe2137e
--- /dev/null
+++ b/AutobusApi.Application/Common/Interfaces/IApplicationDbContext.cs
@@ -0,0 +1,55 @@
+using AutobusApi.Domain.Entities;
+using Microsoft.EntityFrameworkCore;
+
+namespace AutobusApi.Application.Common.Interfaces;
+
+public interface IApplicationDbContext
+{
+ DbSet Countries { get; }
+
+ DbSet Regions { get; }
+
+ DbSet Cities { get; }
+
+ DbSet Addresses { get; }
+
+ DbSet RouteAddresses { get; }
+
+ DbSet Routes { get; }
+
+ DbSet RouteAddressDetails { get; }
+
+ DbSet VehicleEnrollments { get; }
+
+ DbSet Vehicles { get; }
+
+ DbSet Buses { get; }
+
+ DbSet Aircraft { get; }
+
+ DbSet Trains { get; }
+
+ DbSet TrainCarriages { get; }
+
+ DbSet Carriages { get; }
+
+ DbSet Companies { get; }
+
+ DbSet Employees { get; }
+
+ DbSet EmployeeDocuments { get; }
+
+ DbSet vehicleEnrollmentEmployees { get; }
+
+ DbSet ApplicationUsers { get; }
+
+ DbSet TicketGroups { get; }
+
+ DbSet Tickets { get; }
+
+ DbSet TicketDocuments { get; }
+
+ DbSet Reviews { get; }
+
+ Task SaveChangesAsync(CancellationToken cancellationToken = default);
+}
diff --git a/AutobusApi.Application/Common/Interfaces/IIdentityService.cs b/AutobusApi.Application/Common/Interfaces/IIdentityService.cs
new file mode 100644
index 0000000..675f88c
--- /dev/null
+++ b/AutobusApi.Application/Common/Interfaces/IIdentityService.cs
@@ -0,0 +1,14 @@
+using AutobusApi.Application.Common.Models.Identity;
+
+namespace AutobusApi.Application.Common.Interfaces;
+
+public interface IIdentityService
+{
+ Task RegisterAsync(string email, string password, CancellationToken cancellationToken);
+
+ Task LoginAsync(string email, string password, CancellationToken cancellationToken);
+
+ Task RenewAccessTokenAsync(string refreshToken, CancellationToken cancellationToken);
+
+ Task RevokeRefreshTokenAsync(string refreshToken, CancellationToken cancellationToken);
+}
diff --git a/AutobusApi.Application/Common/Models/Identity/Roles.cs b/AutobusApi.Application/Common/Models/Identity/Roles.cs
new file mode 100644
index 0000000..1449951
--- /dev/null
+++ b/AutobusApi.Application/Common/Models/Identity/Roles.cs
@@ -0,0 +1,6 @@
+namespace AutobusApi.Application.Common.Models.Identity;
+
+public enum Roles
+{
+ User = 0,
+}
diff --git a/AutobusApi.Application/Common/Models/Identity/TokensModel.cs b/AutobusApi.Application/Common/Models/Identity/TokensModel.cs
new file mode 100644
index 0000000..dacc7a8
--- /dev/null
+++ b/AutobusApi.Application/Common/Models/Identity/TokensModel.cs
@@ -0,0 +1,16 @@
+namespace AutobusApi.Application.Common.Models.Identity;
+
+public class TokensModel
+{
+ public TokensModel(
+ string accessToken,
+ string refreshToken)
+ {
+ AccessToken = accessToken;
+ RefreshToken = refreshToken;
+ }
+
+ public string AccessToken { get; set; }
+
+ public string RefreshToken { get; set; }
+}
diff --git a/AutobusApi.Application/DependencyInjection.cs b/AutobusApi.Application/DependencyInjection.cs
new file mode 100644
index 0000000..7896730
--- /dev/null
+++ b/AutobusApi.Application/DependencyInjection.cs
@@ -0,0 +1,23 @@
+using System.Reflection;
+using AutobusApi.Application.Common.Behaviours;
+using FluentValidation;
+using MediatR;
+using Microsoft.Extensions.DependencyInjection;
+
+namespace AutobusApi.Application;
+
+public static class DependencyInjection
+{
+ public static IServiceCollection AddApplication(this IServiceCollection services)
+ {
+ services.AddValidatorsFromAssembly(Assembly.GetExecutingAssembly());
+
+ services.AddMediatR(configuration =>
+ {
+ configuration.RegisterServicesFromAssembly(Assembly.GetExecutingAssembly());
+ configuration.AddBehavior(typeof(IPipelineBehavior<,>), typeof(ValidationBehaviour<,>));
+ });
+
+ return services;
+ }
+}
diff --git a/AutobusApi.Application/Identity/Commands/Register/RegisterCommand.cs b/AutobusApi.Application/Identity/Commands/Register/RegisterCommand.cs
new file mode 100644
index 0000000..9d054fd
--- /dev/null
+++ b/AutobusApi.Application/Identity/Commands/Register/RegisterCommand.cs
@@ -0,0 +1,10 @@
+using MediatR;
+
+namespace AutobusApi.Application.Identity.Commands.Register;
+
+public record RegisterCommand : IRequest
+{
+ public required string Email { get; set; }
+
+ public required string Password { get; set; }
+}
diff --git a/AutobusApi.Application/Identity/Commands/Register/RegisterCommandHandler.cs b/AutobusApi.Application/Identity/Commands/Register/RegisterCommandHandler.cs
new file mode 100644
index 0000000..ab6414b
--- /dev/null
+++ b/AutobusApi.Application/Identity/Commands/Register/RegisterCommandHandler.cs
@@ -0,0 +1,21 @@
+using AutobusApi.Application.Common.Interfaces;
+using MediatR;
+
+namespace AutobusApi.Application.Identity.Commands.Register;
+
+public class RegisterCommandHandler : IRequestHandler
+{
+ private readonly IIdentityService _identityService;
+
+ public RegisterCommandHandler(IIdentityService identityService)
+ {
+ _identityService = identityService;
+ }
+
+ public async Task Handle(
+ RegisterCommand command,
+ CancellationToken cancellationToken)
+ {
+ await _identityService.RegisterAsync(command.Email, command.Password, cancellationToken);
+ }
+}
diff --git a/AutobusApi.Application/Identity/Commands/Register/RegisterCommandValidator.cs b/AutobusApi.Application/Identity/Commands/Register/RegisterCommandValidator.cs
new file mode 100644
index 0000000..ec3171a
--- /dev/null
+++ b/AutobusApi.Application/Identity/Commands/Register/RegisterCommandValidator.cs
@@ -0,0 +1,22 @@
+using FluentValidation;
+
+namespace AutobusApi.Application.Identity.Commands.Register;
+
+public class RegisterCommandValidator : AbstractValidator
+{
+ public RegisterCommandValidator()
+ {
+ RuleFor(v => v.Email)
+ .NotEmpty().WithMessage("Email address is required.")
+ .Matches(@"\b[\w\.-]+@[\w\.-]+\.\w{2,4}\b").WithMessage("Email address is invalid.");
+
+ RuleFor(v => v.Password)
+ .NotEmpty().WithMessage("Password is required.")
+ .MinimumLength(8).WithMessage("Password must be at least 8 characters long.")
+ .MaximumLength(64).WithMessage("Password must be at most 64 characters long.")
+ .Matches(@"(?=.*[A-Z]).*").WithMessage("Password must contain at least one uppercase letter.")
+ .Matches(@"(?=.*[a-z]).*").WithMessage("Password must contain at least one lowercase letter.")
+ .Matches(@"(?=.*[\d]).*").WithMessage("Password must contain at least one digit.")
+ .Matches(@"(?=.*[!@#$%^&*()]).*").WithMessage("Password must contain at least one of the following special charactters: !@#$%^&*().");
+ }
+}
diff --git a/AutobusApi.Application/Identity/Commands/RenewAccessToken/RenewAccessTokenCommand.cs b/AutobusApi.Application/Identity/Commands/RenewAccessToken/RenewAccessTokenCommand.cs
new file mode 100644
index 0000000..8ff3b62
--- /dev/null
+++ b/AutobusApi.Application/Identity/Commands/RenewAccessToken/RenewAccessTokenCommand.cs
@@ -0,0 +1,9 @@
+using AutobusApi.Application.Common.Models.Identity;
+using MediatR;
+
+namespace AutobusApi.Application.Identity.Commands.RenewAccessToken;
+
+public record RenewAccessTokenCommand : IRequest
+{
+ public required string RefreshToken { get; set; }
+}
diff --git a/AutobusApi.Application/Identity/Commands/RenewAccessToken/RenewAccessTokenCommandHandler.cs b/AutobusApi.Application/Identity/Commands/RenewAccessToken/RenewAccessTokenCommandHandler.cs
new file mode 100644
index 0000000..c24c400
--- /dev/null
+++ b/AutobusApi.Application/Identity/Commands/RenewAccessToken/RenewAccessTokenCommandHandler.cs
@@ -0,0 +1,22 @@
+using AutobusApi.Application.Common.Interfaces;
+using AutobusApi.Application.Common.Models.Identity;
+using MediatR;
+
+namespace AutobusApi.Application.Identity.Commands.RenewAccessToken;
+
+public class RenewAccessTokenCommandHandler : IRequestHandler
+{
+ private readonly IIdentityService _identityService;
+
+ public RenewAccessTokenCommandHandler(IIdentityService identityService)
+ {
+ _identityService = identityService;
+ }
+
+ public async Task Handle(
+ RenewAccessTokenCommand command,
+ CancellationToken cancellationToken)
+ {
+ return await _identityService.RenewAccessTokenAsync(command.RefreshToken, cancellationToken);
+ }
+}
diff --git a/AutobusApi.Application/Identity/Commands/RenewAccessToken/RenewAccessTokenCommandValidator.cs b/AutobusApi.Application/Identity/Commands/RenewAccessToken/RenewAccessTokenCommandValidator.cs
new file mode 100644
index 0000000..226f846
--- /dev/null
+++ b/AutobusApi.Application/Identity/Commands/RenewAccessToken/RenewAccessTokenCommandValidator.cs
@@ -0,0 +1,12 @@
+using FluentValidation;
+
+namespace AutobusApi.Application.Identity.Commands.RenewAccessToken;
+
+public class RenewAccessTokenCommandValidator : AbstractValidator
+{
+ public RenewAccessTokenCommandValidator()
+ {
+ RuleFor(v => v.RefreshToken)
+ .NotEmpty();
+ }
+}
diff --git a/AutobusApi.Application/Identity/Commands/RevokeRefreshToken/RevokeRefreshTokenCommand.cs b/AutobusApi.Application/Identity/Commands/RevokeRefreshToken/RevokeRefreshTokenCommand.cs
new file mode 100644
index 0000000..20ce4e0
--- /dev/null
+++ b/AutobusApi.Application/Identity/Commands/RevokeRefreshToken/RevokeRefreshTokenCommand.cs
@@ -0,0 +1,8 @@
+using MediatR;
+
+namespace AutobusApi.Application.Identity.Commands.RevokeRefreshToken;
+
+public record RevokeRefreshTokenCommand : IRequest
+{
+ public required string RefreshToken { get; set; }
+}
diff --git a/AutobusApi.Application/Identity/Commands/RevokeRefreshToken/RevokeRefreshTokenCommandHandler.cs b/AutobusApi.Application/Identity/Commands/RevokeRefreshToken/RevokeRefreshTokenCommandHandler.cs
new file mode 100644
index 0000000..dfa9915
--- /dev/null
+++ b/AutobusApi.Application/Identity/Commands/RevokeRefreshToken/RevokeRefreshTokenCommandHandler.cs
@@ -0,0 +1,21 @@
+using AutobusApi.Application.Common.Interfaces;
+using MediatR;
+
+namespace AutobusApi.Application.Identity.Commands.RevokeRefreshToken;
+
+public class RevokeRefreshTokenCommandHandler : IRequestHandler
+{
+ private readonly IIdentityService _identityService;
+
+ public RevokeRefreshTokenCommandHandler(IIdentityService identityService)
+ {
+ _identityService = identityService;
+ }
+
+ public async Task Handle(
+ RevokeRefreshTokenCommand command,
+ CancellationToken cancellationToken)
+ {
+ await _identityService.RevokeRefreshTokenAsync(command.RefreshToken, cancellationToken);
+ }
+}
diff --git a/AutobusApi.Application/Identity/Commands/RevokeRefreshToken/RevokeRefreshTokenCommandValidator.cs b/AutobusApi.Application/Identity/Commands/RevokeRefreshToken/RevokeRefreshTokenCommandValidator.cs
new file mode 100644
index 0000000..3e580dd
--- /dev/null
+++ b/AutobusApi.Application/Identity/Commands/RevokeRefreshToken/RevokeRefreshTokenCommandValidator.cs
@@ -0,0 +1,12 @@
+using FluentValidation;
+
+namespace AutobusApi.Application.Identity.Commands.RevokeRefreshToken;
+
+public class RevokeRefreshTokenCommandValidator : AbstractValidator
+{
+ public RevokeRefreshTokenCommandValidator()
+ {
+ RuleFor(v => v.RefreshToken)
+ .NotEmpty();
+ }
+}
diff --git a/AutobusApi.Application/Identity/Queries/Login/LoginQuery.cs b/AutobusApi.Application/Identity/Queries/Login/LoginQuery.cs
new file mode 100644
index 0000000..79dcfb5
--- /dev/null
+++ b/AutobusApi.Application/Identity/Queries/Login/LoginQuery.cs
@@ -0,0 +1,11 @@
+using AutobusApi.Application.Common.Models.Identity;
+using MediatR;
+
+namespace AutobusApi.Application.Identity.Queries.Login;
+
+public record LoginQuery : IRequest
+{
+ public required string Email { get; set; }
+
+ public required string Password { get; set; }
+}
diff --git a/AutobusApi.Application/Identity/Queries/Login/LoginQueryHandler.cs b/AutobusApi.Application/Identity/Queries/Login/LoginQueryHandler.cs
new file mode 100644
index 0000000..09638da
--- /dev/null
+++ b/AutobusApi.Application/Identity/Queries/Login/LoginQueryHandler.cs
@@ -0,0 +1,22 @@
+using AutobusApi.Application.Common.Interfaces;
+using AutobusApi.Application.Common.Models.Identity;
+using MediatR;
+
+namespace AutobusApi.Application.Identity.Queries.Login;
+
+public class LoginQueryHandler : IRequestHandler
+{
+ private readonly IIdentityService _identityService;
+
+ public LoginQueryHandler(IIdentityService identityService)
+ {
+ _identityService = identityService;
+ }
+
+ public async Task Handle(
+ LoginQuery query,
+ CancellationToken cancellationToken)
+ {
+ return await _identityService.LoginAsync(query.Email, query.Password, cancellationToken);
+ }
+}
diff --git a/AutobusApi.Application/Identity/Queries/Login/LoginQueryValidator.cs b/AutobusApi.Application/Identity/Queries/Login/LoginQueryValidator.cs
new file mode 100644
index 0000000..06560d5
--- /dev/null
+++ b/AutobusApi.Application/Identity/Queries/Login/LoginQueryValidator.cs
@@ -0,0 +1,16 @@
+using FluentValidation;
+
+namespace AutobusApi.Application.Identity.Queries.Login;
+
+public class LoginQueryValidator : AbstractValidator
+{
+ public LoginQueryValidator()
+ {
+ RuleFor(v => v.Email)
+ .NotEmpty().WithMessage("Email address is required.")
+ .EmailAddress().WithMessage("Email address is invalid.");
+
+ RuleFor(v => v.Password)
+ .NotEmpty().WithMessage("Password is required.");
+ }
+}
diff --git a/AutobusApi.Domain/Entities/Address.cs b/AutobusApi.Domain/Entities/Address.cs
index f2594c1..0e7fbdf 100644
--- a/AutobusApi.Domain/Entities/Address.cs
+++ b/AutobusApi.Domain/Entities/Address.cs
@@ -6,15 +6,15 @@ namespace AutobusApi.Domain.Entities;
public class Address : EntityBase
{
- public required string Name { get; set; }
+ public string Name { get; set; } = null!;
- public required ICoordinates Location { get; set; }
+ public ICoordinates Location { get; set; } = null!;
- public required VehicleType VehicleType { get; set; }
+ public VehicleType VehicleType { get; set; }
public ICollection RouteAddresses { get; set; } = null!;
- public required int CityId { get; set; }
+ public int CityId { get; set; }
public City City { get; set; } = null!;
}
diff --git a/AutobusApi.Domain/Entities/Aircraft.cs b/AutobusApi.Domain/Entities/Aircraft.cs
index 5148393..520dd59 100644
--- a/AutobusApi.Domain/Entities/Aircraft.cs
+++ b/AutobusApi.Domain/Entities/Aircraft.cs
@@ -4,13 +4,13 @@ public class Aircraft : Vehicle
{
public Vehicle Vehicle { get; set; } = null!;
- public required string Number { get; set; }
+ public string Number { get; set; } = null!;
- public required string Model { get; set; }
+ public string Model { get; set; } = null!;
- public required int Capacity { get; set; }
+ public int Capacity { get; set; }
- public required bool HasWiFi { get; set; }
+ public bool HasWiFi { get; set; }
- public required bool HasMultimedia { get; set; }
+ public bool HasMultimedia { get; set; }
}
diff --git a/AutobusApi.Domain/Entities/Bus.cs b/AutobusApi.Domain/Entities/Bus.cs
index 3538c26..7075469 100644
--- a/AutobusApi.Domain/Entities/Bus.cs
+++ b/AutobusApi.Domain/Entities/Bus.cs
@@ -4,19 +4,19 @@ public class Bus : Vehicle
{
public Vehicle Vehicle { get; set; } = null!;
- public required string Number { get; set; }
+ public string Number { get; set; } = null!;
- public required string Model { get; set; }
+ public string Model { get; set; } = null!;
- public required int Capacity { get; set; }
+ public int Capacity { get; set; }
- public required bool HasClimateControl { get; set; }
+ public bool HasClimateControl { get; set; }
- public required bool HasWC { get; set; }
+ public bool HasWC { get; set; }
- public required bool HasWiFi { get; set; }
+ public bool HasWiFi { get; set; }
- public required bool HasMultimedia { get; set; }
+ public bool HasMultimedia { get; set; }
- public required bool HasOutlets { get; set; }
+ public bool HasOutlets { get; set; }
}
diff --git a/AutobusApi.Domain/Entities/Carriage.cs b/AutobusApi.Domain/Entities/Carriage.cs
index d737a48..e1d1dcc 100644
--- a/AutobusApi.Domain/Entities/Carriage.cs
+++ b/AutobusApi.Domain/Entities/Carriage.cs
@@ -5,15 +5,15 @@ namespace AutobusApi.Domain.Entities;
public class Carriage : EntityBase
{
- public required CarriageType Type { get; set; }
+ public CarriageType Type { get; set; }
- public required int Capacity { get; set; }
+ public int Capacity { get; set; }
- public required int Number { get; set; }
+ public int Number { get; set; }
- public required bool HasWiFi { get; set; }
+ public bool HasWiFi { get; set; }
- public required bool HasOutlets { get; set; }
+ public bool HasOutlets { get; set; }
public ICollection TrainCarriage { get; set; } = null!;
}
diff --git a/AutobusApi.Domain/Entities/City.cs b/AutobusApi.Domain/Entities/City.cs
index ac50496..c7d5bb6 100644
--- a/AutobusApi.Domain/Entities/City.cs
+++ b/AutobusApi.Domain/Entities/City.cs
@@ -4,11 +4,11 @@ namespace AutobusApi.Domain.Entities;
public class City : EntityBase
{
- public required string Name { get; set; }
+ public string Name { get; set; } = null!;
public ICollection Addresses { get; set; } = null!;
- public required int RegionId { get; set; }
+ public int RegionId { get; set; }
public Region Region { get; set; } = null!;
}
diff --git a/AutobusApi.Domain/Entities/Company.cs b/AutobusApi.Domain/Entities/Company.cs
index 1ff4d97..3623f04 100644
--- a/AutobusApi.Domain/Entities/Company.cs
+++ b/AutobusApi.Domain/Entities/Company.cs
@@ -4,13 +4,13 @@ namespace AutobusApi.Domain.Entities;
public class Company : EntityBase
{
- public required string Name { get; set; }
+ public string Name { get; set; } = null!;
- public required string LegalAddress { get; set; }
+ public string LegalAddress { get; set; } = null!;
- public required string ContactEmail { get; set; }
+ public string ContactEmail { get; set; } = null!;
- public required string ContactPhoneNumber { get; set; }
+ public string ContactPhoneNumber { get; set; } = null!;
public ICollection Vehicles { get; set; } = null!;
diff --git a/AutobusApi.Domain/Entities/Country.cs b/AutobusApi.Domain/Entities/Country.cs
index ddb860e..2b320cf 100644
--- a/AutobusApi.Domain/Entities/Country.cs
+++ b/AutobusApi.Domain/Entities/Country.cs
@@ -4,7 +4,7 @@ namespace AutobusApi.Domain.Entities;
public class Country : EntityBase
{
- public required string Name { get; set; }
+ public string Name { get; set; } = null!;
public ICollection Regions { get; set; } = null!;
}
diff --git a/AutobusApi.Domain/Entities/Employee.cs b/AutobusApi.Domain/Entities/Employee.cs
index 6e32101..e2f738e 100644
--- a/AutobusApi.Domain/Entities/Employee.cs
+++ b/AutobusApi.Domain/Entities/Employee.cs
@@ -5,17 +5,19 @@ namespace AutobusApi.Domain.Entities;
public class Employee : EntityBase
{
- public required string FisrtName { get; set; }
+ public string FisrtName { get; set; } = null!;
- public required string LastName { get; set; }
+ public string LastName { get; set; } = null!;
- public required string Patronymic { get; set; }
+ public string Patronymic { get; set; } = null!;
- public required Sex Sex { get; set; }
+ public Sex Sex { get; set; }
- public required DateOnly BirthDate { get; set; }
+ public DateOnly BirthDate { get; set; }
- public required int EmployerCompanyId { get; set; }
+ public int IdentityId { get; set; }
+
+ public int EmployerCompanyId { get; set; }
public Company EmployerCompany { get; set; } = null!;
diff --git a/AutobusApi.Domain/Entities/EmployeeDocument.cs b/AutobusApi.Domain/Entities/EmployeeDocument.cs
index 2fda8e5..d5c50dd 100644
--- a/AutobusApi.Domain/Entities/EmployeeDocument.cs
+++ b/AutobusApi.Domain/Entities/EmployeeDocument.cs
@@ -5,11 +5,11 @@ namespace AutobusApi.Domain.Entities;
public class EmployeeDocument : EntityBase
{
- public required EmployeeDocumentType Type { get; set; }
+ public EmployeeDocumentType Type { get; set; }
- public required string Information { get; set; }
+ public string Information { get; set; } = null!;
- public required int EmployeeId { get; set; }
+ public int EmployeeId { get; set; }
public Employee Employee { get; set; } = null!;
}
diff --git a/AutobusApi.Domain/Entities/Region.cs b/AutobusApi.Domain/Entities/Region.cs
index 6fc3d39..b0d7ed1 100644
--- a/AutobusApi.Domain/Entities/Region.cs
+++ b/AutobusApi.Domain/Entities/Region.cs
@@ -4,11 +4,11 @@ namespace AutobusApi.Domain.Entities;
public class Region : EntityBase
{
- public required string Name { get; set; }
+ public string Name { get; set; } = null!;
public ICollection Cities { get; set; } = null!;
- public required int CountryId { get; set; }
+ public int CountryId { get; set; }
public Country Country { get; set; } = null!;
}
diff --git a/AutobusApi.Domain/Entities/Review.cs b/AutobusApi.Domain/Entities/Review.cs
index 485eace..4fa27c2 100644
--- a/AutobusApi.Domain/Entities/Review.cs
+++ b/AutobusApi.Domain/Entities/Review.cs
@@ -4,17 +4,17 @@ namespace AutobusApi.Domain.Entities;
public class Review : EntityBase
{
- public required int Rating { get; set; }
+ public int Rating { get; set; }
- public required string? Comment { get; set; }
+ public string? Comment { get; set; }
- public required DateTime PostDateTimeUtc { get; set; }
+ public DateTime PostDateTimeUtc { get; set; }
- public required int UserId { get; set; }
+ public int UserId { get; set; }
public User User { get; set; } = null!;
- public required int VehicleEnrollmentId { get; set; }
+ public int VehicleEnrollmentId { get; set; }
public VehicleEnrollment VehicleEnrollment { get; set; } = null!;
}
diff --git a/AutobusApi.Domain/Entities/RouteAddress.cs b/AutobusApi.Domain/Entities/RouteAddress.cs
index 50b3bbe..344069f 100644
--- a/AutobusApi.Domain/Entities/RouteAddress.cs
+++ b/AutobusApi.Domain/Entities/RouteAddress.cs
@@ -4,13 +4,13 @@ namespace AutobusApi.Domain.Entities;
public class RouteAddress : EntityBase
{
- public required int Order { get; set; }
+ public int Order { get; set; }
- public required int AddressId { get; set; }
+ public int AddressId { get; set; }
public Address Address { get; set; } = null!;
- public required int RouteId { get; set; }
+ public int RouteId { get; set; }
public Route Route { get; set; } = null!;
diff --git a/AutobusApi.Domain/Entities/RouteAddressDetails.cs b/AutobusApi.Domain/Entities/RouteAddressDetails.cs
index bcc73a8..49ba4ab 100644
--- a/AutobusApi.Domain/Entities/RouteAddressDetails.cs
+++ b/AutobusApi.Domain/Entities/RouteAddressDetails.cs
@@ -4,17 +4,17 @@ namespace AutobusApi.Domain.Entities;
public class RouteAddressDetails : EntityBase
{
- public required TimeSpan TimeToNextAddress { get; set; }
+ public TimeSpan TimeToNextAddress { get; set; }
- public required double CostToNextAddress { get; set; }
+ public double CostToNextAddress { get; set; }
- public required TimeSpan CurrentAddressStopTime { get; set; }
+ public TimeSpan CurrentAddressStopTime { get; set; }
- public required int RouteAddressId { get; set; }
+ public int RouteAddressId { get; set; }
public RouteAddress RouteAddress { get; set; } = null!;
- public required int VehicleEnrollmentId { get; set; }
+ public int VehicleEnrollmentId { get; set; }
public VehicleEnrollment VehicleEnrollment { get; set; } = null!;
}
diff --git a/AutobusApi.Domain/Entities/Ticket.cs b/AutobusApi.Domain/Entities/Ticket.cs
index 03e7017..0c09e71 100644
--- a/AutobusApi.Domain/Entities/Ticket.cs
+++ b/AutobusApi.Domain/Entities/Ticket.cs
@@ -4,11 +4,11 @@ namespace AutobusApi.Domain.Entities;
public class Ticket : EntityBase
{
- public required int TicketGroupId { get; set; }
+ public int TicketGroupId { get; set; }
public TicketGroup TicketGroup { get; set; } = null!;
- public required int VehicleEnrollmentId { get; set; }
+ public int VehicleEnrollmentId { get; set; }
public VehicleEnrollment VehicleEnrollment { get; set; } = null!;
}
diff --git a/AutobusApi.Domain/Entities/TicketDocument.cs b/AutobusApi.Domain/Entities/TicketDocument.cs
index 9500602..f1c4bbf 100644
--- a/AutobusApi.Domain/Entities/TicketDocument.cs
+++ b/AutobusApi.Domain/Entities/TicketDocument.cs
@@ -5,11 +5,11 @@ namespace AutobusApi.Domain.Entities;
public class TicketDocument : EntityBase
{
- public required TicketDocumentType Type { get; set; }
+ public TicketDocumentType Type { get; set; }
- public required string Information { get; set; }
+ public string Information { get; set; } = null!;
- public required int TicketGroupId { get; set; }
+ public int TicketGroupId { get; set; }
public TicketGroup TicketGroup { get; set; } = null!;
}
diff --git a/AutobusApi.Domain/Entities/TicketGroup.cs b/AutobusApi.Domain/Entities/TicketGroup.cs
index 00125b6..71cf18b 100644
--- a/AutobusApi.Domain/Entities/TicketGroup.cs
+++ b/AutobusApi.Domain/Entities/TicketGroup.cs
@@ -5,33 +5,33 @@ namespace AutobusApi.Domain.Entities;
public class TicketGroup : EntityBase
{
- public required string BuyerFirstName { get; set; }
+ public string BuyerFirstName { get; set; } = null!;
- public required string BuyerLastName { get; set; }
+ public string BuyerLastName { get; set; } = null!;
- public required string BuyerPhoneNumber { get; set; }
+ public string BuyerPhoneNumber { get; set; } = null!;
- public required string BuyerEmailAddress { get; set; }
+ public string BuyerEmailAddress { get; set; } = null!;
- public required string PassengerFirstName { get; set; }
+ public string PassengerFirstName { get; set; } = null!;
- public required string PassengerLastName { get; set; }
+ public string PassengerLastName { get; set; } = null!;
- public required string PassengerPatronymic { get; set; }
+ public string PassengerPatronymic { get; set; } = null!;
- public required Sex PassengerSex { get; set; }
+ public Sex PassengerSex { get; set; }
- public required DateOnly PassengerBirthDate { get; set; }
+ public DateOnly PassengerBirthDate { get; set; }
- public required DateTime PurchaseDateTimeUtc { get; set; }
+ public DateTime PurchaseDateTimeUtc { get; set; }
- public required bool IsReturned { get; set; }
+ public bool IsReturned { get; set; }
public int? UserId { get; set; }
public User? User { get; set; }
- public required int TicketDocumentId { get; set; }
+ public int TicketDocumentId { get; set; }
public TicketDocument TicketDocument { get; set; } = null!;
diff --git a/AutobusApi.Domain/Entities/Train.cs b/AutobusApi.Domain/Entities/Train.cs
index f3a07ec..427dc01 100644
--- a/AutobusApi.Domain/Entities/Train.cs
+++ b/AutobusApi.Domain/Entities/Train.cs
@@ -4,7 +4,7 @@ public class Train : Vehicle
{
public Vehicle Vehicle { get; set; } = null!;
- public required string Number { get; set; }
+ public string Number { get; set; } = null!;
public ICollection TrainCarriage { get; set; } = null!;
}
diff --git a/AutobusApi.Domain/Entities/TrainCarriage.cs b/AutobusApi.Domain/Entities/TrainCarriage.cs
index cc41180..a33fd83 100644
--- a/AutobusApi.Domain/Entities/TrainCarriage.cs
+++ b/AutobusApi.Domain/Entities/TrainCarriage.cs
@@ -4,11 +4,11 @@ namespace AutobusApi.Domain.Entities;
public class TrainCarriage : EntityBase
{
- public required int TrainId { get; set; }
+ public int TrainId { get; set; }
public Train Train { get; set; } = null!;
- public required int CarriageId { get; set; }
+ public int CarriageId { get; set; }
public Carriage Carriage { get; set; } = null!;
}
diff --git a/AutobusApi.Domain/Entities/User.cs b/AutobusApi.Domain/Entities/User.cs
index 858f56f..9b13e29 100644
--- a/AutobusApi.Domain/Entities/User.cs
+++ b/AutobusApi.Domain/Entities/User.cs
@@ -4,6 +4,8 @@ namespace AutobusApi.Domain.Entities;
public class User : EntityBase
{
+ public int IdentityId { get; set; }
+
public ICollection TicketGroups { get; set; } = null!;
public ICollection Reviews { get; set; } = null!;
diff --git a/AutobusApi.Domain/Entities/Vehicle.cs b/AutobusApi.Domain/Entities/Vehicle.cs
index 3bd58ac..ced2b19 100644
--- a/AutobusApi.Domain/Entities/Vehicle.cs
+++ b/AutobusApi.Domain/Entities/Vehicle.cs
@@ -4,7 +4,7 @@ namespace AutobusApi.Domain.Entities;
public class Vehicle : EntityBase
{
- public required int CompanyId { get; set; }
+ public int CompanyId { get; set; }
public Company Company { get; set; } = null!;
diff --git a/AutobusApi.Domain/Entities/VehicleEnrollment.cs b/AutobusApi.Domain/Entities/VehicleEnrollment.cs
index ebf9c71..895e8cd 100644
--- a/AutobusApi.Domain/Entities/VehicleEnrollment.cs
+++ b/AutobusApi.Domain/Entities/VehicleEnrollment.cs
@@ -4,13 +4,13 @@ namespace AutobusApi.Domain.Entities;
public class VehicleEnrollment : EntityBase
{
- public required DateTime DepartureDateTimeUtc { get; set; }
+ public DateTime DepartureDateTimeUtc { get; set; }
- public required int VehicleId { get; set; }
+ public int VehicleId { get; set; }
public Vehicle Vehicle { get; set; } = null!;
- public required int RouteId { get; set; }
+ public int RouteId { get; set; }
public Route Route { get; set; } = null!;
diff --git a/AutobusApi.Domain/Entities/VehicleEnrollmentEmployee.cs b/AutobusApi.Domain/Entities/VehicleEnrollmentEmployee.cs
index 10271b7..a135a0a 100644
--- a/AutobusApi.Domain/Entities/VehicleEnrollmentEmployee.cs
+++ b/AutobusApi.Domain/Entities/VehicleEnrollmentEmployee.cs
@@ -4,11 +4,11 @@ namespace AutobusApi.Domain.Entities;
public class VehicleEnrollmentEmployee : EntityBase
{
- public required int EmployeeId { get; set; }
+ public int EmployeeId { get; set; }
public Employee Employee { get; set; } = null!;
- public required int VehicleEnrollmentId { get; set; }
+ public int VehicleEnrollmentId { get; set; }
public VehicleEnrollment VehicleEnrollment { get; set; } = null!;
}
diff --git a/AutobusApi.Domain/Enums/IdentityRoles.cs b/AutobusApi.Domain/Enums/IdentityRoles.cs
new file mode 100644
index 0000000..b5ddb1b
--- /dev/null
+++ b/AutobusApi.Domain/Enums/IdentityRoles.cs
@@ -0,0 +1,6 @@
+namespace AutobusApi.Domain.Enums;
+
+public enum IdentityRoles
+{
+ User = 0
+}
diff --git a/AutobusApi.Infrastructure/AutobusApi.Infrastructure.csproj b/AutobusApi.Infrastructure/AutobusApi.Infrastructure.csproj
index d297ac0..fc64e66 100644
--- a/AutobusApi.Infrastructure/AutobusApi.Infrastructure.csproj
+++ b/AutobusApi.Infrastructure/AutobusApi.Infrastructure.csproj
@@ -7,13 +7,20 @@
-
-
+
+
+
+
+
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+ all
+
+
+
-
diff --git a/AutobusApi.Infrastructure/Data/ApplicationDbContext.cs b/AutobusApi.Infrastructure/Data/ApplicationDbContext.cs
new file mode 100644
index 0000000..6072d37
--- /dev/null
+++ b/AutobusApi.Infrastructure/Data/ApplicationDbContext.cs
@@ -0,0 +1,71 @@
+using System.Reflection;
+using AutobusApi.Application.Common.Interfaces;
+using AutobusApi.Domain.Entities;
+using Microsoft.EntityFrameworkCore;
+
+namespace AutoubsApi.Infrastructure.Data;
+
+public class ApplicationDbContext : DbContext, IApplicationDbContext
+{
+ public ApplicationDbContext(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 ApplicationUsers { 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 builder)
+ {
+ base.OnModelCreating(builder);
+
+ builder.HasPostgresExtension("postgis");
+
+ builder.HasDefaultSchema("domain");
+
+ builder.ApplyConfigurationsFromAssembly(
+ Assembly.GetExecutingAssembly(),
+ t => t.Namespace == "AutobusApi.Infrastructure.Data.Configurations"
+ );
+ }
+}
diff --git a/AutobusApi.Persistence/Contexts/Configurations/AddressConfiguration.cs b/AutobusApi.Infrastructure/Data/Configurations/AddressConfiguration.cs
similarity index 96%
rename from AutobusApi.Persistence/Contexts/Configurations/AddressConfiguration.cs
rename to AutobusApi.Infrastructure/Data/Configurations/AddressConfiguration.cs
index 059d5e6..8a6581d 100644
--- a/AutobusApi.Persistence/Contexts/Configurations/AddressConfiguration.cs
+++ b/AutobusApi.Infrastructure/Data/Configurations/AddressConfiguration.cs
@@ -4,7 +4,7 @@ using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
using NetTopologySuite.Geometries;
-namespace AutobusApi.Persistence.Contexts.Configurations;
+namespace AutobusApi.Infrastructure.Data.Configurations;
public class AddressConfiguration : EntityBaseConfiguration
{
diff --git a/AutobusApi.Persistence/Contexts/Configurations/AircraftConfiguration.cs b/AutobusApi.Infrastructure/Data/Configurations/AircraftConfiguration.cs
similarity index 96%
rename from AutobusApi.Persistence/Contexts/Configurations/AircraftConfiguration.cs
rename to AutobusApi.Infrastructure/Data/Configurations/AircraftConfiguration.cs
index 03a8958..fd5cee0 100644
--- a/AutobusApi.Persistence/Contexts/Configurations/AircraftConfiguration.cs
+++ b/AutobusApi.Infrastructure/Data/Configurations/AircraftConfiguration.cs
@@ -2,7 +2,7 @@ using AutobusApi.Domain.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
-namespace AutobusApi.Persistence.Contexts.Configurations;
+namespace AutobusApi.Infrastructure.Data.Configurations;
public class AircraftConfiguration : EntityBaseConfiguration
{
diff --git a/AutobusApi.Persistence/Contexts/Configurations/BusConfiguration.cs b/AutobusApi.Infrastructure/Data/Configurations/BusConfiguration.cs
similarity index 97%
rename from AutobusApi.Persistence/Contexts/Configurations/BusConfiguration.cs
rename to AutobusApi.Infrastructure/Data/Configurations/BusConfiguration.cs
index ed831b5..416280c 100644
--- a/AutobusApi.Persistence/Contexts/Configurations/BusConfiguration.cs
+++ b/AutobusApi.Infrastructure/Data/Configurations/BusConfiguration.cs
@@ -2,7 +2,7 @@ using AutobusApi.Domain.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
-namespace AutobusApi.Persistence.Contexts.Configurations;
+namespace AutobusApi.Infrastructure.Data.Configurations;
public class BusConfiguration : EntityBaseConfiguration
{
diff --git a/AutobusApi.Persistence/Contexts/Configurations/CarriageConfiguration.cs b/AutobusApi.Infrastructure/Data/Configurations/CarriageConfiguration.cs
similarity index 96%
rename from AutobusApi.Persistence/Contexts/Configurations/CarriageConfiguration.cs
rename to AutobusApi.Infrastructure/Data/Configurations/CarriageConfiguration.cs
index 2952857..08fab05 100644
--- a/AutobusApi.Persistence/Contexts/Configurations/CarriageConfiguration.cs
+++ b/AutobusApi.Infrastructure/Data/Configurations/CarriageConfiguration.cs
@@ -3,7 +3,7 @@ using AutobusApi.Domain.Enums;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
-namespace AutobusApi.Persistence.Contexts.Configurations;
+namespace AutobusApi.Infrastructure.Data.Configurations;
public class CarriageConfiguration : EntityBaseConfiguration
{
diff --git a/AutobusApi.Persistence/Contexts/Configurations/CityConfiguration.cs b/AutobusApi.Infrastructure/Data/Configurations/CityConfiguration.cs
similarity index 94%
rename from AutobusApi.Persistence/Contexts/Configurations/CityConfiguration.cs
rename to AutobusApi.Infrastructure/Data/Configurations/CityConfiguration.cs
index ff55a52..36ceaaf 100644
--- a/AutobusApi.Persistence/Contexts/Configurations/CityConfiguration.cs
+++ b/AutobusApi.Infrastructure/Data/Configurations/CityConfiguration.cs
@@ -2,7 +2,7 @@ using AutobusApi.Domain.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
-namespace AutobusApi.Persistence.Contexts.Configurations;
+namespace AutobusApi.Infrastructure.Data.Configurations;
public class CityConfiguration : EntityBaseConfiguration
{
diff --git a/AutobusApi.Persistence/Contexts/Configurations/CompanyConfiguration.cs b/AutobusApi.Infrastructure/Data/Configurations/CompanyConfiguration.cs
similarity index 95%
rename from AutobusApi.Persistence/Contexts/Configurations/CompanyConfiguration.cs
rename to AutobusApi.Infrastructure/Data/Configurations/CompanyConfiguration.cs
index f560fde..cef4842 100644
--- a/AutobusApi.Persistence/Contexts/Configurations/CompanyConfiguration.cs
+++ b/AutobusApi.Infrastructure/Data/Configurations/CompanyConfiguration.cs
@@ -2,7 +2,7 @@ using AutobusApi.Domain.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
-namespace AutobusApi.Persistence.Contexts.Configurations;
+namespace AutobusApi.Infrastructure.Data.Configurations;
public class CompanyConfiguration : EntityBaseConfiguration
{
diff --git a/AutobusApi.Persistence/Contexts/Configurations/CountryConfiguration.cs b/AutobusApi.Infrastructure/Data/Configurations/CountryConfiguration.cs
similarity index 92%
rename from AutobusApi.Persistence/Contexts/Configurations/CountryConfiguration.cs
rename to AutobusApi.Infrastructure/Data/Configurations/CountryConfiguration.cs
index 9fcc5a0..9c682c9 100644
--- a/AutobusApi.Persistence/Contexts/Configurations/CountryConfiguration.cs
+++ b/AutobusApi.Infrastructure/Data/Configurations/CountryConfiguration.cs
@@ -2,7 +2,7 @@ using AutobusApi.Domain.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
-namespace AutobusApi.Persistence.Contexts.Configurations;
+namespace AutobusApi.Infrastructure.Data.Configurations;
public class CountryConfiguration : EntityBaseConfiguration
{
diff --git a/AutobusApi.Persistence/Contexts/Configurations/EmployeeConfiguration.cs b/AutobusApi.Infrastructure/Data/Configurations/EmployeeConfiguration.cs
similarity index 87%
rename from AutobusApi.Persistence/Contexts/Configurations/EmployeeConfiguration.cs
rename to AutobusApi.Infrastructure/Data/Configurations/EmployeeConfiguration.cs
index 6c47f4d..2247427 100644
--- a/AutobusApi.Persistence/Contexts/Configurations/EmployeeConfiguration.cs
+++ b/AutobusApi.Infrastructure/Data/Configurations/EmployeeConfiguration.cs
@@ -3,7 +3,7 @@ using AutobusApi.Domain.Enums;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
-namespace AutobusApi.Persistence.Contexts.Configurations;
+namespace AutobusApi.Infrastructure.Data.Configurations;
public class EmployeeConfiguration : EntityBaseConfiguration
{
@@ -49,6 +49,16 @@ public class EmployeeConfiguration : EntityBaseConfiguration
.HasColumnType("date")
.IsRequired();
+ builder
+ .Property(e => e.IdentityId)
+ .HasColumnName("identity_id")
+ .HasColumnType("int")
+ .IsRequired();
+
+ builder
+ .HasIndex(e => e.IdentityId)
+ .IsUnique();
+
builder
.Property(e => e.EmployerCompanyId)
.HasColumnName("employer_company_id")
diff --git a/AutobusApi.Persistence/Contexts/Configurations/EmployeeDocumentConfiguration.cs b/AutobusApi.Infrastructure/Data/Configurations/EmployeeDocumentConfiguration.cs
similarity index 96%
rename from AutobusApi.Persistence/Contexts/Configurations/EmployeeDocumentConfiguration.cs
rename to AutobusApi.Infrastructure/Data/Configurations/EmployeeDocumentConfiguration.cs
index db5b34b..a3c7021 100644
--- a/AutobusApi.Persistence/Contexts/Configurations/EmployeeDocumentConfiguration.cs
+++ b/AutobusApi.Infrastructure/Data/Configurations/EmployeeDocumentConfiguration.cs
@@ -3,7 +3,7 @@ using AutobusApi.Domain.Enums;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
-namespace AutobusApi.Persistence.Contexts.Configurations;
+namespace AutobusApi.Infrastructure.Data.Configurations;
public class EmployeeDocumentConfiguration : EntityBaseConfiguration
{
diff --git a/AutobusApi.Persistence/Contexts/Configurations/EntityBaseConfiguration.cs b/AutobusApi.Infrastructure/Data/Configurations/EntityBaseConfiguration.cs
similarity index 92%
rename from AutobusApi.Persistence/Contexts/Configurations/EntityBaseConfiguration.cs
rename to AutobusApi.Infrastructure/Data/Configurations/EntityBaseConfiguration.cs
index cc86b1d..6ec33cc 100644
--- a/AutobusApi.Persistence/Contexts/Configurations/EntityBaseConfiguration.cs
+++ b/AutobusApi.Infrastructure/Data/Configurations/EntityBaseConfiguration.cs
@@ -2,7 +2,7 @@ using AutobusApi.Domain.Common;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
-namespace AutobusApi.Persistence.Contexts.Configurations;
+namespace AutobusApi.Infrastructure.Data.Configurations;
public class EntityBaseConfiguration : IEntityTypeConfiguration
where TEntity : EntityBase
diff --git a/AutobusApi.Persistence/Contexts/Configurations/RegionConfiguration.cs b/AutobusApi.Infrastructure/Data/Configurations/RegionConfiguration.cs
similarity index 95%
rename from AutobusApi.Persistence/Contexts/Configurations/RegionConfiguration.cs
rename to AutobusApi.Infrastructure/Data/Configurations/RegionConfiguration.cs
index 9f9deee..fc9351a 100644
--- a/AutobusApi.Persistence/Contexts/Configurations/RegionConfiguration.cs
+++ b/AutobusApi.Infrastructure/Data/Configurations/RegionConfiguration.cs
@@ -2,7 +2,7 @@ using AutobusApi.Domain.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
-namespace AutobusApi.Persistence.Contexts.Configurations;
+namespace AutobusApi.Infrastructure.Data.Configurations;
public class RegionConfiguration : EntityBaseConfiguration
{
diff --git a/AutobusApi.Persistence/Contexts/Configurations/ReviewConfiguration.cs b/AutobusApi.Infrastructure/Data/Configurations/ReviewConfiguration.cs
similarity index 94%
rename from AutobusApi.Persistence/Contexts/Configurations/ReviewConfiguration.cs
rename to AutobusApi.Infrastructure/Data/Configurations/ReviewConfiguration.cs
index 0986db1..43eb646 100644
--- a/AutobusApi.Persistence/Contexts/Configurations/ReviewConfiguration.cs
+++ b/AutobusApi.Infrastructure/Data/Configurations/ReviewConfiguration.cs
@@ -2,7 +2,7 @@ using AutobusApi.Domain.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
-namespace AutobusApi.Persistence.Contexts.Configurations;
+namespace AutobusApi.Infrastructure.Data.Configurations;
public class ReviewConfiguration : EntityBaseConfiguration
{
@@ -29,7 +29,7 @@ public class ReviewConfiguration : EntityBaseConfiguration
builder
.Property(r => r.PostDateTimeUtc)
.HasColumnName("post_timestamp_utc")
- .HasColumnType("timestamp")
+ .HasColumnType("timestamptz")
.IsRequired();
builder
diff --git a/AutobusApi.Persistence/Contexts/Configurations/RouteAddressConfiguration.cs b/AutobusApi.Infrastructure/Data/Configurations/RouteAddressConfiguration.cs
similarity index 96%
rename from AutobusApi.Persistence/Contexts/Configurations/RouteAddressConfiguration.cs
rename to AutobusApi.Infrastructure/Data/Configurations/RouteAddressConfiguration.cs
index d7e1491..023e25d 100644
--- a/AutobusApi.Persistence/Contexts/Configurations/RouteAddressConfiguration.cs
+++ b/AutobusApi.Infrastructure/Data/Configurations/RouteAddressConfiguration.cs
@@ -2,7 +2,7 @@ using AutobusApi.Domain.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
-namespace AutobusApi.Persistence.Contexts.Configurations;
+namespace AutobusApi.Infrastructure.Data.Configurations;
public class RouteAddressConfiguration : EntityBaseConfiguration
{
diff --git a/AutobusApi.Persistence/Contexts/Configurations/RouteAddressDetailsConfiguration.cs b/AutobusApi.Infrastructure/Data/Configurations/RouteAddressDetailsConfiguration.cs
similarity index 97%
rename from AutobusApi.Persistence/Contexts/Configurations/RouteAddressDetailsConfiguration.cs
rename to AutobusApi.Infrastructure/Data/Configurations/RouteAddressDetailsConfiguration.cs
index 7f4d8fb..54f110f 100644
--- a/AutobusApi.Persistence/Contexts/Configurations/RouteAddressDetailsConfiguration.cs
+++ b/AutobusApi.Infrastructure/Data/Configurations/RouteAddressDetailsConfiguration.cs
@@ -2,7 +2,7 @@ using AutobusApi.Domain.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
-namespace AutobusApi.Persistence.Contexts.Configurations;
+namespace AutobusApi.Infrastructure.Data.Configurations;
public class RouteAddressDeatilsConfiguration : EntityBaseConfiguration
{
diff --git a/AutobusApi.Persistence/Contexts/Configurations/RouteConfiguration.cs b/AutobusApi.Infrastructure/Data/Configurations/RouteConfiguration.cs
similarity index 92%
rename from AutobusApi.Persistence/Contexts/Configurations/RouteConfiguration.cs
rename to AutobusApi.Infrastructure/Data/Configurations/RouteConfiguration.cs
index 73d2505..dd2ca61 100644
--- a/AutobusApi.Persistence/Contexts/Configurations/RouteConfiguration.cs
+++ b/AutobusApi.Infrastructure/Data/Configurations/RouteConfiguration.cs
@@ -2,7 +2,7 @@ using AutobusApi.Domain.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
-namespace AutobusApi.Persistence.Contexts.Configurations;
+namespace AutobusApi.Infrastructure.Data.Configurations;
public class RouteConfiguration : EntityBaseConfiguration
{
diff --git a/AutobusApi.Persistence/Contexts/Configurations/TicketConfiguration.cs b/AutobusApi.Infrastructure/Data/Configurations/TicketConfiguration.cs
similarity index 95%
rename from AutobusApi.Persistence/Contexts/Configurations/TicketConfiguration.cs
rename to AutobusApi.Infrastructure/Data/Configurations/TicketConfiguration.cs
index 9e0002a..702e502 100644
--- a/AutobusApi.Persistence/Contexts/Configurations/TicketConfiguration.cs
+++ b/AutobusApi.Infrastructure/Data/Configurations/TicketConfiguration.cs
@@ -2,7 +2,7 @@ using AutobusApi.Domain.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
-namespace AutobusApi.Persistence.Contexts.Configurations;
+namespace AutobusApi.Infrastructure.Data.Configurations;
public class TicketConfiguration : EntityBaseConfiguration
{
diff --git a/AutobusApi.Persistence/Contexts/Configurations/TicketDocumentConfiguration.cs b/AutobusApi.Infrastructure/Data/Configurations/TicketDocumentConfiguration.cs
similarity index 96%
rename from AutobusApi.Persistence/Contexts/Configurations/TicketDocumentConfiguration.cs
rename to AutobusApi.Infrastructure/Data/Configurations/TicketDocumentConfiguration.cs
index 36ea420..3bdf4d9 100644
--- a/AutobusApi.Persistence/Contexts/Configurations/TicketDocumentConfiguration.cs
+++ b/AutobusApi.Infrastructure/Data/Configurations/TicketDocumentConfiguration.cs
@@ -3,7 +3,7 @@ using AutobusApi.Domain.Enums;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
-namespace AutobusApi.Persistence.Contexts.Configurations;
+namespace AutobusApi.Infrastructure.Data.Configurations;
public class TicketDocumentConfiguration : EntityBaseConfiguration
{
diff --git a/AutobusApi.Persistence/Contexts/Configurations/TicketGroupConfiguraions.cs b/AutobusApi.Infrastructure/Data/Configurations/TicketGroupConfiguraions.cs
similarity index 97%
rename from AutobusApi.Persistence/Contexts/Configurations/TicketGroupConfiguraions.cs
rename to AutobusApi.Infrastructure/Data/Configurations/TicketGroupConfiguraions.cs
index 7f1bb9b..7bf0f85 100644
--- a/AutobusApi.Persistence/Contexts/Configurations/TicketGroupConfiguraions.cs
+++ b/AutobusApi.Infrastructure/Data/Configurations/TicketGroupConfiguraions.cs
@@ -3,7 +3,7 @@ using AutobusApi.Domain.Enums;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
-namespace AutobusApi.Persistence.Contexts.Configurations;
+namespace AutobusApi.Infrastructure.Data.Configurations;
public class TicketGroupConfiguration : EntityBaseConfiguration
{
@@ -76,7 +76,7 @@ public class TicketGroupConfiguration : EntityBaseConfiguration
builder
.Property(tg => tg.PurchaseDateTimeUtc)
.HasColumnName("purchase_timestamp_utc")
- .HasColumnType("timestamp")
+ .HasColumnType("timestamptz")
.IsRequired();
builder
diff --git a/AutobusApi.Persistence/Contexts/Configurations/TrainCarriageConfiguration.cs b/AutobusApi.Infrastructure/Data/Configurations/TrainCarriageConfiguration.cs
similarity index 95%
rename from AutobusApi.Persistence/Contexts/Configurations/TrainCarriageConfiguration.cs
rename to AutobusApi.Infrastructure/Data/Configurations/TrainCarriageConfiguration.cs
index 38922ca..051c729 100644
--- a/AutobusApi.Persistence/Contexts/Configurations/TrainCarriageConfiguration.cs
+++ b/AutobusApi.Infrastructure/Data/Configurations/TrainCarriageConfiguration.cs
@@ -2,7 +2,7 @@ using AutobusApi.Domain.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
-namespace AutobusApi.Persistence.Contexts.Configurations;
+namespace AutobusApi.Infrastructure.Data.Configurations;
public class TrainCarriageConfiguration : EntityBaseConfiguration
{
diff --git a/AutobusApi.Persistence/Contexts/Configurations/TrainConfiguration.cs b/AutobusApi.Infrastructure/Data/Configurations/TrainConfiguration.cs
similarity index 94%
rename from AutobusApi.Persistence/Contexts/Configurations/TrainConfiguration.cs
rename to AutobusApi.Infrastructure/Data/Configurations/TrainConfiguration.cs
index 830dce2..7cb55ee 100644
--- a/AutobusApi.Persistence/Contexts/Configurations/TrainConfiguration.cs
+++ b/AutobusApi.Infrastructure/Data/Configurations/TrainConfiguration.cs
@@ -2,7 +2,7 @@ using AutobusApi.Domain.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
-namespace AutobusApi.Persistence.Contexts.Configurations;
+namespace AutobusApi.Infrastructure.Data.Configurations;
public class TrainConfiguration : EntityBaseConfiguration
{
diff --git a/AutobusApi.Persistence/Contexts/Configurations/UserConfiguration.cs b/AutobusApi.Infrastructure/Data/Configurations/UserConfiguration.cs
similarity index 65%
rename from AutobusApi.Persistence/Contexts/Configurations/UserConfiguration.cs
rename to AutobusApi.Infrastructure/Data/Configurations/UserConfiguration.cs
index 573697d..6d0889c 100644
--- a/AutobusApi.Persistence/Contexts/Configurations/UserConfiguration.cs
+++ b/AutobusApi.Infrastructure/Data/Configurations/UserConfiguration.cs
@@ -2,7 +2,7 @@ using AutobusApi.Domain.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
-namespace AutobusApi.Persistence.Contexts.Configurations;
+namespace AutobusApi.Infrastructure.Data.Configurations;
public class UserConfiguration : EntityBaseConfiguration
{
@@ -12,7 +12,17 @@ public class UserConfiguration : EntityBaseConfiguration
builder
.ToTable("users")
- .HasKey(e => e.Id);
+ .HasKey(u => u.Id);
+
+ builder
+ .Property(u => u.IdentityId)
+ .HasColumnName("identity_id")
+ .HasColumnType("int")
+ .IsRequired();
+
+ builder
+ .HasIndex(u => u.IdentityId)
+ .IsUnique();
builder
.HasMany(u => u.Reviews)
diff --git a/AutobusApi.Persistence/Contexts/Configurations/VehicleConfiguration.cs b/AutobusApi.Infrastructure/Data/Configurations/VehicleConfiguration.cs
similarity index 94%
rename from AutobusApi.Persistence/Contexts/Configurations/VehicleConfiguration.cs
rename to AutobusApi.Infrastructure/Data/Configurations/VehicleConfiguration.cs
index cf2ca53..aef7365 100644
--- a/AutobusApi.Persistence/Contexts/Configurations/VehicleConfiguration.cs
+++ b/AutobusApi.Infrastructure/Data/Configurations/VehicleConfiguration.cs
@@ -2,7 +2,7 @@ using AutobusApi.Domain.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
-namespace AutobusApi.Persistence.Contexts.Configurations;
+namespace AutobusApi.Infrastructure.Data.Configurations;
public class VehicleConfiguration : EntityBaseConfiguration
{
diff --git a/AutobusApi.Persistence/Contexts/Configurations/VehicleEnrollmentConfiguration.cs b/AutobusApi.Infrastructure/Data/Configurations/VehicleEnrollmentConfiguration.cs
similarity index 95%
rename from AutobusApi.Persistence/Contexts/Configurations/VehicleEnrollmentConfiguration.cs
rename to AutobusApi.Infrastructure/Data/Configurations/VehicleEnrollmentConfiguration.cs
index 934775a..441dd07 100644
--- a/AutobusApi.Persistence/Contexts/Configurations/VehicleEnrollmentConfiguration.cs
+++ b/AutobusApi.Infrastructure/Data/Configurations/VehicleEnrollmentConfiguration.cs
@@ -2,7 +2,7 @@ using AutobusApi.Domain.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
-namespace AutobusApi.Persistence.Contexts.Configurations;
+namespace AutobusApi.Infrastructure.Data.Configurations;
public class VehicleEnrollmentConfiguration : EntityBaseConfiguration
{
@@ -17,7 +17,7 @@ public class VehicleEnrollmentConfiguration : EntityBaseConfiguration ve.DepartureDateTimeUtc)
.HasColumnName("departure_timestamp_utc")
- .HasColumnType("timestamp")
+ .HasColumnType("timestamptz")
.IsRequired();
builder
diff --git a/AutobusApi.Persistence/Contexts/Configurations/VehicleEnrollmentEmployeeConfiguration.cs b/AutobusApi.Infrastructure/Data/Configurations/VehicleEnrollmentEmployeeConfiguration.cs
similarity index 96%
rename from AutobusApi.Persistence/Contexts/Configurations/VehicleEnrollmentEmployeeConfiguration.cs
rename to AutobusApi.Infrastructure/Data/Configurations/VehicleEnrollmentEmployeeConfiguration.cs
index 0c4693b..8306c2d 100644
--- a/AutobusApi.Persistence/Contexts/Configurations/VehicleEnrollmentEmployeeConfiguration.cs
+++ b/AutobusApi.Infrastructure/Data/Configurations/VehicleEnrollmentEmployeeConfiguration.cs
@@ -2,7 +2,7 @@ using AutobusApi.Domain.Entities;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
-namespace AutobusApi.Persistence.Contexts.Configurations;
+namespace AutobusApi.Infrastructure.Data.Configurations;
public class VehicleEnrollmentEmployeeConfiguration : EntityBaseConfiguration
{
diff --git a/AutobusApi.Persistence/Entities/Coordinates.cs b/AutobusApi.Infrastructure/Data/Entities/Coordinates.cs
similarity index 87%
rename from AutobusApi.Persistence/Entities/Coordinates.cs
rename to AutobusApi.Infrastructure/Data/Entities/Coordinates.cs
index f649088..f7016d9 100644
--- a/AutobusApi.Persistence/Entities/Coordinates.cs
+++ b/AutobusApi.Infrastructure/Data/Entities/Coordinates.cs
@@ -1,7 +1,7 @@
using AutobusApi.Domain.IEntities;
using NetTopologySuite.Geometries;
-namespace AutobusApi.Persistence.Entities;
+namespace AutobusApi.Infrastructure.Data.Entities;
public class Coordinates : ICoordinates
{
diff --git a/AutobusApi.Persistence/Migrations/20231101122211_initial_create.Designer.cs b/AutobusApi.Infrastructure/Data/Migrations/20231113193110_InitialCreate.Designer.cs
similarity index 95%
rename from AutobusApi.Persistence/Migrations/20231101122211_initial_create.Designer.cs
rename to AutobusApi.Infrastructure/Data/Migrations/20231113193110_InitialCreate.Designer.cs
index 7ba0a4f..59f506e 100644
--- a/AutobusApi.Persistence/Migrations/20231101122211_initial_create.Designer.cs
+++ b/AutobusApi.Infrastructure/Data/Migrations/20231113193110_InitialCreate.Designer.cs
@@ -1,6 +1,6 @@
//
using System;
-using AutoubsApi.Persistence.Contexts;
+using AutoubsApi.Infrastructure.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
@@ -10,17 +10,18 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
-namespace AutobusApi.Persistence.Migrations
+namespace AutobusApi.Infrastructure.Data.Migrations
{
- [DbContext(typeof(PostgresContext))]
- [Migration("20231101122211_initial_create")]
- partial class initial_create
+ [DbContext(typeof(ApplicationDbContext))]
+ [Migration("20231113193110_InitialCreate")]
+ partial class InitialCreate
{
///
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
+ .HasDefaultSchema("domain")
.HasAnnotation("ProductVersion", "7.0.13")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
@@ -63,7 +64,7 @@ namespace AutobusApi.Persistence.Migrations
b.HasIndex("CityId");
- b.ToTable("addresses", (string)null);
+ b.ToTable("addresses", "domain");
});
modelBuilder.Entity("AutobusApi.Domain.Entities.Carriage", b =>
@@ -102,7 +103,7 @@ namespace AutobusApi.Persistence.Migrations
b.HasKey("Id");
- b.ToTable("carriages", (string)null);
+ b.ToTable("carriages", "domain");
});
modelBuilder.Entity("AutobusApi.Domain.Entities.City", b =>
@@ -131,7 +132,7 @@ namespace AutobusApi.Persistence.Migrations
b.HasIndex("RegionId");
- b.ToTable("cities", (string)null);
+ b.ToTable("cities", "domain");
});
modelBuilder.Entity("AutobusApi.Domain.Entities.Company", b =>
@@ -169,7 +170,7 @@ namespace AutobusApi.Persistence.Migrations
b.HasKey("Id");
- b.ToTable("companies", (string)null);
+ b.ToTable("companies", "domain");
});
modelBuilder.Entity("AutobusApi.Domain.Entities.Country", b =>
@@ -192,7 +193,7 @@ namespace AutobusApi.Persistence.Migrations
b.HasKey("Id");
- b.ToTable("countries", (string)null);
+ b.ToTable("countries", "domain");
});
modelBuilder.Entity("AutobusApi.Domain.Entities.Employee", b =>
@@ -217,6 +218,10 @@ namespace AutobusApi.Persistence.Migrations
.HasColumnType("varchar(32)")
.HasColumnName("first_name");
+ b.Property("IdentityId")
+ .HasColumnType("int")
+ .HasColumnName("identity_id");
+
b.Property("IsDeleted")
.HasColumnType("boolean")
.HasColumnName("is_deleted");
@@ -240,7 +245,10 @@ namespace AutobusApi.Persistence.Migrations
b.HasIndex("EmployerCompanyId");
- b.ToTable("employees", (string)null);
+ b.HasIndex("IdentityId")
+ .IsUnique();
+
+ b.ToTable("employees", "domain");
});
modelBuilder.Entity("AutobusApi.Domain.Entities.EmployeeDocument", b =>
@@ -274,7 +282,7 @@ namespace AutobusApi.Persistence.Migrations
b.HasIndex("EmployeeId");
- b.ToTable("employee_documents", (string)null);
+ b.ToTable("employee_documents", "domain");
});
modelBuilder.Entity("AutobusApi.Domain.Entities.Region", b =>
@@ -303,7 +311,7 @@ namespace AutobusApi.Persistence.Migrations
b.HasIndex("CountryId");
- b.ToTable("regions", (string)null);
+ b.ToTable("regions", "domain");
});
modelBuilder.Entity("AutobusApi.Domain.Entities.Review", b =>
@@ -325,7 +333,7 @@ namespace AutobusApi.Persistence.Migrations
.HasColumnName("is_deleted");
b.Property("PostDateTimeUtc")
- .HasColumnType("timestamp")
+ .HasColumnType("timestamptz")
.HasColumnName("post_timestamp_utc");
b.Property("Rating")
@@ -346,7 +354,7 @@ namespace AutobusApi.Persistence.Migrations
b.HasIndex("VehicleEnrollmentId");
- b.ToTable("reviews", (string)null);
+ b.ToTable("reviews", "domain");
});
modelBuilder.Entity("AutobusApi.Domain.Entities.Route", b =>
@@ -364,7 +372,7 @@ namespace AutobusApi.Persistence.Migrations
b.HasKey("Id");
- b.ToTable("routes", (string)null);
+ b.ToTable("routes", "domain");
});
modelBuilder.Entity("AutobusApi.Domain.Entities.RouteAddress", b =>
@@ -398,7 +406,7 @@ namespace AutobusApi.Persistence.Migrations
b.HasIndex("RouteId");
- b.ToTable("route_addresses", (string)null);
+ b.ToTable("route_addresses", "domain");
});
modelBuilder.Entity("AutobusApi.Domain.Entities.RouteAddressDetails", b =>
@@ -440,7 +448,7 @@ namespace AutobusApi.Persistence.Migrations
b.HasIndex("VehicleEnrollmentId");
- b.ToTable("route_address_details", (string)null);
+ b.ToTable("route_address_details", "domain");
});
modelBuilder.Entity("AutobusApi.Domain.Entities.Ticket", b =>
@@ -470,7 +478,7 @@ namespace AutobusApi.Persistence.Migrations
b.HasIndex("VehicleEnrollmentId");
- b.ToTable("tickets", (string)null);
+ b.ToTable("tickets", "domain");
});
modelBuilder.Entity("AutobusApi.Domain.Entities.TicketDocument", b =>
@@ -502,7 +510,7 @@ namespace AutobusApi.Persistence.Migrations
b.HasKey("Id");
- b.ToTable("ticket_documents", (string)null);
+ b.ToTable("ticket_documents", "domain");
});
modelBuilder.Entity("AutobusApi.Domain.Entities.TicketGroup", b =>
@@ -567,7 +575,7 @@ namespace AutobusApi.Persistence.Migrations
.HasColumnName("passenger_sex");
b.Property("PurchaseDateTimeUtc")
- .HasColumnType("timestamp")
+ .HasColumnType("timestamptz")
.HasColumnName("purchase_timestamp_utc");
b.Property("TicketDocumentId")
@@ -584,7 +592,7 @@ namespace AutobusApi.Persistence.Migrations
b.HasIndex("UserId");
- b.ToTable("ticket_groups", (string)null);
+ b.ToTable("ticket_groups", "domain");
});
modelBuilder.Entity("AutobusApi.Domain.Entities.TrainCarriage", b =>
@@ -612,7 +620,7 @@ namespace AutobusApi.Persistence.Migrations
b.HasIndex("TrainId");
- b.ToTable("train_carriages", (string)null);
+ b.ToTable("train_carriages", "domain");
});
modelBuilder.Entity("AutobusApi.Domain.Entities.User", b =>
@@ -624,13 +632,20 @@ namespace AutobusApi.Persistence.Migrations
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+ b.Property("IdentityId")
+ .HasColumnType("int")
+ .HasColumnName("identity_id");
+
b.Property("IsDeleted")
.HasColumnType("boolean")
.HasColumnName("is_deleted");
b.HasKey("Id");
- b.ToTable("users", (string)null);
+ b.HasIndex("IdentityId")
+ .IsUnique();
+
+ b.ToTable("users", "domain");
});
modelBuilder.Entity("AutobusApi.Domain.Entities.Vehicle", b =>
@@ -654,7 +669,7 @@ namespace AutobusApi.Persistence.Migrations
b.HasIndex("CompanyId");
- b.ToTable("vehicles", (string)null);
+ b.ToTable("vehicles", "domain");
b.UseTptMappingStrategy();
});
@@ -669,7 +684,7 @@ namespace AutobusApi.Persistence.Migrations
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
b.Property("DepartureDateTimeUtc")
- .HasColumnType("timestamp")
+ .HasColumnType("timestamptz")
.HasColumnName("departure_timestamp_utc");
b.Property("IsDeleted")
@@ -690,7 +705,7 @@ namespace AutobusApi.Persistence.Migrations
b.HasIndex("VehicleId");
- b.ToTable("vehicle_enrollments", (string)null);
+ b.ToTable("vehicle_enrollments", "domain");
});
modelBuilder.Entity("AutobusApi.Domain.Entities.VehicleEnrollmentEmployee", b =>
@@ -720,7 +735,7 @@ namespace AutobusApi.Persistence.Migrations
b.HasIndex("VehicleEnrollmentId");
- b.ToTable("vehicle_enrollment_employees", (string)null);
+ b.ToTable("vehicle_enrollment_employees", "domain");
});
modelBuilder.Entity("AutobusApi.Domain.Entities.Aircraft", b =>
@@ -749,7 +764,7 @@ namespace AutobusApi.Persistence.Migrations
.HasColumnType("varchar(8)")
.HasColumnName("number");
- b.ToTable("aircrafts", (string)null);
+ b.ToTable("aircrafts", "domain");
});
modelBuilder.Entity("AutobusApi.Domain.Entities.Bus", b =>
@@ -790,7 +805,7 @@ namespace AutobusApi.Persistence.Migrations
.HasColumnType("varchar(8)")
.HasColumnName("number");
- b.ToTable("buses", (string)null);
+ b.ToTable("buses", "domain");
});
modelBuilder.Entity("AutobusApi.Domain.Entities.Train", b =>
@@ -802,7 +817,7 @@ namespace AutobusApi.Persistence.Migrations
.HasColumnType("varchar(8)")
.HasColumnName("number");
- b.ToTable("trains", (string)null);
+ b.ToTable("trains", "domain");
});
modelBuilder.Entity("AutobusApi.Domain.Entities.Address", b =>
diff --git a/AutobusApi.Persistence/Migrations/20231101122211_initial_create.cs b/AutobusApi.Infrastructure/Data/Migrations/20231113193110_InitialCreate.cs
similarity index 86%
rename from AutobusApi.Persistence/Migrations/20231101122211_initial_create.cs
rename to AutobusApi.Infrastructure/Data/Migrations/20231113193110_InitialCreate.cs
index 2b98317..9730f46 100644
--- a/AutobusApi.Persistence/Migrations/20231101122211_initial_create.cs
+++ b/AutobusApi.Infrastructure/Data/Migrations/20231113193110_InitialCreate.cs
@@ -5,19 +5,23 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
-namespace AutobusApi.Persistence.Migrations
+namespace AutobusApi.Infrastructure.Data.Migrations
{
///
- public partial class initial_create : Migration
+ public partial class InitialCreate : Migration
{
///
protected override void Up(MigrationBuilder migrationBuilder)
{
+ migrationBuilder.EnsureSchema(
+ name: "domain");
+
migrationBuilder.AlterDatabase()
.Annotation("Npgsql:PostgresExtension:postgis", ",,");
migrationBuilder.CreateTable(
name: "carriages",
+ schema: "domain",
columns: table => new
{
id = table.Column(type: "int", nullable: false)
@@ -36,6 +40,7 @@ namespace AutobusApi.Persistence.Migrations
migrationBuilder.CreateTable(
name: "companies",
+ schema: "domain",
columns: table => new
{
id = table.Column(type: "int", nullable: false)
@@ -53,6 +58,7 @@ namespace AutobusApi.Persistence.Migrations
migrationBuilder.CreateTable(
name: "countries",
+ schema: "domain",
columns: table => new
{
id = table.Column(type: "int", nullable: false)
@@ -67,6 +73,7 @@ namespace AutobusApi.Persistence.Migrations
migrationBuilder.CreateTable(
name: "routes",
+ schema: "domain",
columns: table => new
{
id = table.Column(type: "int", nullable: false)
@@ -80,6 +87,7 @@ namespace AutobusApi.Persistence.Migrations
migrationBuilder.CreateTable(
name: "ticket_documents",
+ schema: "domain",
columns: table => new
{
id = table.Column(type: "int", nullable: false)
@@ -96,10 +104,12 @@ namespace AutobusApi.Persistence.Migrations
migrationBuilder.CreateTable(
name: "users",
+ schema: "domain",
columns: table => new
{
id = table.Column(type: "int", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
+ identity_id = table.Column(type: "int", nullable: false),
is_deleted = table.Column(type: "boolean", nullable: false)
},
constraints: table =>
@@ -109,6 +119,7 @@ namespace AutobusApi.Persistence.Migrations
migrationBuilder.CreateTable(
name: "employees",
+ schema: "domain",
columns: table => new
{
id = table.Column(type: "int", nullable: false)
@@ -118,6 +129,7 @@ namespace AutobusApi.Persistence.Migrations
patronymic = table.Column(type: "varchar(32)", nullable: false),
sex = table.Column(type: "varchar(16)", nullable: false),
birth_date = table.Column(type: "date", nullable: false),
+ identity_id = table.Column(type: "int", nullable: false),
employer_company_id = table.Column(type: "int", nullable: false),
is_deleted = table.Column(type: "boolean", nullable: false)
},
@@ -127,6 +139,7 @@ namespace AutobusApi.Persistence.Migrations
table.ForeignKey(
name: "fk_employees_companies_employerCompanyId",
column: x => x.employer_company_id,
+ principalSchema: "domain",
principalTable: "companies",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
@@ -134,6 +147,7 @@ namespace AutobusApi.Persistence.Migrations
migrationBuilder.CreateTable(
name: "vehicles",
+ schema: "domain",
columns: table => new
{
id = table.Column(type: "int", nullable: false)
@@ -147,6 +161,7 @@ namespace AutobusApi.Persistence.Migrations
table.ForeignKey(
name: "fk_vehicles_companies_companyId",
column: x => x.company_id,
+ principalSchema: "domain",
principalTable: "companies",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
@@ -154,6 +169,7 @@ namespace AutobusApi.Persistence.Migrations
migrationBuilder.CreateTable(
name: "regions",
+ schema: "domain",
columns: table => new
{
id = table.Column(type: "int", nullable: false)
@@ -168,6 +184,7 @@ namespace AutobusApi.Persistence.Migrations
table.ForeignKey(
name: "fk_regions_coutries_countryId",
column: x => x.country_id,
+ principalSchema: "domain",
principalTable: "countries",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
@@ -175,6 +192,7 @@ namespace AutobusApi.Persistence.Migrations
migrationBuilder.CreateTable(
name: "ticket_groups",
+ schema: "domain",
columns: table => new
{
id = table.Column(type: "int", nullable: false)
@@ -188,7 +206,7 @@ namespace AutobusApi.Persistence.Migrations
passenger_patronymic = table.Column(type: "varchar(32)", nullable: false),
passenger_sex = table.Column(type: "varchar(16)", nullable: false),
passenger_birth_date = table.Column(type: "date", nullable: false),
- purchase_timestamp_utc = table.Column(type: "timestamp", nullable: false),
+ purchase_timestamp_utc = table.Column(type: "timestamptz", nullable: false),
is_returned = table.Column(type: "boolean", nullable: false),
user_id = table.Column(type: "int", nullable: true),
TicketDocumentId = table.Column(type: "int", nullable: false),
@@ -200,12 +218,14 @@ namespace AutobusApi.Persistence.Migrations
table.ForeignKey(
name: "fk_ticketGroups_ticketDocuments_ticketDocumentId",
column: x => x.TicketDocumentId,
+ principalSchema: "domain",
principalTable: "ticket_documents",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "fk_ticketGroups_users_userId",
column: x => x.user_id,
+ principalSchema: "domain",
principalTable: "users",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
@@ -213,6 +233,7 @@ namespace AutobusApi.Persistence.Migrations
migrationBuilder.CreateTable(
name: "employee_documents",
+ schema: "domain",
columns: table => new
{
id = table.Column(type: "int", nullable: false)
@@ -228,6 +249,7 @@ namespace AutobusApi.Persistence.Migrations
table.ForeignKey(
name: "fk_employeeDocuments_employees_employeeId",
column: x => x.employee_id,
+ principalSchema: "domain",
principalTable: "employees",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
@@ -235,6 +257,7 @@ namespace AutobusApi.Persistence.Migrations
migrationBuilder.CreateTable(
name: "aircrafts",
+ schema: "domain",
columns: table => new
{
id = table.Column(type: "int", nullable: false),
@@ -250,6 +273,7 @@ namespace AutobusApi.Persistence.Migrations
table.ForeignKey(
name: "fk_aircrafts_vehicles_id",
column: x => x.id,
+ principalSchema: "domain",
principalTable: "vehicles",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
@@ -257,6 +281,7 @@ namespace AutobusApi.Persistence.Migrations
migrationBuilder.CreateTable(
name: "buses",
+ schema: "domain",
columns: table => new
{
id = table.Column(type: "int", nullable: false),
@@ -275,6 +300,7 @@ namespace AutobusApi.Persistence.Migrations
table.ForeignKey(
name: "fk_buses_vehicles_id",
column: x => x.id,
+ principalSchema: "domain",
principalTable: "vehicles",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
@@ -282,6 +308,7 @@ namespace AutobusApi.Persistence.Migrations
migrationBuilder.CreateTable(
name: "trains",
+ schema: "domain",
columns: table => new
{
id = table.Column(type: "int", nullable: false),
@@ -293,6 +320,7 @@ namespace AutobusApi.Persistence.Migrations
table.ForeignKey(
name: "fk_trains_vehicles_id",
column: x => x.id,
+ principalSchema: "domain",
principalTable: "vehicles",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
@@ -300,11 +328,12 @@ namespace AutobusApi.Persistence.Migrations
migrationBuilder.CreateTable(
name: "vehicle_enrollments",
+ schema: "domain",
columns: table => new
{
id = table.Column(type: "int", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
- departure_timestamp_utc = table.Column(type: "timestamp", nullable: false),
+ departure_timestamp_utc = table.Column(type: "timestamptz", nullable: false),
vehicle_id = table.Column(type: "int", nullable: false),
route_id = table.Column(type: "int", nullable: false),
is_deleted = table.Column(type: "boolean", nullable: false)
@@ -315,12 +344,14 @@ namespace AutobusApi.Persistence.Migrations
table.ForeignKey(
name: "fk_vehicleEnrollments_routes_routeId",
column: x => x.route_id,
+ principalSchema: "domain",
principalTable: "routes",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "fk_vehicleEnrollments_vehicles_vehicleId",
column: x => x.vehicle_id,
+ principalSchema: "domain",
principalTable: "vehicles",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
@@ -328,6 +359,7 @@ namespace AutobusApi.Persistence.Migrations
migrationBuilder.CreateTable(
name: "cities",
+ schema: "domain",
columns: table => new
{
id = table.Column(type: "int", nullable: false)
@@ -342,6 +374,7 @@ namespace AutobusApi.Persistence.Migrations
table.ForeignKey(
name: "fk_cities_regions_regionId",
column: x => x.region_id,
+ principalSchema: "domain",
principalTable: "regions",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
@@ -349,6 +382,7 @@ namespace AutobusApi.Persistence.Migrations
migrationBuilder.CreateTable(
name: "train_carriages",
+ schema: "domain",
columns: table => new
{
id = table.Column(type: "int", nullable: false)
@@ -363,12 +397,14 @@ namespace AutobusApi.Persistence.Migrations
table.ForeignKey(
name: "fk_trainCarriages_trains_carriageId",
column: x => x.train_id,
+ principalSchema: "domain",
principalTable: "carriages",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "fk_trainCarriages_trains_trainId",
column: x => x.train_id,
+ principalSchema: "domain",
principalTable: "trains",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
@@ -376,13 +412,14 @@ namespace AutobusApi.Persistence.Migrations
migrationBuilder.CreateTable(
name: "reviews",
+ schema: "domain",
columns: table => new
{
id = table.Column(type: "int", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
rating = table.Column(type: "numeric(1,0)", nullable: false),
comment = table.Column(type: "varchar(128)", nullable: false),
- post_timestamp_utc = table.Column(type: "timestamp", nullable: false),
+ post_timestamp_utc = table.Column(type: "timestamptz", nullable: false),
user_id = table.Column(type: "int", nullable: false),
vehicle_enrollment_id = table.Column(type: "int", nullable: false),
is_deleted = table.Column(type: "boolean", nullable: false)
@@ -393,12 +430,14 @@ namespace AutobusApi.Persistence.Migrations
table.ForeignKey(
name: "fk_reviews_users_userId",
column: x => x.user_id,
+ principalSchema: "domain",
principalTable: "users",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "fk_reviews_vehicleEnrollments_vehicleEnrollmentId",
column: x => x.vehicle_enrollment_id,
+ principalSchema: "domain",
principalTable: "vehicle_enrollments",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
@@ -406,6 +445,7 @@ namespace AutobusApi.Persistence.Migrations
migrationBuilder.CreateTable(
name: "tickets",
+ schema: "domain",
columns: table => new
{
id = table.Column(type: "int", nullable: false)
@@ -420,12 +460,14 @@ namespace AutobusApi.Persistence.Migrations
table.ForeignKey(
name: "fk_tickets_ticketGroups_ticketGroupId",
column: x => x.ticket_group_id,
+ principalSchema: "domain",
principalTable: "ticket_groups",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "fk_tickets_vehicleEnrollments_vehicleEnrollmentId",
column: x => x.vehicle_enrollment_id,
+ principalSchema: "domain",
principalTable: "vehicle_enrollments",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
@@ -433,6 +475,7 @@ namespace AutobusApi.Persistence.Migrations
migrationBuilder.CreateTable(
name: "vehicle_enrollment_employees",
+ schema: "domain",
columns: table => new
{
id = table.Column(type: "int", nullable: false)
@@ -447,12 +490,14 @@ namespace AutobusApi.Persistence.Migrations
table.ForeignKey(
name: "fk_vehicleEnrollmentEmployees_employees_employeeId",
column: x => x.employee_id,
+ principalSchema: "domain",
principalTable: "employees",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "fk_vehicleEnrollmentEmployees_vehicleEnrollments_vehicleEnrollmentId",
column: x => x.vehicle_enrollment_id,
+ principalSchema: "domain",
principalTable: "vehicle_enrollments",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
@@ -460,6 +505,7 @@ namespace AutobusApi.Persistence.Migrations
migrationBuilder.CreateTable(
name: "addresses",
+ schema: "domain",
columns: table => new
{
id = table.Column(type: "int", nullable: false)
@@ -476,6 +522,7 @@ namespace AutobusApi.Persistence.Migrations
table.ForeignKey(
name: "fk_addresses_city_id",
column: x => x.city_id,
+ principalSchema: "domain",
principalTable: "cities",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
@@ -483,6 +530,7 @@ namespace AutobusApi.Persistence.Migrations
migrationBuilder.CreateTable(
name: "route_addresses",
+ schema: "domain",
columns: table => new
{
id = table.Column(type: "int", nullable: false)
@@ -498,12 +546,14 @@ namespace AutobusApi.Persistence.Migrations
table.ForeignKey(
name: "fk_routeAddresses_addresses_addressId",
column: x => x.address_id,
+ principalSchema: "domain",
principalTable: "addresses",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "fk_routeAddresses_routes_routeId",
column: x => x.route_id,
+ principalSchema: "domain",
principalTable: "routes",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
@@ -511,6 +561,7 @@ namespace AutobusApi.Persistence.Migrations
migrationBuilder.CreateTable(
name: "route_address_details",
+ schema: "domain",
columns: table => new
{
id = table.Column(type: "int", nullable: false)
@@ -528,12 +579,14 @@ namespace AutobusApi.Persistence.Migrations
table.ForeignKey(
name: "fk_routeAddressDetails_routeAddress_routeAddressId",
column: x => x.route_address_id,
+ principalSchema: "domain",
principalTable: "route_addresses",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "fk_routeAddressDetails_vehicleEnrollments_vehicleEnrollmentId",
column: x => x.vehicle_enrollment_id,
+ principalSchema: "domain",
principalTable: "vehicle_enrollments",
principalColumn: "id",
onDelete: ReferentialAction.Cascade);
@@ -541,107 +594,142 @@ namespace AutobusApi.Persistence.Migrations
migrationBuilder.CreateIndex(
name: "IX_addresses_city_id",
+ schema: "domain",
table: "addresses",
column: "city_id");
migrationBuilder.CreateIndex(
name: "IX_cities_region_id",
+ schema: "domain",
table: "cities",
column: "region_id");
migrationBuilder.CreateIndex(
name: "IX_employee_documents_employee_id",
+ schema: "domain",
table: "employee_documents",
column: "employee_id");
migrationBuilder.CreateIndex(
name: "IX_employees_employer_company_id",
+ schema: "domain",
table: "employees",
column: "employer_company_id");
+ migrationBuilder.CreateIndex(
+ name: "IX_employees_identity_id",
+ schema: "domain",
+ table: "employees",
+ column: "identity_id",
+ unique: true);
+
migrationBuilder.CreateIndex(
name: "IX_regions_country_id",
+ schema: "domain",
table: "regions",
column: "country_id");
migrationBuilder.CreateIndex(
name: "IX_reviews_user_id",
+ schema: "domain",
table: "reviews",
column: "user_id");
migrationBuilder.CreateIndex(
name: "IX_reviews_vehicle_enrollment_id",
+ schema: "domain",
table: "reviews",
column: "vehicle_enrollment_id");
migrationBuilder.CreateIndex(
name: "IX_route_address_details_route_address_id",
+ schema: "domain",
table: "route_address_details",
column: "route_address_id");
migrationBuilder.CreateIndex(
name: "IX_route_address_details_vehicle_enrollment_id",
+ schema: "domain",
table: "route_address_details",
column: "vehicle_enrollment_id");
migrationBuilder.CreateIndex(
name: "IX_route_addresses_address_id",
+ schema: "domain",
table: "route_addresses",
column: "address_id");
migrationBuilder.CreateIndex(
name: "IX_route_addresses_route_id",
+ schema: "domain",
table: "route_addresses",
column: "route_id");
migrationBuilder.CreateIndex(
name: "IX_ticket_groups_TicketDocumentId",
+ schema: "domain",
table: "ticket_groups",
column: "TicketDocumentId",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_ticket_groups_user_id",
+ schema: "domain",
table: "ticket_groups",
column: "user_id");
migrationBuilder.CreateIndex(
name: "IX_tickets_ticket_group_id",
+ schema: "domain",
table: "tickets",
column: "ticket_group_id");
migrationBuilder.CreateIndex(
name: "IX_tickets_vehicle_enrollment_id",
+ schema: "domain",
table: "tickets",
column: "vehicle_enrollment_id");
migrationBuilder.CreateIndex(
name: "IX_train_carriages_train_id",
+ schema: "domain",
table: "train_carriages",
column: "train_id");
+ migrationBuilder.CreateIndex(
+ name: "IX_users_identity_id",
+ schema: "domain",
+ table: "users",
+ column: "identity_id",
+ unique: true);
+
migrationBuilder.CreateIndex(
name: "IX_vehicle_enrollment_employees_employee_id",
+ schema: "domain",
table: "vehicle_enrollment_employees",
column: "employee_id");
migrationBuilder.CreateIndex(
name: "IX_vehicle_enrollment_employees_vehicle_enrollment_id",
+ schema: "domain",
table: "vehicle_enrollment_employees",
column: "vehicle_enrollment_id");
migrationBuilder.CreateIndex(
name: "IX_vehicle_enrollments_route_id",
+ schema: "domain",
table: "vehicle_enrollments",
column: "route_id");
migrationBuilder.CreateIndex(
name: "IX_vehicle_enrollments_vehicle_id",
+ schema: "domain",
table: "vehicle_enrollments",
column: "vehicle_id");
migrationBuilder.CreateIndex(
name: "IX_vehicles_company_id",
+ schema: "domain",
table: "vehicles",
column: "company_id");
}
@@ -650,73 +738,96 @@ namespace AutobusApi.Persistence.Migrations
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
- name: "aircrafts");
+ name: "aircrafts",
+ schema: "domain");
migrationBuilder.DropTable(
- name: "buses");
+ name: "buses",
+ schema: "domain");
migrationBuilder.DropTable(
- name: "employee_documents");
+ name: "employee_documents",
+ schema: "domain");
migrationBuilder.DropTable(
- name: "reviews");
+ name: "reviews",
+ schema: "domain");
migrationBuilder.DropTable(
- name: "route_address_details");
+ name: "route_address_details",
+ schema: "domain");
migrationBuilder.DropTable(
- name: "tickets");
+ name: "tickets",
+ schema: "domain");
migrationBuilder.DropTable(
- name: "train_carriages");
+ name: "train_carriages",
+ schema: "domain");
migrationBuilder.DropTable(
- name: "vehicle_enrollment_employees");
+ name: "vehicle_enrollment_employees",
+ schema: "domain");
migrationBuilder.DropTable(
- name: "route_addresses");
+ name: "route_addresses",
+ schema: "domain");
migrationBuilder.DropTable(
- name: "ticket_groups");
+ name: "ticket_groups",
+ schema: "domain");
migrationBuilder.DropTable(
- name: "carriages");
+ name: "carriages",
+ schema: "domain");
migrationBuilder.DropTable(
- name: "trains");
+ name: "trains",
+ schema: "domain");
migrationBuilder.DropTable(
- name: "employees");
+ name: "employees",
+ schema: "domain");
migrationBuilder.DropTable(
- name: "vehicle_enrollments");
+ name: "vehicle_enrollments",
+ schema: "domain");
migrationBuilder.DropTable(
- name: "addresses");
+ name: "addresses",
+ schema: "domain");
migrationBuilder.DropTable(
- name: "ticket_documents");
+ name: "ticket_documents",
+ schema: "domain");
migrationBuilder.DropTable(
- name: "users");
+ name: "users",
+ schema: "domain");
migrationBuilder.DropTable(
- name: "routes");
+ name: "routes",
+ schema: "domain");
migrationBuilder.DropTable(
- name: "vehicles");
+ name: "vehicles",
+ schema: "domain");
migrationBuilder.DropTable(
- name: "cities");
+ name: "cities",
+ schema: "domain");
migrationBuilder.DropTable(
- name: "companies");
+ name: "companies",
+ schema: "domain");
migrationBuilder.DropTable(
- name: "regions");
+ name: "regions",
+ schema: "domain");
migrationBuilder.DropTable(
- name: "countries");
+ name: "countries",
+ schema: "domain");
}
}
}
diff --git a/AutobusApi.Persistence/Migrations/PostgresContextModelSnapshot.cs b/AutobusApi.Infrastructure/Data/Migrations/ApplicationDbContextModelSnapshot.cs
similarity index 95%
rename from AutobusApi.Persistence/Migrations/PostgresContextModelSnapshot.cs
rename to AutobusApi.Infrastructure/Data/Migrations/ApplicationDbContextModelSnapshot.cs
index 556c95f..9f888fa 100644
--- a/AutobusApi.Persistence/Migrations/PostgresContextModelSnapshot.cs
+++ b/AutobusApi.Infrastructure/Data/Migrations/ApplicationDbContextModelSnapshot.cs
@@ -1,6 +1,6 @@
//
using System;
-using AutoubsApi.Persistence.Contexts;
+using AutoubsApi.Infrastructure.Data;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
@@ -9,15 +9,16 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
-namespace AutobusApi.Persistence.Migrations
+namespace AutobusApi.Infrastructure.Data.Migrations
{
- [DbContext(typeof(PostgresContext))]
- partial class PostgresContextModelSnapshot : ModelSnapshot
+ [DbContext(typeof(ApplicationDbContext))]
+ partial class ApplicationDbContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
+ .HasDefaultSchema("domain")
.HasAnnotation("ProductVersion", "7.0.13")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
@@ -60,7 +61,7 @@ namespace AutobusApi.Persistence.Migrations
b.HasIndex("CityId");
- b.ToTable("addresses", (string)null);
+ b.ToTable("addresses", "domain");
});
modelBuilder.Entity("AutobusApi.Domain.Entities.Carriage", b =>
@@ -99,7 +100,7 @@ namespace AutobusApi.Persistence.Migrations
b.HasKey("Id");
- b.ToTable("carriages", (string)null);
+ b.ToTable("carriages", "domain");
});
modelBuilder.Entity("AutobusApi.Domain.Entities.City", b =>
@@ -128,7 +129,7 @@ namespace AutobusApi.Persistence.Migrations
b.HasIndex("RegionId");
- b.ToTable("cities", (string)null);
+ b.ToTable("cities", "domain");
});
modelBuilder.Entity("AutobusApi.Domain.Entities.Company", b =>
@@ -166,7 +167,7 @@ namespace AutobusApi.Persistence.Migrations
b.HasKey("Id");
- b.ToTable("companies", (string)null);
+ b.ToTable("companies", "domain");
});
modelBuilder.Entity("AutobusApi.Domain.Entities.Country", b =>
@@ -189,7 +190,7 @@ namespace AutobusApi.Persistence.Migrations
b.HasKey("Id");
- b.ToTable("countries", (string)null);
+ b.ToTable("countries", "domain");
});
modelBuilder.Entity("AutobusApi.Domain.Entities.Employee", b =>
@@ -214,6 +215,10 @@ namespace AutobusApi.Persistence.Migrations
.HasColumnType("varchar(32)")
.HasColumnName("first_name");
+ b.Property("IdentityId")
+ .HasColumnType("int")
+ .HasColumnName("identity_id");
+
b.Property("IsDeleted")
.HasColumnType("boolean")
.HasColumnName("is_deleted");
@@ -237,7 +242,10 @@ namespace AutobusApi.Persistence.Migrations
b.HasIndex("EmployerCompanyId");
- b.ToTable("employees", (string)null);
+ b.HasIndex("IdentityId")
+ .IsUnique();
+
+ b.ToTable("employees", "domain");
});
modelBuilder.Entity("AutobusApi.Domain.Entities.EmployeeDocument", b =>
@@ -271,7 +279,7 @@ namespace AutobusApi.Persistence.Migrations
b.HasIndex("EmployeeId");
- b.ToTable("employee_documents", (string)null);
+ b.ToTable("employee_documents", "domain");
});
modelBuilder.Entity("AutobusApi.Domain.Entities.Region", b =>
@@ -300,7 +308,7 @@ namespace AutobusApi.Persistence.Migrations
b.HasIndex("CountryId");
- b.ToTable("regions", (string)null);
+ b.ToTable("regions", "domain");
});
modelBuilder.Entity("AutobusApi.Domain.Entities.Review", b =>
@@ -322,7 +330,7 @@ namespace AutobusApi.Persistence.Migrations
.HasColumnName("is_deleted");
b.Property("PostDateTimeUtc")
- .HasColumnType("timestamp")
+ .HasColumnType("timestamptz")
.HasColumnName("post_timestamp_utc");
b.Property("Rating")
@@ -343,7 +351,7 @@ namespace AutobusApi.Persistence.Migrations
b.HasIndex("VehicleEnrollmentId");
- b.ToTable("reviews", (string)null);
+ b.ToTable("reviews", "domain");
});
modelBuilder.Entity("AutobusApi.Domain.Entities.Route", b =>
@@ -361,7 +369,7 @@ namespace AutobusApi.Persistence.Migrations
b.HasKey("Id");
- b.ToTable("routes", (string)null);
+ b.ToTable("routes", "domain");
});
modelBuilder.Entity("AutobusApi.Domain.Entities.RouteAddress", b =>
@@ -395,7 +403,7 @@ namespace AutobusApi.Persistence.Migrations
b.HasIndex("RouteId");
- b.ToTable("route_addresses", (string)null);
+ b.ToTable("route_addresses", "domain");
});
modelBuilder.Entity("AutobusApi.Domain.Entities.RouteAddressDetails", b =>
@@ -437,7 +445,7 @@ namespace AutobusApi.Persistence.Migrations
b.HasIndex("VehicleEnrollmentId");
- b.ToTable("route_address_details", (string)null);
+ b.ToTable("route_address_details", "domain");
});
modelBuilder.Entity("AutobusApi.Domain.Entities.Ticket", b =>
@@ -467,7 +475,7 @@ namespace AutobusApi.Persistence.Migrations
b.HasIndex("VehicleEnrollmentId");
- b.ToTable("tickets", (string)null);
+ b.ToTable("tickets", "domain");
});
modelBuilder.Entity("AutobusApi.Domain.Entities.TicketDocument", b =>
@@ -499,7 +507,7 @@ namespace AutobusApi.Persistence.Migrations
b.HasKey("Id");
- b.ToTable("ticket_documents", (string)null);
+ b.ToTable("ticket_documents", "domain");
});
modelBuilder.Entity("AutobusApi.Domain.Entities.TicketGroup", b =>
@@ -564,7 +572,7 @@ namespace AutobusApi.Persistence.Migrations
.HasColumnName("passenger_sex");
b.Property("PurchaseDateTimeUtc")
- .HasColumnType("timestamp")
+ .HasColumnType("timestamptz")
.HasColumnName("purchase_timestamp_utc");
b.Property("TicketDocumentId")
@@ -581,7 +589,7 @@ namespace AutobusApi.Persistence.Migrations
b.HasIndex("UserId");
- b.ToTable("ticket_groups", (string)null);
+ b.ToTable("ticket_groups", "domain");
});
modelBuilder.Entity("AutobusApi.Domain.Entities.TrainCarriage", b =>
@@ -609,7 +617,7 @@ namespace AutobusApi.Persistence.Migrations
b.HasIndex("TrainId");
- b.ToTable("train_carriages", (string)null);
+ b.ToTable("train_carriages", "domain");
});
modelBuilder.Entity("AutobusApi.Domain.Entities.User", b =>
@@ -621,13 +629,20 @@ namespace AutobusApi.Persistence.Migrations
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+ b.Property("IdentityId")
+ .HasColumnType("int")
+ .HasColumnName("identity_id");
+
b.Property("IsDeleted")
.HasColumnType("boolean")
.HasColumnName("is_deleted");
b.HasKey("Id");
- b.ToTable("users", (string)null);
+ b.HasIndex("IdentityId")
+ .IsUnique();
+
+ b.ToTable("users", "domain");
});
modelBuilder.Entity("AutobusApi.Domain.Entities.Vehicle", b =>
@@ -651,7 +666,7 @@ namespace AutobusApi.Persistence.Migrations
b.HasIndex("CompanyId");
- b.ToTable("vehicles", (string)null);
+ b.ToTable("vehicles", "domain");
b.UseTptMappingStrategy();
});
@@ -666,7 +681,7 @@ namespace AutobusApi.Persistence.Migrations
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
b.Property("DepartureDateTimeUtc")
- .HasColumnType("timestamp")
+ .HasColumnType("timestamptz")
.HasColumnName("departure_timestamp_utc");
b.Property("IsDeleted")
@@ -687,7 +702,7 @@ namespace AutobusApi.Persistence.Migrations
b.HasIndex("VehicleId");
- b.ToTable("vehicle_enrollments", (string)null);
+ b.ToTable("vehicle_enrollments", "domain");
});
modelBuilder.Entity("AutobusApi.Domain.Entities.VehicleEnrollmentEmployee", b =>
@@ -717,7 +732,7 @@ namespace AutobusApi.Persistence.Migrations
b.HasIndex("VehicleEnrollmentId");
- b.ToTable("vehicle_enrollment_employees", (string)null);
+ b.ToTable("vehicle_enrollment_employees", "domain");
});
modelBuilder.Entity("AutobusApi.Domain.Entities.Aircraft", b =>
@@ -746,7 +761,7 @@ namespace AutobusApi.Persistence.Migrations
.HasColumnType("varchar(8)")
.HasColumnName("number");
- b.ToTable("aircrafts", (string)null);
+ b.ToTable("aircrafts", "domain");
});
modelBuilder.Entity("AutobusApi.Domain.Entities.Bus", b =>
@@ -787,7 +802,7 @@ namespace AutobusApi.Persistence.Migrations
.HasColumnType("varchar(8)")
.HasColumnName("number");
- b.ToTable("buses", (string)null);
+ b.ToTable("buses", "domain");
});
modelBuilder.Entity("AutobusApi.Domain.Entities.Train", b =>
@@ -799,7 +814,7 @@ namespace AutobusApi.Persistence.Migrations
.HasColumnType("varchar(8)")
.HasColumnName("number");
- b.ToTable("trains", (string)null);
+ b.ToTable("trains", "domain");
});
modelBuilder.Entity("AutobusApi.Domain.Entities.Address", b =>
diff --git a/AutobusApi.Infrastructure/DbInitializer.cs b/AutobusApi.Infrastructure/DbInitializer.cs
new file mode 100644
index 0000000..69d1561
--- /dev/null
+++ b/AutobusApi.Infrastructure/DbInitializer.cs
@@ -0,0 +1,59 @@
+using AutobusApi.Domain.Enums;
+using AutobusApi.Infrastructure.Identity;
+using AutoubsApi.Infrastructure.Data;
+using Microsoft.AspNetCore.Identity;
+using Microsoft.EntityFrameworkCore;
+
+namespace AutobusApi.Infrastructure;
+
+public static class DbInitializer
+{
+ public static void Initialize(ApplicationDbContext dbContext, ApplicationIdentityDbContext identityDbContext)
+ {
+ if (dbContext.Database.IsRelational())
+ {
+ var domainAppliedMigrations = dbContext.Database.GetAppliedMigrations();
+ var identityAppliedMigrations = identityDbContext.Database.GetAppliedMigrations();
+
+ if (domainAppliedMigrations.Count() == 0)
+ {
+ dbContext.Database.Migrate();
+ InitializeDomain(dbContext);
+ }
+
+ if (identityAppliedMigrations.Count() == 0)
+ {
+ identityDbContext.Database.Migrate();
+ InitializeIdentity(identityDbContext);
+ }
+ }
+ else
+ {
+ dbContext.Database.EnsureCreated();
+ InitializeDomain(dbContext);
+
+ identityDbContext.Database.EnsureCreated();
+ InitializeIdentity(identityDbContext);
+ }
+ }
+
+ private static void InitializeDomain(ApplicationDbContext dbContext)
+ {
+
+ }
+
+ private static void InitializeIdentity(ApplicationIdentityDbContext identityDbContext)
+ {
+ foreach (var role in Enum.GetValues(typeof(IdentityRoles)).Cast())
+ {
+ identityDbContext.Roles.Add(new IdentityRole
+ {
+ Name = role.ToString(),
+ NormalizedName = role.ToString().ToUpper(),
+ ConcurrencyStamp = Guid.NewGuid().ToString()
+ });
+ }
+
+ identityDbContext.SaveChanges();
+ }
+}
diff --git a/AutobusApi.Infrastructure/DependencyInjection.cs b/AutobusApi.Infrastructure/DependencyInjection.cs
new file mode 100644
index 0000000..05cb8c2
--- /dev/null
+++ b/AutobusApi.Infrastructure/DependencyInjection.cs
@@ -0,0 +1,89 @@
+using System.Text;
+using AutobusApi.Application.Common.Interfaces;
+using AutobusApi.Infrastructure.Identity;
+using AutobusApi.Infrastructure.Services;
+using AutoubsApi.Infrastructure.Data;
+using Microsoft.AspNetCore.Authentication.JwtBearer;
+using Microsoft.AspNetCore.Identity;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.Extensions.Configuration;
+using Microsoft.Extensions.DependencyInjection;
+using Microsoft.IdentityModel.Tokens;
+
+namespace AutobusApi.Infrastructure;
+
+public static class DependencyInjection
+{
+ public static IServiceCollection AddInfrastructure(this IServiceCollection services, IConfiguration configuration)
+ {
+ services.AddApplicationDbContext(configuration);
+ services.AddIdentity(configuration);
+ services.AddServices();
+ services.AddAuthentication();
+
+ return services;
+ }
+
+ private static IServiceCollection AddApplicationDbContext(this IServiceCollection services, IConfiguration configuration)
+ {
+ services.AddDbContext(options =>
+ {
+ options.UseNpgsql(
+ configuration.GetConnectionString("DefaultConnection"),
+ npgsqOptions => npgsqOptions.UseNetTopologySuite()
+ );
+ });
+
+ services.AddScoped();
+
+ return services;
+ }
+
+ private static IServiceCollection AddIdentity(this IServiceCollection services, IConfiguration configuration)
+ {
+
+ services.AddDbContext(options =>
+ {
+ options.UseNpgsql(configuration.GetConnectionString("DefaultConnection"));
+ });
+
+ services.AddIdentity>()
+ .AddEntityFrameworkStores()
+ .AddDefaultTokenProviders();
+
+ return services;
+ }
+
+ private static IServiceCollection AddServices(this IServiceCollection services)
+ {
+ services.AddScoped();
+
+ return services;
+ }
+
+ private static IServiceCollection AddAuthenticationWithJwt(this IServiceCollection services, IConfiguration configuration)
+ {
+ services.AddAuthentication(options =>
+ {
+ options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
+ options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
+ options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
+ })
+ .AddJwtBearer(options =>
+ {
+ options.SaveToken = true;
+ options.RequireHttpsMetadata = false;
+ options.TokenValidationParameters = new TokenValidationParameters()
+ {
+ ValidateIssuer = true,
+ ValidateAudience = true,
+ ValidAudience = configuration["Jwt:Audience"],
+ ValidIssuer = configuration["Jwt:Issuer"],
+ ClockSkew = TimeSpan.Zero,
+ IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["Jwt:IssuerSigningKey"]!))
+ };
+ });
+
+ return services;
+ }
+}
diff --git a/AutobusApi.Infrastructure/Identity/ApplicationIdentityDbContext.cs b/AutobusApi.Infrastructure/Identity/ApplicationIdentityDbContext.cs
new file mode 100644
index 0000000..fec9505
--- /dev/null
+++ b/AutobusApi.Infrastructure/Identity/ApplicationIdentityDbContext.cs
@@ -0,0 +1,24 @@
+using System.Reflection;
+using Microsoft.AspNetCore.Identity;
+using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore;
+
+namespace AutobusApi.Infrastructure.Identity;
+
+public class ApplicationIdentityDbContext : IdentityDbContext, int>
+{
+ public ApplicationIdentityDbContext(DbContextOptions options)
+ : base(options) { }
+
+ protected override void OnModelCreating(ModelBuilder builder)
+ {
+ base.OnModelCreating(builder);
+
+ builder.HasDefaultSchema("identity");
+
+ builder.ApplyConfigurationsFromAssembly(
+ Assembly.GetExecutingAssembly(),
+ t => t.Namespace == "AutobusApi.Infrastructure.Identity.Configurations"
+ );
+ }
+}
diff --git a/AutobusApi.Infrastructure/Identity/ApplicationUser.cs b/AutobusApi.Infrastructure/Identity/ApplicationUser.cs
new file mode 100644
index 0000000..ba98a3a
--- /dev/null
+++ b/AutobusApi.Infrastructure/Identity/ApplicationUser.cs
@@ -0,0 +1,8 @@
+using Microsoft.AspNetCore.Identity;
+
+namespace AutobusApi.Infrastructure.Identity;
+
+public class ApplicationUser : IdentityUser
+{
+ public ICollection RefreshTokens { get; set; } = null!;
+}
diff --git a/AutobusApi.Infrastructure/Identity/Configurations/IdentityRoleClaimConfiguration.cs b/AutobusApi.Infrastructure/Identity/Configurations/IdentityRoleClaimConfiguration.cs
new file mode 100644
index 0000000..4ee5f58
--- /dev/null
+++ b/AutobusApi.Infrastructure/Identity/Configurations/IdentityRoleClaimConfiguration.cs
@@ -0,0 +1,30 @@
+using Microsoft.AspNetCore.Identity;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+
+namespace AutobusApi.Infrastructure.Identity.Configurations;
+
+public class IdentityRoleClaimConfiguration : IEntityTypeConfiguration>
+{
+ public void Configure(EntityTypeBuilder> builder)
+ {
+ builder
+ .ToTable("identity_role_claims");
+
+ builder
+ .Property(rc => rc.Id)
+ .HasColumnName("id");
+
+ builder
+ .Property(rc => rc.RoleId)
+ .HasColumnName("role_id");
+
+ builder
+ .Property(rc => rc.ClaimType)
+ .HasColumnName("claim_type");
+
+ builder
+ .Property(rc => rc.ClaimValue)
+ .HasColumnName("claim_value");
+ }
+}
diff --git a/AutobusApi.Infrastructure/Identity/Configurations/IdentityRoleConfiguration.cs b/AutobusApi.Infrastructure/Identity/Configurations/IdentityRoleConfiguration.cs
new file mode 100644
index 0000000..3e4198a
--- /dev/null
+++ b/AutobusApi.Infrastructure/Identity/Configurations/IdentityRoleConfiguration.cs
@@ -0,0 +1,30 @@
+using Microsoft.AspNetCore.Identity;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+
+namespace AutobusApi.Infrastructure.Identity.Configurations;
+
+public class IdentityRoleConfiguration : IEntityTypeConfiguration>
+{
+ public void Configure(EntityTypeBuilder> builder)
+ {
+ builder
+ .ToTable("identity_roles");
+
+ builder
+ .Property(r => r.Id)
+ .HasColumnName("id");
+
+ builder
+ .Property(r => r.Name)
+ .HasColumnName("name");
+
+ builder
+ .Property(r => r.NormalizedName)
+ .HasColumnName("normalized_name");
+
+ builder
+ .Property(r => r.ConcurrencyStamp)
+ .HasColumnName("concurrency_stamp");
+ }
+}
diff --git a/AutobusApi.Infrastructure/Identity/Configurations/IdentityUserClaimConfiguration.cs b/AutobusApi.Infrastructure/Identity/Configurations/IdentityUserClaimConfiguration.cs
new file mode 100644
index 0000000..d4b97b1
--- /dev/null
+++ b/AutobusApi.Infrastructure/Identity/Configurations/IdentityUserClaimConfiguration.cs
@@ -0,0 +1,30 @@
+using Microsoft.AspNetCore.Identity;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+
+namespace AutobusApi.Infrastructure.Identity.Configurations;
+
+public class IdentityUserClaimConfiguration : IEntityTypeConfiguration>
+{
+ public void Configure(EntityTypeBuilder> builder)
+ {
+ builder
+ .ToTable("identity_user_claims");
+
+ builder
+ .Property(uc => uc.Id)
+ .HasColumnName("id");
+
+ builder
+ .Property(uc => uc.UserId)
+ .HasColumnName("user_id");
+
+ builder
+ .Property(uc => uc.ClaimType)
+ .HasColumnName("claim_type");
+
+ builder
+ .Property(uc => uc.ClaimValue)
+ .HasColumnName("claim_value");
+ }
+}
diff --git a/AutobusApi.Infrastructure/Identity/Configurations/IdentityUserConfiguration.cs b/AutobusApi.Infrastructure/Identity/Configurations/IdentityUserConfiguration.cs
new file mode 100644
index 0000000..28a61fd
--- /dev/null
+++ b/AutobusApi.Infrastructure/Identity/Configurations/IdentityUserConfiguration.cs
@@ -0,0 +1,123 @@
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+
+namespace AutobusApi.Infrastructure.Identity.Configurations;
+
+public class IdentityUserConfiguration : IEntityTypeConfiguration
+{
+ public void Configure(EntityTypeBuilder builder)
+ {
+ builder
+ .ToTable("identity_users");
+
+ // builder
+ // .Ignore(u => u.UserName);
+ //
+ // builder
+ // .Ignore(u => u.NormalizedUserName);
+
+ builder
+ .Ignore(u => u.PhoneNumber);
+
+ builder
+ .Ignore(u => u.PhoneNumberConfirmed);
+
+ builder
+ .Property(u => u.Id)
+ .HasColumnName("id");
+
+ builder
+ .Property(u => u.Email)
+ .HasColumnName("email");
+
+ builder
+ .Property(u => u.NormalizedEmail)
+ .HasColumnName("normalized_email");
+
+ builder
+ .Property(u => u.EmailConfirmed)
+ .HasColumnName("email_confirmed");
+
+ builder
+ .Property(u => u.PasswordHash)
+ .HasColumnName("password_hash");
+
+ builder
+ .Property(u => u.SecurityStamp)
+ .HasColumnName("security_stamp");
+
+ builder
+ .Property(u => u.ConcurrencyStamp)
+ .HasColumnName("concurrency_stamp");
+
+ builder
+ .Property(u => u.TwoFactorEnabled)
+ .HasColumnName("two_factor_enabled");
+
+ builder
+ .Property(u => u.LockoutEnabled)
+ .HasColumnName("lockout_enabled");
+
+ builder
+ .Property(u => u.LockoutEnd)
+ .HasColumnName("lockout_end");
+
+ builder
+ .Property(u => u.AccessFailedCount)
+ .HasColumnName("access_failed_count");
+
+ builder
+ .OwnsMany(u => u.RefreshTokens,
+ refreshToken =>
+ {
+ refreshToken
+ .ToTable("identity_user_refresh_tokens");
+
+ refreshToken
+ .HasKey(rt => rt.Id)
+ .HasName("id");
+
+ refreshToken
+ .WithOwner(rt => rt.ApplicationUser)
+ .HasForeignKey(rt => rt.ApplicationUserId)
+ .HasConstraintName("fk_identityUserRefreshTokens_identityUser_userId");
+
+ refreshToken
+ .Property(rt => rt.Id)
+ .HasColumnName("id")
+ .HasColumnType("int")
+ .IsRequired();
+
+ refreshToken
+ .Property(rt => rt.ApplicationUserId)
+ .HasColumnName("identity_user_id")
+ .HasColumnType("int")
+ .IsRequired();
+
+ refreshToken
+ .Property(rt => rt.Value)
+ .HasColumnName("value")
+ .HasColumnType("varchar(256)")
+ .IsRequired();
+
+ refreshToken
+ .Property(rt => rt.CreationDateTimeUtc)
+ .HasColumnName("creation_timestamp_utc")
+ .HasColumnType("timestamptz")
+ .IsRequired();
+
+ refreshToken
+ .Property(rt => rt.ExpirationDateTimeUtc)
+ .HasColumnName("expiration_timestamp_utc")
+ .HasColumnType("timestamptz")
+ .IsRequired();
+
+ refreshToken
+ .Property(rt => rt.RevokationDateTimeUtc)
+ .HasColumnName("revokation_timestamp_utc")
+ .HasColumnType("timestamptz")
+ .IsRequired(false);
+ }
+ );
+ }
+}
diff --git a/AutobusApi.Infrastructure/Identity/Configurations/IdentityUserLoginConfigurations.cs b/AutobusApi.Infrastructure/Identity/Configurations/IdentityUserLoginConfigurations.cs
new file mode 100644
index 0000000..9c7a367
--- /dev/null
+++ b/AutobusApi.Infrastructure/Identity/Configurations/IdentityUserLoginConfigurations.cs
@@ -0,0 +1,30 @@
+using Microsoft.AspNetCore.Identity;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+
+namespace AutobusApi.Infrastructure.Identity.Configurations;
+
+public class IdentityUserLoginConfiguration : IEntityTypeConfiguration>
+{
+ public void Configure(EntityTypeBuilder> builder)
+ {
+ builder
+ .ToTable("identity_user_logins");
+
+ builder
+ .Property(ul => ul.LoginProvider)
+ .HasColumnName("login_provider");
+
+ builder
+ .Property(ul => ul.ProviderKey)
+ .HasColumnName("provider_key");
+
+ builder
+ .Property(ul => ul.ProviderDisplayName)
+ .HasColumnName("provider_display_name");
+
+ builder
+ .Property(ul => ul.UserId)
+ .HasColumnName("user_id");
+ }
+}
diff --git a/AutobusApi.Infrastructure/Identity/Configurations/IdentityUserRoleConfiguration.cs b/AutobusApi.Infrastructure/Identity/Configurations/IdentityUserRoleConfiguration.cs
new file mode 100644
index 0000000..02b2bf1
--- /dev/null
+++ b/AutobusApi.Infrastructure/Identity/Configurations/IdentityUserRoleConfiguration.cs
@@ -0,0 +1,22 @@
+using Microsoft.AspNetCore.Identity;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+
+namespace AutobusApi.Infrastructure.Identity.Configurations;
+
+public class IdentityUserRoleConfiguration : IEntityTypeConfiguration>
+{
+ public void Configure(EntityTypeBuilder> builder)
+ {
+ builder
+ .ToTable("identity_user_roles");
+
+ builder
+ .Property(ur => ur.UserId)
+ .HasColumnName("user_id");
+
+ builder
+ .Property(ur => ur.RoleId)
+ .HasColumnName("role_id");
+ }
+}
diff --git a/AutobusApi.Infrastructure/Identity/Configurations/IdentityUserTokenConfiguration.cs b/AutobusApi.Infrastructure/Identity/Configurations/IdentityUserTokenConfiguration.cs
new file mode 100644
index 0000000..a0b2f7b
--- /dev/null
+++ b/AutobusApi.Infrastructure/Identity/Configurations/IdentityUserTokenConfiguration.cs
@@ -0,0 +1,30 @@
+using Microsoft.AspNetCore.Identity;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Metadata.Builders;
+
+namespace AutobusApi.Infrastructure.Identity.Configurations;
+
+public class IdentityUserTokenConfiguration : IEntityTypeConfiguration>
+{
+ public void Configure(EntityTypeBuilder> builder)
+ {
+ builder
+ .ToTable("identity_user_tokens");
+
+ builder
+ .Property(ut => ut.UserId)
+ .HasColumnName("user_id");
+
+ builder
+ .Property(ut => ut.LoginProvider)
+ .HasColumnName("login_provider");
+
+ builder
+ .Property(ut => ut.Name)
+ .HasColumnName("name");
+
+ builder
+ .Property(ut => ut.Value)
+ .HasColumnName("value");
+ }
+}
diff --git a/AutobusApi.Infrastructure/Identity/Migrations/20231113193302_InitialCreate.Designer.cs b/AutobusApi.Infrastructure/Identity/Migrations/20231113193302_InitialCreate.Designer.cs
new file mode 100644
index 0000000..ea1bc8f
--- /dev/null
+++ b/AutobusApi.Infrastructure/Identity/Migrations/20231113193302_InitialCreate.Designer.cs
@@ -0,0 +1,357 @@
+//
+using System;
+using AutobusApi.Infrastructure.Identity;
+using Microsoft.EntityFrameworkCore;
+using Microsoft.EntityFrameworkCore.Infrastructure;
+using Microsoft.EntityFrameworkCore.Migrations;
+using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
+using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
+
+#nullable disable
+
+namespace AutobusApi.Infrastructure.Identity.Migrations
+{
+ [DbContext(typeof(ApplicationIdentityDbContext))]
+ [Migration("20231113193302_InitialCreate")]
+ partial class InitialCreate
+ {
+ ///
+ protected override void BuildTargetModel(ModelBuilder modelBuilder)
+ {
+#pragma warning disable 612, 618
+ modelBuilder
+ .HasDefaultSchema("identity")
+ .HasAnnotation("ProductVersion", "7.0.13")
+ .HasAnnotation("Relational:MaxIdentifierLength", 63);
+
+ NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
+
+ modelBuilder.Entity("AutobusApi.Infrastructure.Identity.ApplicationUser", b =>
+ {
+ b.Property("Id")
+ .ValueGeneratedOnAdd()
+ .HasColumnType("integer")
+ .HasColumnName("id");
+
+ NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id"));
+
+ b.Property("AccessFailedCount")
+ .HasColumnType("integer")
+ .HasColumnName("access_failed_count");
+
+ b.Property("ConcurrencyStamp")
+ .IsConcurrencyToken()
+ .HasColumnType("text")
+ .HasColumnName("concurrency_stamp");
+
+ b.Property("Email")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)")
+ .HasColumnName("email");
+
+ b.Property("EmailConfirmed")
+ .HasColumnType("boolean")
+ .HasColumnName("email_confirmed");
+
+ b.Property("LockoutEnabled")
+ .HasColumnType("boolean")
+ .HasColumnName("lockout_enabled");
+
+ b.Property("LockoutEnd")
+ .HasColumnType("timestamp with time zone")
+ .HasColumnName("lockout_end");
+
+ b.Property("NormalizedEmail")
+ .HasMaxLength(256)
+ .HasColumnType("character varying(256)")
+ .HasColumnName("normalized_email");
+
+ b.Property