diff --git a/Backend/prepAIred.API/Controllers/AuthController.cs b/Backend/prepAIred.API/Controllers/AuthController.cs
index 530fb33..5721b74 100644
--- a/Backend/prepAIred.API/Controllers/AuthController.cs
+++ b/Backend/prepAIred.API/Controllers/AuthController.cs
@@ -1,5 +1,6 @@
using prepAIred.Data;
using prepAIred.Services;
+using prepAIred.Exceptions;
using Microsoft.AspNetCore.Mvc;
namespace prepAIred.API
@@ -9,43 +10,107 @@ namespace prepAIred.API
///
///
/// This controller is responsible for handling HTTP requests related to authentication flows. It interacts
- /// with the for authentication operations and for token management.
+ /// with the for authentication operations and for token management.
///
- /// Repository for handling authentication operations
- /// Repository for managing refresh tokens
+ /// Repository for handling authentication operations
+ /// Repository for managing refresh tokens
[ApiController]
- [Route("api/[controller]")]
- public class AuthController(IAuthRepository authRepository, IRefreshTokenRepository refreshTokenRepository) : Controller
+ [Route("api/auth")]
+ public class AuthController(IAuthService authService, IRefreshTokenService refreshTokenService) : Controller
{
- private readonly IAuthRepository _authRepository = authRepository;
- private readonly IRefreshTokenRepository _refreshTokenService = refreshTokenRepository;
+ private readonly IAuthService _authService = authService;
+ private readonly IRefreshTokenService _refreshTokenService = refreshTokenService;
[HttpPost("register")]
public async Task Register([FromBody] UserCredentialsDTO userCredentialsDto)
{
- await _authRepository.RegisterAsync(userCredentialsDto);
- return Ok("Register successful");
+ try
+ {
+ await _authService.RegisterAsync(userCredentialsDto);
+ return Ok("Register successful");
+ }
+ catch (InvalidCredentialsException ex)
+ {
+ return Unauthorized(ex.Message);
+ }
+ catch (UserAlreadyExistsException ex)
+ {
+ return Conflict(ex.Message);
+ }
+ catch (EmptyFieldsException ex)
+ {
+ return BadRequest(ex.Message);
+ }
+ catch (Exception ex)
+ {
+ return StatusCode(500, ex.Message);
+ }
}
[HttpPost("login")]
public async Task Login([FromBody] LoginDTO loginDto)
{
- await _authRepository.LoginAsync(loginDto);
- return Ok("Login successful");
+ try
+ {
+ await _authService.LoginAsync(loginDto);
+ return Ok("Login successful");
+ }
+ catch (InvalidCredentialsException ex)
+ {
+ return Unauthorized(ex.Message);
+ }
+ catch (EmptyFieldsException ex)
+ {
+ return BadRequest(ex.Message);
+ }
+ catch (Exception ex)
+ {
+ return StatusCode(500, ex.Message);
+ }
}
[HttpPost("refresh-token")]
public async Task GenerateNewRefreshToken()
{
- RefreshTokenResponseDTO newRefreshToken = await _refreshTokenService.GenerateNewRefreshTokenAsync();
- return Ok(newRefreshToken);
+ try
+ {
+ RefreshTokenResponseDTO newRefreshToken = await _refreshTokenService.GenerateNewRefreshTokenAsync();
+ return Ok(newRefreshToken);
+ }
+ catch (InvalidRefreshTokenException ex)
+ {
+ return Unauthorized(ex.Message);
+ }
+ catch (InvalidAccessTokenException ex)
+ {
+ return Unauthorized(ex.Message);
+ }
+ catch (NoUserLoggedInException ex)
+ {
+ return Unauthorized(ex.Message);
+ }
+ catch (Exception ex)
+ {
+ return StatusCode(500, ex.Message);
+ }
}
[HttpPost("logout")]
public async Task Logout()
{
- await _authRepository.LogoutAsync();
- return Ok("Logged out successfully");
+ try
+ {
+ await _authService.LogoutAsync();
+ return Ok("Logged out successfully");
+ }
+ catch (NoUserLoggedInException ex)
+ {
+ return Unauthorized(ex.Message);
+ }
+ catch (Exception ex)
+ {
+ return StatusCode(500, ex.Message);
+ }
}
}
}
\ No newline at end of file
diff --git a/Backend/prepAIred.API/Controllers/InterviewController.cs b/Backend/prepAIred.API/Controllers/InterviewController.cs
index e46fa81..7aa3dd2 100644
--- a/Backend/prepAIred.API/Controllers/InterviewController.cs
+++ b/Backend/prepAIred.API/Controllers/InterviewController.cs
@@ -1,5 +1,6 @@
using prepAIred.Data;
using prepAIred.Services;
+using prepAIred.Exceptions;
using Microsoft.AspNetCore.Mvc;
namespace prepAIred.API
@@ -9,54 +10,144 @@ namespace prepAIred.API
///
/// This controller serves as the API layer for interacting with interview data. It exposes
/// endpoints for creating new AI interviews and retrieving existing ones. The controller depends on an
- /// implementation to handle interview data operations.
- /// Repository for handling interview operations
+ /// implementation to handle interview data operations.
+ /// Repository for handling interview operations
[ApiController]
- [Route("api/[controller]")]
- public class InterviewController(IInterviewRepository interviewRepository) : Controller
+ [Route("api/interviews")]
+ public class InterviewController(IInterviewService interviewService) : Controller
{
- private readonly IInterviewRepository _interviewRepository = interviewRepository;
+ private readonly IInterviewService _interviewService = interviewService;
- [HttpPost("generate-hr-interviews")]
+ [HttpPost("hr")]
public async Task GenerateHrInterview([FromBody] HrRequestDTO hrRequest)
{
- await _interviewRepository.GenerateInterviewsAsync(hrRequest);
- return Ok("HR interviews created successfully.");
+ try
+ {
+ await _interviewService.GenerateInterviewsAsync(hrRequest);
+ return Ok("HR interviews created successfully.");
+ }
+ catch (InterviewSessionNotFoundException ex)
+ {
+ return NotFound(ex.Message);
+ }
+ catch (ResourceNotFoundException ex)
+ {
+ return NotFound(ex.Message);
+ }
+ catch (Exception ex)
+ {
+ return StatusCode(500, ex.Message);
+ }
}
- [HttpGet("get-latest-hr-interviews")]
+ [HttpGet("hr/latest")]
public async Task GetLatestHrInterview()
{
- List hrInterviews = await _interviewRepository.GetLatestInterviewsAsync();
- return Ok(hrInterviews);
+ try
+ {
+ List hrInterviews = await _interviewService.GetLatestInterviewsAsync();
+ return Ok(hrInterviews);
+ }
+ catch (InterviewSessionNotFoundException ex)
+ {
+ return NotFound(ex.Message);
+ }
+ catch (ResourceNotFoundException ex)
+ {
+ return NotFound(ex.Message);
+ }
+ catch (Exception ex)
+ {
+ return StatusCode(500, ex.Message);
+ }
}
- [HttpPost("evaluate-hr-interviews")]
+ [HttpPost("hr/evaluations")]
public async Task EvaluateHrInterviews([FromBody] List evaluateRequests)
{
- await _interviewRepository.EvaluateInterviewsAsync(evaluateRequests);
- return Ok("HR interviews evaluated successfully.");
+ try
+ {
+ await _interviewService.EvaluateInterviewsAsync(evaluateRequests);
+ return Ok("HR interviews evaluated successfully.");
+ }
+ catch (InterviewSessionNotFoundException ex)
+ {
+ return NotFound(ex.Message);
+ }
+ catch (ResourceNotFoundException ex)
+ {
+ return NotFound(ex.Message);
+ }
+ catch (Exception ex)
+ {
+ return StatusCode(500, ex.Message);
+ }
}
- [HttpPost("generate-technical-interviews")]
+ [HttpPost("technical")]
public async Task GenerateTechnicalInterviews([FromBody] TechnicalRequestDTO technicalRequest)
{
- await _interviewRepository.GenerateInterviewsAsync(technicalRequest);
- return Ok("Technical interviews created successfully.");
+ try
+ {
+ await _interviewService.GenerateInterviewsAsync(technicalRequest);
+ return Ok("Technical interviews created successfully.");
+ }
+ catch (InterviewSessionNotFoundException ex)
+ {
+ return NotFound(ex.Message);
+ }
+ catch (ResourceNotFoundException ex)
+ {
+ return NotFound(ex.Message);
+ }
+ catch (Exception ex)
+ {
+ return StatusCode(500, ex.Message);
+ }
}
- [HttpGet("get-latest-technical-interviews")]
+ [HttpGet("technical/latest")]
public async Task GetLatestTechnicalInterview()
{
- List technicalInterviews = await _interviewRepository.GetLatestInterviewsAsync();
- return Ok(technicalInterviews);
+ try
+ {
+ List technicalInterviews = await _interviewService.GetLatestInterviewsAsync();
+ return Ok(technicalInterviews);
+ }
+ catch (InterviewSessionNotFoundException ex)
+ {
+ return NotFound(ex.Message);
+ }
+ catch (ResourceNotFoundException ex)
+ {
+ return NotFound(ex.Message);
+ }
+ catch (Exception ex)
+ {
+ return StatusCode(500, ex.Message);
+ }
}
- [HttpPost("evaluate-technical-interviews")]
+ [HttpPost("technical/evaluations")]
public async Task EvaluateTechnicalInterviews([FromBody] List evaluateRequests)
{
- await _interviewRepository.EvaluateInterviewsAsync(evaluateRequests);
- return Ok("Technical interviews evaluated successfully.");
+ try
+ {
+ await _interviewService.EvaluateInterviewsAsync(evaluateRequests);
+ return Ok("Technical interviews evaluated successfully.");
+ }
+ catch (InterviewSessionNotFoundException ex)
+ {
+ return NotFound(ex.Message);
+ }
+ catch (ResourceNotFoundException ex)
+ {
+ return NotFound(ex.Message);
+ }
+ catch (Exception ex)
+ {
+ return StatusCode(500, ex.Message);
+ }
}
}
}
\ No newline at end of file
diff --git a/Backend/prepAIred.API/Controllers/InterviewSessionController.cs b/Backend/prepAIred.API/Controllers/InterviewSessionController.cs
index a67b170..31eb2b3 100644
--- a/Backend/prepAIred.API/Controllers/InterviewSessionController.cs
+++ b/Backend/prepAIred.API/Controllers/InterviewSessionController.cs
@@ -1,5 +1,6 @@
using prepAIred.Data;
using prepAIred.Services;
+using prepAIred.Exceptions;
using Microsoft.AspNetCore.Mvc;
namespace prepAIred.API
@@ -8,69 +9,157 @@ namespace prepAIred.API
/// Provides endpoints for managing interview sessions, including retrieving and deleting sessions.
///
/// This controller handles HTTP requests related to interview sessions. It interacts with the
- /// to perform operations such as retrieving a list of interview sessions
+ /// to perform operations such as retrieving a list of interview sessions
/// and deleting all existing sessions.
- ///
+ ///
[ApiController]
- [Route("api/[controller]")]
- public class InterviewSessionController(IInterviewSessionRepository interviewSessionRepository) : Controller
+ [Route("api/interview-sessions")]
+ public class InterviewSessionController(IInterviewSessionService interviewSessionService) : Controller
{
- private readonly IInterviewSessionRepository _interviewSessionRepository = interviewSessionRepository;
+ private readonly IInterviewSessionService _interviewSessionService = interviewSessionService;
- [HttpGet("get-interview-sessions")]
+ [HttpGet]
public async Task GetInterviewSessionDTOs()
{
- List interviewSessions = await _interviewSessionRepository.GetInterviewSessionDTOsAsync();
- return Ok(interviewSessions);
+ try
+ {
+ List interviewSessions = await _interviewSessionService.GetInterviewSessionDTOsAsync();
+ return Ok(interviewSessions);
+ }
+ catch (InterviewSessionNotFoundException ex)
+ {
+ return NotFound(ex.Message);
+ }
+ catch (Exception ex)
+ {
+ return StatusCode(500, ex.Message);
+ }
}
- [HttpGet("get-interview-session-activities")]
+ [HttpGet("activities")]
public async Task GetInterviewSessionActivities()
{
- List interviewSessionActivities = await _interviewSessionRepository.GetInterviewSessionActivitiesAsync();
- return Ok(interviewSessionActivities);
+ try
+ {
+ List interviewSessionActivities = await _interviewSessionService.GetInterviewSessionActivitiesAsync();
+ return Ok(interviewSessionActivities);
+ }
+ catch (InterviewSessionNotFoundException ex)
+ {
+ return NotFound(ex.Message);
+ }
+ catch (Exception ex)
+ {
+ return StatusCode(500, ex.Message);
+ }
}
- [HttpGet("get-interview-session-statistics")]
+ [HttpGet("statistics")]
public async Task GetInterviewSessionStatistics()
{
- ProfileStatisticsDTO profileStats = await _interviewSessionRepository.GetInterviewSessionStatisticsAsync();
- return Ok(profileStats);
+ try
+ {
+ ProfileStatisticsDTO profileStats = await _interviewSessionService.GetInterviewSessionStatisticsAsync();
+ return Ok(profileStats);
+ }
+ catch (InterviewSessionNotFoundException ex)
+ {
+ return NotFound(ex.Message);
+ }
+ catch (Exception ex)
+ {
+ return StatusCode(500, ex.Message);
+ }
}
- [HttpGet("get-interview-session-performance")]
+ [HttpGet("performance")]
public async Task GetInterviewSessionPerformance()
{
- List performanceData = await _interviewSessionRepository.GetInterviewSessionPerformanceAsync();
- return Ok(performanceData);
+ try
+ {
+ List performanceData = await _interviewSessionService.GetInterviewSessionPerformanceAsync();
+ return Ok(performanceData);
+ }
+ catch (InterviewSessionNotFoundException ex)
+ {
+ return NotFound(ex.Message);
+ }
+ catch (Exception ex)
+ {
+ return StatusCode(500, ex.Message);
+ }
}
- [HttpGet("get-interview-session-programming-language-data")]
+ [HttpGet("programming-languages")]
public async Task GetInterviewSessionProgrammingLanguageData()
{
- List programmingLanguageData = await _interviewSessionRepository.GetInterviewSessionProgrammingLanguageDataAsync();
- return Ok(programmingLanguageData);
+ try
+ {
+ List programmingLanguageData = await _interviewSessionService.GetInterviewSessionProgrammingLanguageDataAsync();
+ return Ok(programmingLanguageData);
+ }
+ catch (InterviewSessionNotFoundException ex)
+ {
+ return NotFound(ex.Message);
+ }
+ catch (Exception ex)
+ {
+ return StatusCode(500, ex.Message);
+ }
}
- [HttpGet("get-interview-session-position-data")]
+ [HttpGet("positions")]
public async Task GetInterviewSessionPositionData()
{
- List positionData = await _interviewSessionRepository.GetInterviewSessionPositionDataAsync();
- return Ok(positionData);
+ try
+ {
+ List positionData = await _interviewSessionService.GetInterviewSessionPositionDataAsync();
+ return Ok(positionData);
+ }
+ catch (InterviewSessionNotFoundException ex)
+ {
+ return NotFound(ex.Message);
+ }
+ catch (Exception ex)
+ {
+ return StatusCode(500, ex.Message);
+ }
}
- [HttpPut("finish-interview-session")]
+ [HttpPut("current/finish")]
public async Task FinishInterviewSession()
{
- await _interviewSessionRepository.FinishInterviewSessionAsync();
- return Ok("Interview session finished successfully.");
+ try
+ {
+ await _interviewSessionService.FinishInterviewSessionAsync();
+ return Ok("Interview session finished successfully.");
+ }
+ catch (InterviewSessionNotFoundException ex)
+ {
+ return NotFound(ex.Message);
+ }
+ catch (Exception ex)
+ {
+ return StatusCode(500, ex.Message);
+ }
}
- [HttpDelete("delete-interview-sessions")]
+ [HttpDelete]
public async Task DeleteInterviewSessions()
{
- await _interviewSessionRepository.DeleteInterviewSessionsAsync();
- return Ok("All interview sessions deleted successfully.");
+ try
+ {
+ await _interviewSessionService.DeleteInterviewSessionsAsync();
+ return Ok("All interview sessions deleted successfully.");
+ }
+ catch (InterviewSessionNotFoundException ex)
+ {
+ return NotFound(ex.Message);
+ }
+ catch (Exception ex)
+ {
+ return StatusCode(500, ex.Message);
+ }
}
}
}
diff --git a/Backend/prepAIred.API/Controllers/ProfilePictureController.cs b/Backend/prepAIred.API/Controllers/ProfilePictureController.cs
index dcee73e..f67871b 100644
--- a/Backend/prepAIred.API/Controllers/ProfilePictureController.cs
+++ b/Backend/prepAIred.API/Controllers/ProfilePictureController.cs
@@ -1,27 +1,54 @@
using prepAIred.Data;
using prepAIred.Services;
+using prepAIred.Exceptions;
using Microsoft.AspNetCore.Mvc;
namespace prepAIred.API
{
[ApiController]
- [Route("api/[controller]")]
- public class ProfilePictureController(IProfilePictureRepository profilePictureRepository) : Controller
+ [Route("api/profile-pictures")]
+ public class ProfilePictureController(IProfilePictureService profilePictureService) : Controller
{
- private readonly IProfilePictureRepository _profilePictureRepository = profilePictureRepository;
+ private readonly IProfilePictureService _profilePictureService = profilePictureService;
- [HttpGet("get-profile-picture-url")]
+ [HttpGet]
public async Task GetProfilePicture()
{
- string profilePictureUrl = await _profilePictureRepository.GetProfilePictureUrlAsync();
- return Ok(profilePictureUrl);
+ try
+ {
+ string profilePictureUrl = await _profilePictureService.GetProfilePictureUrlAsync();
+ return Ok(profilePictureUrl);
+ }
+ catch (ResourceNotFoundException ex)
+ {
+ return NotFound(ex.Message);
+ }
+ catch (Exception ex)
+ {
+ return StatusCode(500, ex.Message);
+ }
}
- [HttpPost("change-profile-picture")]
+ [HttpPut]
public async Task ChangeProfilePicture([FromForm] ProfilePictureDTO profilePictureDTO)
{
- await _profilePictureRepository.ChangeProfilePictureAsync(profilePictureDTO);
- return Ok("Profile picture changed");
+ try
+ {
+ await _profilePictureService.ChangeProfilePictureAsync(profilePictureDTO);
+ return Ok("Profile picture changed");
+ }
+ catch (UnsupportedFileExtensionException ex)
+ {
+ return BadRequest(ex.Message);
+ }
+ catch (ProfilePictureException ex)
+ {
+ return BadRequest(ex.Message);
+ }
+ catch (Exception ex)
+ {
+ return StatusCode(500, ex.Message);
+ }
}
}
}
diff --git a/Backend/prepAIred.API/Controllers/UserController.cs b/Backend/prepAIred.API/Controllers/UserController.cs
index 58c1be5..c7e2a00 100644
--- a/Backend/prepAIred.API/Controllers/UserController.cs
+++ b/Backend/prepAIred.API/Controllers/UserController.cs
@@ -1,5 +1,6 @@
using prepAIred.Data;
using prepAIred.Services;
+using prepAIred.Exceptions;
using Microsoft.AspNetCore.Mvc;
namespace prepAIred.API
@@ -9,39 +10,76 @@ namespace prepAIred.API
///
///
/// This controller is responsible for handling HTTP requests related to user data. It interacts
- /// with the to retrieve and manage user information.
+ /// with the to retrieve and manage user information.
///
- /// Repository for handling user-related operations
+ /// Repository for handling user-related operations
[ApiController]
- [Route("api/[controller]")]
- public class UserController(IUserRepository userRepository) : Controller
+ [Route("api/users")]
+ public class UserController(IUserService userService) : Controller
{
- private readonly IUserRepository _userRepository = userRepository;
+ private readonly IUserService _userService = userService;
- [HttpGet("get-current-user")]
+ [HttpGet("me")]
public async Task GetCurrentUser()
{
- if (string.IsNullOrEmpty(Request.Cookies["AccessToken"]))
+ try
{
- return NoContent();
- }
+ if (string.IsNullOrEmpty(Request.Cookies["AccessToken"]))
+ {
+ return NoContent();
+ }
- CurrentUserDTO currentUser = await _userRepository.GetCurrentUserAsync();
- return Ok(currentUser);
+ CurrentUserDTO currentUser = await _userService.GetCurrentUserAsync();
+ return Ok(currentUser);
+ }
+ catch (ResourceNotFoundException ex)
+ {
+ return NotFound(ex.Message);
+ }
+ catch (Exception ex)
+ {
+ return StatusCode(500, ex.Message);
+ }
}
- [HttpPut("update-current-user")]
+ [HttpPut("me")]
public async Task UpdateCurrentUser([FromBody] UserCredentialsDTO userCredentialsDto)
{
- await _userRepository.UpdateCurrentUserAsync(userCredentialsDto);
- return Ok("User updated");
+ try
+ {
+ await _userService.UpdateCurrentUserAsync(userCredentialsDto);
+ return Ok("User updated");
+ }
+ catch (DataValidationException ex)
+ {
+ return BadRequest(ex.Message);
+ }
+ catch (ResourceNotFoundException ex)
+ {
+ return NotFound(ex.Message);
+ }
+ catch (Exception ex)
+ {
+ return StatusCode(500, ex.Message);
+ }
}
- [HttpDelete("delete-current-user")]
+ [HttpDelete("me")]
public async Task DeleteCurrentUser()
{
- await _userRepository.DeleteCurrentUserAsync();
- return Ok("User deleted");
+ try
+ {
+ await _userService.DeleteCurrentUserAsync();
+ return Ok("User deleted");
+ }
+ catch (ResourceNotFoundException ex)
+ {
+ return NotFound(ex.Message);
+ }
+ catch (Exception ex)
+ {
+ return StatusCode(500, ex.Message);
+ }
}
}
}
diff --git a/Backend/prepAIred.API/Program.cs b/Backend/prepAIred.API/Program.cs
index db2df57..7b43e6e 100644
--- a/Backend/prepAIred.API/Program.cs
+++ b/Backend/prepAIred.API/Program.cs
@@ -35,21 +35,21 @@
options.UseSqlServer(connectionString);
});
-builder.Services.AddScoped();
builder.Services.AddScoped();
+builder.Services.AddScoped();
builder.Services.AddScoped();
-builder.Services.AddScoped();
builder.Services.AddScoped();
+builder.Services.AddScoped();
builder.Services.AddScoped();
-builder.Services.AddScoped();
builder.Services.AddScoped();
-builder.Services.AddScoped();
+builder.Services.AddScoped();
builder.Services.AddScoped();
+builder.Services.AddScoped();
builder.Services.AddScoped();
-builder.Services.AddScoped();
builder.Services.AddScoped();
-builder.Services.AddScoped();
+builder.Services.AddScoped();
builder.Services.AddScoped();
+builder.Services.AddScoped();
builder.Services.AddScoped();
builder.Services.AddScoped();
builder.Services.AddScoped();
diff --git a/Backend/prepAIred.Exceptions/Exceptions/CustomExceptions.cs b/Backend/prepAIred.Exceptions/Exceptions/CustomExceptions.cs
index 84053de..2dc3eb1 100644
--- a/Backend/prepAIred.Exceptions/Exceptions/CustomExceptions.cs
+++ b/Backend/prepAIred.Exceptions/Exceptions/CustomExceptions.cs
@@ -49,4 +49,19 @@ public class ProfilePictureException(string message) : Exception(message);
/// Exception thrown when an unsupported image format is specified.
///
public class UnsupportedFileExtensionException(string message) : Exception(message);
+
+ ///
+ /// Exception thrown when an interview session is not found.
+ ///
+ public class InterviewSessionNotFoundException(string message) : Exception(message);
+
+ ///
+ /// Exception thrown when an interview is not found.
+ ///
+ public class InterviewNotFoundException(string message) : Exception(message);
+
+ ///
+ /// Exception thrown when user data validation fails (e.g., invalid email format, weak password).
+ ///
+ public class DataValidationException(string message) : Exception(message);
}
diff --git a/Backend/prepAIred.Exceptions/Exceptions/GlobalExceptionHandler.cs b/Backend/prepAIred.Exceptions/Exceptions/GlobalExceptionHandler.cs
index 7983421..c10bf38 100644
--- a/Backend/prepAIred.Exceptions/Exceptions/GlobalExceptionHandler.cs
+++ b/Backend/prepAIred.Exceptions/Exceptions/GlobalExceptionHandler.cs
@@ -16,7 +16,12 @@ public async ValueTask TryHandleAsync(HttpContext httpContext, Exception e
InvalidRefreshTokenException => StatusCodes.Status401Unauthorized,
UserAlreadyExistsException => StatusCodes.Status409Conflict,
ResourceNotFoundException => StatusCodes.Status404NotFound,
+ InterviewSessionNotFoundException => StatusCodes.Status404NotFound,
+ InterviewNotFoundException => StatusCodes.Status404NotFound,
EmptyFieldsException => StatusCodes.Status400BadRequest,
+ DataValidationException => StatusCodes.Status400BadRequest,
+ UnsupportedFileExtensionException => StatusCodes.Status400BadRequest,
+ ProfilePictureException => StatusCodes.Status400BadRequest,
ApplicationException => StatusCodes.Status400BadRequest,
_ => StatusCodes.Status500InternalServerError
};
diff --git a/Backend/prepAIred.Services/Interfaces/Authentication/Auth/IAuthRepository.cs b/Backend/prepAIred.Services/Interfaces/Authentication/Auth/IAuthRepository.cs
index eb5db77..d418ff9 100644
--- a/Backend/prepAIred.Services/Interfaces/Authentication/Auth/IAuthRepository.cs
+++ b/Backend/prepAIred.Services/Interfaces/Authentication/Auth/IAuthRepository.cs
@@ -3,26 +3,35 @@
namespace prepAIred.Services
{
///
- /// Repository interface for handling authentication-related data operations.
+ /// Service interface for handling authentication business logic.
///
public interface IAuthRepository
{
///
- /// Registers a new user in the system.
+ /// Registers a new user with hashed credentials.
///
- /// The registration data transfer object containing user details.
- /// A task representing the asynchronous operation.
- Task RegisterAsync(UserCredentialsDTO userCredentialsDto);
+ /// The registration details.
+ /// The pre-hashed password.
+ /// The salt used in password hashing.
+ /// The newly created user entity.
+ Task RegisterAsync(UserCredentialsDTO userCredentialsDto, byte[] hashedPassword, byte[] saltPassword);
+
+ ///
+ /// Authenticates a user and returns their information.
+ ///
+ /// The login credentials.
+ /// The authenticated user entity.
+ Task LoginAsync(LoginDTO loginDto);
///
- /// Authenticates a user using their credentials.
+ /// Generates authentication response for a user.
///
- /// The login data transfer object containing user credentials.
+ /// The user to generate authentication response for.
/// A task representing the asynchronous operation.
- Task LoginAsync(LoginDTO loginDto);
+ Task GenerateAuthResponseAsync(CurrentUserDTO currentUser);
///
- /// Logs out the current user from the system.
+ /// Logs out the current user and cleans up their session.
///
/// A task representing the asynchronous operation.
Task LogoutAsync();
diff --git a/Backend/prepAIred.Services/Interfaces/Authentication/Auth/IAuthService.cs b/Backend/prepAIred.Services/Interfaces/Authentication/Auth/IAuthService.cs
index a556b75..8dd21a2 100644
--- a/Backend/prepAIred.Services/Interfaces/Authentication/Auth/IAuthService.cs
+++ b/Backend/prepAIred.Services/Interfaces/Authentication/Auth/IAuthService.cs
@@ -3,35 +3,26 @@
namespace prepAIred.Services
{
///
- /// Service interface for handling authentication business logic.
+ /// Repository interface for handling authentication-related data operations.
///
public interface IAuthService
{
///
- /// Registers a new user with hashed credentials.
+ /// Registers a new user in the system.
///
- /// The registration details.
- /// The pre-hashed password.
- /// The salt used in password hashing.
- /// The newly created user entity.
- Task RegisterAsync(UserCredentialsDTO userCredentialsDto, byte[] hashedPassword, byte[] saltPassword);
-
- ///
- /// Authenticates a user and returns their information.
- ///
- /// The login credentials.
- /// The authenticated user entity.
- Task LoginAsync(LoginDTO loginDto);
+ /// The registration data transfer object containing user details.
+ /// A task representing the asynchronous operation.
+ Task RegisterAsync(UserCredentialsDTO userCredentialsDto);
///
- /// Generates authentication response for a user.
+ /// Authenticates a user using their credentials.
///
- /// The user to generate authentication response for.
+ /// The login data transfer object containing user credentials.
/// A task representing the asynchronous operation.
- Task GenerateAuthResponseAsync(CurrentUserDTO currentUser);
+ Task LoginAsync(LoginDTO loginDto);
///
- /// Logs out the current user and cleans up their session.
+ /// Logs out the current user from the system.
///
/// A task representing the asynchronous operation.
Task LogoutAsync();
diff --git a/Backend/prepAIred.Services/Interfaces/Authentication/RefreshToken/IRefreshTokenRepository.cs b/Backend/prepAIred.Services/Interfaces/Authentication/RefreshToken/IRefreshTokenRepository.cs
index 5bc3f59..13819f1 100644
--- a/Backend/prepAIred.Services/Interfaces/Authentication/RefreshToken/IRefreshTokenRepository.cs
+++ b/Backend/prepAIred.Services/Interfaces/Authentication/RefreshToken/IRefreshTokenRepository.cs
@@ -3,14 +3,29 @@
namespace prepAIred.Services
{
///
- /// Repository interface for managing refresh token data operations.
+ /// Service interface for managing refresh token operations.
///
public interface IRefreshTokenRepository
{
///
- /// Generates a new refresh token and its associated response.
+ /// Adds a new refresh token to the system.
///
- /// A response containing the new refresh token and access token details.
- Task GenerateNewRefreshTokenAsync();
+ /// The refresh token to add.
+ /// The added refresh token entity.
+ Task AddRefreshTokenAsync(RefreshToken refreshToken);
+
+ ///
+ /// Retrieves a refresh token by its token string.
+ ///
+ /// The token string to search for.
+ /// The matching refresh token entity if found.
+ Task GetRefreshTokenAsync(string refreshToken);
+
+ ///
+ /// Retrieves a refresh token by user ID.
+ ///
+ /// The ID of the user.
+ /// The refresh token entity associated with the user if found.
+ Task GetRefreshTokenByUserIdAsync(int userID);
}
}
diff --git a/Backend/prepAIred.Services/Interfaces/Authentication/RefreshToken/IRefreshTokenService.cs b/Backend/prepAIred.Services/Interfaces/Authentication/RefreshToken/IRefreshTokenService.cs
index 64d4268..a169990 100644
--- a/Backend/prepAIred.Services/Interfaces/Authentication/RefreshToken/IRefreshTokenService.cs
+++ b/Backend/prepAIred.Services/Interfaces/Authentication/RefreshToken/IRefreshTokenService.cs
@@ -3,29 +3,14 @@
namespace prepAIred.Services
{
///
- /// Service interface for managing refresh token operations.
+ /// Repository interface for managing refresh token data operations.
///
public interface IRefreshTokenService
{
///
- /// Adds a new refresh token to the system.
+ /// Generates a new refresh token and its associated response.
///
- /// The refresh token to add.
- /// The added refresh token entity.
- Task AddRefreshTokenAsync(RefreshToken refreshToken);
-
- ///
- /// Retrieves a refresh token by its token string.
- ///
- /// The token string to search for.
- /// The matching refresh token entity if found.
- Task GetRefreshTokenAsync(string refreshToken);
-
- ///
- /// Retrieves a refresh token by user ID.
- ///
- /// The ID of the user.
- /// The refresh token entity associated with the user if found.
- Task GetRefreshTokenByUserIdAsync(int userID);
+ /// A response containing the new refresh token and access token details.
+ Task GenerateNewRefreshTokenAsync();
}
}
diff --git a/Backend/prepAIred.Services/Interfaces/Interview/InterviewSessions/IInterviewSessionRepository.cs b/Backend/prepAIred.Services/Interfaces/Interview/InterviewSessions/IInterviewSessionRepository.cs
index 3226b5b..95bbe84 100644
--- a/Backend/prepAIred.Services/Interfaces/Interview/InterviewSessions/IInterviewSessionRepository.cs
+++ b/Backend/prepAIred.Services/Interfaces/Interview/InterviewSessions/IInterviewSessionRepository.cs
@@ -3,61 +3,128 @@
namespace prepAIred.Services
{
///
- /// Defines methods for managing interview session data.
+ /// Defines methods for managing interview session entities.
///
public interface IInterviewSessionRepository
{
///
- /// Asynchronously retrieves a list of interview session data transfer objects (DTOs).
+ /// Creates and persists a new interview session entity asynchronously.
///
- /// A task that represents the asynchronous operation. The task result contains a list of
- /// objects representing the interview sessions.
- Task> GetInterviewSessionDTOsAsync();
+ /// The entity to create and store.
+ /// A task representing the asynchronous operation.
+ Task CreateInterviewSessionAsync(InterviewSession interviewSession);
///
- /// Asynchronously retrieves the most recent interview sessions for the current user.
+ /// Updates the details of an existing interview session.
///
- /// A task that represents the asynchronous operation. The task result contains a list of
- /// objects representing the most recent interview sessions.
- Task> GetInterviewSessionActivitiesAsync();
+ /// This method updates the interview session with the provided details. Ensure that the
+ /// object contains valid and complete information before calling this
+ /// method.
+ /// The object containing the updated details of the interview session.
+ /// A task that represents the asynchronous operation.
+ Task UpdateInterviewSessionAsync(InterviewSession interviewSession);
+
+ ///
+ /// Retrieves the interview session that is adjacent to the current session for the specified user.
+ ///
+ /// This method is intended to be used in scenarios where interview sessions are
+ /// sequentially linked for a user. The definition of "adjacent" may depend on the implementation, such as the
+ /// next or previous session in chronological order.
+ /// The unique identifier of the user whose adjacent interview session is to be retrieved.
+ /// A task that represents the asynchronous operation. The task result contains the adjacent for the specified user, or if no adjacent session exists.
+ Task GetAdjacentInterviewSessionAsync(int userID);
+
+ ///
+ /// Retrieves an interview session by its unique identifier.
+ ///
+ /// The unique identifier of the interview session to retrieve.
+ /// A task that represents the asynchronous operation. The task result contains the object with the specified ID, or if not found.
+ Task GetInterviewSessionByIdAsync(int sessionID);
///
- /// Asynchronously retrieves interview session statistics.
+ /// Gets an interview session based on the provided evaluation requests.
///
- /// A task that represents the asynchronous operation. The task result contains a
- /// object representing the interview session statistics.
- Task GetInterviewSessionStatisticsAsync();
+ /// A list of evaluation requests containing the questions and answer.
+ /// A task that represents the asynchronous operation. The task result contains the generated
+ /// object based on the provided evaluation requests.
+ Task GetInterviewSessionFromQuestionsAsync(List evaluateRequests);
///
- /// Asynchronously retrieves performance data for interview sessions.
+ /// Retrieves the most recent interview session ID associated with the specified user.
///
- /// A task that represents the asynchronous operation. The task result contains a list of
- /// objects representing the performance data for interview sessions.
- Task> GetInterviewSessionPerformanceAsync();
+ /// The unique identifier of the user whose latest interview session ID is to be retrieved.
+ /// A task that represents the asynchronous operation. The task result contains the ID of the latest interview session.
+ Task GetLatestInterviewSessionIDAsync(int userID);
///
- /// Asynchronously retrieves programming language data for interview sessions.
+ /// Retrieves all interviews associated with a specific user by their unique identifier.
///
- /// A task that represents the asynchronous operation. The task result contains a list of
- /// objects representing the programming language data.
- Task> GetInterviewSessionProgrammingLanguageDataAsync();
+ /// The unique identifier of the user.
+ /// A task that represents the asynchronous operation. The task result contains a list of objects.
+ Task> GetInterviewSessionsByUserIdAsync(int userID);
///
- /// Asynchronously retrieves position data for interview sessions.
+ /// Deletes the specified interview sessions asynchronously.
///
- /// A task that represents the asynchronous operation. The task result contains a list of
- /// objects representing the position data.
- Task> GetInterviewSessionPositionDataAsync();
+ /// A list of objects representing the interview sessions to delete.
+ Task DeleteInterviewSessionsAsync(List interviewSessions);
///
- /// Completes the current interview session and performs any necessary finalization tasks.
+ /// Marks an interview session as finished and updates its completion status.
///
+ /// The object to finish.
/// A task that represents the asynchronous operation.
- Task FinishInterviewSessionAsync();
+ Task FinishInterviewSessionAsync(InterviewSession interviewSession);
+
+ ///
+ /// Retrieves the total count of interview sessions associated with a specific user.
+ ///
+ /// The unique identifier of the user.
+ /// A task that represents the asynchronous operation. The task result contains the total number of interview sessions.
+ Task GetTotalInterviewSessionsAsync(int userID);
+
+ ///
+ /// Retrieves the count of passed interview sessions for a specific user.
+ ///
+ /// The unique identifier of the user.
+ /// A task that represents the asynchronous operation. The task result contains the number of interview sessions that were passed.
+ Task GetPassedInterviewSessionsAsync(int userID);
+
+ ///
+ /// Retrieves the count of ongoing interview sessions for a specific user.
+ ///
+ /// The unique identifier of the user.
+ /// A task that represents the asynchronous operation. The task result contains the number of interview sessions that are currently ongoing.
+ Task GetOngoingInterviewSessionsAsync(int userID);
+
+ ///
+ /// Calculates and retrieves the average score of all interview sessions for a specific user.
+ ///
+ /// The unique identifier of the user.
+ /// A task that represents the asynchronous operation. The task result contains the average score as a decimal value.
+ Task GetAverageScoreAsync(int userID);
+
+ ///
+ /// Calculates and retrieves the completion rate of interview sessions for a specific user.
+ ///
+ /// The unique identifier of the user.
+ /// A task that represents the asynchronous operation. The task result contains the completion rate as a decimal percentage value.
+ Task GetCompletionRateAsync(int userID);
+
+ ///
+ /// Finalizes an interview session by updating its status and associated interviews based on the evaluated interviews
+ ///
+ /// The type of interview being finalized.
+ /// The interview session to be finalized.
+ /// The list of evaluated interviews to update.
+ void FinalizeInterviewSession(InterviewSession interviewSession, List evaluatedTInterviews) where TInterview : Interview;
///
- /// Deletes all interview sessions asynchronously.
+ /// Retrieves recent interview session activities for the user.
///
- Task DeleteInterviewSessionsAsync();
+ /// The unique identifier of the user.
+ /// A task that represents the asynchronous operation. The task result contains a list of recent interview session activities.
+ Task> GetInterviewSessionActivitiesAsync(int userID);
}
}
diff --git a/Backend/prepAIred.Services/Interfaces/Interview/InterviewSessions/IInterviewSessionService.cs b/Backend/prepAIred.Services/Interfaces/Interview/InterviewSessions/IInterviewSessionService.cs
index 71bb781..92778b3 100644
--- a/Backend/prepAIred.Services/Interfaces/Interview/InterviewSessions/IInterviewSessionService.cs
+++ b/Backend/prepAIred.Services/Interfaces/Interview/InterviewSessions/IInterviewSessionService.cs
@@ -3,128 +3,61 @@
namespace prepAIred.Services
{
///
- /// Defines methods for managing interview session entities.
+ /// Defines methods for managing interview session data.
///
public interface IInterviewSessionService
{
///
- /// Creates and persists a new interview session entity asynchronously.
+ /// Asynchronously retrieves a list of interview session data transfer objects (DTOs).
///
- /// The entity to create and store.
- /// A task representing the asynchronous operation.
- Task CreateInterviewSessionAsync(InterviewSession interviewSession);
+ /// A task that represents the asynchronous operation. The task result contains a list of
+ /// objects representing the interview sessions.
+ Task> GetInterviewSessionDTOsAsync();
///
- /// Updates the details of an existing interview session.
+ /// Asynchronously retrieves the most recent interview sessions for the current user.
///
- /// This method updates the interview session with the provided details. Ensure that the
- /// object contains valid and complete information before calling this
- /// method.
- /// The object containing the updated details of the interview session.
- /// A task that represents the asynchronous operation.
- Task UpdateInterviewSessionAsync(InterviewSession interviewSession);
-
- ///
- /// Retrieves the interview session that is adjacent to the current session for the specified user.
- ///
- /// This method is intended to be used in scenarios where interview sessions are
- /// sequentially linked for a user. The definition of "adjacent" may depend on the implementation, such as the
- /// next or previous session in chronological order.
- /// The unique identifier of the user whose adjacent interview session is to be retrieved.
- /// A task that represents the asynchronous operation. The task result contains the adjacent for the specified user, or if no adjacent session exists.
- Task GetAdjacentInterviewSessionAsync(int userID);
-
- ///
- /// Retrieves an interview session by its unique identifier.
- ///
- /// The unique identifier of the interview session to retrieve.
- /// A task that represents the asynchronous operation. The task result contains the object with the specified ID, or if not found.
- Task GetInterviewSessionByIdAsync(int sessionID);
+ /// A task that represents the asynchronous operation. The task result contains a list of
+ /// objects representing the most recent interview sessions.
+ Task> GetInterviewSessionActivitiesAsync();
///
- /// Gets an interview session based on the provided evaluation requests.
+ /// Asynchronously retrieves interview session statistics.
///
- /// A list of evaluation requests containing the questions and answer.
- /// A task that represents the asynchronous operation. The task result contains the generated
- /// object based on the provided evaluation requests.
- Task GetInterviewSessionFromQuestionsAsync(List evaluateRequests);
+ /// A task that represents the asynchronous operation. The task result contains a
+ /// object representing the interview session statistics.
+ Task GetInterviewSessionStatisticsAsync();
///
- /// Retrieves the most recent interview session ID associated with the specified user.
+ /// Asynchronously retrieves performance data for interview sessions.
///
- /// The unique identifier of the user whose latest interview session ID is to be retrieved.
- /// A task that represents the asynchronous operation. The task result contains the ID of the latest interview session.
- Task GetLatestInterviewSessionIDAsync(int userID);
+ /// A task that represents the asynchronous operation. The task result contains a list of
+ /// objects representing the performance data for interview sessions.
+ Task> GetInterviewSessionPerformanceAsync();
///
- /// Retrieves all interviews associated with a specific user by their unique identifier.
+ /// Asynchronously retrieves programming language data for interview sessions.
///
- /// The unique identifier of the user.
- /// A task that represents the asynchronous operation. The task result contains a list of objects.
- Task> GetInterviewSessionsByUserIdAsync(int userID);
+ /// A task that represents the asynchronous operation. The task result contains a list of
+ /// objects representing the programming language data.
+ Task> GetInterviewSessionProgrammingLanguageDataAsync();
///
- /// Deletes the specified interview sessions asynchronously.
+ /// Asynchronously retrieves position data for interview sessions.
///
- /// A list of objects representing the interview sessions to delete.
- Task DeleteInterviewSessionsAsync(List interviewSessions);
+ /// A task that represents the asynchronous operation. The task result contains a list of
+ /// objects representing the position data.
+ Task> GetInterviewSessionPositionDataAsync();
///
- /// Marks an interview session as finished and updates its completion status.
+ /// Completes the current interview session and performs any necessary finalization tasks.
///
- /// The object to finish.
/// A task that represents the asynchronous operation.
- Task FinishInterviewSessionAsync(InterviewSession interviewSession);
-
- ///
- /// Retrieves the total count of interview sessions associated with a specific user.
- ///
- /// The unique identifier of the user.
- /// A task that represents the asynchronous operation. The task result contains the total number of interview sessions.
- Task GetTotalInterviewSessionsAsync(int userID);
-
- ///
- /// Retrieves the count of passed interview sessions for a specific user.
- ///
- /// The unique identifier of the user.
- /// A task that represents the asynchronous operation. The task result contains the number of interview sessions that were passed.
- Task GetPassedInterviewSessionsAsync(int userID);
-
- ///
- /// Retrieves the count of ongoing interview sessions for a specific user.
- ///
- /// The unique identifier of the user.
- /// A task that represents the asynchronous operation. The task result contains the number of interview sessions that are currently ongoing.
- Task GetOngoingInterviewSessionsAsync(int userID);
-
- ///
- /// Calculates and retrieves the average score of all interview sessions for a specific user.
- ///
- /// The unique identifier of the user.
- /// A task that represents the asynchronous operation. The task result contains the average score as a decimal value.
- Task GetAverageScoreAsync(int userID);
-
- ///
- /// Calculates and retrieves the completion rate of interview sessions for a specific user.
- ///
- /// The unique identifier of the user.
- /// A task that represents the asynchronous operation. The task result contains the completion rate as a decimal percentage value.
- Task GetCompletionRateAsync(int userID);
-
- ///
- /// Finalizes an interview session by updating its status and associated interviews based on the evaluated interviews
- ///
- /// The type of interview being finalized.
- /// The interview session to be finalized.
- /// The list of evaluated interviews to update.
- void FinalizeInterviewSession(InterviewSession interviewSession, List evaluatedTInterviews) where TInterview : Interview;
+ Task FinishInterviewSessionAsync();
///
- /// Retrieves recent interview session activities for the user.
+ /// Deletes all interview sessions asynchronously.
///
- /// The unique identifier of the user.
- /// A task that represents the asynchronous operation. The task result contains a list of recent interview session activities.
- Task> GetInterviewSessionActivitiesAsync(int userID);
+ Task DeleteInterviewSessionsAsync();
}
}
diff --git a/Backend/prepAIred.Services/Interfaces/Interview/Interviews/IInterviewRepository.cs b/Backend/prepAIred.Services/Interfaces/Interview/Interviews/IInterviewRepository.cs
index 9e7ac5a..b5ebbe1 100644
--- a/Backend/prepAIred.Services/Interfaces/Interview/Interviews/IInterviewRepository.cs
+++ b/Backend/prepAIred.Services/Interfaces/Interview/Interviews/IInterviewRepository.cs
@@ -3,35 +3,54 @@
namespace prepAIred.Services
{
///
- /// Defines methods for performing data operations related to AI-generated interviews.
+ /// Defines methods for managing and retrieving interview data.
///
public interface IInterviewRepository
{
///
- /// Generates a collection of interviews based on the specified AI request.
+ /// Creates and persists multiple interview entities in the database for a given user and session.
///
- /// The type of the interview objects to generate. Must be a reference type.
- /// The AI request containing the parameters and context for generating interviews.
- /// A task that represents the asynchronous operation.
- Task GenerateInterviewsAsync(BaseRequestDTO aIRequest) where TInterview : Interview;
+ /// The list of entities to create.
+ /// The user for whom the interviews are being created.
+ /// The interview session to which the interviews belong.
+ /// A task representing the asynchronous operation.
+ Task CreateInterviewsAsync(List interviews, User currentUser, InterviewSession interviewSession);
///
- /// Retrieves the most recent interview record and maps it to the specified DTO type.
+ /// Updates multiple interview entities in the database with their current state and evaluation results.
///
- /// The type representing the interview entity in the data source.
- /// The type to which the interview entity will be mapped.
- /// A task that represents the asynchronous operation. The task result contains the most recent interview
- /// mapped to the specified DTO type, or if no interviews are available.
- Task> GetLatestInterviewsAsync()
- where TInterview : Interview
+ /// The type of interview objects to update. Must derive from the Interview class.
+ /// The list of interview objects containing updated information to persist to the database.
+ /// A task representing the asynchronous update operation.
+ Task UpdateInterviewAsync(List interviews) where TInterview : Interview;
+
+ ///
+ /// Retrieves a list of interviews associated with the specified session ID.
+ ///
+ /// The type of interview to retrieve. Must derive from the class.
+ /// The unique identifier of the session for which interviews are to be retrieved. Must be a positive integer.
+ /// A task that represents the asynchronous operation. The task result contains a list of interviews of type
+ /// associated with the specified session ID. If no interviews are found, the list will be empty.
+ Task> GetInterviewsBySessionIdAsync(int sessionID) where TInterview : Interview;
+
+ ///
+ /// Retrieves the latest interviews from the provided list and maps them to the specified DTO type.
+ ///
+ /// The type of the interview entities, which must inherit from .
+ /// The type of the interview DTOs, which must inherit from .
+ /// The list of interview entities to process.
+ /// A list of the latest interviews mapped to the specified DTO type. The list will be empty if no interviews
+ /// are provided.
+ List GetLatestInterviews(List interviews)
+ where TInterview : Interview
where TInterviewDTO : InterviewDTO;
///
- /// Evaluates a collection of interviews based on the specified evaluation request.
+ /// Updates an existing interview in the collection with the provided evaluated interview.
///
- /// The type of interview to evaluate. Must derive from the class.
- /// The evaluation request containing the criteria and parameters for the evaluation process.
- /// A task that represents the asynchronous operation.
- Task EvaluateInterviewsAsync(List evaluateRequest) where TInterview : Interview;
+ /// The type of the interview, which must derive from .
+ /// The evaluated interview to update the existing interview with.
+ /// The collection of existing interviews to search for a match to update.
+ void UpdateExistingInterviewWithEvaluation(List evaluatedInterviews, List existingInterviews) where TInterview : Interview;
}
-}
+}
\ No newline at end of file
diff --git a/Backend/prepAIred.Services/Interfaces/Interview/Interviews/IInterviewService.cs b/Backend/prepAIred.Services/Interfaces/Interview/Interviews/IInterviewService.cs
index a945e7c..8744157 100644
--- a/Backend/prepAIred.Services/Interfaces/Interview/Interviews/IInterviewService.cs
+++ b/Backend/prepAIred.Services/Interfaces/Interview/Interviews/IInterviewService.cs
@@ -3,54 +3,35 @@
namespace prepAIred.Services
{
///
- /// Defines methods for managing and retrieving interview data.
+ /// Defines methods for performing data operations related to AI-generated interviews.
///
public interface IInterviewService
{
///
- /// Creates and persists multiple interview entities in the database for a given user and session.
+ /// Generates a collection of interviews based on the specified AI request.
///
- /// The list of entities to create.
- /// The user for whom the interviews are being created.
- /// The interview session to which the interviews belong.
- /// A task representing the asynchronous operation.
- Task CreateInterviewsAsync(List interviews, User currentUser, InterviewSession interviewSession);
+ /// The type of the interview objects to generate. Must be a reference type.
+ /// The AI request containing the parameters and context for generating interviews.
+ /// A task that represents the asynchronous operation.
+ Task GenerateInterviewsAsync(BaseRequestDTO aIRequest) where TInterview : Interview;
///
- /// Updates multiple interview entities in the database with their current state and evaluation results.
+ /// Retrieves the most recent interview record and maps it to the specified DTO type.
///
- /// The type of interview objects to update. Must derive from the Interview class.
- /// The list of interview objects containing updated information to persist to the database.
- /// A task representing the asynchronous update operation.
- Task UpdateInterviewAsync(List interviews) where TInterview : Interview;
-
- ///
- /// Retrieves a list of interviews associated with the specified session ID.
- ///
- /// The type of interview to retrieve. Must derive from the class.
- /// The unique identifier of the session for which interviews are to be retrieved. Must be a positive integer.
- /// A task that represents the asynchronous operation. The task result contains a list of interviews of type
- /// associated with the specified session ID. If no interviews are found, the list will be empty.
- Task> GetInterviewsBySessionIdAsync(int sessionID) where TInterview : Interview;
-
- ///
- /// Retrieves the latest interviews from the provided list and maps them to the specified DTO type.
- ///
- /// The type of the interview entities, which must inherit from .
- /// The type of the interview DTOs, which must inherit from .
- /// The list of interview entities to process.
- /// A list of the latest interviews mapped to the specified DTO type. The list will be empty if no interviews
- /// are provided.
- List GetLatestInterviews(List interviews)
- where TInterview : Interview
+ /// The type representing the interview entity in the data source.
+ /// The type to which the interview entity will be mapped.
+ /// A task that represents the asynchronous operation. The task result contains the most recent interview
+ /// mapped to the specified DTO type, or if no interviews are available.
+ Task> GetLatestInterviewsAsync()
+ where TInterview : Interview
where TInterviewDTO : InterviewDTO;
///
- /// Updates an existing interview in the collection with the provided evaluated interview.
+ /// Evaluates a collection of interviews based on the specified evaluation request.
///
- /// The type of the interview, which must derive from .
- /// The evaluated interview to update the existing interview with.
- /// The collection of existing interviews to search for a match to update.
- void UpdateExistingInterviewWithEvaluation(List evaluatedInterviews, List existingInterviews) where TInterview : Interview;
+ /// The type of interview to evaluate. Must derive from the class.
+ /// The evaluation request containing the criteria and parameters for the evaluation process.
+ /// A task that represents the asynchronous operation.
+ Task EvaluateInterviewsAsync(List evaluateRequest) where TInterview : Interview;
}
-}
\ No newline at end of file
+}
diff --git a/Backend/prepAIred.Services/Interfaces/ProfilePicture/IProfilePictureRepository.cs b/Backend/prepAIred.Services/Interfaces/ProfilePicture/IProfilePictureRepository.cs
index 0138505..562cbcb 100644
--- a/Backend/prepAIred.Services/Interfaces/ProfilePicture/IProfilePictureRepository.cs
+++ b/Backend/prepAIred.Services/Interfaces/ProfilePicture/IProfilePictureRepository.cs
@@ -1,24 +1,32 @@
-using prepAIred.Data;
+using Microsoft.AspNetCore.Http;
namespace prepAIred.Services
{
///
- /// Repository interface for managing profile picture data operations in the database.
- /// Handles retrieval and updates of user profile picture information.
+ /// Service interface for managing profile picture operations including file storage, retrieval, and deletion.
+ /// Coordinates between file system operations and database updates for profile picture management.
///
public interface IProfilePictureRepository
{
///
- /// Retrieves the profile picture URL for the current authenticated user.
+ /// Saves an uploaded image file to the file system and returns the file name.
///
+ /// The uploaded image file to save
+ /// The saved file name with extension
+ Task SaveFileAsync(IFormFile imageFile);
+
+ ///
+ /// Retrieves the profile picture URL for a specific user.
+ ///
+ /// The unique identifier of the user
/// The URL path to the user's profile picture
- Task GetProfilePictureUrlAsync();
+ Task GetProfilePictureUrlByUserIdAsync(int userId);
///
- /// Updates the user's profile picture information in the database.
+ /// Deletes a profile picture file from the file system.
///
- /// Data transfer object containing profile picture details
+ /// The complete file name including extension to delete
/// A task representing the asynchronous operation
- Task ChangeProfilePictureAsync(ProfilePictureDTO profilePictureDTO);
+ Task DeleteProfilePictureAsync(string fileNameWithExtension);
}
}
diff --git a/Backend/prepAIred.Services/Interfaces/ProfilePicture/IProfilePictureService.cs b/Backend/prepAIred.Services/Interfaces/ProfilePicture/IProfilePictureService.cs
index a40779f..b645afc 100644
--- a/Backend/prepAIred.Services/Interfaces/ProfilePicture/IProfilePictureService.cs
+++ b/Backend/prepAIred.Services/Interfaces/ProfilePicture/IProfilePictureService.cs
@@ -1,32 +1,24 @@
-using Microsoft.AspNetCore.Http;
+using prepAIred.Data;
namespace prepAIred.Services
{
///
- /// Service interface for managing profile picture operations including file storage, retrieval, and deletion.
- /// Coordinates between file system operations and database updates for profile picture management.
+ /// Repository interface for managing profile picture data operations in the database.
+ /// Handles retrieval and updates of user profile picture information.
///
public interface IProfilePictureService
{
///
- /// Saves an uploaded image file to the file system and returns the file name.
+ /// Retrieves the profile picture URL for the current authenticated user.
///
- /// The uploaded image file to save
- /// The saved file name with extension
- Task SaveFileAsync(IFormFile imageFile);
-
- ///
- /// Retrieves the profile picture URL for a specific user.
- ///
- /// The unique identifier of the user
/// The URL path to the user's profile picture
- Task GetProfilePictureUrlByUserIdAsync(int userId);
+ Task GetProfilePictureUrlAsync();
///
- /// Deletes a profile picture file from the file system.
+ /// Updates the user's profile picture information in the database.
///
- /// The complete file name including extension to delete
+ /// Data transfer object containing profile picture details
/// A task representing the asynchronous operation
- Task DeleteProfilePictureAsync(string fileNameWithExtension);
+ Task ChangeProfilePictureAsync(ProfilePictureDTO profilePictureDTO);
}
}
diff --git a/Backend/prepAIred.Services/Interfaces/User/IUserRepository.cs b/Backend/prepAIred.Services/Interfaces/User/IUserRepository.cs
index 1df0490..ce6231d 100644
--- a/Backend/prepAIred.Services/Interfaces/User/IUserRepository.cs
+++ b/Backend/prepAIred.Services/Interfaces/User/IUserRepository.cs
@@ -3,27 +3,127 @@
namespace prepAIred.Services
{
///
- /// Repository interface for handling user data persistence operations.
+ /// Service interface for managing user-related business operations.
///
public interface IUserRepository
{
///
- /// Retrieves the currently authenticated user's information.
+ /// Creates a new user in the system.
///
- /// A DTO containing the current user's public information.
+ /// The user entity to create.
+ /// The created user entity.
+ Task CreateUserAsync(User user);
+
+ ///
+ /// Retrieves a user by their email address.
+ ///
+ /// The email address to search for.
+ /// The matching user entity if found.
+ Task GetUserByEmailAsync(string email);
+
+ ///
+ /// Retrieves a user by their username.
+ ///
+ /// The username to search for.
+ /// The matching user entity if found.
+ Task GetUserByUsernameAsync(string name);
+
+ ///
+ /// Retrieves a user dto by their ID.
+ ///
+ /// The ID of the user to retrieve.
+ /// The matching user dto if found.
+ Task GetUserByIdAsync(int userId);
+
+ ///
+ /// Retrieves a user entity by their ID.
+ ///
+ /// The ID of the user to retrieve.
+ /// The matching user entity if found.
+ Task GetCurrentUserEntityByIdAsync(int userId);
+
+ ///
+ /// Retrieves the currently authenticated user.
+ ///
+ /// The current user entity.
Task GetCurrentUserAsync();
///
- /// Updates the current user's information based on the provided data.
+ /// Asynchronously retrieves the unique identifier of the currently authenticated user.
+ ///
+ /// The task result contains the unique identifier of the current user.
+ Task GetCurrentUserID();
+
+ ///
+ /// Updates the details of an existing user asynchronously.
///
- /// An object containing the updated user information. This parameter cannot be null.
+ /// The object containing the updated user details. The user must already exist in the system.
+ /// The object containing the updated user information.
/// A task that represents the asynchronous operation.
- Task UpdateCurrentUserAsync(UserCredentialsDTO userCredentialsDTO);
+ Task UpdateUserAsync(User user, UserCredentialsDTO? userCredentialsDto);
///
- /// Deletes the currently authenticated user from the system.
+ /// Deletes the user with the specified user ID.
///
+ /// The unique identifier of the user to delete. Must be a positive integer.
/// A task that represents the asynchronous operation.
- Task DeleteCurrentUserAsync();
+ Task DeleteUserAsync(int userID);
+
+ ///
+ /// Validates user registration data.
+ ///
+ /// The registration data to validate.
+ /// A task representing the validation operation.
+ Task ValidateUserAsync(UserCredentialsDTO registerDto);
+
+ ///
+ /// Validates user update data.
+ ///
+ /// The update data to validate.
+ /// A void representing the validation operation.
+ Task ValidateUpdateUserDataAsync(UserCredentialsDTO userCredentialsDto);
+
+ ///
+ /// Checks if a user with the specified email exists.
+ ///
+ /// The email address to check.
+ /// True if the user exists, false otherwise.
+ Task UserExistsAsync(string email);
+
+ ///
+ /// Checks if required registration fields are empty.
+ ///
+ /// The registration data to check.
+ /// True if any required fields are empty, false otherwise.
+ bool AreFieldsEmpty(UserCredentialsDTO userCredentialsDto);
+
+ ///
+ /// Validates the format of the email.
+ ///
+ /// The email address to validate.
+ /// True if the email is valid, false otherwise.
+ bool ValidateEmail(string email);
+
+ ///
+ /// Validates the format of the password.
+ ///
+ /// The password to validate.
+ /// True if the password is valid, false otherwise.
+ bool ValidatePassword(string password);
+
+ ///
+ /// Hashes a user's password during registration.
+ ///
+ /// The registration data containing the password to hash.
+ /// A tuple containing the hashed password and salt.
+ (byte[] hashedPassword, byte[] saltPassword) HashPassword(UserCredentialsDTO userCredentialsDto);
+
+ ///
+ /// Verifies a user's password during login.
+ ///
+ /// The user entity to check against.
+ /// The login credentials to verify.
+ /// True if the password is correct, false otherwise.
+ bool CheckPassword(User currentUser, LoginDTO loginDto);
}
}
diff --git a/Backend/prepAIred.Services/Interfaces/User/IUserService.cs b/Backend/prepAIred.Services/Interfaces/User/IUserService.cs
index 2dba6ed..90729a0 100644
--- a/Backend/prepAIred.Services/Interfaces/User/IUserService.cs
+++ b/Backend/prepAIred.Services/Interfaces/User/IUserService.cs
@@ -3,127 +3,27 @@
namespace prepAIred.Services
{
///
- /// Service interface for managing user-related business operations.
+ /// Repository interface for handling user data persistence operations.
///
public interface IUserService
{
///
- /// Creates a new user in the system.
+ /// Retrieves the currently authenticated user's information.
///
- /// The user entity to create.
- /// The created user entity.
- Task CreateUserAsync(User user);
-
- ///
- /// Retrieves a user by their email address.
- ///
- /// The email address to search for.
- /// The matching user entity if found.
- Task GetUserByEmailAsync(string email);
-
- ///
- /// Retrieves a user by their username.
- ///
- /// The username to search for.
- /// The matching user entity if found.
- Task GetUserByUsernameAsync(string name);
-
- ///
- /// Retrieves a user dto by their ID.
- ///
- /// The ID of the user to retrieve.
- /// The matching user dto if found.
- Task GetUserByIdAsync(int userId);
-
- ///
- /// Retrieves a user entity by their ID.
- ///
- /// The ID of the user to retrieve.
- /// The matching user entity if found.
- Task GetCurrentUserEntityByIdAsync(int userId);
-
- ///
- /// Retrieves the currently authenticated user.
- ///
- /// The current user entity.
+ /// A DTO containing the current user's public information.
Task GetCurrentUserAsync();
///
- /// Asynchronously retrieves the unique identifier of the currently authenticated user.
- ///
- /// The task result contains the unique identifier of the current user.
- Task GetCurrentUserID();
-
- ///
- /// Updates the details of an existing user asynchronously.
+ /// Updates the current user's information based on the provided data.
///
- /// The object containing the updated user details. The user must already exist in the system.
- /// The object containing the updated user information.
+ /// An object containing the updated user information. This parameter cannot be null.
/// A task that represents the asynchronous operation.
- Task UpdateUserAsync(User user, UserCredentialsDTO? userCredentialsDto);
+ Task UpdateCurrentUserAsync(UserCredentialsDTO userCredentialsDTO);
///
- /// Deletes the user with the specified user ID.
+ /// Deletes the currently authenticated user from the system.
///
- /// The unique identifier of the user to delete. Must be a positive integer.
/// A task that represents the asynchronous operation.
- Task DeleteUserAsync(int userID);
-
- ///
- /// Validates user registration data.
- ///
- /// The registration data to validate.
- /// A task representing the validation operation.
- Task ValidateUserAsync(UserCredentialsDTO registerDto);
-
- ///
- /// Validates user update data.
- ///
- /// The update data to validate.
- /// A void representing the validation operation.
- Task ValidateUpdateUserDataAsync(UserCredentialsDTO userCredentialsDto);
-
- ///
- /// Checks if a user with the specified email exists.
- ///
- /// The email address to check.
- /// True if the user exists, false otherwise.
- Task UserExistsAsync(string email);
-
- ///
- /// Checks if required registration fields are empty.
- ///
- /// The registration data to check.
- /// True if any required fields are empty, false otherwise.
- bool AreFieldsEmpty(UserCredentialsDTO userCredentialsDto);
-
- ///
- /// Validates the format of the email.
- ///
- /// The email address to validate.
- /// True if the email is valid, false otherwise.
- bool ValidateEmail(string email);
-
- ///
- /// Validates the format of the password.
- ///
- /// The password to validate.
- /// True if the password is valid, false otherwise.
- bool ValidatePassword(string password);
-
- ///
- /// Hashes a user's password during registration.
- ///
- /// The registration data containing the password to hash.
- /// A tuple containing the hashed password and salt.
- (byte[] hashedPassword, byte[] saltPassword) HashPassword(UserCredentialsDTO userCredentialsDto);
-
- ///
- /// Verifies a user's password during login.
- ///
- /// The user entity to check against.
- /// The login credentials to verify.
- /// True if the password is correct, false otherwise.
- bool CheckPassword(User currentUser, LoginDTO loginDto);
+ Task DeleteCurrentUserAsync();
}
}
diff --git a/Backend/prepAIred.Services/Services/Authentication/Auth/AuthRepository.cs b/Backend/prepAIred.Services/Services/Authentication/Auth/AuthRepository.cs
index b8c0f79..21cb1fb 100644
--- a/Backend/prepAIred.Services/Services/Authentication/Auth/AuthRepository.cs
+++ b/Backend/prepAIred.Services/Services/Authentication/Auth/AuthRepository.cs
@@ -1,33 +1,61 @@
using prepAIred.Data;
+using prepAIred.Exceptions;
namespace prepAIred.Services
{
- public class AuthRepository(IAuthService authService, IUserService userService) : IAuthRepository
+ public class AuthRepository(IJwtService jwtService, IRefreshTokenRepository refreshTokenRepository, ICookieService cookieService, IUserRepository userRepository) : IAuthRepository
{
- private readonly IAuthService _authService = authService;
- private readonly IUserService _userService = userService;
+ private readonly IJwtService _jwtService = jwtService;
+ private readonly IRefreshTokenRepository _refreshTokenRepository = refreshTokenRepository;
+ private readonly ICookieService _cookieService = cookieService;
+ private readonly IUserRepository _userRepository = userRepository;
- public async Task RegisterAsync(UserCredentialsDTO userCredentialsDto)
+ public async Task RegisterAsync(UserCredentialsDTO userCredentialsDto, byte[] hashedPassword, byte[] saltPassword)
{
- await _userService.ValidateUserAsync(userCredentialsDto);
+ User newUser = new User()
+ {
+ Email = userCredentialsDto.Email,
+ Username = userCredentialsDto.Username,
+ PasswordHash = hashedPassword,
+ PasswordSalt = saltPassword
+ };
- (byte[] hashedPassword, byte[] saltPassword) = _userService.HashPassword(userCredentialsDto);
+ await _userRepository.CreateUserAsync(newUser);
- CurrentUserDTO currentUser = await _authService.RegisterAsync(userCredentialsDto, hashedPassword, saltPassword);
-
- await _authService.GenerateAuthResponseAsync(currentUser);
+ return newUser.ToDto();
}
- public async Task LoginAsync(LoginDTO loginDto)
+ public async Task LoginAsync(LoginDTO loginDto)
{
- CurrentUserDTO currentUser = await _authService.LoginAsync(loginDto);
+ if (!await _userRepository.UserExistsAsync(loginDto.Email)) throw new ResourceNotFoundException("Invalid Username or Password");
+
+ User currentUser = await _userRepository.GetUserByEmailAsync(loginDto.Email);
+
+ if (!_userRepository.CheckPassword(currentUser, loginDto)) throw new InvalidCredentialsException("Invalid Username or Password");
- await _authService.GenerateAuthResponseAsync(currentUser);
+ return currentUser.ToDto();
+ }
+
+ public async Task GenerateAuthResponseAsync(CurrentUserDTO currentUser)
+ {
+ string accessToken = _jwtService.GenerateAcessToken(currentUser.ID);
+ string refreshToken = _jwtService.GenerateRefreshToken(currentUser.ID);
+
+ await _refreshTokenRepository.AddRefreshTokenAsync(new RefreshToken()
+ {
+ Token = refreshToken,
+ ExpiryDate = DateTime.Now.AddDays(1),
+ UserID = currentUser.ID
+ });
+
+ _cookieService.CreateCookie("AccessToken", accessToken);
+ _cookieService.CreateCookie("RefreshToken", refreshToken);
}
public async Task LogoutAsync()
{
- await _authService.LogoutAsync();
+ _cookieService.DeleteCookie("AccessToken");
+ _cookieService.DeleteCookie("RefreshToken");
await Task.CompletedTask;
}
diff --git a/Backend/prepAIred.Services/Services/Authentication/Auth/AuthService.cs b/Backend/prepAIred.Services/Services/Authentication/Auth/AuthService.cs
index 96cfb04..7ed73c2 100644
--- a/Backend/prepAIred.Services/Services/Authentication/Auth/AuthService.cs
+++ b/Backend/prepAIred.Services/Services/Authentication/Auth/AuthService.cs
@@ -1,61 +1,33 @@
using prepAIred.Data;
-using prepAIred.Exceptions;
namespace prepAIred.Services
{
- public class AuthService(IJwtService jwtService, IRefreshTokenService refreshTokenService, ICookieService cookieService, IUserService userService) : IAuthService
+ public class AuthService(IAuthRepository authRepository, IUserRepository userRepository) : IAuthService
{
- private readonly IJwtService _jwtService = jwtService;
- private readonly IRefreshTokenService _refreshTokenService = refreshTokenService;
- private readonly ICookieService _cookieService = cookieService;
- private readonly IUserService _userService = userService;
+ private readonly IAuthRepository _authRepository = authRepository;
+ private readonly IUserRepository _userRepository = userRepository;
- public async Task RegisterAsync(UserCredentialsDTO userCredentialsDto, byte[] hashedPassword, byte[] saltPassword)
+ public async Task RegisterAsync(UserCredentialsDTO userCredentialsDto)
{
- User newUser = new User()
- {
- Email = userCredentialsDto.Email,
- Username = userCredentialsDto.Username,
- PasswordHash = hashedPassword,
- PasswordSalt = saltPassword
- };
+ await _userRepository.ValidateUserAsync(userCredentialsDto);
- await _userService.CreateUserAsync(newUser);
+ (byte[] hashedPassword, byte[] saltPassword) = _userRepository.HashPassword(userCredentialsDto);
- return newUser.ToDto();
- }
-
- public async Task LoginAsync(LoginDTO loginDto)
- {
- if (!await _userService.UserExistsAsync(loginDto.Email)) throw new ResourceNotFoundException("Invalid Username or Password");
+ CurrentUserDTO currentUser = await _authRepository.RegisterAsync(userCredentialsDto, hashedPassword, saltPassword);
- User currentUser = await _userService.GetUserByEmailAsync(loginDto.Email);
-
- if (!_userService.CheckPassword(currentUser, loginDto)) throw new InvalidCredentialsException("Invalid Username or Password");
-
- return currentUser.ToDto();
+ await _authRepository.GenerateAuthResponseAsync(currentUser);
}
- public async Task GenerateAuthResponseAsync(CurrentUserDTO currentUser)
+ public async Task LoginAsync(LoginDTO loginDto)
{
- string accessToken = _jwtService.GenerateAcessToken(currentUser.ID);
- string refreshToken = _jwtService.GenerateRefreshToken(currentUser.ID);
-
- await _refreshTokenService.AddRefreshTokenAsync(new RefreshToken()
- {
- Token = refreshToken,
- ExpiryDate = DateTime.Now.AddDays(1),
- UserID = currentUser.ID
- });
-
- _cookieService.CreateCookie("AccessToken", accessToken);
- _cookieService.CreateCookie("RefreshToken", refreshToken);
+ CurrentUserDTO currentUser = await _authRepository.LoginAsync(loginDto);
+
+ await _authRepository.GenerateAuthResponseAsync(currentUser);
}
public async Task LogoutAsync()
{
- _cookieService.DeleteCookie("AccessToken");
- _cookieService.DeleteCookie("RefreshToken");
+ await _authRepository.LogoutAsync();
await Task.CompletedTask;
}
diff --git a/Backend/prepAIred.Services/Services/Authentication/RefreshToken/RefreshTokenRepository.cs b/Backend/prepAIred.Services/Services/Authentication/RefreshToken/RefreshTokenRepository.cs
index fe820f3..c529902 100644
--- a/Backend/prepAIred.Services/Services/Authentication/RefreshToken/RefreshTokenRepository.cs
+++ b/Backend/prepAIred.Services/Services/Authentication/RefreshToken/RefreshTokenRepository.cs
@@ -1,53 +1,27 @@
using prepAIred.Data;
-using prepAIred.Exceptions;
-using Microsoft.AspNetCore.Http;
+using Microsoft.EntityFrameworkCore;
namespace prepAIred.Services
{
- public class RefreshTokenRepository(IHttpContextAccessor httpContextAccessor, IRefreshTokenService refreshTokenService,
- IJwtService jwtService, ICookieService cookieService, IUserService userService) : IRefreshTokenRepository
+ public class RefreshTokenRepository(DataContext dataContext) : IRefreshTokenRepository
{
- private readonly IHttpContextAccessor _httpContextAccessor = httpContextAccessor;
- private readonly IRefreshTokenService _refreshTokenService = refreshTokenService;
- private readonly IJwtService _jwtService = jwtService;
- private readonly ICookieService _cookieService = cookieService;
- private readonly IUserService _userService = userService;
+ private readonly DataContext _dataContext = dataContext;
- public async Task GenerateNewRefreshTokenAsync()
+ public async Task AddRefreshTokenAsync(RefreshToken refreshToken)
{
- string refreshToken = _httpContextAccessor.HttpContext!.Request.Cookies["RefreshToken"]!;
- RefreshToken storedToken = await _refreshTokenService.GetRefreshTokenAsync(refreshToken);
-
- if (storedToken is null || storedToken.ExpiryDate < DateTime.Now || storedToken.IsRevoked)
- {
- throw new InvalidRefreshTokenException("Invalid or expired refresh token.");
- }
-
- storedToken.IsRevoked = true;
-
- string newRefreshToken = _jwtService.GenerateRefreshToken(storedToken.UserID);
- string newAccessToken = _jwtService.GenerateAcessToken(storedToken.UserID);
-
- RefreshToken newRefreshTokenEntity = await _refreshTokenService.AddRefreshTokenAsync(new RefreshToken()
- {
- Token = newRefreshToken,
- ExpiryDate = DateTime.Now.AddDays(7),
- UserID = storedToken.UserID,
- });
-
- CurrentUserDTO currentUser = await _userService.GetUserByIdAsync(storedToken.UserID);
+ _dataContext.RefreshTokens.Add(refreshToken);
+ await _dataContext.SaveChangesAsync();
+ return refreshToken;
+ }
- _cookieService.DeleteCookie("RefreshToken");
- _cookieService.CreateCookie("AccessToken", newAccessToken);
- _cookieService.CreateCookie("RefreshToken", newRefreshToken);
+ public async Task GetRefreshTokenAsync(string refreshToken)
+ {
+ return await _dataContext.RefreshTokens.FirstOrDefaultAsync(t => t.Token == refreshToken) ?? new RefreshToken();
+ }
- return new RefreshTokenResponseDTO()
- {
- NewAccessToken = newAccessToken,
- NewRefreshToken = newRefreshToken,
- ExpiresIn = 600,
- Username = currentUser.Username
- };
+ public async Task GetRefreshTokenByUserIdAsync(int userID)
+ {
+ return await _dataContext.RefreshTokens.FirstOrDefaultAsync(t => t.UserID == userID && !t.IsRevoked) ?? new RefreshToken();
}
}
}
diff --git a/Backend/prepAIred.Services/Services/Authentication/RefreshToken/RefreshTokenService.cs b/Backend/prepAIred.Services/Services/Authentication/RefreshToken/RefreshTokenService.cs
index b91f7d0..2ec97d4 100644
--- a/Backend/prepAIred.Services/Services/Authentication/RefreshToken/RefreshTokenService.cs
+++ b/Backend/prepAIred.Services/Services/Authentication/RefreshToken/RefreshTokenService.cs
@@ -1,27 +1,53 @@
using prepAIred.Data;
-using Microsoft.EntityFrameworkCore;
+using prepAIred.Exceptions;
+using Microsoft.AspNetCore.Http;
namespace prepAIred.Services
{
- public class RefreshTokenService(DataContext dataContext) : IRefreshTokenService
+ public class RefreshTokenService(IHttpContextAccessor httpContextAccessor, IRefreshTokenRepository refreshTokenRepository,
+ IJwtService jwtService, ICookieService cookieService, IUserRepository userRepository) : IRefreshTokenService
{
- private readonly DataContext _dataContext = dataContext;
+ private readonly IHttpContextAccessor _httpContextAccessor = httpContextAccessor;
+ private readonly IRefreshTokenRepository _refreshTokenRepository = refreshTokenRepository;
+ private readonly IJwtService _jwtService = jwtService;
+ private readonly ICookieService _cookieService = cookieService;
+ private readonly IUserRepository _userRepository = userRepository;
- public async Task AddRefreshTokenAsync(RefreshToken refreshToken)
+ public async Task GenerateNewRefreshTokenAsync()
{
- _dataContext.RefreshTokens.Add(refreshToken);
- await _dataContext.SaveChangesAsync();
- return refreshToken;
- }
+ string refreshToken = _httpContextAccessor.HttpContext!.Request.Cookies["RefreshToken"]!;
+ RefreshToken storedToken = await _refreshTokenRepository.GetRefreshTokenAsync(refreshToken);
- public async Task GetRefreshTokenAsync(string refreshToken)
- {
- return await _dataContext.RefreshTokens.FirstOrDefaultAsync(t => t.Token == refreshToken) ?? new RefreshToken();
- }
+ if (storedToken is null || storedToken.ExpiryDate < DateTime.Now || storedToken.IsRevoked)
+ {
+ throw new InvalidRefreshTokenException("Invalid or expired refresh token.");
+ }
- public async Task GetRefreshTokenByUserIdAsync(int userID)
- {
- return await _dataContext.RefreshTokens.FirstOrDefaultAsync(t => t.UserID == userID && !t.IsRevoked) ?? new RefreshToken();
+ storedToken.IsRevoked = true;
+
+ string newRefreshToken = _jwtService.GenerateRefreshToken(storedToken.UserID);
+ string newAccessToken = _jwtService.GenerateAcessToken(storedToken.UserID);
+
+ RefreshToken newRefreshTokenEntity = await _refreshTokenRepository.AddRefreshTokenAsync(new RefreshToken()
+ {
+ Token = newRefreshToken,
+ ExpiryDate = DateTime.Now.AddDays(7),
+ UserID = storedToken.UserID,
+ });
+
+ CurrentUserDTO currentUser = await _userRepository.GetUserByIdAsync(storedToken.UserID);
+
+ _cookieService.DeleteCookie("RefreshToken");
+ _cookieService.CreateCookie("AccessToken", newAccessToken);
+ _cookieService.CreateCookie("RefreshToken", newRefreshToken);
+
+ return new RefreshTokenResponseDTO()
+ {
+ NewAccessToken = newAccessToken,
+ NewRefreshToken = newRefreshToken,
+ ExpiresIn = 600,
+ Username = currentUser.Username
+ };
}
}
}
diff --git a/Backend/prepAIred.Services/Services/Interview/InterviewSessions/InterviewSessionRepository.cs b/Backend/prepAIred.Services/Services/Interview/InterviewSessions/InterviewSessionRepository.cs
index 315e703..ff63b9e 100644
--- a/Backend/prepAIred.Services/Services/Interview/InterviewSessions/InterviewSessionRepository.cs
+++ b/Backend/prepAIred.Services/Services/Interview/InterviewSessions/InterviewSessionRepository.cs
@@ -1,109 +1,179 @@
using prepAIred.Data;
+using prepAIred.Exceptions;
+using Microsoft.EntityFrameworkCore;
namespace prepAIred.Services
{
- public class InterviewSessionRepository(IInterviewSessionService interviewSessionService, IUserService userService) : IInterviewSessionRepository
+ public class InterviewSessionRepository(DataContext dataContext) : IInterviewSessionRepository
{
- private readonly IInterviewSessionService _interviewSessionService = interviewSessionService;
- private readonly IUserService _userService = userService;
+ private readonly DataContext _dataContext = dataContext;
- public async Task> GetInterviewSessionDTOsAsync()
+ public async Task CreateInterviewSessionAsync(InterviewSession interviewSession)
{
- int currentUserID = await _userService.GetCurrentUserID();
- List interviewSessions = await _interviewSessionService.GetInterviewSessionsByUserIdAsync(currentUserID);
- List interviewSessionsDTOs = interviewSessions.ConvertAll(session => session.ToDto());
+ await _dataContext.InterviewSessions.AddAsync(interviewSession);
+ }
- return interviewSessionsDTOs;
+ public async Task UpdateInterviewSessionAsync(InterviewSession interviewSession)
+ {
+ _dataContext.InterviewSessions.Update(interviewSession);
+ await _dataContext.SaveChangesAsync();
}
- public async Task> GetInterviewSessionActivitiesAsync()
+ public async Task GetAdjacentInterviewSessionAsync(int currentUserID)
{
- int currentUserID = await _userService.GetCurrentUserID();
- List activities = await _interviewSessionService.GetInterviewSessionActivitiesAsync(currentUserID);
+ return await _dataContext.InterviewSessions
+ .Where(intSession => intSession.UserID == currentUserID)
+ .OrderByDescending(s => s.DateCreated)
+ .FirstOrDefaultAsync() ?? throw new InterviewSessionNotFoundException("No interview session found for the current user.");
+ }
- return activities;
+ public async Task> GetInterviewSessionsByUserIdAsync(int userID)
+ {
+ return await _dataContext.InterviewSessions
+ .Where(intSession => intSession.UserID == userID)
+ .Include(s => s.Interviews)
+ .ToListAsync();
}
- public async Task GetInterviewSessionStatisticsAsync()
+ public async Task GetInterviewSessionByIdAsync(int sessionID)
{
- int currentUserID = await _userService.GetCurrentUserID();
+ return await _dataContext.InterviewSessions
+ .Where(s => s.ID == sessionID)
+ .FirstOrDefaultAsync();
+ }
- int totalInterviewSessions = await _interviewSessionService.GetTotalInterviewSessionsAsync(currentUserID);
- int passedInterviewSessions = await _interviewSessionService.GetPassedInterviewSessionsAsync(currentUserID);
- int ongoingInterviewSessions = await _interviewSessionService.GetOngoingInterviewSessionsAsync(currentUserID);
- decimal averageScore = await _interviewSessionService.GetAverageScoreAsync(currentUserID);
- decimal completionRate = await _interviewSessionService.GetCompletionRateAsync(currentUserID);
+ public async Task GetInterviewSessionFromQuestionsAsync(List evaluateRequests)
+ {
+ EvaluateRequestDTO firstRequest = evaluateRequests.FirstOrDefault()!;
+ string firstQuestion = firstRequest?.Question!;
+
+ return await _dataContext.InterviewSessions
+ .Include(s => s.Interviews)
+ .Where(s => s.Interviews.Any(i => i.Question == firstQuestion && !i.IsAnswered))
+ .FirstOrDefaultAsync() ?? throw new InterviewSessionNotFoundException("No interview session found matching the provided questions.");
+ }
- ProfileStatisticsDTO profileStatistics = new ProfileStatisticsDTO()
+ public async Task DeleteInterviewSessionsAsync(List interviewSessions)
+ {
+ _dataContext.InterviewSessions.RemoveRange(interviewSessions);
+ await _dataContext.SaveChangesAsync();
+ }
+
+ public async Task GetLatestInterviewSessionIDAsync(int userID)
+ {
+ return await _dataContext.InterviewSessions
+ .Where(intSession => intSession.UserID == userID)
+ .OrderByDescending(s => s.DateCreated)
+ .Select(s => s.ID)
+ .FirstOrDefaultAsync();
+ }
+
+ public async Task FinishInterviewSessionAsync(InterviewSession interviewSession)
+ {
+ if (interviewSession.AverageScore > 5)
{
- TotalInterviewSessions = totalInterviewSessions,
- PassedInterviewSessions = passedInterviewSessions,
- OngoingInterviewSessions = ongoingInterviewSessions,
- AverageScore = averageScore,
- CompletionRate = completionRate
- };
+ interviewSession.Status = InterviewSessionStatus.Passed;
+ }
+ else
+ {
+ interviewSession.Status = InterviewSessionStatus.Failed;
+ }
- return profileStatistics;
+ _dataContext.InterviewSessions.Update(interviewSession);
+ await _dataContext.SaveChangesAsync();
}
- public async Task> GetInterviewSessionPerformanceAsync()
+ public async Task GetTotalInterviewSessionsAsync(int userID)
{
- List activities = await GetInterviewSessionActivitiesAsync();
- List performanceData = activities
- .OrderBy(activity => activity.DateCreated)
- .Select(activity => new InterviewSessionPerformanceDTO()
- {
- ID = activity.ID,
- DateCreated = activity.DateCreated,
- Score = activity.AverageScore
- }).ToList();
+ return await _dataContext.InterviewSessions
+ .Where(intSession => intSession.UserID == userID && intSession.Status != InterviewSessionStatus.Ongoing)
+ .CountAsync();
+ }
- return performanceData;
+ public async Task GetPassedInterviewSessionsAsync(int userID)
+ {
+ return await _dataContext.InterviewSessions
+ .Where(intSession => intSession.UserID == userID && intSession.Status == InterviewSessionStatus.Passed)
+ .CountAsync();
}
- public async Task> GetInterviewSessionProgrammingLanguageDataAsync()
+ public async Task GetOngoingInterviewSessionsAsync(int userID)
{
- List activities = await GetInterviewSessionActivitiesAsync();
- List programmingLanguageData = activities
- .GroupBy(activity => activity.ProgrammingLanguage)
- .Select(activity => new ProgrammingLanguageDataDTO()
- {
- Language = activity.Key,
- Sessions = activity.Count()
- }).ToList();
+ return await _dataContext.InterviewSessions
+ .Where(intSession => intSession.UserID == userID && intSession.Status == InterviewSessionStatus.Ongoing)
+ .CountAsync();
+ }
- return programmingLanguageData;
+ public async Task GetAverageScoreAsync(int userID)
+ {
+ List sessions = await _dataContext.InterviewSessions
+ .Where(intSession => intSession.UserID == userID && intSession.Status != InterviewSessionStatus.Ongoing)
+ .ToListAsync();
+
+ decimal averageScore = (decimal)(sessions.Count != 0 ? sessions.Average(s => s.AverageScore) : 0);
+
+ return averageScore;
}
- public async Task> GetInterviewSessionPositionDataAsync()
+ public async Task GetCompletionRateAsync(int userID)
{
- List activities = await GetInterviewSessionActivitiesAsync();
- List positionData = activities
- .GroupBy(activity => activity.Position)
- .Select(activity => new PositionDataDTO()
- {
- Position = activity.Key,
- Sessions = activity.Count()
- }).ToList();
+ int totalSessions = await GetTotalInterviewSessionsAsync(userID);
+ int passedSessions = await GetPassedInterviewSessionsAsync(userID);
+
+ if (totalSessions == 0) return 0;
- return positionData;
+ decimal rate = (passedSessions / (decimal)totalSessions) * 100;
+
+ return Math.Round(rate, 2);
}
- public async Task FinishInterviewSessionAsync()
+ public void FinalizeInterviewSession(InterviewSession interviewSession, List evaluatedTInterviews) where TInterview : Interview
{
- int currentUserID = await _userService.GetCurrentUserID();
- int interviewSessionID = await _interviewSessionService.GetLatestInterviewSessionIDAsync(currentUserID);
- InterviewSession latestSession = await _interviewSessionService.GetInterviewSessionByIdAsync(interviewSessionID);
+ if (interviewSession.HrScore == 0)
+ {
+ float hrScore = evaluatedTInterviews.OfType().Any()
+ ? evaluatedTInterviews.OfType().Average(i => i.Score)
+ : 0;
+
+ interviewSession.HrScore = hrScore;
+ }
+
+ if (interviewSession.TechnicalScore == 0)
+ {
+ float technicalScore = evaluatedTInterviews.OfType().Any()
+ ? evaluatedTInterviews.OfType().Average(i => i.Score)
+ : 0;
- await _interviewSessionService.FinishInterviewSessionAsync(latestSession);
+ interviewSession.TechnicalScore = technicalScore;
+ }
}
- public async Task DeleteInterviewSessionsAsync()
+ public async Task> GetInterviewSessionActivitiesAsync(int userID)
{
- int currentUserID = await _userService.GetCurrentUserID();
- List interviewSessions = await _interviewSessionService.GetInterviewSessionsByUserIdAsync(currentUserID);
+ List interviewSessions = await _dataContext.InterviewSessions
+ .Where(session => session.UserID == userID && session.Status != InterviewSessionStatus.Ongoing)
+ .Include(session => session.Interviews)
+ .OrderByDescending(session => session.DateCreated)
+ .ToListAsync();
+
+ List activityDTOs = interviewSessions.ConvertAll(session =>
+ {
+ TechnicalInterview? technicalInterview = session.Interviews.OfType().FirstOrDefault();
- await _interviewSessionService.DeleteInterviewSessionsAsync(interviewSessions);
+ return new InterviewSessionActivityDTO()
+ {
+ ID = session.ID,
+ DateCreated = session.DateCreated,
+ Subject = session.Subject,
+ AverageScore = session.AverageScore,
+ AiAgent = session.AIAgent.ToString(),
+ Position = technicalInterview?.Position ?? "Junior Developer",
+ ProgrammingLanguage = technicalInterview?.ProgrammingLanguage ?? "C#",
+ Status = session.Status.ToString()
+ };
+ });
+
+ return activityDTOs;
}
}
}
diff --git a/Backend/prepAIred.Services/Services/Interview/InterviewSessions/InterviewSessionService.cs b/Backend/prepAIred.Services/Services/Interview/InterviewSessions/InterviewSessionService.cs
index fa97c75..2862ed7 100644
--- a/Backend/prepAIred.Services/Services/Interview/InterviewSessions/InterviewSessionService.cs
+++ b/Backend/prepAIred.Services/Services/Interview/InterviewSessions/InterviewSessionService.cs
@@ -1,178 +1,109 @@
using prepAIred.Data;
-using Microsoft.EntityFrameworkCore;
namespace prepAIred.Services
{
- public class InterviewSessionService(DataContext dataContext) : IInterviewSessionService
+ public class InterviewSessionService(IInterviewSessionRepository interviewSessionRepository, IUserRepository userRepository) : IInterviewSessionService
{
- private readonly DataContext _dataContext = dataContext;
+ private readonly IInterviewSessionRepository _interviewSessionRepository = interviewSessionRepository;
+ private readonly IUserRepository _userRepository = userRepository;
- public async Task CreateInterviewSessionAsync(InterviewSession interviewSession)
+ public async Task> GetInterviewSessionDTOsAsync()
{
- await _dataContext.InterviewSessions.AddAsync(interviewSession);
- }
+ int currentUserID = await _userRepository.GetCurrentUserID();
+ List interviewSessions = await _interviewSessionRepository.GetInterviewSessionsByUserIdAsync(currentUserID);
+ List interviewSessionsDTOs = interviewSessions.ConvertAll(session => session.ToDto());
- public async Task UpdateInterviewSessionAsync(InterviewSession interviewSession)
- {
- _dataContext.InterviewSessions.Update(interviewSession);
- await _dataContext.SaveChangesAsync();
+ return interviewSessionsDTOs;
}
- public async Task GetAdjacentInterviewSessionAsync(int currentUserID)
+ public async Task> GetInterviewSessionActivitiesAsync()
{
- return await _dataContext.InterviewSessions
- .Where(intSession => intSession.UserID == currentUserID)
- .OrderByDescending(s => s.DateCreated)
- .FirstOrDefaultAsync();
- }
+ int currentUserID = await _userRepository.GetCurrentUserID();
+ List activities = await _interviewSessionRepository.GetInterviewSessionActivitiesAsync(currentUserID);
- public async Task> GetInterviewSessionsByUserIdAsync(int userID)
- {
- return await _dataContext.InterviewSessions
- .Where(intSession => intSession.UserID == userID)
- .Include(s => s.Interviews)
- .ToListAsync();
+ return activities;
}
- public async Task GetInterviewSessionByIdAsync(int sessionID)
+ public async Task GetInterviewSessionStatisticsAsync()
{
- return await _dataContext.InterviewSessions
- .Where(s => s.ID == sessionID)
- .FirstOrDefaultAsync();
- }
+ int currentUserID = await _userRepository.GetCurrentUserID();
- public async Task GetInterviewSessionFromQuestionsAsync(List evaluateRequests)
- {
- EvaluateRequestDTO firstRequest = evaluateRequests.FirstOrDefault()!;
- string firstQuestion = firstRequest?.Question!;
-
- return await _dataContext.InterviewSessions
- .Include(s => s.Interviews)
- .Where(s => s.Interviews.Any(i => i.Question == firstQuestion && !i.IsAnswered))
- .FirstOrDefaultAsync();
- }
+ int totalInterviewSessions = await _interviewSessionRepository.GetTotalInterviewSessionsAsync(currentUserID);
+ int passedInterviewSessions = await _interviewSessionRepository.GetPassedInterviewSessionsAsync(currentUserID);
+ int ongoingInterviewSessions = await _interviewSessionRepository.GetOngoingInterviewSessionsAsync(currentUserID);
+ decimal averageScore = await _interviewSessionRepository.GetAverageScoreAsync(currentUserID);
+ decimal completionRate = await _interviewSessionRepository.GetCompletionRateAsync(currentUserID);
- public async Task DeleteInterviewSessionsAsync(List interviewSessions)
- {
- _dataContext.InterviewSessions.RemoveRange(interviewSessions);
- await _dataContext.SaveChangesAsync();
- }
-
- public async Task GetLatestInterviewSessionIDAsync(int userID)
- {
- return await _dataContext.InterviewSessions
- .Where(intSession => intSession.UserID == userID)
- .OrderByDescending(s => s.DateCreated)
- .Select(s => s.ID)
- .FirstOrDefaultAsync();
- }
-
- public async Task FinishInterviewSessionAsync(InterviewSession interviewSession)
- {
- if (interviewSession.AverageScore > 5)
+ ProfileStatisticsDTO profileStatistics = new ProfileStatisticsDTO()
{
- interviewSession.Status = InterviewSessionStatus.Passed;
- }
- else
- {
- interviewSession.Status = InterviewSessionStatus.Failed;
- }
-
- _dataContext.InterviewSessions.Update(interviewSession);
- await _dataContext.SaveChangesAsync();
- }
+ TotalInterviewSessions = totalInterviewSessions,
+ PassedInterviewSessions = passedInterviewSessions,
+ OngoingInterviewSessions = ongoingInterviewSessions,
+ AverageScore = averageScore,
+ CompletionRate = completionRate
+ };
- public async Task