diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml deleted file mode 100644 index 2e503d0..0000000 --- a/.github/workflows/main.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: Swagger to HTML - -on: - push: - branches: - - swaggerhub - -jobs: - generate-and-commit-html: - runs-on: ubuntu-latest - - steps: - - name: Checkout - uses: actions/checkout@v3 - - - name: Set up Node.js - uses: actions/setup-node@v3 - with: - node-version: '14' - - - name: Install Redoc CLI - run: npm install -g redoc-cli - - - name: Generate HTML from Swagger YAML - run: redoc-cli bundle swagger.yaml -o node-output/swagger.html - - - name: Commit and Push HTML - run: | - git config --local user.email "action@github.com" - git config --local user.name "GitHub Action" - git add node-output/swagger.html - git commit -m "Generate HTML from Swagger YAML" || echo "No changes to commit" - git push origin HEAD:swaggerhub diff --git a/Directory.Packages.props b/Directory.Packages.props index a9605f2..aa16be3 100644 --- a/Directory.Packages.props +++ b/Directory.Packages.props @@ -4,15 +4,24 @@ false - - - + + + + + + + + + + - + + + \ No newline at end of file diff --git a/src/Application/DoctorsHelp.Application.Contracts/DoctorsHelp.Application.Contracts.csproj b/src/Application/DoctorsHelp.Application.Contracts/DoctorsHelp.Application.Contracts.csproj index a613ac5..0efbdd7 100644 --- a/src/Application/DoctorsHelp.Application.Contracts/DoctorsHelp.Application.Contracts.csproj +++ b/src/Application/DoctorsHelp.Application.Contracts/DoctorsHelp.Application.Contracts.csproj @@ -1,10 +1,8 @@ + - - - \ No newline at end of file diff --git a/src/Application/DoctorsHelp.Application.Contracts/IAppointmentService.cs b/src/Application/DoctorsHelp.Application.Contracts/IAppointmentService.cs index 6aacce2..62dc2bd 100644 --- a/src/Application/DoctorsHelp.Application.Contracts/IAppointmentService.cs +++ b/src/Application/DoctorsHelp.Application.Contracts/IAppointmentService.cs @@ -4,11 +4,11 @@ namespace DoctorsHelp.Application.Contracts; public interface IAppointmentService { - Appointment Create(User patient, Schedule schedule); + Appointment Create(Guid patientId, int scheduleId); - Appointment GetAppointment(int patientId); + Appointment? GetAppointment(int patientId); Appointment Update(int id, Dictionary data); bool Delete(int id); -} \ No newline at end of file +} diff --git a/src/Application/DoctorsHelp.Application.Contracts/IEmployeeService.cs b/src/Application/DoctorsHelp.Application.Contracts/IEmployeeService.cs index 1ea302c..d20faa5 100644 --- a/src/Application/DoctorsHelp.Application.Contracts/IEmployeeService.cs +++ b/src/Application/DoctorsHelp.Application.Contracts/IEmployeeService.cs @@ -4,11 +4,9 @@ namespace DoctorsHelp.Application.Contracts; public interface IEmployeeService { - Employee Create(User user, Specialization specialization, string graduate, string experience); + Employee Create(Guid userId, int specializationId, string graduate, string experience); - Employee GetEmployee(); - - Employee GetById(int id); + Employee? GetEmployee(int employeeId); Employee Update(int id, Dictionary data); diff --git a/src/Application/DoctorsHelp.Application.Contracts/IReviewService.cs b/src/Application/DoctorsHelp.Application.Contracts/IReviewService.cs index a36b487..3d64b36 100644 --- a/src/Application/DoctorsHelp.Application.Contracts/IReviewService.cs +++ b/src/Application/DoctorsHelp.Application.Contracts/IReviewService.cs @@ -4,9 +4,9 @@ namespace DoctorsHelp.Application.Contracts; public interface IReviewService { - Review Create(Appointment appointment, int grade, string comment); + Review Create(int appointmentId, int? grade, string comment); - Review GetReview(int appointmentId); + Review? GetReview(int reviewId); Review Update(int id, Dictionary data); diff --git a/src/Application/DoctorsHelp.Application.Contracts/IScheduleService.cs b/src/Application/DoctorsHelp.Application.Contracts/IScheduleService.cs index 9bc72e0..0a457cf 100644 --- a/src/Application/DoctorsHelp.Application.Contracts/IScheduleService.cs +++ b/src/Application/DoctorsHelp.Application.Contracts/IScheduleService.cs @@ -4,11 +4,11 @@ namespace DoctorsHelp.Application.Contracts; public interface IScheduleService { - Review Create(Employee employee, DateTime dateStart, DateTime dateEnd); + Schedule Create(int employeeId, DateTime? dateStart, DateTime? dateEnd); - Review GeSchedule(int employeeId); + Schedule? GetSchedule(int scheduleId); - Review Update(int id, Dictionary data); + Schedule Update(int id, Dictionary data); bool Delete(int id); } \ No newline at end of file diff --git a/src/Application/DoctorsHelp.Application.Contracts/ISpecializationService.cs b/src/Application/DoctorsHelp.Application.Contracts/ISpecializationService.cs index 9591000..dfc2a3d 100644 --- a/src/Application/DoctorsHelp.Application.Contracts/ISpecializationService.cs +++ b/src/Application/DoctorsHelp.Application.Contracts/ISpecializationService.cs @@ -6,7 +6,7 @@ public interface ISpecializationService { Specialization Create(string name, string description); - Specialization GetSpecialization(int id); + Specialization? GetSpecialization(int id); Specialization Update(int id, Dictionary data); diff --git a/src/Application/DoctorsHelp.Application.Contracts/IUserService.cs b/src/Application/DoctorsHelp.Application.Contracts/IUserService.cs index 999f393..8bee8be 100644 --- a/src/Application/DoctorsHelp.Application.Contracts/IUserService.cs +++ b/src/Application/DoctorsHelp.Application.Contracts/IUserService.cs @@ -4,13 +4,11 @@ namespace DoctorsHelp.Application.Contracts; public interface IUserService { - User Register(string name, string surname, string phone, string email, string password, DateTime birthdate); + User Register(string name, string surname, string phone, string email, string password, DateOnly? birthdate); - User Login(string phone, string password); + User? GetUser(Guid id); - User GetUser(int id); + User UpdateUser(Guid id, Dictionary data); - User Update(int id, Dictionary data); - - bool Delete(int id); + bool DeleteUser(Guid id); } \ No newline at end of file diff --git a/src/Application/DoctorsHelp.Application.Contracts/Services/AppointmentService.cs b/src/Application/DoctorsHelp.Application.Contracts/Services/AppointmentService.cs new file mode 100644 index 0000000..e51837f --- /dev/null +++ b/src/Application/DoctorsHelp.Application.Contracts/Services/AppointmentService.cs @@ -0,0 +1,77 @@ +using DoctorsHelp.Application.Models; +using DoctorsHelp.Infrastructure.Persistence.Converters; +using DoctorsHelp.Infrastructure.Persistence.Interfaces; +using DoctorsHelp.Infrastructure.Persistence.Repositories; +using Infrastructure.Persistence.Models; + +namespace DoctorsHelp.Application.Contracts.Services; + +public class AppointmentService : IAppointmentService +{ + private readonly IAppointmentRepository _appointmentRepository; + private readonly IUserRepository _patientRepository; + private readonly IScheduleRepository _scheduleRepository; + + public AppointmentService(AppointmentRepository appointmentRepository, UserRepository userRepository, ScheduleRepository scheduleRepository) + { + _appointmentRepository = appointmentRepository; + _patientRepository = userRepository; + _scheduleRepository = scheduleRepository; + } + + public Appointment Create(Guid patientId, int scheduleId) + { + User patient = UserConverter.UserModelToUser(_patientRepository.GetUser(patientId)); + Schedule schedule = ScheduleConverter.ScheduleModelToSchedule(_scheduleRepository.GetSchedule(scheduleId)); + + var appointment = new Appointment + { + // Assuming Appointment has a constructor or properties for this + Patient = patient, + Schedule = schedule, + }; + _appointmentRepository.Add(appointment); + return appointment; + } + + public Appointment? GetAppointment(int patientId) + { + var appointmentModel = _appointmentRepository.GetAppointment(patientId); + + return AppointmentConverter.AppointmentModelToAppointment(appointmentModel); + } + + public Appointment Update(int id, Dictionary data) + { + AppointmentModel appointmentToUpdate = _appointmentRepository.GetAppointment(id); + + foreach (var entry in data) + { + switch (entry.Key) + { + case "PatientId": + Guid patientId; + if (Guid.TryParse(entry.Value, out patientId)) + appointmentToUpdate.PatientId = patientId; + break; + case "ScheduleId": + int scheduleId; + if (int.TryParse(entry.Value, out scheduleId)) + appointmentToUpdate.ScheduleId = scheduleId; + break; + case "Status": + int status; + if (int.TryParse(entry.Value, out status)) + appointmentToUpdate.Status = status; + break; + } + } + + return AppointmentConverter.AppointmentModelToAppointment(appointmentToUpdate); + } + + public bool Delete(int id) + { + return _appointmentRepository.Delete(new Appointment { Id = id, }); + } +} diff --git a/src/Application/DoctorsHelp.Application.Contracts/Services/EmployeeService.cs b/src/Application/DoctorsHelp.Application.Contracts/Services/EmployeeService.cs new file mode 100644 index 0000000..004b8d7 --- /dev/null +++ b/src/Application/DoctorsHelp.Application.Contracts/Services/EmployeeService.cs @@ -0,0 +1,79 @@ +using DoctorsHelp.Application.Models; +using DoctorsHelp.Infrastructure.Persistence.Converters; +using DoctorsHelp.Infrastructure.Persistence.Interfaces; +using DoctorsHelp.Infrastructure.Persistence.Repositories; +using Infrastructure.Persistence.Models; + +namespace DoctorsHelp.Application.Contracts.Services; + +public class EmployeeService : IEmployeeService +{ + private readonly IEmployeeRepository _employeeRepository; + private readonly IUserRepository _userRepository; + private readonly ISpecializationRepository _specializationRepository; + + public EmployeeService(EmployeeRepository appointmentRepository, UserRepository userRepository, SpecializationRepository specializationRepository) + { + _employeeRepository = appointmentRepository; + _userRepository = userRepository; + _specializationRepository = specializationRepository; + } + + public Employee Create(Guid userId, int specializationId, string graduate, string experience) + { + User user = UserConverter.UserModelToUser(_userRepository.GetUser(userId)); + Specialization specialization = SpecializationConverter.SpecializationModelToSpecialization(_specializationRepository.GetSpecialization(specializationId)); + + var employee = new Employee + { + User = user, + Specialization = specialization, + Graduate = graduate, + Experience = experience, + }; + _employeeRepository.Add(employee); + return employee; + } + + public Employee? GetEmployee(int employeeId) + { + var employeeModel = _employeeRepository.GetEmployee(employeeId); + + return EmployeeConverter.EmployeeModelToEmployee(employeeModel); + } + + public Employee Update(int id, Dictionary data) + { + EmployeeModel employeeToUpdate = _employeeRepository.GetEmployee(id); + + foreach (var entry in data) + { + switch (entry.Key) + { + case "UserId": + Guid userId; + if (Guid.TryParse(entry.Value, out userId)) + employeeToUpdate.UserId = userId; + break; + case "SpecializationId": + int specializationId; + if (int.TryParse(entry.Value, out specializationId)) + employeeToUpdate.SpecializationId = specializationId; + break; + case "Graduate": + employeeToUpdate.Graduate = entry.Value; + break; + case "Experience": + employeeToUpdate.Experience = entry.Value; + break; + } + } + + return EmployeeConverter.EmployeeModelToEmployee(employeeToUpdate); + } + + public bool Delete(int id) + { + return _employeeRepository.Delete(new Employee { Id = id, }); + } +} \ No newline at end of file diff --git a/src/Application/DoctorsHelp.Application.Contracts/Services/ReviewService.cs b/src/Application/DoctorsHelp.Application.Contracts/Services/ReviewService.cs new file mode 100644 index 0000000..6da3f73 --- /dev/null +++ b/src/Application/DoctorsHelp.Application.Contracts/Services/ReviewService.cs @@ -0,0 +1,72 @@ +using DoctorsHelp.Application.Models; +using DoctorsHelp.Infrastructure.Persistence.Converters; +using DoctorsHelp.Infrastructure.Persistence.Interfaces; +using DoctorsHelp.Infrastructure.Persistence.Repositories; +using Infrastructure.Persistence.Models; + +namespace DoctorsHelp.Application.Contracts.Services; + +public class ReviewService : IReviewService +{ + private readonly IReviewRepository _reviewRepository; + private readonly IAppointmentRepository _appointmentRepository; + + public ReviewService(ReviewRepository reviewRepository, AppointmentRepository appointmentRepository) + { + _reviewRepository = reviewRepository; + _appointmentRepository = appointmentRepository; + } + + public Review Create(int appointmentId, int? grade, string comment) + { + Appointment appointment = AppointmentConverter.AppointmentModelToAppointment(_appointmentRepository.GetAppointment(appointmentId)); + + var review = new Review + { + Appointment = appointment, + Grade = grade, + Comment = comment, + }; + _reviewRepository.Add(review); + return review; + } + + public Review? GetReview(int reviewId) + { + var reviewModel = _reviewRepository.GetReview(reviewId); + + return ReviewConverter.ReviewModelToReview(reviewModel); + } + + public Review Update(int id, Dictionary data) + { + ReviewModel reviewToUpdate = _reviewRepository.GetReview(id); + + foreach (var entry in data) + { + switch (entry.Key) + { + case "AppointmentId": + int appointmentId; + if (int.TryParse(entry.Value, out appointmentId)) + reviewToUpdate.AppointmentId = appointmentId; + break; + case "Rating": + int grade; + if (int.TryParse(entry.Value, out grade)) + reviewToUpdate.Grade = grade; + break; + case "Comment": + reviewToUpdate.Comment = entry.Value; + break; + } + } + + return ReviewConverter.ReviewModelToReview(reviewToUpdate); + } + + public bool Delete(int id) + { + return _reviewRepository.Delete(new Review { Id = id }); + } +} \ No newline at end of file diff --git a/src/Application/DoctorsHelp.Application.Contracts/Services/ScheduleService.cs b/src/Application/DoctorsHelp.Application.Contracts/Services/ScheduleService.cs new file mode 100644 index 0000000..b3135ea --- /dev/null +++ b/src/Application/DoctorsHelp.Application.Contracts/Services/ScheduleService.cs @@ -0,0 +1,71 @@ +using DoctorsHelp.Application.Models; +using DoctorsHelp.Infrastructure.Persistence.Converters; +using DoctorsHelp.Infrastructure.Persistence.Interfaces; +using DoctorsHelp.Infrastructure.Persistence.Repositories; +using Infrastructure.Persistence.Models; + +namespace DoctorsHelp.Application.Contracts.Services; + +public class ScheduleService : IScheduleService +{ + private readonly IScheduleRepository _scheduleRepository; + private readonly IEmployeeRepository _employeeRepository; + + public ScheduleService(ScheduleRepository scheduleRepository, EmployeeRepository employeeRepository) + { + _scheduleRepository = scheduleRepository; + _employeeRepository = employeeRepository; + } + + public Schedule Create(int employeeId, DateTime? dateStart, DateTime? dateEnd) + { + Employee employee = EmployeeConverter.EmployeeModelToEmployee(_employeeRepository.GetEmployee(employeeId)); + + var schedule = new Schedule + { + // Assuming Appointment has a constructor or properties for this + Employee = employee, + DateStart = dateStart, + DateEnd = dateEnd, + }; + _scheduleRepository.Add(schedule); + return schedule; + } + + public Schedule? GetSchedule(int scheduleId) + { + var scheduleModel = _scheduleRepository.GetSchedule(scheduleId); + + return ScheduleConverter.ScheduleModelToSchedule(scheduleModel); + } + + public Schedule Update(int id, Dictionary data) + { + ScheduleModel scheduleToUpdate = _scheduleRepository.GetSchedule(id); + + foreach (var entry in data) + { + switch (entry.Key) + { + case "EmployeeId": + int employeeId; + if (int.TryParse(entry.Value, out employeeId)) + scheduleToUpdate.EmployeeId = employeeId; + break; + case "DateStart": + scheduleToUpdate.DateStart = new DateTime(Convert.ToInt32(entry.Value)); + break; + case "DateEnd": + scheduleToUpdate.DateEnd = new DateTime(Convert.ToInt32(entry.Value)); + break; + } + } + + return ScheduleConverter.ScheduleModelToSchedule(scheduleToUpdate); + } + + public bool Delete(int id) + { + return _scheduleRepository.Delete(new Schedule { Id = id, }); + } +} \ No newline at end of file diff --git a/src/Application/DoctorsHelp.Application.Contracts/Services/SpecializationService.cs b/src/Application/DoctorsHelp.Application.Contracts/Services/SpecializationService.cs new file mode 100644 index 0000000..60b8889 --- /dev/null +++ b/src/Application/DoctorsHelp.Application.Contracts/Services/SpecializationService.cs @@ -0,0 +1,60 @@ +using DoctorsHelp.Application.Models; +using DoctorsHelp.Infrastructure.Persistence.Converters; +using DoctorsHelp.Infrastructure.Persistence.Interfaces; +using DoctorsHelp.Infrastructure.Persistence.Repositories; +using Infrastructure.Persistence.Models; + +namespace DoctorsHelp.Application.Contracts.Services; + +public class SpecializationService : ISpecializationService +{ + private readonly ISpecializationRepository _specializationRepository; + + public SpecializationService(SpecializationRepository specializationRepository) + { + _specializationRepository = specializationRepository; + } + + public Specialization Create(string name, string description) + { + var specialization = new Specialization + { + Name = name, + Description = description, + }; + _specializationRepository.Add(specialization); + return specialization; + } + + public Specialization? GetSpecialization(int id) + { + var specializationModel = _specializationRepository.GetSpecialization(id); + + return SpecializationConverter.SpecializationModelToSpecialization(specializationModel); + } + + public Specialization Update(int id, Dictionary data) + { + SpecializationModel specializationToUpdate = _specializationRepository.GetSpecialization(id); + + foreach (var entry in data) + { + switch (entry.Key) + { + case "Name": + specializationToUpdate.Name = entry.Value; + break; + case "Description": + specializationToUpdate.Description = entry.Value; + break; + } + } + + return SpecializationConverter.SpecializationModelToSpecialization(specializationToUpdate); + } + + public bool Delete(int id) + { + return _specializationRepository.Delete(new Specialization { Id = id }); + } +} \ No newline at end of file diff --git a/src/Application/DoctorsHelp.Application.Contracts/Services/UserService.cs b/src/Application/DoctorsHelp.Application.Contracts/Services/UserService.cs new file mode 100644 index 0000000..cd0fe69 --- /dev/null +++ b/src/Application/DoctorsHelp.Application.Contracts/Services/UserService.cs @@ -0,0 +1,70 @@ +using DoctorsHelp.Application.Models; +using DoctorsHelp.Infrastructure.Persistence.Converters; +using DoctorsHelp.Infrastructure.Persistence.Interfaces; +using DoctorsHelp.Infrastructure.Persistence.Repositories; +using Infrastructure.Persistence.Models; + +namespace DoctorsHelp.Application.Contracts.Services; + +public class UserService : IUserService +{ + private readonly IUserRepository _userRepository; + + public UserService(UserRepository userRepository) + { + _userRepository = userRepository; + } + + public User Register(string name, string surname, string phone, string email, string password, DateOnly? birthdate) + { + var user = new User + { + Name = name, + Surname = surname, + HashedPassword = password, + Phone = phone, + Email = email, + Birthdate = birthdate, + }; + _userRepository.Add(user); + return user; + } + + public User? GetUser(Guid id) + { + var userModel = _userRepository.GetUser(id); + + return UserConverter.UserModelToUser(userModel); + } + + public User UpdateUser(Guid id, Dictionary data) + { + UserModel userToUpdate = _userRepository.GetUser(id); + + foreach (var entry in data) + { + switch (entry.Key) + { + case "Name": + userToUpdate.Name = entry.Value; + break; + case "Surname": + userToUpdate.Surname = entry.Value; + break; + case "Phone": + userToUpdate.Phone = entry.Value; + break; + case "Email": + userToUpdate.Email = entry.Value; + break; + } + } + + return UserConverter.UserModelToUser(userToUpdate); + } + + public bool DeleteUser(Guid id) + { + return _userRepository.Delete(new User { Id = id }); + } +} \ No newline at end of file diff --git a/src/Application/DoctorsHelp.Application.Models/Appointment.cs b/src/Application/DoctorsHelp.Application.Models/Appointment.cs index 3f2a153..b8acd80 100644 --- a/src/Application/DoctorsHelp.Application.Models/Appointment.cs +++ b/src/Application/DoctorsHelp.Application.Models/Appointment.cs @@ -2,15 +2,15 @@ public class Appointment { - public int Id { get; set; } + public int? Id { get; set; } public User? Patient { get; set; } public Schedule? Schedule { get; set; } - public DateTime CreatedAt { get; set; } + public DateTime? CreatedAt { get; set; } - public DateTime UpdatedAt { get; set; } + public DateTime? UpdatedAt { get; set; } - public int Status { get; set; } + public int? Status { get; set; } } \ No newline at end of file diff --git a/src/Application/DoctorsHelp.Application.Models/DoctorsHelp.Application.Models.csproj b/src/Application/DoctorsHelp.Application.Models/DoctorsHelp.Application.Models.csproj index 35e3d84..6b512ec 100644 --- a/src/Application/DoctorsHelp.Application.Models/DoctorsHelp.Application.Models.csproj +++ b/src/Application/DoctorsHelp.Application.Models/DoctorsHelp.Application.Models.csproj @@ -1,2 +1 @@ - - + diff --git a/src/Application/DoctorsHelp.Application.Models/Employee.cs b/src/Application/DoctorsHelp.Application.Models/Employee.cs index 66440a8..a8219db 100644 --- a/src/Application/DoctorsHelp.Application.Models/Employee.cs +++ b/src/Application/DoctorsHelp.Application.Models/Employee.cs @@ -2,11 +2,11 @@ public class Employee { - public int Id { get; set; } + public int? Id { get; set; } public User? User { get; set; } - public int Specialization { get; set; } + public Specialization? Specialization { get; set; } public string? Graduate { get; set; } diff --git a/src/Application/DoctorsHelp.Application.Models/Review.cs b/src/Application/DoctorsHelp.Application.Models/Review.cs index a3e6769..57987e6 100644 --- a/src/Application/DoctorsHelp.Application.Models/Review.cs +++ b/src/Application/DoctorsHelp.Application.Models/Review.cs @@ -2,15 +2,15 @@ public class Review { - public int Id { get; set; } + public int? Id { get; set; } public Appointment? Appointment { get; set; } - public int Grade { get; set; } + public int? Grade { get; set; } public string? Comment { get; set; } - public DateTime CreatedAt { get; set; } + public DateTime? CreatedAt { get; set; } - public DateTime UpdatedAt { get; set; } + public DateTime? UpdatedAt { get; set; } } \ No newline at end of file diff --git a/src/Application/DoctorsHelp.Application.Models/Schedule.cs b/src/Application/DoctorsHelp.Application.Models/Schedule.cs index 2d04da3..6fa2aaa 100644 --- a/src/Application/DoctorsHelp.Application.Models/Schedule.cs +++ b/src/Application/DoctorsHelp.Application.Models/Schedule.cs @@ -2,13 +2,13 @@ public class Schedule { - public int Id { get; set; } + public int? Id { get; set; } public Employee? Employee { get; set; } - public DateTime DateStart { get; set; } + public DateTime? DateStart { get; set; } - public DateTime DateEnd { get; set; } + public DateTime? DateEnd { get; set; } - public int Status { get; set; } + public int? Status { get; set; } } \ No newline at end of file diff --git a/src/Application/DoctorsHelp.Application.Models/Specialization.cs b/src/Application/DoctorsHelp.Application.Models/Specialization.cs index 335b580..2c73aef 100644 --- a/src/Application/DoctorsHelp.Application.Models/Specialization.cs +++ b/src/Application/DoctorsHelp.Application.Models/Specialization.cs @@ -2,7 +2,7 @@ public class Specialization { - public int Id { get; set; } + public int? Id { get; set; } public string? Name { get; set; } diff --git a/src/Application/DoctorsHelp.Application.Models/User.cs b/src/Application/DoctorsHelp.Application.Models/User.cs index 2e5a3b2..127ce12 100644 --- a/src/Application/DoctorsHelp.Application.Models/User.cs +++ b/src/Application/DoctorsHelp.Application.Models/User.cs @@ -2,7 +2,7 @@ public class User { - public Guid Id { get; set; } + public Guid? Id { get; set; } public string? Name { get; set; } @@ -14,7 +14,7 @@ public class User public string? HashedPassword { get; set; } - public DateOnly Birthdate { get; set; } + public DateOnly? Birthdate { get; set; } public string? Role { get; set; } } \ No newline at end of file diff --git a/src/Application/DoctorsHelp.Application/Extensions/ServiceCollectionExtensions.cs b/src/Application/DoctorsHelp.Application/Extensions/ServiceCollectionExtensions.cs index f0449dc..7cefcf8 100644 --- a/src/Application/DoctorsHelp.Application/Extensions/ServiceCollectionExtensions.cs +++ b/src/Application/DoctorsHelp.Application/Extensions/ServiceCollectionExtensions.cs @@ -1,3 +1,5 @@ +using DoctorsHelp.Application.Contracts; +using DoctorsHelp.Application.Contracts.Services; using Microsoft.Extensions.DependencyInjection; namespace DoctorsHelp.Application.Extensions; @@ -6,7 +8,12 @@ public static class ServiceCollectionExtensions { public static IServiceCollection AddApplication(this IServiceCollection collection) { - // TODO: add services + collection.AddScoped(); + collection.AddScoped(); + collection.AddScoped(); + collection.AddScoped(); + collection.AddScoped(); + collection.AddScoped(); return collection; } } \ No newline at end of file diff --git a/src/DoctorsHelp/DoctorsHelp.csproj b/src/DoctorsHelp/DoctorsHelp.csproj index f201af4..7d12243 100644 --- a/src/DoctorsHelp/DoctorsHelp.csproj +++ b/src/DoctorsHelp/DoctorsHelp.csproj @@ -1,15 +1,17 @@ - - + + - + + + diff --git a/src/DoctorsHelp/Program.cs b/src/DoctorsHelp/Program.cs index 7fe3860..e651835 100644 --- a/src/DoctorsHelp/Program.cs +++ b/src/DoctorsHelp/Program.cs @@ -5,34 +5,26 @@ using DoctorsHelp.Presentation.Http.Extensions; using Itmo.Dev.Platform.Common.Extensions; using Itmo.Dev.Platform.Logging.Extensions; -using Microsoft.Extensions.Options; -using Newtonsoft.Json; WebApplicationBuilder builder = WebApplication.CreateBuilder(args); -builder.Configuration.AddUserSecrets(); - -builder.Services.AddOptions(); -builder.Services.AddSingleton(sp => sp.GetRequiredService>().Value); +builder.Services.AddEndpointsApiExplorer(); +builder.Services.AddSwaggerGen(); +builder.Host.AddPlatformSerilog(builder.Configuration); +builder.Services.AddUtcDateTimeProvider(); builder.Services.AddApplication(); -builder.Services.AddInfrastructurePersistence(); +builder.Services.AddInfrastructurePersistence(builder.Configuration); builder.Services .AddControllers() .AddNewtonsoftJson() .AddPresentationHttp(); -builder.Services.AddSwaggerGen().AddEndpointsApiExplorer(); - -builder.Host.AddPlatformSerilog(builder.Configuration); -builder.Services.AddUtcDateTimeProvider(); - WebApplication app = builder.Build(); -app.UseRouting(); app.UseSwagger(); app.UseSwaggerUI(); - +app.UseRouting(); app.MapControllers(); await app.RunAsync(); \ No newline at end of file diff --git a/src/DoctorsHelp/Util/Profiles.cs b/src/DoctorsHelp/Util/Profiles.cs new file mode 100644 index 0000000..79dfd46 --- /dev/null +++ b/src/DoctorsHelp/Util/Profiles.cs @@ -0,0 +1,8 @@ +namespace DoctorsHelp.Util; + +public enum Profiles +{ + Local, + + Prod, +} \ No newline at end of file diff --git a/src/DoctorsHelp/appsettings.Local.json b/src/DoctorsHelp/appsettings.Local.json index a26180e..73ad381 100644 --- a/src/DoctorsHelp/appsettings.Local.json +++ b/src/DoctorsHelp/appsettings.Local.json @@ -4,7 +4,7 @@ "Postgres": { "Host": "localhost", "Port": 6432, - "Database": "postgres", + "Database": "doctorshelp", "Username": "postgres", "Password": "postgres", "SslMode": "Prefer", @@ -17,6 +17,18 @@ "Host": "localhost:9092" } }, + "Kestrel": { + "Endpoints": { + "gRPC": { + "Url": "http://*:3071", + "Protocols": "Http2" + }, + "http": { + "Url": "http://*:3070", + "Protocols": "Http1" + } + } + }, "Platform": { "Environment": "Local" }, diff --git a/src/DoctorsHelp/appsettings.json b/src/DoctorsHelp/appsettings.json index 46b1ad6..1a15e03 100644 --- a/src/DoctorsHelp/appsettings.json +++ b/src/DoctorsHelp/appsettings.json @@ -3,20 +3,14 @@ "Infrastructure": { "Persistence": { "Postgres": { - "Host": "", - "Port": -1, - "Database": "", - "Username": "", - "Password": "", - "SslMode": "Prefer", - "Pooling": true + "ConnectionString": "Host=127.0.0.1;Port=5432;Database=doctorshelp;Username=postgres;Password=postgres" } - }, + } }, "Presentation": { }, "Platform": { - "Environment": "", + "Environment": "" }, "Sentry": { "Enabled": true, @@ -30,8 +24,12 @@ "Kestrel": { "Endpoints": { "gRPC": { - "Url": "http://*:8070", + "Url": "http://*:3071", "Protocols": "Http2" + }, + "http": { + "Url": "http://*:3070", + "Protocols": "Http1" } } }, diff --git a/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Contexts/ApplicationDbContext.cs b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Contexts/ApplicationDbContext.cs new file mode 100644 index 0000000..e52df6c --- /dev/null +++ b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Contexts/ApplicationDbContext.cs @@ -0,0 +1,30 @@ +using Infrastructure.Persistence.Models; +using Microsoft.EntityFrameworkCore; + +namespace DoctorsHelp.Infrastructure.Persistence.Contexts; + +public class ApplicationDbContext : DbContext +{ + public ApplicationDbContext() { } + + public ApplicationDbContext(DbContextOptions options) : base(options) { } + + required public DbSet Users { get; set; } + + required public DbSet Appointments { get; set; } + + required public DbSet Employees { get; set; } + + required public DbSet Reviews { get; set; } + + required public DbSet Schedules { get; set; } + + required public DbSet Specializations { get; set; } + + protected override void OnModelCreating(ModelBuilder modelBuilder) + { + modelBuilder.ApplyConfigurationsFromAssembly(typeof(ApplicationDbContext).Assembly); + + base.OnModelCreating(modelBuilder); + } +} \ No newline at end of file diff --git a/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Converters/AppointmentConverter.cs b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Converters/AppointmentConverter.cs new file mode 100644 index 0000000..a7f2cc1 --- /dev/null +++ b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Converters/AppointmentConverter.cs @@ -0,0 +1,20 @@ +using DoctorsHelp.Application.Models; +using Infrastructure.Persistence.Models; + +namespace DoctorsHelp.Infrastructure.Persistence.Converters; + +public class AppointmentConverter +{ + public static Appointment AppointmentModelToAppointment(AppointmentModel? appointmentModel) + { + return new Appointment + { + Id = appointmentModel?.Id, + Patient = UserConverter.UserModelToUser(appointmentModel?.Patient), + Schedule = ScheduleConverter.ScheduleModelToSchedule(appointmentModel?.Schedule), + CreatedAt = appointmentModel?.CreatedAt, + UpdatedAt = appointmentModel?.UpdatedAt, + Status = appointmentModel?.Status, + }; + } +} \ No newline at end of file diff --git a/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Converters/EmployeeConverter.cs b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Converters/EmployeeConverter.cs new file mode 100644 index 0000000..6821fc3 --- /dev/null +++ b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Converters/EmployeeConverter.cs @@ -0,0 +1,19 @@ +using DoctorsHelp.Application.Models; +using Infrastructure.Persistence.Models; + +namespace DoctorsHelp.Infrastructure.Persistence.Converters; + +public class EmployeeConverter +{ + public static Employee EmployeeModelToEmployee(EmployeeModel? employeeModel) + { + return new Employee + { + Id = employeeModel?.Id, + User = UserConverter.UserModelToUser(employeeModel?.User), + Specialization = SpecializationConverter.SpecializationModelToSpecialization(employeeModel?.Specialization), + Graduate = employeeModel?.Graduate, + Experience = employeeModel?.Experience, + }; + } +} \ No newline at end of file diff --git a/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Converters/ReviewConverter.cs b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Converters/ReviewConverter.cs new file mode 100644 index 0000000..d8eb167 --- /dev/null +++ b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Converters/ReviewConverter.cs @@ -0,0 +1,20 @@ +using DoctorsHelp.Application.Models; +using Infrastructure.Persistence.Models; + +namespace DoctorsHelp.Infrastructure.Persistence.Converters; + +public class ReviewConverter +{ + public static Review ReviewModelToReview(ReviewModel? reviewModel) + { + return new Review + { + Id = reviewModel?.Id, + Appointment = AppointmentConverter.AppointmentModelToAppointment(reviewModel?.Appointment), + Grade = reviewModel?.Grade, + Comment = reviewModel?.Comment, + CreatedAt = reviewModel?.CreatedAt, + UpdatedAt = reviewModel?.UpdatedAt, + }; + } +} \ No newline at end of file diff --git a/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Converters/ScheduleConverter.cs b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Converters/ScheduleConverter.cs new file mode 100644 index 0000000..eda27ad --- /dev/null +++ b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Converters/ScheduleConverter.cs @@ -0,0 +1,19 @@ +using DoctorsHelp.Application.Models; +using Infrastructure.Persistence.Models; + +namespace DoctorsHelp.Infrastructure.Persistence.Converters; + +public class ScheduleConverter +{ + public static Schedule ScheduleModelToSchedule(ScheduleModel? scheduleModel) + { + return new Schedule + { + Id = scheduleModel?.Id, + Employee = EmployeeConverter.EmployeeModelToEmployee(scheduleModel?.Employee), + DateStart = scheduleModel?.DateStart, + DateEnd = scheduleModel?.DateEnd, + Status = scheduleModel?.Status, + }; + } +} \ No newline at end of file diff --git a/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Converters/SpecializationConverter.cs b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Converters/SpecializationConverter.cs new file mode 100644 index 0000000..d17a6ba --- /dev/null +++ b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Converters/SpecializationConverter.cs @@ -0,0 +1,17 @@ +using DoctorsHelp.Application.Models; +using Infrastructure.Persistence.Models; + +namespace DoctorsHelp.Infrastructure.Persistence.Converters; + +public class SpecializationConverter +{ + public static Specialization SpecializationModelToSpecialization(SpecializationModel? specializationModel) + { + return new Specialization + { + Id = specializationModel?.Id, + Name = specializationModel?.Name, + Description = specializationModel?.Description, + }; + } +} \ No newline at end of file diff --git a/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Converters/UserConverter.cs b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Converters/UserConverter.cs new file mode 100644 index 0000000..98b4a57 --- /dev/null +++ b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Converters/UserConverter.cs @@ -0,0 +1,22 @@ +using DoctorsHelp.Application.Models; +using Infrastructure.Persistence.Models; + +namespace DoctorsHelp.Infrastructure.Persistence.Converters; + +public class UserConverter +{ + public static User UserModelToUser(UserModel? userModel) + { + return new User + { + Id = userModel?.Id, + Name = userModel?.Name, + Surname = userModel?.Surname, + Phone = userModel?.Phone, + Email = userModel?.Email, + HashedPassword = userModel?.HashedPassword, + Birthdate = userModel?.Birthdate, + Role = userModel?.Role, + }; + } +} \ No newline at end of file diff --git a/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/DoctorsHelp.Infrastructure.Persistence.csproj b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/DoctorsHelp.Infrastructure.Persistence.csproj index 2aec2b3..e3a3b03 100644 --- a/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/DoctorsHelp.Infrastructure.Persistence.csproj +++ b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/DoctorsHelp.Infrastructure.Persistence.csproj @@ -9,4 +9,12 @@ + + + + + + + + \ No newline at end of file diff --git a/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Extensions/ServiceCollectionExtensions.cs b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Extensions/ServiceCollectionExtensions.cs index dbad899..e6f2fe1 100644 --- a/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Extensions/ServiceCollectionExtensions.cs +++ b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Extensions/ServiceCollectionExtensions.cs @@ -1,24 +1,25 @@ -using DoctorsHelp.Application.Abstractions.Persistence; -using DoctorsHelp.Infrastructure.Persistence.Migrations; -using DoctorsHelp.Infrastructure.Persistence.Plugins; -using Itmo.Dev.Platform.Postgres.Extensions; -using Itmo.Dev.Platform.Postgres.Plugins; +using DoctorsHelp.Infrastructure.Persistence.Contexts; +using DoctorsHelp.Infrastructure.Persistence.Interfaces; +using DoctorsHelp.Infrastructure.Persistence.Repositories; +using Microsoft.EntityFrameworkCore; +using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; namespace DoctorsHelp.Infrastructure.Persistence.Extensions; public static class ServiceCollectionExtensions { - public static IServiceCollection AddInfrastructurePersistence(this IServiceCollection collection) + public static IServiceCollection AddInfrastructurePersistence(this IServiceCollection collection, IConfiguration configuration) { - collection.AddPlatformPostgres(builder => builder.BindConfiguration("Infrastructure:Persistence:Postgres")); - collection.AddSingleton(); + collection.AddDbContext(options => + options.UseNpgsql(configuration.GetSection("Infrastructure:Persistence:Postgres:ConnectionString").Value)); - collection.AddPlatformMigrations(typeof(IAssemblyMarker).Assembly); - collection.AddHostedService(); - - // TODO: add repositories - collection.AddScoped(); + collection.AddScoped(); + collection.AddScoped(); + collection.AddScoped(); + collection.AddScoped(); + collection.AddScoped(); + collection.AddScoped(); return collection; } diff --git a/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Interfaces/IAppointmentRepository.cs b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Interfaces/IAppointmentRepository.cs new file mode 100644 index 0000000..0d999cb --- /dev/null +++ b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Interfaces/IAppointmentRepository.cs @@ -0,0 +1,15 @@ +using DoctorsHelp.Application.Models; +using Infrastructure.Persistence.Models; + +namespace DoctorsHelp.Infrastructure.Persistence.Interfaces; + +public interface IAppointmentRepository +{ + void Add(Appointment appointment); + + AppointmentModel GetAppointment(int id); + + void UpdateAppointment(Appointment appointment); + + bool Delete(Appointment appointment); +} \ No newline at end of file diff --git a/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Interfaces/IEmployeeRepository.cs b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Interfaces/IEmployeeRepository.cs new file mode 100644 index 0000000..c066bbc --- /dev/null +++ b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Interfaces/IEmployeeRepository.cs @@ -0,0 +1,15 @@ +using DoctorsHelp.Application.Models; +using Infrastructure.Persistence.Models; + +namespace DoctorsHelp.Infrastructure.Persistence.Interfaces; + +public interface IEmployeeRepository +{ + void Add(Employee employee); + + EmployeeModel GetEmployee(int id); + + void UpdateEmployee(Employee employee); + + bool Delete(Employee employee); +} \ No newline at end of file diff --git a/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Interfaces/IReviewRepository.cs b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Interfaces/IReviewRepository.cs new file mode 100644 index 0000000..8314493 --- /dev/null +++ b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Interfaces/IReviewRepository.cs @@ -0,0 +1,15 @@ +using DoctorsHelp.Application.Models; +using Infrastructure.Persistence.Models; + +namespace DoctorsHelp.Infrastructure.Persistence.Interfaces; + +public interface IReviewRepository +{ + void Add(Review review); + + ReviewModel GetReview(int id); + + void UpdateReview(Review review); + + bool Delete(Review review); +} \ No newline at end of file diff --git a/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Interfaces/IScheduleRepository.cs b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Interfaces/IScheduleRepository.cs new file mode 100644 index 0000000..1e6da01 --- /dev/null +++ b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Interfaces/IScheduleRepository.cs @@ -0,0 +1,15 @@ +using DoctorsHelp.Application.Models; +using Infrastructure.Persistence.Models; + +namespace DoctorsHelp.Infrastructure.Persistence.Interfaces; + +public interface IScheduleRepository +{ + void Add(Schedule schedule); + + ScheduleModel GetSchedule(int id); + + void Update(Schedule schedule); + + bool Delete(Schedule schedule); +} \ No newline at end of file diff --git a/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Interfaces/ISpecializationRepository.cs b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Interfaces/ISpecializationRepository.cs new file mode 100644 index 0000000..02c66ef --- /dev/null +++ b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Interfaces/ISpecializationRepository.cs @@ -0,0 +1,15 @@ +using DoctorsHelp.Application.Models; +using Infrastructure.Persistence.Models; + +namespace DoctorsHelp.Infrastructure.Persistence.Interfaces; + +public interface ISpecializationRepository +{ + void Add(Specialization specialization); + + SpecializationModel GetSpecialization(int id); + + void UpdateSpecialization(Specialization specialization); + + bool Delete(Specialization specialization); +} \ No newline at end of file diff --git a/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Interfaces/IUserRepository.cs b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Interfaces/IUserRepository.cs new file mode 100644 index 0000000..8921927 --- /dev/null +++ b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Interfaces/IUserRepository.cs @@ -0,0 +1,15 @@ +using DoctorsHelp.Application.Models; +using Infrastructure.Persistence.Models; + +namespace DoctorsHelp.Infrastructure.Persistence.Interfaces; + +public interface IUserRepository +{ + void Add(User user); + + UserModel GetUser(Guid id); + + void UpdateUser(User user); + + bool Delete(User user); +} \ No newline at end of file diff --git a/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Migrations/20240316100013_Initial.Designer.cs b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Migrations/20240316100013_Initial.Designer.cs new file mode 100644 index 0000000..24a26aa --- /dev/null +++ b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Migrations/20240316100013_Initial.Designer.cs @@ -0,0 +1,239 @@ +// +using System; +using DoctorsHelp.Infrastructure.Persistence.Contexts; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Migrations; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace DoctorsHelp.Infrastructure.Persistence.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + [Migration("20240316100013_Initial")] + partial class Initial + { + /// + protected override void BuildTargetModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.10") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("DoctorsHelp.Application.Models.Appointment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("PatientId") + .HasColumnType("uuid"); + + b.Property("ScheduleId") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("PatientId"); + + b.HasIndex("ScheduleId"); + + b.ToTable("Appointments"); + }); + + modelBuilder.Entity("DoctorsHelp.Application.Models.Employee", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Experience") + .HasColumnType("text"); + + b.Property("Graduate") + .HasColumnType("text"); + + b.Property("Specialization") + .HasColumnType("integer"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Employees"); + }); + + modelBuilder.Entity("DoctorsHelp.Application.Models.Review", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AppointmentId") + .HasColumnType("integer"); + + b.Property("Comment") + .HasColumnType("text"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Grade") + .HasColumnType("integer"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("AppointmentId"); + + b.ToTable("Reviews"); + }); + + modelBuilder.Entity("DoctorsHelp.Application.Models.Schedule", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("DateEnd") + .HasColumnType("timestamp with time zone"); + + b.Property("DateStart") + .HasColumnType("timestamp with time zone"); + + b.Property("EmployeeId") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("EmployeeId"); + + b.ToTable("Schedules"); + }); + + modelBuilder.Entity("DoctorsHelp.Application.Models.Specialization", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Description") + .HasColumnType("text"); + + b.Property("Name") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Specializations"); + }); + + modelBuilder.Entity("DoctorsHelp.Application.Models.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Birthdate") + .HasColumnType("date"); + + b.Property("Email") + .HasColumnType("text"); + + b.Property("HashedPassword") + .HasColumnType("text"); + + b.Property("Name") + .HasColumnType("text"); + + b.Property("Phone") + .HasColumnType("text"); + + b.Property("Role") + .HasColumnType("text"); + + b.Property("Surname") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("DoctorsHelp.Application.Models.Appointment", b => + { + b.HasOne("DoctorsHelp.Application.Models.User", "Patient") + .WithMany() + .HasForeignKey("PatientId"); + + b.HasOne("DoctorsHelp.Application.Models.Schedule", "Schedule") + .WithMany() + .HasForeignKey("ScheduleId"); + + b.Navigation("Patient"); + + b.Navigation("Schedule"); + }); + + modelBuilder.Entity("DoctorsHelp.Application.Models.Employee", b => + { + b.HasOne("DoctorsHelp.Application.Models.User", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("DoctorsHelp.Application.Models.Review", b => + { + b.HasOne("DoctorsHelp.Application.Models.Appointment", "Appointment") + .WithMany() + .HasForeignKey("AppointmentId"); + + b.Navigation("Appointment"); + }); + + modelBuilder.Entity("DoctorsHelp.Application.Models.Schedule", b => + { + b.HasOne("DoctorsHelp.Application.Models.Employee", "Employee") + .WithMany() + .HasForeignKey("EmployeeId"); + + b.Navigation("Employee"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Migrations/20240316100013_Initial.cs b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Migrations/20240316100013_Initial.cs new file mode 100644 index 0000000..2013210 --- /dev/null +++ b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Migrations/20240316100013_Initial.cs @@ -0,0 +1,184 @@ +using Microsoft.EntityFrameworkCore.Migrations; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace DoctorsHelp.Infrastructure.Persistence.Migrations; + +/// +public partial class Initial : Migration +{ + /// + protected override void Up(MigrationBuilder migrationBuilder) + { + migrationBuilder.CreateTable( + name: "Specializations", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + Name = table.Column(type: "text", nullable: true), + Description = table.Column(type: "text", nullable: true), + }, + constraints: table => + { + table.PrimaryKey("PK_Specializations", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Users", + columns: table => new + { + Id = table.Column(type: "uuid", nullable: false), + Name = table.Column(type: "text", nullable: true), + Surname = table.Column(type: "text", nullable: true), + Phone = table.Column(type: "text", nullable: true), + Email = table.Column(type: "text", nullable: true), + HashedPassword = table.Column(type: "text", nullable: true), + Birthdate = table.Column(type: "date", nullable: false), + Role = table.Column(type: "text", nullable: true), + }, + constraints: table => + { + table.PrimaryKey("PK_Users", x => x.Id); + }); + + migrationBuilder.CreateTable( + name: "Employees", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + UserId = table.Column(type: "uuid", nullable: true), + Specialization = table.Column(type: "integer", nullable: false), + Graduate = table.Column(type: "text", nullable: true), + Experience = table.Column(type: "text", nullable: true), + }, + constraints: table => + { + table.PrimaryKey("PK_Employees", x => x.Id); + table.ForeignKey( + name: "FK_Employees_Users_UserId", + column: x => x.UserId, + principalTable: "Users", + principalColumn: "Id"); + }); + + migrationBuilder.CreateTable( + name: "Schedules", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + EmployeeId = table.Column(type: "integer", nullable: true), + DateStart = table.Column(type: "timestamp with time zone", nullable: false), + DateEnd = table.Column(type: "timestamp with time zone", nullable: false), + Status = table.Column(type: "integer", nullable: false), + }, + constraints: table => + { + table.PrimaryKey("PK_Schedules", x => x.Id); + table.ForeignKey( + name: "FK_Schedules_Employees_EmployeeId", + column: x => x.EmployeeId, + principalTable: "Employees", + principalColumn: "Id"); + }); + + migrationBuilder.CreateTable( + name: "Appointments", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + PatientId = table.Column(type: "uuid", nullable: true), + ScheduleId = table.Column(type: "integer", nullable: true), + CreatedAt = table.Column(type: "timestamp with time zone", nullable: false), + UpdatedAt = table.Column(type: "timestamp with time zone", nullable: false), + Status = table.Column(type: "integer", nullable: false), + }, + constraints: table => + { + table.PrimaryKey("PK_Appointments", x => x.Id); + table.ForeignKey( + name: "FK_Appointments_Schedules_ScheduleId", + column: x => x.ScheduleId, + principalTable: "Schedules", + principalColumn: "Id"); + table.ForeignKey( + name: "FK_Appointments_Users_PatientId", + column: x => x.PatientId, + principalTable: "Users", + principalColumn: "Id"); + }); + + migrationBuilder.CreateTable( + name: "Reviews", + columns: table => new + { + Id = table.Column(type: "integer", nullable: false) + .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), + AppointmentId = table.Column(type: "integer", nullable: true), + Grade = table.Column(type: "integer", nullable: false), + Comment = table.Column(type: "text", nullable: true), + CreatedAt = table.Column(type: "timestamp with time zone", nullable: false), + UpdatedAt = table.Column(type: "timestamp with time zone", nullable: false), + }, + constraints: table => + { + table.PrimaryKey("PK_Reviews", x => x.Id); + table.ForeignKey( + name: "FK_Reviews_Appointments_AppointmentId", + column: x => x.AppointmentId, + principalTable: "Appointments", + principalColumn: "Id"); + }); + + migrationBuilder.CreateIndex( + name: "IX_Appointments_PatientId", + table: "Appointments", + column: "PatientId"); + + migrationBuilder.CreateIndex( + name: "IX_Appointments_ScheduleId", + table: "Appointments", + column: "ScheduleId"); + + migrationBuilder.CreateIndex( + name: "IX_Employees_UserId", + table: "Employees", + column: "UserId"); + + migrationBuilder.CreateIndex( + name: "IX_Reviews_AppointmentId", + table: "Reviews", + column: "AppointmentId"); + + migrationBuilder.CreateIndex( + name: "IX_Schedules_EmployeeId", + table: "Schedules", + column: "EmployeeId"); + } + + /// + protected override void Down(MigrationBuilder migrationBuilder) + { + migrationBuilder.DropTable( + name: "Reviews"); + + migrationBuilder.DropTable( + name: "Specializations"); + + migrationBuilder.DropTable( + name: "Appointments"); + + migrationBuilder.DropTable( + name: "Schedules"); + + migrationBuilder.DropTable( + name: "Employees"); + + migrationBuilder.DropTable( + name: "Users"); + } +} diff --git a/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Migrations/ApplicationDbContextModelSnapshot.cs b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Migrations/ApplicationDbContextModelSnapshot.cs new file mode 100644 index 0000000..93cea9d --- /dev/null +++ b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Migrations/ApplicationDbContextModelSnapshot.cs @@ -0,0 +1,236 @@ +// +using System; +using DoctorsHelp.Infrastructure.Persistence.Contexts; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage.ValueConversion; +using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; + +#nullable disable + +namespace DoctorsHelp.Infrastructure.Persistence.Migrations +{ + [DbContext(typeof(ApplicationDbContext))] + partial class ApplicationDbContextModelSnapshot : ModelSnapshot + { + protected override void BuildModel(ModelBuilder modelBuilder) + { +#pragma warning disable 612, 618 + modelBuilder + .HasAnnotation("ProductVersion", "7.0.10") + .HasAnnotation("Relational:MaxIdentifierLength", 63); + + NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder); + + modelBuilder.Entity("DoctorsHelp.Application.Models.Appointment", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("PatientId") + .HasColumnType("uuid"); + + b.Property("ScheduleId") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("integer"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("PatientId"); + + b.HasIndex("ScheduleId"); + + b.ToTable("Appointments"); + }); + + modelBuilder.Entity("DoctorsHelp.Application.Models.Employee", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Experience") + .HasColumnType("text"); + + b.Property("Graduate") + .HasColumnType("text"); + + b.Property("Specialization") + .HasColumnType("integer"); + + b.Property("UserId") + .HasColumnType("uuid"); + + b.HasKey("Id"); + + b.HasIndex("UserId"); + + b.ToTable("Employees"); + }); + + modelBuilder.Entity("DoctorsHelp.Application.Models.Review", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("AppointmentId") + .HasColumnType("integer"); + + b.Property("Comment") + .HasColumnType("text"); + + b.Property("CreatedAt") + .HasColumnType("timestamp with time zone"); + + b.Property("Grade") + .HasColumnType("integer"); + + b.Property("UpdatedAt") + .HasColumnType("timestamp with time zone"); + + b.HasKey("Id"); + + b.HasIndex("AppointmentId"); + + b.ToTable("Reviews"); + }); + + modelBuilder.Entity("DoctorsHelp.Application.Models.Schedule", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("DateEnd") + .HasColumnType("timestamp with time zone"); + + b.Property("DateStart") + .HasColumnType("timestamp with time zone"); + + b.Property("EmployeeId") + .HasColumnType("integer"); + + b.Property("Status") + .HasColumnType("integer"); + + b.HasKey("Id"); + + b.HasIndex("EmployeeId"); + + b.ToTable("Schedules"); + }); + + modelBuilder.Entity("DoctorsHelp.Application.Models.Specialization", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("integer"); + + NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property("Id")); + + b.Property("Description") + .HasColumnType("text"); + + b.Property("Name") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Specializations"); + }); + + modelBuilder.Entity("DoctorsHelp.Application.Models.User", b => + { + b.Property("Id") + .ValueGeneratedOnAdd() + .HasColumnType("uuid"); + + b.Property("Birthdate") + .HasColumnType("date"); + + b.Property("Email") + .HasColumnType("text"); + + b.Property("HashedPassword") + .HasColumnType("text"); + + b.Property("Name") + .HasColumnType("text"); + + b.Property("Phone") + .HasColumnType("text"); + + b.Property("Role") + .HasColumnType("text"); + + b.Property("Surname") + .HasColumnType("text"); + + b.HasKey("Id"); + + b.ToTable("Users"); + }); + + modelBuilder.Entity("DoctorsHelp.Application.Models.Appointment", b => + { + b.HasOne("DoctorsHelp.Application.Models.User", "Patient") + .WithMany() + .HasForeignKey("PatientId"); + + b.HasOne("DoctorsHelp.Application.Models.Schedule", "Schedule") + .WithMany() + .HasForeignKey("ScheduleId"); + + b.Navigation("Patient"); + + b.Navigation("Schedule"); + }); + + modelBuilder.Entity("DoctorsHelp.Application.Models.Employee", b => + { + b.HasOne("DoctorsHelp.Application.Models.User", "User") + .WithMany() + .HasForeignKey("UserId"); + + b.Navigation("User"); + }); + + modelBuilder.Entity("DoctorsHelp.Application.Models.Review", b => + { + b.HasOne("DoctorsHelp.Application.Models.Appointment", "Appointment") + .WithMany() + .HasForeignKey("AppointmentId"); + + b.Navigation("Appointment"); + }); + + modelBuilder.Entity("DoctorsHelp.Application.Models.Schedule", b => + { + b.HasOne("DoctorsHelp.Application.Models.Employee", "Employee") + .WithMany() + .HasForeignKey("EmployeeId"); + + b.Navigation("Employee"); + }); +#pragma warning restore 612, 618 + } + } +} diff --git a/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Models/AppointmentModel.cs b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Models/AppointmentModel.cs new file mode 100644 index 0000000..cda19da --- /dev/null +++ b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Models/AppointmentModel.cs @@ -0,0 +1,20 @@ +namespace Infrastructure.Persistence.Models; + +public class AppointmentModel +{ + public int? Id { get; set; } + + public Guid PatientId { get; set; } + + public int ScheduleId { get; set; } + + public DateTime? CreatedAt { get; set; } + + public DateTime? UpdatedAt { get; set; } + + public int? Status { get; set; } + + public UserModel? Patient { get; set; } + + public ScheduleModel? Schedule { get; set; } +} \ No newline at end of file diff --git a/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Models/EmployeeModel.cs b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Models/EmployeeModel.cs new file mode 100644 index 0000000..634d9fd --- /dev/null +++ b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Models/EmployeeModel.cs @@ -0,0 +1,18 @@ +namespace Infrastructure.Persistence.Models; + +public class EmployeeModel +{ + public int? Id { get; set; } + + public Guid UserId { get; set; } + + public int? SpecializationId { get; set; } + + public string? Graduate { get; set; } + + public string? Experience { get; set; } + + public UserModel? User { get; set; } + + public SpecializationModel? Specialization { get; set; } +} \ No newline at end of file diff --git a/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Models/ReviewModel.cs b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Models/ReviewModel.cs new file mode 100644 index 0000000..08f3dfc --- /dev/null +++ b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Models/ReviewModel.cs @@ -0,0 +1,18 @@ +namespace Infrastructure.Persistence.Models; + +public class ReviewModel +{ + public int? Id { get; set; } + + public int AppointmentId { get; set; } + + public int? Grade { get; set; } + + public string? Comment { get; set; } + + public DateTime? CreatedAt { get; set; } + + public DateTime? UpdatedAt { get; set; } + + public AppointmentModel? Appointment { get; set; } +} \ No newline at end of file diff --git a/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Models/ScheduleModel.cs b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Models/ScheduleModel.cs new file mode 100644 index 0000000..5a432c3 --- /dev/null +++ b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Models/ScheduleModel.cs @@ -0,0 +1,16 @@ +namespace Infrastructure.Persistence.Models; + +public class ScheduleModel +{ + public int? Id { get; set; } + + public int EmployeeId { get; set; } + + public DateTime? DateStart { get; set; } + + public DateTime? DateEnd { get; set; } + + public int? Status { get; set; } + + public EmployeeModel? Employee { get; set; } +} \ No newline at end of file diff --git a/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Models/SpecializationModel.cs b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Models/SpecializationModel.cs new file mode 100644 index 0000000..277cb44 --- /dev/null +++ b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Models/SpecializationModel.cs @@ -0,0 +1,10 @@ +namespace Infrastructure.Persistence.Models; + +public class SpecializationModel +{ + public int? Id { get; set; } + + public string? Name { get; set; } + + public string? Description { get; set; } +} \ No newline at end of file diff --git a/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Models/UserModel.cs b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Models/UserModel.cs new file mode 100644 index 0000000..87ba2a9 --- /dev/null +++ b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Models/UserModel.cs @@ -0,0 +1,20 @@ +namespace Infrastructure.Persistence.Models; + +public class UserModel +{ + public Guid? Id { get; set; } + + public string? Name { get; set; } + + public string? Surname { get; set; } + + public string? Phone { get; set; } + + public string? Email { get; set; } + + public string? HashedPassword { get; set; } + + public DateOnly? Birthdate { get; set; } + + public string? Role { get; set; } +} \ No newline at end of file diff --git a/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Repositories/AppointmentRepository.cs b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Repositories/AppointmentRepository.cs new file mode 100644 index 0000000..5ade7f7 --- /dev/null +++ b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Repositories/AppointmentRepository.cs @@ -0,0 +1,59 @@ +using DoctorsHelp.Application.Models; +using DoctorsHelp.Infrastructure.Persistence.Contexts; +using DoctorsHelp.Infrastructure.Persistence.Interfaces; +using Infrastructure.Persistence.Models; +using Microsoft.EntityFrameworkCore; + +namespace DoctorsHelp.Infrastructure.Persistence.Repositories; + +public class AppointmentRepository : RepositoryBase, IAppointmentRepository +{ + public AppointmentRepository(ApplicationDbContext context) : base(context) + { + } + + public AppointmentModel GetAppointment(int id) + { + return GetEntry(new Appointment { Id = id }).Entity; + } + + public void UpdateAppointment(Appointment appointment) + { + Update(appointment); + } + + public bool Delete(Appointment appointment) + { + Remove(appointment); + return true; + } + + protected override DbSet DbSet => ((ApplicationDbContext)Context).Appointments; + + protected override AppointmentModel MapFrom(Appointment entity) + { + return new AppointmentModel + { + Id = entity.Id, + PatientId = entity.Patient?.Id ?? Guid.Empty, + ScheduleId = entity.Schedule?.Id ?? 0, + CreatedAt = entity.CreatedAt, + UpdatedAt = entity.UpdatedAt, + Status = entity.Status, + }; + } + + protected override bool Equal(Appointment entity, AppointmentModel model) + { + return entity.Id == model.Id; + } + + protected override void UpdateModel(AppointmentModel model, Appointment entity) + { + model.PatientId = entity.Patient?.Id ?? Guid.Empty; + model.ScheduleId = entity.Schedule?.Id ?? 0; + model.CreatedAt = entity.CreatedAt; + model.UpdatedAt = entity.UpdatedAt; + model.Status = entity.Status; + } +} \ No newline at end of file diff --git a/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Repositories/EmployeeRepository.cs b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Repositories/EmployeeRepository.cs new file mode 100644 index 0000000..ab358e6 --- /dev/null +++ b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Repositories/EmployeeRepository.cs @@ -0,0 +1,57 @@ +using DoctorsHelp.Application.Models; +using DoctorsHelp.Infrastructure.Persistence.Contexts; +using DoctorsHelp.Infrastructure.Persistence.Interfaces; +using Infrastructure.Persistence.Models; +using Microsoft.EntityFrameworkCore; + +namespace DoctorsHelp.Infrastructure.Persistence.Repositories; + +public class EmployeeRepository : RepositoryBase, IEmployeeRepository +{ + public EmployeeRepository(ApplicationDbContext context) : base(context) + { + } + + public EmployeeModel GetEmployee(int id) + { + return GetEntry(new Employee { Id = id }).Entity; + } + + public void UpdateEmployee(Employee employee) + { + Update(employee); + } + + public bool Delete(Employee employee) + { + Remove(employee); + return true; + } + + protected override DbSet DbSet => ((ApplicationDbContext)Context).Employees; + + protected override EmployeeModel MapFrom(Employee entity) + { + return new EmployeeModel + { + Id = entity.Id, + UserId = entity.User?.Id ?? Guid.Empty, + SpecializationId = entity.Specialization?.Id, + Graduate = entity.Graduate, + Experience = entity.Experience, + }; + } + + protected override bool Equal(Employee entity, EmployeeModel model) + { + return entity.Id == model.Id; + } + + protected override void UpdateModel(EmployeeModel model, Employee entity) + { + model.UserId = entity.User?.Id ?? Guid.Empty; + model.SpecializationId = entity.Specialization?.Id; + model.Graduate = entity.Graduate; + model.Experience = entity.Experience; + } +} \ No newline at end of file diff --git a/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Repositories/RepositoryBase.cs b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Repositories/RepositoryBase.cs new file mode 100644 index 0000000..ee3fdae --- /dev/null +++ b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Repositories/RepositoryBase.cs @@ -0,0 +1,60 @@ +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.ChangeTracking; + +namespace DoctorsHelp.Infrastructure.Persistence.Repositories; + +public abstract class RepositoryBase where TModel : class +{ + #pragma warning disable IDE0032 + private readonly DbContext _context; + + protected DbContext Context => _context; + + protected RepositoryBase(DbContext context) + { + this._context = context; + } + + protected abstract DbSet DbSet { get; } + + public void Add(TEntity entity) + { + TModel model = MapFrom(entity); + DbSet.Add(model); + } + + public void AddRange(IEnumerable entities) + { + IEnumerable models = entities.Select(MapFrom); + DbSet.AddRange(models); + } + + public void Update(TEntity entity) + { + EntityEntry entry = GetEntry(entity); + UpdateModel(entry.Entity, entity); + + entry.State = EntityState.Modified; + } + + public void Remove(TEntity entity) + { + EntityEntry entry = GetEntry(entity); + entry.State = entry.State is EntityState.Added ? EntityState.Detached : EntityState.Deleted; + } + + protected abstract TModel MapFrom(TEntity entity); + + protected abstract bool Equal(TEntity entity, TModel model); + + protected abstract void UpdateModel(TModel model, TEntity entity); + + protected EntityEntry GetEntry(TEntity entity) + { + TModel? existing = DbSet.Local.FirstOrDefault(model => Equal(entity, model)); + + return existing is not null + ? _context.Entry(existing) + : DbSet.Attach(MapFrom(entity)); + } +} \ No newline at end of file diff --git a/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Repositories/ReviewRepository.cs b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Repositories/ReviewRepository.cs new file mode 100644 index 0000000..71343bb --- /dev/null +++ b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Repositories/ReviewRepository.cs @@ -0,0 +1,59 @@ +using DoctorsHelp.Application.Models; +using DoctorsHelp.Infrastructure.Persistence.Contexts; +using DoctorsHelp.Infrastructure.Persistence.Interfaces; +using Infrastructure.Persistence.Models; +using Microsoft.EntityFrameworkCore; + +namespace DoctorsHelp.Infrastructure.Persistence.Repositories; + +public class ReviewRepository : RepositoryBase, IReviewRepository +{ + public ReviewRepository(ApplicationDbContext context) : base(context) + { + } + + public ReviewModel GetReview(int id) + { + return GetEntry(new Review { Id = id }).Entity; + } + + public void UpdateReview(Review review) + { + Update(review); + } + + public bool Delete(Review review) + { + Remove(review); + return true; + } + + protected override DbSet DbSet => ((ApplicationDbContext)Context).Reviews; + + protected override ReviewModel MapFrom(Review entity) + { + return new ReviewModel + { + Id = entity.Id, + AppointmentId = entity.Appointment?.Id ?? 0, + Grade = entity.Grade, + Comment = entity.Comment, + CreatedAt = entity.CreatedAt, + UpdatedAt = entity.UpdatedAt, + }; + } + + protected override bool Equal(Review entity, ReviewModel model) + { + return entity.Id == model.Id; + } + + protected override void UpdateModel(ReviewModel model, Review entity) + { + model.AppointmentId = entity.Appointment?.Id ?? 0; + model.Grade = entity.Grade; + model.Comment = entity.Comment; + model.CreatedAt = entity.CreatedAt; + model.UpdatedAt = entity.UpdatedAt; + } +} \ No newline at end of file diff --git a/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Repositories/ScheduleRepository.cs b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Repositories/ScheduleRepository.cs new file mode 100644 index 0000000..3e838dc --- /dev/null +++ b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Repositories/ScheduleRepository.cs @@ -0,0 +1,52 @@ +using DoctorsHelp.Application.Models; +using DoctorsHelp.Infrastructure.Persistence.Contexts; +using DoctorsHelp.Infrastructure.Persistence.Interfaces; +using Infrastructure.Persistence.Models; +using Microsoft.EntityFrameworkCore; + +namespace DoctorsHelp.Infrastructure.Persistence.Repositories; + +public class ScheduleRepository : RepositoryBase, IScheduleRepository +{ + public ScheduleRepository(ApplicationDbContext context) : base(context) + { + } + + public ScheduleModel GetSchedule(int id) + { + return GetEntry(new Schedule { Id = id }).Entity; + } + + public bool Delete(Schedule schedule) + { + Remove(schedule); + return true; + } + + protected override DbSet DbSet => ((ApplicationDbContext)Context).Schedules; + + protected override ScheduleModel MapFrom(Schedule entity) + { + return new ScheduleModel + { + Id = entity.Id, + EmployeeId = entity.Employee?.Id ?? 0, + DateStart = entity.DateStart, + DateEnd = entity.DateEnd, + Status = entity.Status, + }; + } + + protected override bool Equal(Schedule entity, ScheduleModel model) + { + return entity.Id == model.Id; + } + + protected override void UpdateModel(ScheduleModel model, Schedule entity) + { + model.EmployeeId = entity.Employee?.Id ?? 0; + model.DateStart = entity.DateStart; + model.DateEnd = entity.DateEnd; + model.Status = entity.Status; + } +} \ No newline at end of file diff --git a/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Repositories/SpecializationRepository.cs b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Repositories/SpecializationRepository.cs new file mode 100644 index 0000000..532a45c --- /dev/null +++ b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Repositories/SpecializationRepository.cs @@ -0,0 +1,53 @@ +using DoctorsHelp.Application.Models; +using DoctorsHelp.Infrastructure.Persistence.Contexts; +using DoctorsHelp.Infrastructure.Persistence.Interfaces; +using Infrastructure.Persistence.Models; +using Microsoft.EntityFrameworkCore; + +namespace DoctorsHelp.Infrastructure.Persistence.Repositories; + +public class SpecializationRepository : RepositoryBase, ISpecializationRepository +{ + public SpecializationRepository(ApplicationDbContext context) : base(context) + { + } + + public void UpdateSpecialization(Specialization specialization) + { + Update(specialization); + } + + public SpecializationModel GetSpecialization(int id) + { + return GetEntry(new Specialization { Id = id }).Entity; + } + + public bool Delete(Specialization specialization) + { + Remove(specialization); + return true; + } + + protected override DbSet DbSet => ((ApplicationDbContext)Context).Specializations; + + protected override SpecializationModel MapFrom(Specialization entity) + { + return new SpecializationModel + { + Id = entity.Id, + Name = entity.Name, + Description = entity.Description, + }; + } + + protected override bool Equal(Specialization entity, SpecializationModel model) + { + return entity.Id == model.Id; + } + + protected override void UpdateModel(SpecializationModel model, Specialization entity) + { + model.Name = entity.Name; + model.Description = entity.Description; + } +} \ No newline at end of file diff --git a/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Repositories/UserRepository.cs b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Repositories/UserRepository.cs new file mode 100644 index 0000000..0082838 --- /dev/null +++ b/src/Infrastructure/DoctorsHelp.Infrastructure.Persistence/Repositories/UserRepository.cs @@ -0,0 +1,63 @@ +using DoctorsHelp.Application.Models; +using DoctorsHelp.Infrastructure.Persistence.Contexts; +using DoctorsHelp.Infrastructure.Persistence.Interfaces; +using Infrastructure.Persistence.Models; +using Microsoft.EntityFrameworkCore; + +namespace DoctorsHelp.Infrastructure.Persistence.Repositories; + +public class UserRepository : RepositoryBase, IUserRepository +{ + public UserRepository(ApplicationDbContext context) : base(context) + { + } + + public UserModel GetUser(Guid id) + { + return GetEntry(new User { Id = id }).Entity; + } + + public void UpdateUser(User user) + { + Update(user); + } + + public bool Delete(User user) + { + Remove(user); + return true; + } + + protected override DbSet DbSet => ((ApplicationDbContext)Context).Users; + + protected override UserModel MapFrom(User entity) + { + return new UserModel + { + Id = entity.Id, + Name = entity.Name, + Surname = entity.Surname, + Phone = entity.Phone, + Email = entity.Email, + HashedPassword = entity.HashedPassword, + Birthdate = entity.Birthdate, + Role = entity.Role, + }; + } + + protected override bool Equal(User entity, UserModel model) + { + return entity.Id == model.Id; + } + + protected override void UpdateModel(UserModel model, User entity) + { + model.Name = entity.Name; + model.Surname = entity.Surname; + model.Phone = entity.Phone; + model.Email = entity.Email; + model.HashedPassword = entity.HashedPassword; + model.Birthdate = entity.Birthdate; + model.Role = entity.Role; + } +} \ No newline at end of file diff --git a/src/Presentation/DoctorsHelp.Presentation.Http/Controllers/AppointmentController.cs b/src/Presentation/DoctorsHelp.Presentation.Http/Controllers/AppointmentController.cs new file mode 100644 index 0000000..1dcd99d --- /dev/null +++ b/src/Presentation/DoctorsHelp.Presentation.Http/Controllers/AppointmentController.cs @@ -0,0 +1,71 @@ +using DoctorsHelp.Application.Contracts; +using DoctorsHelp.Application.Models; +using DoctorsHelp.Presentation.Http.Requests; +using Microsoft.AspNetCore.Mvc; + +namespace DoctorsHelp.Presentation.Http.Controllers; +[ApiController] +[Route("[controller]")] +public class AppointmentController : ControllerBase +{ + private readonly IAppointmentService _appointmentService; + + public AppointmentController(IAppointmentService appointmentService) + { + _appointmentService = appointmentService; + } + + [HttpGet("{id}")] + public ActionResult Get(int id) + { + var appointment = _appointmentService.GetAppointment(id); + if (appointment == null) + { + return NotFound(); + } + + return Ok(appointment); + } + + [HttpPost] + public ActionResult Post([FromBody] AppointmentPost data) + { + try + { + var createdAppointment = _appointmentService.Create(data.PatientId, data.ScheduleId); + return CreatedAtAction(nameof(Get), new { id = createdAppointment.Id }, createdAppointment); + } + catch (Exception ex) + { + return StatusCode(500, "An error occurred while creating the appointment." + ex); + } + } + + [HttpPut("{id}")] + public ActionResult Update(int id, [FromBody] Dictionary data) + { + try + { + var updatedAppointment = _appointmentService.Update(id, data); + return Ok(updatedAppointment); + } + catch (KeyNotFoundException) + { + return NotFound(); + } + } + + [HttpDelete("{id}")] + public IActionResult Delete(int id) + { + var result = _appointmentService.Delete(id); + if (result) + { + return NoContent(); + } + else + { + return NotFound(); + } + } +} diff --git a/src/Presentation/DoctorsHelp.Presentation.Http/Controllers/EmployeeController.cs b/src/Presentation/DoctorsHelp.Presentation.Http/Controllers/EmployeeController.cs new file mode 100644 index 0000000..51ec312 --- /dev/null +++ b/src/Presentation/DoctorsHelp.Presentation.Http/Controllers/EmployeeController.cs @@ -0,0 +1,77 @@ +using DoctorsHelp.Application.Contracts; +using DoctorsHelp.Application.Models; +using DoctorsHelp.Presentation.Http.Requests; +using Microsoft.AspNetCore.Mvc; + +namespace DoctorsHelp.Presentation.Http.Controllers; + +[ApiController] +[Route("[controller]")] +public class EmployeeController : ControllerBase +{ + private readonly IEmployeeService _employeeService; + + public EmployeeController(IEmployeeService employeeService) + { + _employeeService = employeeService; + } + + [HttpGet("{id}")] + public ActionResult Get(int id) + { + var employee = _employeeService.GetEmployee(id); + if (employee == null) + { + return NotFound(); + } + + return Ok(employee); + } + + [HttpPost] + public ActionResult Post([FromBody] EmployeePost data) + { + if (string.IsNullOrWhiteSpace(data.Graduate) || string.IsNullOrWhiteSpace(data.Experience)) + { + return BadRequest("User, Specialization, Graduate, and Experience are required."); + } + + try + { + var createdEmployee = _employeeService.Create(data.UserId, data.SpecializationId, data.Graduate, data.Experience); + return CreatedAtAction(nameof(Get), new { id = createdEmployee.Id }, createdEmployee); + } + catch (Exception ex) + { + return StatusCode(500, "An error occurred while creating the employee. " + ex.Message); + } + } + + [HttpPut("{id}")] + public ActionResult Update(int id, [FromBody] Dictionary data) + { + try + { + var updatedEmployee = _employeeService.Update(id, data); + return Ok(updatedEmployee); + } + catch (KeyNotFoundException) + { + return NotFound(); + } + } + + [HttpDelete("{id}")] + public IActionResult Delete(int id) + { + var result = _employeeService.Delete(id); + if (result) + { + return NoContent(); + } + else + { + return NotFound(); + } + } +} diff --git a/src/Presentation/DoctorsHelp.Presentation.Http/Controllers/ReviewController.cs b/src/Presentation/DoctorsHelp.Presentation.Http/Controllers/ReviewController.cs new file mode 100644 index 0000000..f505756 --- /dev/null +++ b/src/Presentation/DoctorsHelp.Presentation.Http/Controllers/ReviewController.cs @@ -0,0 +1,77 @@ +using DoctorsHelp.Application.Contracts; +using DoctorsHelp.Application.Models; +using DoctorsHelp.Presentation.Http.Requests; +using Microsoft.AspNetCore.Mvc; + +namespace DoctorsHelp.Presentation.Http.Controllers; + +[ApiController] +[Route("[controller]")] +public class ReviewController : ControllerBase +{ + private readonly IReviewService _reviewService; + + public ReviewController(IReviewService reviewService) + { + _reviewService = reviewService; + } + + [HttpGet("{id}")] + public ActionResult Get(int id) + { + var review = _reviewService.GetReview(id); + if (review == null) + { + return NotFound(); + } + + return Ok(review); + } + + [HttpPost] + public ActionResult Post([FromBody] ReviewPost data) + { + if (data.Grade < 1 || string.IsNullOrWhiteSpace(data.Comment)) + { + return BadRequest("Appointment, Grade, and Comment are required."); + } + + try + { + var createdReview = _reviewService.Create(data.AppointmentId, data.Grade, data.Comment); + return CreatedAtAction(nameof(Get), new { id = createdReview.Id }, createdReview); + } + catch (Exception ex) + { + return StatusCode(500, "An error occurred while creating the review. " + ex.Message); + } + } + + [HttpPut("{id}")] + public ActionResult Update(int id, [FromBody] Dictionary data) + { + try + { + var updatedReview = _reviewService.Update(id, data); + return Ok(updatedReview); + } + catch (KeyNotFoundException) + { + return NotFound(); + } + } + + [HttpDelete("{id}")] + public IActionResult Delete(int id) + { + var result = _reviewService.Delete(id); + if (result) + { + return NoContent(); + } + else + { + return NotFound(); + } + } +} diff --git a/src/Presentation/DoctorsHelp.Presentation.Http/Controllers/ScheduleController.cs b/src/Presentation/DoctorsHelp.Presentation.Http/Controllers/ScheduleController.cs new file mode 100644 index 0000000..6f25469 --- /dev/null +++ b/src/Presentation/DoctorsHelp.Presentation.Http/Controllers/ScheduleController.cs @@ -0,0 +1,82 @@ +using DoctorsHelp.Application.Contracts; +using DoctorsHelp.Application.Models; +using DoctorsHelp.Presentation.Http.Requests; +using Microsoft.AspNetCore.Mvc; + +namespace DoctorsHelp.Presentation.Http.Controllers; + +[ApiController] +[Route("[controller]")] +public class ScheduleController : ControllerBase +{ + private readonly IScheduleService _scheduleService; + + public ScheduleController(IScheduleService scheduleService) + { + _scheduleService = scheduleService; + } + + [HttpGet("{id}")] + public ActionResult Get(int id) + { + var schedule = _scheduleService.GetSchedule(id); + if (schedule == null) + { + return NotFound(); + } + + return Ok(schedule); + } + + [HttpPost] + public ActionResult Post([FromBody] SchedulePost data) + { + if (data.DateStart == default || data.DateEnd == default) + { + return BadRequest("Employee, DateStart, and DateEnd are required."); + } + + if (data.DateStart >= data.DateEnd) + { + return BadRequest("DateStart must be before DateEnd."); + } + + try + { + var createdSchedule = _scheduleService.Create(data.EmployeeId, data.DateStart, data.DateEnd); + return CreatedAtAction(nameof(Get), new { id = createdSchedule.Id }, createdSchedule); + } + catch (Exception ex) + { + return StatusCode(500, "An error occurred while creating the schedule. " + ex.Message); + } + } + + [HttpPut("{id}")] + public ActionResult Update(int id, [FromBody] Dictionary data) + { + try + { + var updatedSchedule = _scheduleService.Update(id, data); + return Ok(updatedSchedule); + } + catch (KeyNotFoundException) + { + return NotFound(); + } + } + + [HttpDelete("{id}")] + public IActionResult Delete(int id) + { + var result = _scheduleService.Delete(id); + if (result) + { + return NoContent(); + } + else + { + return NotFound(); + } + } +} diff --git a/src/Presentation/DoctorsHelp.Presentation.Http/Controllers/SpecializationController.cs b/src/Presentation/DoctorsHelp.Presentation.Http/Controllers/SpecializationController.cs new file mode 100644 index 0000000..bf36cd4 --- /dev/null +++ b/src/Presentation/DoctorsHelp.Presentation.Http/Controllers/SpecializationController.cs @@ -0,0 +1,77 @@ +using DoctorsHelp.Application.Contracts; +using DoctorsHelp.Application.Models; +using DoctorsHelp.Presentation.Http.Requests; +using Microsoft.AspNetCore.Mvc; + +namespace DoctorsHelp.Presentation.Http.Controllers; + +[ApiController] +[Route("[controller]")] +public class SpecializationController : ControllerBase +{ + private readonly ISpecializationService _specializationService; + + public SpecializationController(ISpecializationService specializationService) + { + _specializationService = specializationService; + } + + [HttpGet("{id}")] + public ActionResult Get(int id) + { + var specialization = _specializationService.GetSpecialization(id); + if (specialization == null) + { + return NotFound(); + } + + return Ok(specialization); + } + + [HttpPost] + public ActionResult Post([FromBody] SpecializationPost data) + { + if (data.Name == null || data.Description == null) + { + return BadRequest("Name and Description are required."); + } + + try + { + var createdSpecialization = _specializationService.Create(data.Name, data.Description); + return CreatedAtAction(nameof(Get), new { id = createdSpecialization.Id }, createdSpecialization); + } + catch (Exception ex) + { + return StatusCode(500, "An error occurred while creating the specialization." + ex); + } + } + + [HttpPut("{id}")] + public ActionResult Update(int id, [FromBody] Dictionary data) + { + try + { + var updatedSpecialization = _specializationService.Update(id, data); + return Ok(updatedSpecialization); + } + catch (KeyNotFoundException) + { + return NotFound(); + } + } + + [HttpDelete("{id}")] + public IActionResult Delete(int id) + { + var result = _specializationService.Delete(id); + if (result) + { + return NoContent(); + } + else + { + return NotFound(); + } + } +} \ No newline at end of file diff --git a/src/Presentation/DoctorsHelp.Presentation.Http/Controllers/UserController.cs b/src/Presentation/DoctorsHelp.Presentation.Http/Controllers/UserController.cs new file mode 100644 index 0000000..4224753 --- /dev/null +++ b/src/Presentation/DoctorsHelp.Presentation.Http/Controllers/UserController.cs @@ -0,0 +1,81 @@ +using DoctorsHelp.Application.Contracts; +using DoctorsHelp.Application.Models; +using DoctorsHelp.Presentation.Http.Requests; +using Microsoft.AspNetCore.Mvc; + +namespace DoctorsHelp.Presentation.Http.Controllers; + +[ApiController] +[Route("[controller]")] +public class UserController : ControllerBase +{ + private readonly IUserService _userService; + + public UserController(IUserService userService) + { + _userService = userService; + } + + [HttpGet("{id}")] + public ActionResult Get(Guid id) + { + var user = _userService.GetUser(id); + if (user == null) + { + return NotFound(); + } + + return Ok(user); + } + + [HttpPost("register")] + public ActionResult Register([FromBody] UserPost data) + { + if (string.IsNullOrWhiteSpace(data.Name) || + string.IsNullOrWhiteSpace(data.Surname) || + string.IsNullOrWhiteSpace(data.Phone) || + string.IsNullOrWhiteSpace(data.Email) || + string.IsNullOrWhiteSpace(data.Password)) + { + return BadRequest("All fields are required."); + } + + try + { + var user = _userService.Register(data.Name, data.Surname, data.Phone, data.Email, data.Password, data.Birthdate); + return CreatedAtAction(nameof(Get), new { id = user.Id }, user); + } + catch (Exception ex) + { + return StatusCode(500, "An error occurred while registering the user. " + ex.Message); + } + } + + [HttpPut("{id}")] + public ActionResult Update(Guid id, [FromBody] Dictionary data) + { + try + { + var updatedUser = _userService.UpdateUser(id, data); + return Ok(updatedUser); + } + catch (KeyNotFoundException) + { + return NotFound(); + } + } + + [HttpDelete("{id}")] + public IActionResult Delete(Guid id) + { + var result = _userService.DeleteUser(id); + if (result) + { + return NoContent(); + } + else + { + return NotFound(); + } + } +} \ No newline at end of file diff --git a/src/Presentation/DoctorsHelp.Presentation.Http/DoctorsHelp.Presentation.Http.csproj b/src/Presentation/DoctorsHelp.Presentation.Http/DoctorsHelp.Presentation.Http.csproj index 21d1366..b0f89eb 100644 --- a/src/Presentation/DoctorsHelp.Presentation.Http/DoctorsHelp.Presentation.Http.csproj +++ b/src/Presentation/DoctorsHelp.Presentation.Http/DoctorsHelp.Presentation.Http.csproj @@ -5,7 +5,7 @@ - + \ No newline at end of file diff --git a/src/Presentation/DoctorsHelp.Presentation.Http/Requests/AppointmentPost.cs b/src/Presentation/DoctorsHelp.Presentation.Http/Requests/AppointmentPost.cs new file mode 100644 index 0000000..a039709 --- /dev/null +++ b/src/Presentation/DoctorsHelp.Presentation.Http/Requests/AppointmentPost.cs @@ -0,0 +1,8 @@ +namespace DoctorsHelp.Presentation.Http.Requests; + +public class AppointmentPost +{ + public Guid PatientId { get; set; } + + public int ScheduleId { get; set; } +} \ No newline at end of file diff --git a/src/Presentation/DoctorsHelp.Presentation.Http/Requests/EmployeePost.cs b/src/Presentation/DoctorsHelp.Presentation.Http/Requests/EmployeePost.cs new file mode 100644 index 0000000..ec39450 --- /dev/null +++ b/src/Presentation/DoctorsHelp.Presentation.Http/Requests/EmployeePost.cs @@ -0,0 +1,12 @@ +namespace DoctorsHelp.Presentation.Http.Requests; + +public class EmployeePost +{ + public Guid UserId { get; set; } + + public int SpecializationId { get; set; } + + public string? Graduate { get; set; } + + public string? Experience { get; set; } +} \ No newline at end of file diff --git a/src/Presentation/DoctorsHelp.Presentation.Http/Requests/ReviewPost.cs b/src/Presentation/DoctorsHelp.Presentation.Http/Requests/ReviewPost.cs new file mode 100644 index 0000000..432f679 --- /dev/null +++ b/src/Presentation/DoctorsHelp.Presentation.Http/Requests/ReviewPost.cs @@ -0,0 +1,10 @@ +namespace DoctorsHelp.Presentation.Http.Requests; + +public class ReviewPost +{ + public int AppointmentId { get; set; } + + public int Grade { get; set; } + + public string? Comment { get; set; } +} \ No newline at end of file diff --git a/src/Presentation/DoctorsHelp.Presentation.Http/Requests/SchedulePost.cs b/src/Presentation/DoctorsHelp.Presentation.Http/Requests/SchedulePost.cs new file mode 100644 index 0000000..76b7e45 --- /dev/null +++ b/src/Presentation/DoctorsHelp.Presentation.Http/Requests/SchedulePost.cs @@ -0,0 +1,10 @@ +namespace DoctorsHelp.Presentation.Http.Requests; + +public class SchedulePost +{ + public int EmployeeId { get; set; } + + public DateTime? DateStart { get; set; } + + public DateTime? DateEnd { get; set; } +} \ No newline at end of file diff --git a/src/Presentation/DoctorsHelp.Presentation.Http/Requests/SpecializationPost.cs b/src/Presentation/DoctorsHelp.Presentation.Http/Requests/SpecializationPost.cs new file mode 100644 index 0000000..92f5848 --- /dev/null +++ b/src/Presentation/DoctorsHelp.Presentation.Http/Requests/SpecializationPost.cs @@ -0,0 +1,8 @@ +namespace DoctorsHelp.Presentation.Http.Requests; + +public class SpecializationPost +{ + public string? Name { get; set; } + + public string? Description { get; set; } +} \ No newline at end of file diff --git a/src/Presentation/DoctorsHelp.Presentation.Http/Requests/UserPost.cs b/src/Presentation/DoctorsHelp.Presentation.Http/Requests/UserPost.cs new file mode 100644 index 0000000..8eeb26b --- /dev/null +++ b/src/Presentation/DoctorsHelp.Presentation.Http/Requests/UserPost.cs @@ -0,0 +1,16 @@ +namespace DoctorsHelp.Presentation.Http.Requests; + +public class UserPost +{ + public string? Name { get; set; } + + public string? Surname { get; set; } + + public string? Phone { get; set; } + + public string? Email { get; set; } + + public string? Password { get; set; } + + public DateOnly Birthdate { get; set; } +} \ No newline at end of file