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