Admin controller, Locations controller, requests to add available countries, request to get available countries

This commit is contained in:
2024-08-17 21:30:51 +03:00
parent 7cbe3d9698
commit 3cb2083222
59 changed files with 477 additions and 167 deletions

View File

@@ -1,4 +1,5 @@
using Domains.ApplicantDomain;
using Domains.Users;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata.Builders;
@@ -16,6 +17,7 @@ public class ApplicantConfiguration : IEntityTypeConfiguration<Applicant>
entity.HasOne(a => a.CityOfBirth).WithMany().OnDelete(DeleteBehavior.Restrict);
entity.HasOne(a => a.CountryOfBirth).WithMany().OnDelete(DeleteBehavior.Restrict);
entity.HasOne<User>().WithOne().HasForeignKey<Applicant>(a => a.UserId);
entity.Property(p => p.Citizenship)
.IsUnicode(false)

View File

@@ -1,5 +1,6 @@
using ApplicationLayer.DataAccessingServices.Applicants.NeededServices;
using Domains.ApplicantDomain;
using Infrastructure.Database.Applicants.Repositories.Exceptions;
using Infrastructure.Database.Generic;
using Microsoft.EntityFrameworkCore;
@@ -8,9 +9,8 @@ namespace Infrastructure.Database.Applicants.Repositories;
/// Repository pattern for <see cref="Applicant"/>
/// <param name="reader"><inheritdoc cref="IGenericReader"/></param>
/// <param name="writer"><inheritdoc cref="IGenericWriter"/></param>
/// <param name="unitOfWork"><inheritdoc cref="IUnitOfWork"/></param>
public sealed class ApplicantsRepository(IGenericReader reader, IGenericWriter writer, IUnitOfWork unitOfWork)
: GenericRepository<Applicant>(reader, writer, unitOfWork), IApplicantsRepository
public sealed class ApplicantsRepository(IGenericReader reader, IGenericWriter writer)
: GenericRepository<Applicant>(reader, writer), IApplicantsRepository
{
protected override IQueryable<Applicant> LoadDomain()
{
@@ -19,4 +19,10 @@ public sealed class ApplicantsRepository(IGenericReader reader, IGenericWriter w
.Include(a => a.CityOfBirth)
.Include(a => a.PlaceOfWork);
}
async Task<Applicant> IApplicantsRepository.FindByUserIdAsync(Guid userId, CancellationToken cancellationToken)
{
var result = await LoadDomain().SingleOrDefaultAsync(a => a.UserId == userId, cancellationToken);
return result ?? throw new ApplicantNotFoundByUserIdException(userId);
}
}

View File

@@ -0,0 +1,10 @@
using Domains.ApplicantDomain;
using Infrastructure.Database.GeneralExceptions;
namespace Infrastructure.Database.Applicants.Repositories.Exceptions
{
public class ApplicantNotFoundByUserIdException(Guid id) : EntityNotFoundException<Applicant>("Applicant not found.")
{
public Guid UserId { get; private set; } = id;
}
}

View File

@@ -1,4 +1,5 @@
using System.Reflection;
using ApplicationLayer.GeneralNeededServices;
using Infrastructure.Database.Generic;
using Microsoft.EntityFrameworkCore;

View File

@@ -1,8 +1,9 @@
using Domains;
using ApplicationLayer.GeneralExceptions;
using Domains;
namespace Infrastructure.Database.GeneralExceptions;
/// Exception to throw when entity not found
/// <typeparam name="T">Not found entity type</typeparam>
public class EntityNotFoundException<T>(string message) : Exception(message)
public class EntityNotFoundException<T>(string message) : ApiException(message)
where T : class, IEntity;

View File

@@ -7,10 +7,9 @@ namespace Infrastructure.Database.Generic;
/// Generic repository pattern
/// <param name="writer"><inheritdoc cref="IGenericWriter"/></param>
/// <param name="unitOfWork"><inheritdoc cref="IUnitOfWork"/></param>
/// <typeparam name="T">Type of entity</typeparam>
/// <remarks>Should be inherited to create typed repositories</remarks>
public abstract class GenericRepository<T>(IGenericReader reader, IGenericWriter writer, IUnitOfWork unitOfWork) : IGenericRepository<T>
public abstract class GenericRepository<T>(IGenericReader reader, IGenericWriter writer) : IGenericRepository<T>
where T : class, IEntity
{
/// <inheritdoc cref="IGenericRepository{T}.GetAllAsync"/>
@@ -41,10 +40,6 @@ public abstract class GenericRepository<T>(IGenericReader reader, IGenericWriter
writer.Remove(entity);
}
/// <inheritdoc cref="IGenericRepository{T}.SaveAsync"/>
public async Task SaveAsync(CancellationToken cancellationToken)
=> await unitOfWork.SaveAsync(cancellationToken);
/// Should be overriden to load navigation properties of entity
protected virtual IQueryable<T> LoadDomain()
{

View File

@@ -1,4 +1,5 @@
using Domains;
using ApplicationLayer.GeneralNeededServices;
using Domains;
namespace Infrastructure.Database.Generic;

View File

@@ -1,8 +0,0 @@
namespace Infrastructure.Database;
public interface IUnitOfWork
{
/// Saves changes in data storage
/// <param name="cancellationToken">Cancellation Token</param>
Task SaveAsync(CancellationToken cancellationToken);
}

View File

@@ -8,8 +8,10 @@ public class CountryConfiguration : IEntityTypeConfiguration<Country>
{
public void Configure(EntityTypeBuilder<Country> entity)
{
entity.Property(p => p.Name)
entity.Property(c => c.Name)
.IsUnicode(false)
.HasMaxLength(70);
entity.HasIndex(c => c.Name).IsUnique();
}
}
}

View File

@@ -5,8 +5,8 @@ using Microsoft.EntityFrameworkCore;
namespace Infrastructure.Database.Locations.Repositories.Cities;
public sealed class CitiesRepository(IGenericReader reader, IGenericWriter writer, IUnitOfWork unitOfWork)
: GenericRepository<City>(reader, writer, unitOfWork), ICitiesRepository
public sealed class CitiesRepository(IGenericReader reader, IGenericWriter writer)
: GenericRepository<City>(reader, writer), ICitiesRepository
{
protected override IQueryable<City> LoadDomain()
{

View File

@@ -5,11 +5,17 @@ using Microsoft.EntityFrameworkCore;
namespace Infrastructure.Database.Locations.Repositories.Countries;
public sealed class CountriesRepository(IGenericReader reader, IGenericWriter writer, IUnitOfWork unitOfWork)
: GenericRepository<Country>(reader, writer, unitOfWork), ICountriesRepository
public sealed class CountriesRepository(IGenericReader reader, IGenericWriter writer)
: GenericRepository<Country>(reader, writer), ICountriesRepository
{
protected override IQueryable<Country> LoadDomain()
{
return base.LoadDomain().Include(c => c.Cities);
}
}
async Task<Country?> ICountriesRepository.FindByName(string countryName, CancellationToken cancellationToken)
{
var result = await LoadDomain().SingleOrDefaultAsync(c => c.Name == countryName, cancellationToken);
return result;
}
}

View File

@@ -1,4 +1,4 @@
using ApplicationLayer.AuthServices.NeededServices;
using ApplicationLayer.DataAccessingServices.AuthServices.NeededServices;
using Domains.Users;
using Infrastructure.Database.Generic;
using Microsoft.EntityFrameworkCore;
@@ -6,8 +6,8 @@ using Microsoft.EntityFrameworkCore;
namespace Infrastructure.Database.Users.Repositories
{
/// <inheritdoc cref="IUsersRepository"/>
public class UsersRepository(IGenericReader reader, IGenericWriter writer, IUnitOfWork unitOfWork)
: GenericRepository<User>(reader, writer, unitOfWork), IUsersRepository
public class UsersRepository(IGenericReader reader, IGenericWriter writer)
: GenericRepository<User>(reader, writer), IUsersRepository
{
async Task<User?> IUsersRepository.FindByEmailAsync(string email, CancellationToken cancellationToken)
{

View File

@@ -5,8 +5,8 @@ using Microsoft.EntityFrameworkCore;
namespace Infrastructure.Database.VisaApplications.Repositories;
public sealed class VisaApplicationsRepository(IGenericReader reader, IGenericWriter writer, IUnitOfWork unitOfWork)
: GenericRepository<VisaApplication>(reader, writer, unitOfWork), IVisaApplicationsRepository
public sealed class VisaApplicationsRepository(IGenericReader reader, IGenericWriter writer)
: GenericRepository<VisaApplication>(reader, writer), IVisaApplicationsRepository
{
protected override IQueryable<VisaApplication> LoadDomain()
{
@@ -15,4 +15,4 @@ public sealed class VisaApplicationsRepository(IGenericReader reader, IGenericWr
.Include(a => a.PastVisas)
.Include(a => a.PastVisits);
}
}
}