diff --git a/backend/Backend/src/main/java/com/securehealth/backend/config/RequestLoggingFilter.java b/backend/Backend/src/main/java/com/securehealth/backend/config/RequestLoggingFilter.java index f22faba9..149ca9c3 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/config/RequestLoggingFilter.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/config/RequestLoggingFilter.java @@ -16,12 +16,33 @@ import java.io.IOException; +/** + * Filter that logs incoming HTTP requests and their corresponding responses for auditing purposes. + *

+ * This filter intercepts requests, processes them, and logs key details such as URI, status code, + * authenticated user, IP address, and user agent into the {@link AuditLogRepository}. + *

+ */ @Component public class RequestLoggingFilter extends OncePerRequestFilter { @Autowired private AuditLogRepository auditLogRepository; + /** + * Filters incoming requests to log relevant details for authenticated users. + *

+ * It captures the request start time, proceed with the filter chain, then calculates the + * duration and status code. If the user is authenticated and the request is not an auth + * endpoint, it saves an audit log entry. + *

+ * + * @param request the {@link HttpServletRequest} object + * @param response the {@link HttpServletResponse} object + * @param filterChain the {@link FilterChain} for further filter execution + * @throws ServletException if a servlet-specific error occurs + * @throws IOException if an I/O error occurs during processing + */ @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, diff --git a/backend/Backend/src/main/java/com/securehealth/backend/config/SecurityConfig.java b/backend/Backend/src/main/java/com/securehealth/backend/config/SecurityConfig.java index 6962c7d9..3a9a165d 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/config/SecurityConfig.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/config/SecurityConfig.java @@ -26,6 +26,14 @@ import java.util.List; +/** + * Configuration class for Spring Security. + *

+ * This class defines the security filter chain, password encoding, CORS configuration, + * and authorization rules for the application. It also integrates JWT-based authentication + * and provides custom handling for unauthorized and forbidden access attempts. + *

+ */ @Configuration @EnableWebSecurity @EnableMethodSecurity @@ -40,11 +48,28 @@ public class SecurityConfig { @Value("${app.cors.allowed-origins:http://localhost:3000}") private String allowedOrigins; + /** + * Defines the {@link PasswordEncoder} bean using the Argon2 algorithm. + * + * @return an {@link Argon2PasswordEncoder} instance + */ @Bean public PasswordEncoder passwordEncoder() { return new Argon2PasswordEncoder(16, 32, 1, 4096, 3); } + /** + * Configures the {@link SecurityFilterChain} for the application. + *

+ * This method defines CSRF protection, session management, CORS settings, + * request authorization, and custom exception handling for authentication and access denial. + * It also adds the {@link JwtAuthenticationFilter} before the standard username/password filter. + *

+ * + * @param http the {@link HttpSecurity} object to configure + * @return the configured {@link SecurityFilterChain} + * @throws Exception if an error occurs during configuration + */ @Bean public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { @@ -88,6 +113,12 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { return http.build(); } + /** + * Saves a security log entry for unauthorized or forbidden access attempts. + * + * @param action the security action being logged (e.g., "UNAUTHORIZED_ACCESS") + * @param request the {@link HttpServletRequest} associated with the attempt + */ private void saveSecurityLog(String action, HttpServletRequest request) { try { AuditLog log = new AuditLog( @@ -105,6 +136,15 @@ private void saveSecurityLog(String action, HttpServletRequest request) { } } + /** + * Configures the CORS (Cross-Origin Resource Sharing) settings. + *

+ * This method specifies allowed origins, methods, headers, and credential support + * based on application properties and standard requirements. + *

+ * + * @return a {@link CorsConfigurationSource} for use in the security filter chain + */ @Bean public CorsConfigurationSource corsConfigurationSource() { CorsConfiguration configuration = new CorsConfiguration(); diff --git a/backend/Backend/src/main/java/com/securehealth/backend/config/WebConfig.java b/backend/Backend/src/main/java/com/securehealth/backend/config/WebConfig.java index 39033825..ff2c84e6 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/config/WebConfig.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/config/WebConfig.java @@ -5,12 +5,28 @@ import org.springframework.web.servlet.config.annotation.CorsRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +/** + * General web configuration for the application. + *

+ * This class implements {@link WebMvcConfigurer} to customize Spring MVC settings, + * specifically for CORS mappings to allow frontend access. + *

+ */ @Configuration public class WebConfig implements WebMvcConfigurer { @Value("${app.cors.allowed-origins:http://localhost:3000}") private String allowedOrigins; + /** + * Configures CORS mappings for the application. + *

+ * It enables global CORS configuration, allowing specified origins, methods, + * and headers, and supports credentials with a defined max age for pre-flight requests. + *

+ * + * @param registry the {@link CorsRegistry} to add mappings to + */ @Override public void addCorsMappings(CorsRegistry registry) { String[] origins = allowedOrigins.split(","); diff --git a/backend/Backend/src/main/java/com/securehealth/backend/controller/AdminController.java b/backend/Backend/src/main/java/com/securehealth/backend/controller/AdminController.java index 1fcd16d1..630dbbfb 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/controller/AdminController.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/controller/AdminController.java @@ -16,6 +16,13 @@ import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; +/** + * REST controller for administrative operations. + *

+ * This controller provides endpoints for managing system metrics, appointments, + * staff members, and patients. Access is restricted to users with ADMIN authority. + *

+ */ @RestController @RequestMapping("/api/admin") public class AdminController { diff --git a/backend/Backend/src/main/java/com/securehealth/backend/controller/CatalogController.java b/backend/Backend/src/main/java/com/securehealth/backend/controller/CatalogController.java index 0c689705..7a236fda 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/controller/CatalogController.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/controller/CatalogController.java @@ -9,7 +9,11 @@ import java.util.Map; /** - * Controller to provide static/mock data for frontend dropdowns. + * REST controller for providing static or mock catalog data. + *

+ * This controller exposes endpoints for frontend dropdowns, such as medications, + * test types, prescription protocols, conditions, and hospital departments. + *

*/ @RestController @RequestMapping("/api") diff --git a/backend/Backend/src/main/java/com/securehealth/backend/controller/ConsentController.java b/backend/Backend/src/main/java/com/securehealth/backend/controller/ConsentController.java index 617539ac..63d05095 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/controller/ConsentController.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/controller/ConsentController.java @@ -10,6 +10,13 @@ import java.util.Map; +/** + * REST controller for managing patient consents. + *

+ * This controller provides endpoints for patients to list their consents, + * grant new ones, and revoke existing ones. Access is restricted to users with PATIENT authority. + *

+ */ @RestController @RequestMapping("/api/consent") @PreAuthorize("hasAuthority('PATIENT')") diff --git a/backend/Backend/src/main/java/com/securehealth/backend/controller/DoctorController.java b/backend/Backend/src/main/java/com/securehealth/backend/controller/DoctorController.java index 97f588bb..3c9a26fc 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/controller/DoctorController.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/controller/DoctorController.java @@ -11,6 +11,13 @@ import java.util.List; +/** + * REST controller for managing doctor-related operations. + *

+ * Provides endpoints for retrieving lists of doctors, searching by specialty or department, + * updating doctor profiles, and retrieving lists of patients assigned to a doctor. + *

+ */ @RestController @RequestMapping("/api/doctors") public class DoctorController { diff --git a/backend/Backend/src/main/java/com/securehealth/backend/controller/FileUploadController.java b/backend/Backend/src/main/java/com/securehealth/backend/controller/FileUploadController.java index 3870911e..4a758923 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/controller/FileUploadController.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/controller/FileUploadController.java @@ -10,6 +10,13 @@ import java.util.Map; +/** + * REST controller for handling file uploads and downloads. + *

+ * This controller provides endpoints for uploading files (which are encrypted at rest) + * and retrieving/decrypting them. + *

+ */ @RestController @RequestMapping("/api/files") public class FileUploadController { diff --git a/backend/Backend/src/main/java/com/securehealth/backend/controller/LabResultController.java b/backend/Backend/src/main/java/com/securehealth/backend/controller/LabResultController.java index c0cc2f81..e2ac4ef4 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/controller/LabResultController.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/controller/LabResultController.java @@ -14,6 +14,13 @@ import java.util.List; +/** + * REST controller for managing lab test results. + *

+ * Provides endpoints for retrieving lab results by patient, creating new lab tests, + * and listing pending tests for lab technicians. + *

+ */ @RestController @RequestMapping("/api/lab-results") public class LabResultController { diff --git a/backend/Backend/src/main/java/com/securehealth/backend/controller/LabTechnicianController.java b/backend/Backend/src/main/java/com/securehealth/backend/controller/LabTechnicianController.java index 733a4fa5..b892c804 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/controller/LabTechnicianController.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/controller/LabTechnicianController.java @@ -9,6 +9,13 @@ import java.util.Map; +/** + * REST controller for lab technician dashboard and order management. + *

+ * Provides endpoints for lab technicians to view their dashboard, manage test orders, + * update order status, and upload results. Access is restricted to users with LAB_TECHNICIAN authority. + *

+ */ @RestController @RequestMapping("/api/lab-technician") @PreAuthorize("hasAuthority('LAB_TECHNICIAN')") diff --git a/backend/Backend/src/main/java/com/securehealth/backend/controller/MedicalRecordController.java b/backend/Backend/src/main/java/com/securehealth/backend/controller/MedicalRecordController.java index aa67c62f..b537c062 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/controller/MedicalRecordController.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/controller/MedicalRecordController.java @@ -14,6 +14,13 @@ import java.util.List; +/** + * REST controller for managing medical records. + *

+ * Provides endpoints for retrieving medical records by patient, creating new records + * (restricted to doctors), and deleting records (restricted to admins). + *

+ */ @RestController @RequestMapping("/api/medical-records") public class MedicalRecordController { diff --git a/backend/Backend/src/main/java/com/securehealth/backend/controller/NurseController.java b/backend/Backend/src/main/java/com/securehealth/backend/controller/NurseController.java index a6e8c479..f6bfcca3 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/controller/NurseController.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/controller/NurseController.java @@ -9,6 +9,13 @@ import java.util.Map; +/** + * REST controller for nurse-related operations. + *

+ * Provides endpoints for nurses to view their dashboard, assigned patients, tasks, + * and manage handover notes. Access is restricted to users with NURSE authority. + *

+ */ @RestController @RequestMapping("/api/nurse") @PreAuthorize("hasAuthority('NURSE')") diff --git a/backend/Backend/src/main/java/com/securehealth/backend/controller/PatientController.java b/backend/Backend/src/main/java/com/securehealth/backend/controller/PatientController.java index 95f2757e..4b4ce479 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/controller/PatientController.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/controller/PatientController.java @@ -14,6 +14,13 @@ import java.util.List; +/** + * REST controller for managing patient profiles. + *

+ * Provides endpoints for listing all patients (with pagination), retrieving own profile, + * creating/updating patient information, and searching by ID. + *

+ */ @RestController @RequestMapping("/api/patients") public class PatientController { diff --git a/backend/Backend/src/main/java/com/securehealth/backend/controller/PrescriptionController.java b/backend/Backend/src/main/java/com/securehealth/backend/controller/PrescriptionController.java index 1e4c55c2..3a622eb5 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/controller/PrescriptionController.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/controller/PrescriptionController.java @@ -14,6 +14,13 @@ import java.util.List; +/** + * REST controller for managing prescriptions. + *

+ * Provides endpoints for retrieving prescriptions by patient, creating new prescriptions, + * refilling existing ones, and deleting records. + *

+ */ @RestController @RequestMapping("/api/prescriptions") public class PrescriptionController { diff --git a/backend/Backend/src/main/java/com/securehealth/backend/controller/VitalSignController.java b/backend/Backend/src/main/java/com/securehealth/backend/controller/VitalSignController.java index af746ef3..bc440da8 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/controller/VitalSignController.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/controller/VitalSignController.java @@ -14,6 +14,13 @@ import java.util.List; +/** + * REST controller for managing patient vital signs. + *

+ * Provides endpoints for retrieving vital signs history, getting the latest readings, + * and recording new vital signs (restricted to authorized personnel). + *

+ */ @RestController @RequestMapping("/api/vital-signs") public class VitalSignController { diff --git a/backend/Backend/src/main/java/com/securehealth/backend/dto/AdminMetricsDTO.java b/backend/Backend/src/main/java/com/securehealth/backend/dto/AdminMetricsDTO.java index 73d55329..dac5a225 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/dto/AdminMetricsDTO.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/dto/AdminMetricsDTO.java @@ -2,6 +2,13 @@ import lombok.Data; +/** + * Data Transfer Object for administrative dashboard metrics. + *

+ * Contains aggregated counts for patients, doctors, today's appointments, + * and pending appointment approvals. + *

+ */ @Data public class AdminMetricsDTO { private long totalPatients; diff --git a/backend/Backend/src/main/java/com/securehealth/backend/dto/AppointmentDTO.java b/backend/Backend/src/main/java/com/securehealth/backend/dto/AppointmentDTO.java index 55f260da..b418bb35 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/dto/AppointmentDTO.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/dto/AppointmentDTO.java @@ -3,6 +3,13 @@ import java.time.LocalDateTime; import com.securehealth.backend.model.AppointmentStatus; +/** + * Data Transfer Object representing an appointment's details. + *

+ * Used for transferring appointment information between the server and the client, + * including doctor and patient names, date, status, and reason for the visit. + *

+ */ @Data public class AppointmentDTO { private Long appointmentId; diff --git a/backend/Backend/src/main/java/com/securehealth/backend/dto/AppointmentRequest.java b/backend/Backend/src/main/java/com/securehealth/backend/dto/AppointmentRequest.java index 9bc1c62e..3a14319f 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/dto/AppointmentRequest.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/dto/AppointmentRequest.java @@ -6,6 +6,13 @@ import lombok.Data; import java.time.LocalDateTime; +/** + * Data Transfer Object for creating a new appointment request. + *

+ * This DTO is used by patients to submit appointment bookings, requiring + * a doctor ID, a future appointment date, and a reason for the visit. + *

+ */ @Data public class AppointmentRequest { @NotNull(message = "Doctor ID is required") diff --git a/backend/Backend/src/main/java/com/securehealth/backend/dto/DoctorDTO.java b/backend/Backend/src/main/java/com/securehealth/backend/dto/DoctorDTO.java index f0623e5d..5997e7f5 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/dto/DoctorDTO.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/dto/DoctorDTO.java @@ -5,6 +5,13 @@ import java.time.DayOfWeek; import java.util.List; +/** + * Data Transfer Object representing a doctor's profile information. + *

+ * Includes basic details like name and contact information, as well as + * professional details like specialty, department, and working schedule. + *

+ */ @Data public class DoctorDTO { private Long id; diff --git a/backend/Backend/src/main/java/com/securehealth/backend/dto/LabTestDTO.java b/backend/Backend/src/main/java/com/securehealth/backend/dto/LabTestDTO.java index b57218be..062badca 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/dto/LabTestDTO.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/dto/LabTestDTO.java @@ -2,6 +2,13 @@ import lombok.Data; import java.time.LocalDateTime; +/** + * Data Transfer Object representing the details of a lab test. + *

+ * Contains comprehensive information about a lab test, including patient details, + * the ordering doctor, test results, status, and associated files. + *

+ */ @Data public class LabTestDTO { private Long testId; diff --git a/backend/Backend/src/main/java/com/securehealth/backend/dto/LabTestRequest.java b/backend/Backend/src/main/java/com/securehealth/backend/dto/LabTestRequest.java index 951b51ad..f62993f9 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/dto/LabTestRequest.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/dto/LabTestRequest.java @@ -4,6 +4,13 @@ import jakarta.validation.constraints.NotNull; import lombok.Data; +/** + * Data Transfer Object for creating or updating a lab test request. + *

+ * Used to specify the patient, test name, category, and initial results or remarks + * when ordering or recording a lab test. + *

+ */ @Data public class LabTestRequest { @NotNull(message = "Patient ID is required") diff --git a/backend/Backend/src/main/java/com/securehealth/backend/dto/LoginRequest.java b/backend/Backend/src/main/java/com/securehealth/backend/dto/LoginRequest.java index a6c3db38..47fc719a 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/dto/LoginRequest.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/dto/LoginRequest.java @@ -8,7 +8,11 @@ import lombok.NoArgsConstructor; // [NEW] Generates empty constructor /** - * DTO for login requests. + * Data Transfer Object for login requests. + *

+ * This DTO is used by users to provide their credentials (email and password) + * for authentication. It includes validation constraints to ensure data integrity. + *

*/ @Data @NoArgsConstructor // Fixes "The constructor LoginRequest() is undefined" diff --git a/backend/Backend/src/main/java/com/securehealth/backend/dto/LoginResponse.java b/backend/Backend/src/main/java/com/securehealth/backend/dto/LoginResponse.java index ab335bba..4952cf6e 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/dto/LoginResponse.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/dto/LoginResponse.java @@ -3,6 +3,14 @@ import lombok.AllArgsConstructor; import lombok.Data; +/** + * Data Transfer Object for login responses. + *

+ * Contains authentication tokens (access and refresh), the user's role, + * authentication status, and the unique user ID upon successful login or + * partial authentication (e.g., when OTP is required). + *

+ */ @Data @AllArgsConstructor public class LoginResponse { diff --git a/backend/Backend/src/main/java/com/securehealth/backend/dto/MedicalRecordDTO.java b/backend/Backend/src/main/java/com/securehealth/backend/dto/MedicalRecordDTO.java index 91b31aa5..2bd523b8 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/dto/MedicalRecordDTO.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/dto/MedicalRecordDTO.java @@ -2,6 +2,13 @@ import lombok.Data; import java.time.LocalDateTime; +/** + * Data Transfer Object representing a medical record's details. + *

+ * Transports information about a patient's diagnosis, symptoms, treatments, + * and notes, along with the recording doctor's name and relevant timestamps. + *

+ */ @Data public class MedicalRecordDTO { private Long recordId; diff --git a/backend/Backend/src/main/java/com/securehealth/backend/dto/MedicalRecordRequest.java b/backend/Backend/src/main/java/com/securehealth/backend/dto/MedicalRecordRequest.java index b12c0fda..fdfc334a 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/dto/MedicalRecordRequest.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/dto/MedicalRecordRequest.java @@ -4,6 +4,13 @@ import jakarta.validation.constraints.NotNull; import lombok.Data; +/** + * Data Transfer Object for creating or updating a medical record request. + *

+ * Used by medical professionals to submit new medical records, requiring + * the patient ID, diagnosis, symptoms, and treatment details. + *

+ */ @Data public class MedicalRecordRequest { @NotNull(message = "Patient ID is required") diff --git a/backend/Backend/src/main/java/com/securehealth/backend/dto/PatientDTO.java b/backend/Backend/src/main/java/com/securehealth/backend/dto/PatientDTO.java index f79a7d3b..79462128 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/dto/PatientDTO.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/dto/PatientDTO.java @@ -6,6 +6,13 @@ import lombok.Data; import java.time.LocalDate; +/** + * Data Transfer Object representing a patient's profile. + *

+ * Contains personal details, contact information, date of birth, gender, + * address, medical history, and the ID of the assigned doctor. + *

+ */ @Data public class PatientDTO { private Long id; // Matches the Frontend's expectation of an 'id' diff --git a/backend/Backend/src/main/java/com/securehealth/backend/dto/PatientDirectoryDTO.java b/backend/Backend/src/main/java/com/securehealth/backend/dto/PatientDirectoryDTO.java index 9c996f1b..66046850 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/dto/PatientDirectoryDTO.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/dto/PatientDirectoryDTO.java @@ -3,6 +3,13 @@ import lombok.Data; import java.time.LocalDate; +/** + * Data Transfer Object for patient directory listings. + *

+ * Provides a subset of patient details suitable for directory views, + * including profile and user IDs, name, email, contact info, and birth date. + *

+ */ @Data public class PatientDirectoryDTO { private Long profileId; diff --git a/backend/Backend/src/main/java/com/securehealth/backend/dto/PatientProfileRequest.java b/backend/Backend/src/main/java/com/securehealth/backend/dto/PatientProfileRequest.java index 6448725b..73733ca0 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/dto/PatientProfileRequest.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/dto/PatientProfileRequest.java @@ -3,6 +3,13 @@ import lombok.Data; import java.time.LocalDate; +/** + * Data Transfer Object for requesting changes to a patient's profile. + *

+ * Used when a user updates their personal information, such as name, + * birth date, gender, contact details, and medical history. + *

+ */ @Data public class PatientProfileRequest { private String firstName; diff --git a/backend/Backend/src/main/java/com/securehealth/backend/dto/PrescriptionDTO.java b/backend/Backend/src/main/java/com/securehealth/backend/dto/PrescriptionDTO.java index 8205ce9d..89da1ad7 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/dto/PrescriptionDTO.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/dto/PrescriptionDTO.java @@ -2,6 +2,13 @@ import lombok.Data; import java.time.LocalDateTime; +/** + * Data Transfer Object representing a prescription's details. + *

+ * Transfers information about prescribed medications, including dosage, + * frequency, duration, status, and refill details. + *

+ */ @Data public class PrescriptionDTO { private Long prescriptionId; diff --git a/backend/Backend/src/main/java/com/securehealth/backend/dto/PrescriptionRequest.java b/backend/Backend/src/main/java/com/securehealth/backend/dto/PrescriptionRequest.java index b8f50446..1d584957 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/dto/PrescriptionRequest.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/dto/PrescriptionRequest.java @@ -4,6 +4,13 @@ import jakarta.validation.constraints.NotNull; import lombok.Data; +/** + * Data Transfer Object for creating or updating a prescription request. + *

+ * Used by doctors to prescribe medications, specifying the patient, + * medication name, dosage, frequency, duration, and any special instructions. + *

+ */ @Data public class PrescriptionRequest { @NotNull(message = "Patient ID is required") diff --git a/backend/Backend/src/main/java/com/securehealth/backend/dto/RegistrationRequest.java b/backend/Backend/src/main/java/com/securehealth/backend/dto/RegistrationRequest.java index 2b49fc83..6223c899 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/dto/RegistrationRequest.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/dto/RegistrationRequest.java @@ -12,7 +12,12 @@ import java.time.LocalDate; /** - * Data Transfer Object (DTO) for User Registration. + * Data Transfer Object for user registration requests. + *

+ * Contains the necessary information to create a new user account, + * including email, password, role, and optional profile details like + * full name, date of birth, and address. + *

*/ @Data @NoArgsConstructor // Fixes Test Error diff --git a/backend/Backend/src/main/java/com/securehealth/backend/dto/ResetPasswordRequest.java b/backend/Backend/src/main/java/com/securehealth/backend/dto/ResetPasswordRequest.java index be8b6c06..1726d4d9 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/dto/ResetPasswordRequest.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/dto/ResetPasswordRequest.java @@ -7,9 +7,10 @@ import lombok.NoArgsConstructor; /** - * DTO for password reset requests. + * Data Transfer Object for password reset requests. *

- * Used when a user submits a new password along with the reset token. + * Used when a user submits a new password along with a valid reset token + * to complete the password recovery process. *

*/ @Data diff --git a/backend/Backend/src/main/java/com/securehealth/backend/dto/RoleUpdateDTO.java b/backend/Backend/src/main/java/com/securehealth/backend/dto/RoleUpdateDTO.java index ab6131bf..9bab50fe 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/dto/RoleUpdateDTO.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/dto/RoleUpdateDTO.java @@ -2,6 +2,12 @@ import lombok.Data; +/** + * Data Transfer Object for updating a user's role. + *

+ * Simple DTO used by administrators to change the role of a staff member. + *

+ */ @Data public class RoleUpdateDTO { private String newRole; diff --git a/backend/Backend/src/main/java/com/securehealth/backend/dto/StaffDTO.java b/backend/Backend/src/main/java/com/securehealth/backend/dto/StaffDTO.java index 902ff5e7..f4aff8cd 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/dto/StaffDTO.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/dto/StaffDTO.java @@ -2,6 +2,13 @@ import lombok.Data; +/** + * Data Transfer Object representing internal staff information. + *

+ * Transports basic staff details such as user ID, email, and current role + * for administrative purposes. + *

+ */ @Data public class StaffDTO { private Long userId; diff --git a/backend/Backend/src/main/java/com/securehealth/backend/dto/VitalSignDTO.java b/backend/Backend/src/main/java/com/securehealth/backend/dto/VitalSignDTO.java index 10da433b..013cde32 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/dto/VitalSignDTO.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/dto/VitalSignDTO.java @@ -3,6 +3,14 @@ import lombok.Data; import java.time.LocalDateTime; +/** + * Data Transfer Object representing patient vital sign readings. + *

+ * Contains recorded values for blood pressure, heart rate, temperature, + * respiratory rate, oxygen saturation, weight, and height, along with + * recording metadata. + *

+ */ @Data public class VitalSignDTO { private Long vitalSignId; diff --git a/backend/Backend/src/main/java/com/securehealth/backend/dto/VitalSignRequest.java b/backend/Backend/src/main/java/com/securehealth/backend/dto/VitalSignRequest.java index 7f88a98a..200aceec 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/dto/VitalSignRequest.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/dto/VitalSignRequest.java @@ -4,6 +4,13 @@ import jakarta.validation.constraints.NotNull; import lombok.Data; +/** + * Data Transfer Object for recording new patient vital signs. + *

+ * Used by medical staff to submit new vital sign readings, requiring + * patient identification and core metrics like blood pressure, heart rate, and temperature. + *

+ */ @Data public class VitalSignRequest { @NotNull(message = "Patient ID is required") diff --git a/backend/Backend/src/main/java/com/securehealth/backend/exception/GlobalExceptionHandler.java b/backend/Backend/src/main/java/com/securehealth/backend/exception/GlobalExceptionHandler.java index 0f6e8f38..87de753b 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/exception/GlobalExceptionHandler.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/exception/GlobalExceptionHandler.java @@ -29,6 +29,12 @@ public class GlobalExceptionHandler { LoggerFactory.getLogger(GlobalExceptionHandler.class); // --- Validation Errors (e.g., @Valid on DTOs) --- + /** + * Handles validation errors triggered by {@code @Valid} annotations on DTOs. + * + * @param ex the {@link MethodArgumentNotValidException} encountered + * @return a {@link ResponseEntity} containing an {@link ErrorResponse} with specific field error details + */ @ExceptionHandler(MethodArgumentNotValidException.class) public ResponseEntity handleValidation(MethodArgumentNotValidException ex) { List details = ex.getBindingResult().getFieldErrors().stream() @@ -45,6 +51,13 @@ public ResponseEntity handleValidation(MethodArgumentNotValidExce } // --- Access Denied (Spring Security @PreAuthorize failures) --- + /** + * Handles {@link AccessDeniedException} which occurs when a user lacks the required + * authority to access a protected endpoint. + * + * @param ex the {@link AccessDeniedException} encountered + * @return a {@link ResponseEntity} with a 403 Forbidden status and a standardized error message + */ @ExceptionHandler(AccessDeniedException.class) public ResponseEntity handleAccessDenied(AccessDeniedException ex) { ErrorResponse error = new ErrorResponse( @@ -55,6 +68,12 @@ public ResponseEntity handleAccessDenied(AccessDeniedException ex } // --- JWT: Expired Token --- + /** + * Handles {@link ExpiredJwtException} when a provided JWT token has expired. + * + * @param ex the {@link ExpiredJwtException} encountered + * @return a {@link ResponseEntity} with a 401 Unauthorized status, prompting the user to log in again + */ @ExceptionHandler(ExpiredJwtException.class) public ResponseEntity handleExpiredJwt(ExpiredJwtException ex) { ErrorResponse error = new ErrorResponse( @@ -65,6 +84,12 @@ public ResponseEntity handleExpiredJwt(ExpiredJwtException ex) { } // --- JWT: Malformed or Invalid Signature --- + /** + * Handles malformed JWTs or tokens with invalid signatures. + * + * @param ex the exception encountered (either {@link MalformedJwtException} or {@link SignatureException}) + * @return a {@link ResponseEntity} with a 401 Unauthorized status and an invalid token message + */ @ExceptionHandler({MalformedJwtException.class, SignatureException.class}) public ResponseEntity handleBadJwt(Exception ex) { ErrorResponse error = new ErrorResponse( @@ -75,6 +100,13 @@ public ResponseEntity handleBadJwt(Exception ex) { } // --- Illegal Argument (e.g., bad enum values, parsing errors) --- + /** + * Handles {@link IllegalArgumentException}, often used for invalid enum values or + * general bad request scenarios in business logic. + * + * @param ex the {@link IllegalArgumentException} encountered + * @return a {@link ResponseEntity} with a 400 Bad Request status and the exception's message + */ @ExceptionHandler(IllegalArgumentException.class) public ResponseEntity handleIllegalArgument(IllegalArgumentException ex) { ErrorResponse error = new ErrorResponse( @@ -85,6 +117,13 @@ public ResponseEntity handleIllegalArgument(IllegalArgumentExcept } // --- General RuntimeException (catch-all for business logic errors) --- + /** + * Catch-all handler for {@link RuntimeException}. + * Maps common business logic errors to appropriate HTTP statuses (e.g., 404 for not found, 409 for conflict). + * + * @param ex the {@link RuntimeException} encountered + * @return a {@link ResponseEntity} with the derived HTTP status and an appropriate error message + */ @ExceptionHandler(RuntimeException.class) public ResponseEntity handleRuntime(RuntimeException ex) { String message = ex.getMessage() != null ? ex.getMessage() : "An unexpected error occurred."; @@ -113,6 +152,12 @@ public ResponseEntity handleRuntime(RuntimeException ex) { } // --- Ultimate fallback for truly unexpected errors --- + /** + * Ultimate fallback handler for any unhandled {@link Exception}. + * + * @param ex the unexpected {@link Exception} encountered + * @return a {@link ResponseEntity} with a 500 Internal Server Error status and a generic message + */ @ExceptionHandler(Exception.class) public ResponseEntity handleAll(Exception ex) { ErrorResponse error = new ErrorResponse( diff --git a/backend/Backend/src/main/java/com/securehealth/backend/model/Appointment.java b/backend/Backend/src/main/java/com/securehealth/backend/model/Appointment.java index a2bebcc0..02f0430a 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/model/Appointment.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/model/Appointment.java @@ -6,6 +6,13 @@ import lombok.NoArgsConstructor; import java.time.LocalDateTime; +/** + * Entity representing a medical appointment. + *

+ * Links a patient profile with a doctor (Login) and tracks the date, + * status, reason for visit, and any doctor notes for the encounter. + *

+ */ @Data @NoArgsConstructor @Entity diff --git a/backend/Backend/src/main/java/com/securehealth/backend/model/AppointmentStatus.java b/backend/Backend/src/main/java/com/securehealth/backend/model/AppointmentStatus.java index 8f55f9db..cf6904f5 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/model/AppointmentStatus.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/model/AppointmentStatus.java @@ -1,5 +1,8 @@ package com.securehealth.backend.model; +/** + * Enumeration of possible appointment statuses. + */ public enum AppointmentStatus { PENDING_APPROVAL, SCHEDULED, diff --git a/backend/Backend/src/main/java/com/securehealth/backend/model/ArchivedUser.java b/backend/Backend/src/main/java/com/securehealth/backend/model/ArchivedUser.java index 87876177..600d9369 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/model/ArchivedUser.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/model/ArchivedUser.java @@ -8,9 +8,12 @@ import java.time.LocalDateTime; /** - * Stores a snapshot of a user account that has been archived due to inactivity. - * The original Login account is flagged as archived but not deleted, - * allowing for future restoration by an admin. + * Entity storing a snapshot of a user account archived due to inactivity. + *

+ * When a user is archived, their original account is flagged as such, + * and this entity preserves their email, role, and last activity + * for record-keeping or potential restoration. + *

*/ @Data @NoArgsConstructor diff --git a/backend/Backend/src/main/java/com/securehealth/backend/model/AuditLog.java b/backend/Backend/src/main/java/com/securehealth/backend/model/AuditLog.java index c57b3160..ccb6db7c 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/model/AuditLog.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/model/AuditLog.java @@ -5,6 +5,13 @@ import lombok.NoArgsConstructor; import java.time.LocalDateTime; +/** + * Entity representing a system audit log entry. + *

+ * Captures critical events for security and administrative review, + * including who performed the action, what was done, when, and from where. + *

+ */ @Entity @Data @NoArgsConstructor diff --git a/backend/Backend/src/main/java/com/securehealth/backend/model/Consent.java b/backend/Backend/src/main/java/com/securehealth/backend/model/Consent.java index c8fdb681..31dfd2d4 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/model/Consent.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/model/Consent.java @@ -9,9 +9,12 @@ import java.time.LocalDateTime; /** - * Represents a patient's consent record for data sharing. - * A patient can grant or revoke access to specific data categories - * for individual healthcare providers (doctors, nurses, lab techs). + * Entity representing a patient's consent for data sharing. + *

+ * Tracks permissions granted by patients to healthcare providers + * (doctors, nurses, technicians) for specific categories of medical data. + * Consents can be active, expired, or revoked. + *

*/ @Data @NoArgsConstructor diff --git a/backend/Backend/src/main/java/com/securehealth/backend/model/DoctorProfile.java b/backend/Backend/src/main/java/com/securehealth/backend/model/DoctorProfile.java index 7108db4b..0c0ec082 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/model/DoctorProfile.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/model/DoctorProfile.java @@ -8,6 +8,14 @@ import java.time.DayOfWeek; import java.util.List; +/** + * Entity representing a doctor's professional profile. + *

+ * Stores specialized information for doctors, such as their specialty, + * department, and shift schedule, while linking back to their core + * authentication account. + *

+ */ @Data @NoArgsConstructor @Entity diff --git a/backend/Backend/src/main/java/com/securehealth/backend/model/HandoverNote.java b/backend/Backend/src/main/java/com/securehealth/backend/model/HandoverNote.java index 79dd7153..9a7faff4 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/model/HandoverNote.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/model/HandoverNote.java @@ -8,6 +8,13 @@ import java.time.LocalDateTime; +/** + * Entity representing a handover note between nursing shifts. + *

+ * Handover notes can be general or patient-specific and include a priority level, + * the note content, and a read status to ensure critical information is communicated. + *

+ */ @Data @NoArgsConstructor @AllArgsConstructor diff --git a/backend/Backend/src/main/java/com/securehealth/backend/model/LabTest.java b/backend/Backend/src/main/java/com/securehealth/backend/model/LabTest.java index 0a319f69..64d55cf6 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/model/LabTest.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/model/LabTest.java @@ -8,6 +8,13 @@ +/** + * Entity representing a laboratory test order and result. + *

+ * Tracks the patient, the ordering doctor, test details (name, category), + * result values, units, reference ranges, and the current status of the test. + *

+ */ @Data @NoArgsConstructor @Entity diff --git a/backend/Backend/src/main/java/com/securehealth/backend/model/Login.java b/backend/Backend/src/main/java/com/securehealth/backend/model/Login.java index cfc8e0b3..0261d886 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/model/Login.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/model/Login.java @@ -9,14 +9,12 @@ import java.time.LocalDateTime; /** - * Represents the core Identity entity for authentication. + * Entity representing the core identity for authentication and authorization. *

- * This entity maps to the 'login' table in the database and stores - * credentials, role information, and active defense states (lockouts). + * Stores user credentials (email, hashed password), role information, + * multi-factor authentication states (OTP), and security-related fields + * for account locking and brute-force protection. *

- * - * @see com.securehealth.backend.repository.LoginRepository - * @author Manas */ @Data // Generates Getters, Setters, toString, Equals, HashCode @NoArgsConstructor // Generates empty constructor (Required by JPA) diff --git a/backend/Backend/src/main/java/com/securehealth/backend/model/MedicalRecord.java b/backend/Backend/src/main/java/com/securehealth/backend/model/MedicalRecord.java index 495e1bf6..e64ebfd6 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/model/MedicalRecord.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/model/MedicalRecord.java @@ -5,6 +5,13 @@ import lombok.NoArgsConstructor; import java.time.LocalDateTime; +/** + * Entity representing a patient's medical record entry. + *

+ * Contains clinical information such as diagnosis, symptoms, and treatments, + * recorded by a healthcare professional for a specific patient. + *

+ */ @Data @NoArgsConstructor @Entity diff --git a/backend/Backend/src/main/java/com/securehealth/backend/model/NurseTask.java b/backend/Backend/src/main/java/com/securehealth/backend/model/NurseTask.java index 77ea9897..0ffbc855 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/model/NurseTask.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/model/NurseTask.java @@ -8,6 +8,13 @@ import java.time.LocalDateTime; +/** + * Entity representing a clinical task assigned to a nurse. + *

+ * Tasks are categorized (e.g., medication, assessment), prioritized, + * and tracked for completion against a due time, often associated with a specific patient. + *

+ */ @Data @NoArgsConstructor @AllArgsConstructor diff --git a/backend/Backend/src/main/java/com/securehealth/backend/model/PasswordHistory.java b/backend/Backend/src/main/java/com/securehealth/backend/model/PasswordHistory.java index 964735a3..7fdf3d4a 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/model/PasswordHistory.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/model/PasswordHistory.java @@ -7,18 +7,11 @@ import java.time.LocalDateTime; /** - * Entity for storing password history. + * Entity for storing previous password hashes to prevent password reuse. *

- * This entity maps to the 'password_history' table and stores - * hashed versions of previously used passwords. Used to prevent - * password reuse (NIST 800-63B compliance). + * Maintains NIST compliance by ensuring users cannot reuse a specified number + * of their most recent passwords. *

- *

- * Default policy: Users cannot reuse their last 5 passwords. - *

- * - * @see com.securehealth.backend.repository.PasswordHistoryRepository - * @author Manas */ @Data @NoArgsConstructor diff --git a/backend/Backend/src/main/java/com/securehealth/backend/model/PasswordResetToken.java b/backend/Backend/src/main/java/com/securehealth/backend/model/PasswordResetToken.java index 5d05c2e5..5f7c354d 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/model/PasswordResetToken.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/model/PasswordResetToken.java @@ -9,13 +9,9 @@ /** * Entity for storing password reset tokens. *

- * This entity maps to the 'password_reset_tokens' table and stores - * secure tokens used for password recovery. Tokens expire after 30 minutes - * and can only be used once. + * Securely stores hashed recovery tokens issued to users, including + * expiration timestamps and usage status to ensure single-use security. *

- * - * @see com.securehealth.backend.repository.PasswordResetTokenRepository - * @author Manas */ @Data @NoArgsConstructor diff --git a/backend/Backend/src/main/java/com/securehealth/backend/model/PatientProfile.java b/backend/Backend/src/main/java/com/securehealth/backend/model/PatientProfile.java index ab1df347..92650541 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/model/PatientProfile.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/model/PatientProfile.java @@ -8,6 +8,13 @@ import java.time.LocalDate; import java.time.LocalDateTime; +/** + * Entity representing a patient's detailed profile. + *

+ * Stores personal information, contact details, medical history, and + * handles relationships with assigned doctors and nurses for coordinated care. + *

+ */ @Data @NoArgsConstructor @AllArgsConstructor diff --git a/backend/Backend/src/main/java/com/securehealth/backend/model/Prescription.java b/backend/Backend/src/main/java/com/securehealth/backend/model/Prescription.java index 68f6bd8c..4c790af0 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/model/Prescription.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/model/Prescription.java @@ -5,6 +5,13 @@ import lombok.NoArgsConstructor; import java.time.LocalDateTime; +/** + * Entity representing a medication prescription. + *

+ * Tracks prescribed medications, dosages, frequencies, and durations, + * along with validity periods and remaining refills for a specific patient. + *

+ */ @Data @NoArgsConstructor @Entity diff --git a/backend/Backend/src/main/java/com/securehealth/backend/model/Role.java b/backend/Backend/src/main/java/com/securehealth/backend/model/Role.java index 0b813915..64b5a051 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/model/Role.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/model/Role.java @@ -1,8 +1,11 @@ package com.securehealth.backend.model; /** - * Defines the authorized roles within the Healthcare System. - * Used for Role-Based Access Control (RBAC). + * Enumeration of authorized user roles within the system. + *

+ * Used for Role-Based Access Control (RBAC) to restrict access to + * specific API endpoints and application features. + *

*/ public enum Role { PATIENT, diff --git a/backend/Backend/src/main/java/com/securehealth/backend/model/Session.java b/backend/Backend/src/main/java/com/securehealth/backend/model/Session.java index d6b9c961..cb95aa25 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/model/Session.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/model/Session.java @@ -5,6 +5,13 @@ import lombok.NoArgsConstructor; import java.time.LocalDateTime; +/** + * Entity representing an active user session. + *

+ * Tracks refresh tokens, client metadata (IP, User Agent), and + * expiration status to manage authentication persistence and security. + *

+ */ @Data @NoArgsConstructor @Entity diff --git a/backend/Backend/src/main/java/com/securehealth/backend/model/VitalSign.java b/backend/Backend/src/main/java/com/securehealth/backend/model/VitalSign.java index 5d087379..1ea3fa0a 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/model/VitalSign.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/model/VitalSign.java @@ -5,6 +5,13 @@ import lombok.NoArgsConstructor; import java.time.LocalDateTime; +/** + * Entity representing a set of patient vital sign readings. + *

+ * Records clinical measurements like blood pressure, heart rate, and temperature + * at a specific point in time, typically performed by a nurse. + *

+ */ @Data @NoArgsConstructor @Entity diff --git a/backend/Backend/src/main/java/com/securehealth/backend/repository/AppointmentRepository.java b/backend/Backend/src/main/java/com/securehealth/backend/repository/AppointmentRepository.java index 46fcf810..c6d7d794 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/repository/AppointmentRepository.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/repository/AppointmentRepository.java @@ -11,6 +11,13 @@ import java.util.List; import java.time.LocalDateTime; +/** + * Repository interface for {@link Appointment} entities. + *

+ * Provides methods for retrieving appointments by patient or doctor, + * checking for scheduling conflicts, and calculating administrative metrics. + *

+ */ @Repository public interface AppointmentRepository extends JpaRepository { diff --git a/backend/Backend/src/main/java/com/securehealth/backend/repository/ArchivedUserRepository.java b/backend/Backend/src/main/java/com/securehealth/backend/repository/ArchivedUserRepository.java index 16980a0d..5e32d4c0 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/repository/ArchivedUserRepository.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/repository/ArchivedUserRepository.java @@ -7,6 +7,13 @@ import java.util.List; import java.util.Optional; +/** + * Repository interface for {@link ArchivedUser} entities. + *

+ * Handles lookups for archived accounts by email or their original user ID + * to facilitate potential restoration by administrators. + *

+ */ @Repository public interface ArchivedUserRepository extends JpaRepository { diff --git a/backend/Backend/src/main/java/com/securehealth/backend/repository/AuditLogRepository.java b/backend/Backend/src/main/java/com/securehealth/backend/repository/AuditLogRepository.java index 765b3dc6..dc443541 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/repository/AuditLogRepository.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/repository/AuditLogRepository.java @@ -4,6 +4,13 @@ import org.springframework.data.jpa.repository.JpaRepository; import java.util.List; +/** + * Repository interface for {@link AuditLog} entities. + *

+ * Used primarily for administrative review of system events, + * allowing for retrieval of logs by user email ordered by time. + *

+ */ public interface AuditLogRepository extends JpaRepository { // This will be used later for the Admin Dashboard (User Story 1.4) diff --git a/backend/Backend/src/main/java/com/securehealth/backend/repository/ConsentRepository.java b/backend/Backend/src/main/java/com/securehealth/backend/repository/ConsentRepository.java index 1d94788f..7f65ee84 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/repository/ConsentRepository.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/repository/ConsentRepository.java @@ -6,6 +6,13 @@ import java.util.List; +/** + * Repository interface for {@link Consent} entities. + *

+ * Manages patient data sharing permissions, including active consent checks + * and provider-specific access lookups. + *

+ */ @Repository public interface ConsentRepository extends JpaRepository { diff --git a/backend/Backend/src/main/java/com/securehealth/backend/repository/DoctorProfileRepository.java b/backend/Backend/src/main/java/com/securehealth/backend/repository/DoctorProfileRepository.java index 4d1fad1a..e7d24e94 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/repository/DoctorProfileRepository.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/repository/DoctorProfileRepository.java @@ -8,6 +8,13 @@ import java.util.List; import java.util.Optional; +/** + * Repository interface for {@link DoctorProfile} entities. + *

+ * Facilitates doctor searches by specialty or department, + * and links core authentication accounts to professional profiles. + *

+ */ @Repository public interface DoctorProfileRepository extends JpaRepository { diff --git a/backend/Backend/src/main/java/com/securehealth/backend/repository/HandoverNoteRepository.java b/backend/Backend/src/main/java/com/securehealth/backend/repository/HandoverNoteRepository.java index 7e4db0e2..4691c40b 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/repository/HandoverNoteRepository.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/repository/HandoverNoteRepository.java @@ -6,6 +6,13 @@ import java.util.List; +/** + * Repository interface for {@link HandoverNote} entities. + *

+ * Enables nurses to retrieve handover notes by author or shift direction, + * ensuring continuity of care between shifts. + *

+ */ @Repository public interface HandoverNoteRepository extends JpaRepository { List findByAuthor_UserIdOrderByTimestampDesc(Long authorId); diff --git a/backend/Backend/src/main/java/com/securehealth/backend/repository/LabTestRepository.java b/backend/Backend/src/main/java/com/securehealth/backend/repository/LabTestRepository.java index ac0986da..eea4f8df 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/repository/LabTestRepository.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/repository/LabTestRepository.java @@ -8,6 +8,13 @@ import java.util.List; +/** + * Repository interface for {@link LabTest} entities. + *

+ * Provides methods for patient-specific result lookups, processing queues + * for technicians, and diagnostic order status for doctors. + *

+ */ @Repository public interface LabTestRepository extends JpaRepository { diff --git a/backend/Backend/src/main/java/com/securehealth/backend/repository/LoginRepository.java b/backend/Backend/src/main/java/com/securehealth/backend/repository/LoginRepository.java index 7580f3d2..6f83ab16 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/repository/LoginRepository.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/repository/LoginRepository.java @@ -9,14 +9,11 @@ import java.util.List; /** - * Data Access Object (DAO) for the Login entity. + * Repository interface for {@link Login} entities, handling user authentication and core identity. *

- * This interface extends JpaRepository to provide standard CRUD operations - * (Create, Read, Update, Delete) without writing SQL. + * Provides essential methods for finding users by email, checking for existence, + * and retrieving users by role for security and administrative purposes. *

- * * @author Manas - * - * @version 1.0 */ @Repository public interface LoginRepository extends JpaRepository { diff --git a/backend/Backend/src/main/java/com/securehealth/backend/repository/MedicalRecordRepository.java b/backend/Backend/src/main/java/com/securehealth/backend/repository/MedicalRecordRepository.java index 116918a8..8e79d2d3 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/repository/MedicalRecordRepository.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/repository/MedicalRecordRepository.java @@ -6,6 +6,13 @@ import java.util.List; +/** + * Repository interface for {@link MedicalRecord} entities. + *

+ * Provides methods for retrieving clinical encounter records for patients, + * typically ordered by creation date to show a chronological history. + *

+ */ @Repository public interface MedicalRecordRepository extends JpaRepository { diff --git a/backend/Backend/src/main/java/com/securehealth/backend/repository/NurseTaskRepository.java b/backend/Backend/src/main/java/com/securehealth/backend/repository/NurseTaskRepository.java index e0f9e1a1..d6fe5e26 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/repository/NurseTaskRepository.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/repository/NurseTaskRepository.java @@ -8,6 +8,13 @@ import java.util.List; import java.util.Optional; +/** + * Repository interface for {@link NurseTask} entities. + *

+ * Supports task management for nursing staff, including counts of pending tasks, + * priority-based filtering, and category-specific task lookups. + *

+ */ @Repository public interface NurseTaskRepository extends JpaRepository { List findByAssignedNurse_UserIdOrderByDueTimeAsc(Long nurseId); diff --git a/backend/Backend/src/main/java/com/securehealth/backend/repository/PasswordHistoryRepository.java b/backend/Backend/src/main/java/com/securehealth/backend/repository/PasswordHistoryRepository.java index e043df45..54159df1 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/repository/PasswordHistoryRepository.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/repository/PasswordHistoryRepository.java @@ -10,17 +10,11 @@ import java.util.List; /** - * Data Access Object (DAO) for the PasswordHistory entity. + * Repository interface for {@link PasswordHistory} entities. *

- * This interface extends JpaRepository to provide standard CRUD operations - * (Create, Read, Update, Delete) without writing SQL. + * Facilitates NIST-compliant password reuse policies by allowing retrieval + * of a user's recent password hashes for comparison during updates. *

- *

- * Used for checking password reuse during password changes/resets. - *

- * - * @author Manas - * @version 1.0 */ @Repository public interface PasswordHistoryRepository extends JpaRepository { diff --git a/backend/Backend/src/main/java/com/securehealth/backend/repository/PasswordResetTokenRepository.java b/backend/Backend/src/main/java/com/securehealth/backend/repository/PasswordResetTokenRepository.java index abb3c890..87e7c784 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/repository/PasswordResetTokenRepository.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/repository/PasswordResetTokenRepository.java @@ -12,14 +12,11 @@ import java.util.Optional; /** - * Data Access Object (DAO) for the PasswordResetToken entity. + * Repository interface for {@link PasswordResetToken} entities. *

- * This interface extends JpaRepository to provide standard CRUD operations - * (Create, Read, Update, Delete) without writing SQL. + * Manages the lifecycle of recovery tokens, including validation of active tokens, + * invalidation of old tokens upon new requests, and periodic cleanup of expired entries. *

- * - * @author Manas - * @version 1.0 */ @Repository public interface PasswordResetTokenRepository extends JpaRepository { diff --git a/backend/Backend/src/main/java/com/securehealth/backend/repository/PatientProfileRepository.java b/backend/Backend/src/main/java/com/securehealth/backend/repository/PatientProfileRepository.java index 8afd7066..2fca231b 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/repository/PatientProfileRepository.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/repository/PatientProfileRepository.java @@ -8,6 +8,13 @@ import java.util.List; import java.util.Optional; +/** + * Repository interface for {@link PatientProfile} entities. + *

+ * Supports lookups for patient profiles by their core user account + * and handles retrieval of assigned patient lists for individual doctors and nurses. + *

+ */ @Repository public interface PatientProfileRepository extends JpaRepository { diff --git a/backend/Backend/src/main/java/com/securehealth/backend/repository/PrescriptionRepository.java b/backend/Backend/src/main/java/com/securehealth/backend/repository/PrescriptionRepository.java index 5b00000c..36263f0a 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/repository/PrescriptionRepository.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/repository/PrescriptionRepository.java @@ -6,6 +6,13 @@ import java.util.List; +/** + * Repository interface for {@link Prescription} entities. + *

+ * Facilitates retrieval of medication prescriptions for patients, + * including filtering by status (active vs historical) and chronological sorting. + *

+ */ @Repository public interface PrescriptionRepository extends JpaRepository { diff --git a/backend/Backend/src/main/java/com/securehealth/backend/repository/SessionRepository.java b/backend/Backend/src/main/java/com/securehealth/backend/repository/SessionRepository.java index f9717ecb..93b6e7b7 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/repository/SessionRepository.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/repository/SessionRepository.java @@ -10,6 +10,13 @@ import java.util.Optional; import java.util.List; +/** + * Repository interface for {@link Session} entities. + *

+ * Manages user authentication sessions, allowing for verification of refresh tokens + * and bulk revocation of sessions for security enforcement. + *

+ */ @Repository public interface SessionRepository extends JpaRepository { Optional findByRefreshTokenHash(String refreshTokenHash); diff --git a/backend/Backend/src/main/java/com/securehealth/backend/repository/VitalSignRepository.java b/backend/Backend/src/main/java/com/securehealth/backend/repository/VitalSignRepository.java index 7ee08f2b..8bf02a25 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/repository/VitalSignRepository.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/repository/VitalSignRepository.java @@ -9,6 +9,13 @@ import java.util.List; import java.util.Optional; +/** + * Repository interface for {@link VitalSign} entities. + *

+ * Supports clinical tracking of physical measurements, providing chronological + * timelines for patients and audit trails for recording nursing staff. + *

+ */ @Repository public interface VitalSignRepository extends JpaRepository { diff --git a/backend/Backend/src/main/java/com/securehealth/backend/security/CustomUserDetailsService.java b/backend/Backend/src/main/java/com/securehealth/backend/security/CustomUserDetailsService.java index 83b9a223..38cc55e8 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/security/CustomUserDetailsService.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/security/CustomUserDetailsService.java @@ -12,12 +12,26 @@ import java.util.Collections; +/** + * Custom implementation of {@link UserDetailsService} to load user-specific data. + *

+ * Bridges the application's {@link Login} entity with Spring Security's + * {@link UserDetails} for authentication and authority mapping. + *

+ */ @Service public class CustomUserDetailsService implements UserDetailsService { @Autowired private LoginRepository loginRepository; + /** + * Locates the user based on the email (username). + * + * @param email the email identifying the user whose data is required + * @return a fully populated {@link UserDetails} object + * @throws UsernameNotFoundException if the user could not be found + */ @Override public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException { // 1. Find User diff --git a/backend/Backend/src/main/java/com/securehealth/backend/security/JwtAuthenticationFilter.java b/backend/Backend/src/main/java/com/securehealth/backend/security/JwtAuthenticationFilter.java index 64d9a333..ba91ab72 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/security/JwtAuthenticationFilter.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/security/JwtAuthenticationFilter.java @@ -17,6 +17,13 @@ import java.io.IOException; +/** + * Servlet filter that intercepts HTTP requests to validate JWT authentication. + *

+ * Extracts the "Authorization" header, verifies the token's validity and revocation status, + * and populates the {@link SecurityContextHolder} if the token is valid. + *

+ */ @Component public class JwtAuthenticationFilter extends OncePerRequestFilter { @@ -29,6 +36,15 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter { @Autowired private TokenBlacklistService tokenBlacklistService; + /** + * Performs the actual filter logic to extract and validate the JWT. + * + * @param request the {@link HttpServletRequest} + * @param response the {@link HttpServletResponse} + * @param chain the {@link FilterChain} + * @throws ServletException in case of servlet errors + * @throws IOException in case of I/O errors + */ @Override protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException { diff --git a/backend/Backend/src/main/java/com/securehealth/backend/security/PatientAccessValidator.java b/backend/Backend/src/main/java/com/securehealth/backend/security/PatientAccessValidator.java index 46e04bdb..05521874 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/security/PatientAccessValidator.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/security/PatientAccessValidator.java @@ -7,12 +7,27 @@ import org.springframework.security.core.GrantedAuthority; import org.springframework.stereotype.Component; +/** + * Component for enforcing granular row-level access control for patient data. + *

+ * Ensures that patients can only access their own records, while providing + * bypasses for staff roles like DOCTOR and ADMIN. + *

+ */ @Component public class PatientAccessValidator { @Autowired private PatientProfileRepository patientProfileRepository; + /** + * Validates if the currently authenticated user is authorized to access + * the specified patient's data. + * + * @param patientId the ID of the patient record being accessed + * @param auth the current {@link Authentication} object + * @throws RuntimeException if access is forbidden or the patient is not found + */ public void validateAccess(Long patientId, Authentication auth) { String role = auth.getAuthorities().stream() .findFirst() diff --git a/backend/Backend/src/main/java/com/securehealth/backend/service/AdminService.java b/backend/Backend/src/main/java/com/securehealth/backend/service/AdminService.java index 6b12f3ea..609fab42 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/service/AdminService.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/service/AdminService.java @@ -18,6 +18,13 @@ import java.time.LocalDate; import java.time.LocalDateTime; +/** + * Service for administrative and management operations. + *

+ * Provides high-level system metrics for the dashboard, staff account management + * (roles and removal), and access to the full patient directory. + *

+ */ @Service public class AdminService { @@ -25,6 +32,12 @@ public class AdminService { @Autowired private LoginRepository loginRepository; @Autowired private AppointmentRepository appointmentRepository; + /** + * Retrieves aggregated system metrics for the admin dashboard. + * + * @return an {@link AdminMetricsDTO} containing counts of patients, doctors, + * pending approvals, and today's appointments + */ @Transactional(readOnly = true) public AdminMetricsDTO getDashboardMetrics() { AdminMetricsDTO metrics = new AdminMetricsDTO(); @@ -46,6 +59,11 @@ public AdminMetricsDTO getDashboardMetrics() { return metrics; } + /** + * Retrieves a list of all non-patient staff members. + * + * @return a list of {@link StaffDTO} objects representing system staff + */ @Transactional(readOnly = true) public List getAllStaff() { // Pass the Enum to the repository, not the string "PATIENT" @@ -59,6 +77,14 @@ public List getAllStaff() { }).collect(Collectors.toList()); } + /** + * Updates the role of a staff member. + * + * @param userId the ID of the user to update + * @param newRole the new role to assign + * @return the updated {@link StaffDTO} + * @throws IllegalArgumentException if the user is not found or is a patient + */ @Transactional public StaffDTO updateStaffRole(Long userId, String newRole) { Login user = loginRepository.findById(userId) @@ -81,6 +107,12 @@ public StaffDTO updateStaffRole(Long userId, String newRole) { return dto; } + /** + * Permanently removes a staff member from the system. + * + * @param userId the ID of the user to remove + * @throws IllegalArgumentException if the staff member is not found + */ @Transactional public void removeStaffMember(Long userId) { // Check if the user exists before trying to delete @@ -90,6 +122,11 @@ public void removeStaffMember(Long userId) { loginRepository.deleteById(userId); } + /** + * Retrieves a directory of all registered patients. + * + * @return a list of {@link PatientDirectoryDTO} objects + */ @Transactional(readOnly = true) public List getAllPatients() { return patientProfileRepository.findAll().stream().map(patient -> { diff --git a/backend/Backend/src/main/java/com/securehealth/backend/service/AppointmentService.java b/backend/Backend/src/main/java/com/securehealth/backend/service/AppointmentService.java index d9a3a9d7..0dee6803 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/service/AppointmentService.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/service/AppointmentService.java @@ -24,6 +24,13 @@ import java.util.ArrayList; import java.util.List; +/** + * Service for managing medical appointments and scheduling. + *

+ * Handles available slot calculation based on doctor shifts, creation of + * appointment requests, administrative approval/rejection, and status updates. + *

+ */ @Service public class AppointmentService { @@ -39,6 +46,13 @@ public class AppointmentService { @Autowired private PatientProfileRepository patientProfileRepository; + /** + * Calculates available time slots for a doctor on a specific date. + * + * @param doctorId the ID of the doctor + * @param targetDate the date to check availability for + * @return a list of {@link LocalTime} representing available slots + */ public List getAvailableSlots(Long doctorId, LocalDate targetDate) { // 1. Fetch Doctor Profile (Note: doctorId is the Login ID, so we find by User) DoctorProfile doctor = doctorProfileRepository.findByUser_UserId(doctorId) @@ -78,6 +92,13 @@ public List getAvailableSlots(Long doctorId, LocalDate targetDate) { return availableSlots; } + /** + * Creates a new pending appointment request for a patient. + * + * @param request the {@link AppointmentRequest} containing details + * @param requesterEmail the email of the user making the request + * @return the saved {@link Appointment} + */ @Transactional public Appointment createAppointment(AppointmentRequest request, String requesterEmail) { Login user = loginRepository.findByEmail(requesterEmail) @@ -157,6 +178,11 @@ private AppointmentDTO toDTO(Appointment app) { return dto; } + /** + * Retrieves all appointments currently pending administrative approval. + * + * @return a list of {@link AppointmentDTO} objects + */ @Transactional(readOnly = true) public List getPendingAppointments() { return appointmentRepository.findByStatus(com.securehealth.backend.model.AppointmentStatus.PENDING_APPROVAL).stream() @@ -164,6 +190,13 @@ public List getPendingAppointments() { .collect(Collectors.toList()); } + /** + * Marks an appointment as completed by the attending doctor. + * + * @param id the ID of the appointment + * @param doctorEmail the email of the doctor performing the action + * @return the updated {@link Appointment} + */ @Transactional public Appointment completeAppointment(Long id, String doctorEmail) { Appointment appointment = appointmentRepository.findById(id) @@ -178,6 +211,14 @@ public Appointment completeAppointment(Long id, String doctorEmail) { return appointmentRepository.save(appointment); } + /** + * Updates appointment details, such as the scheduled date/time. + * + * @param id the ID of the appointment + * @param request the {@link AppointmentDTO} with updated details + * @param doctorEmail the email of the doctor performing the update + * @return the updated {@link Appointment} + */ @Transactional public Appointment updateAppointment(Long id, AppointmentDTO request, String doctorEmail) { Appointment appointment = appointmentRepository.findById(id) @@ -195,6 +236,14 @@ public Appointment updateAppointment(Long id, AppointmentDTO request, String doc return appointmentRepository.save(appointment); } + /** + * Cancels an existing appointment. + * + * @param id the ID of the appointment to cancel + * @param requesterEmail the email of the user cancelling the appointment + * @param role the role of the requester (ADMIN, DOCTOR, or PATIENT) + * @return the cancelled {@link Appointment} + */ @Transactional public Appointment cancelAppointment(Long id, String requesterEmail, String role) { Appointment appointment = appointmentRepository.findById(id) @@ -210,6 +259,11 @@ public Appointment cancelAppointment(Long id, String requesterEmail, String role return appointmentRepository.save(appointment); } + /** + * Permanently deletes an appointment from the system. + * + * @param id the ID of the appointment to delete + */ @Transactional public void deleteAppointment(Long id) { if (!appointmentRepository.existsById(id)) { @@ -219,6 +273,12 @@ public void deleteAppointment(Long id) { } + /** + * Retrieves all appointments for a specific patient. + * + * @param patientId the ID of the patient + * @return a list of {@link AppointmentDTO} objects + */ @Transactional(readOnly = true) public List getAppointmentsByDoctor(Long doctorId) { return appointmentRepository.findByDoctor_UserIdOrderByAppointmentDateAsc(doctorId).stream().map(app -> { @@ -250,6 +310,11 @@ public List getAppointmentsByPatient(Long patientId) { }).collect(Collectors.toList()); } + /** + * Retrieves a list of all appointments in the system. + * + * @return a list of {@link AppointmentDTO} objects + */ @Transactional(readOnly = true) public List getAllAppointments() { return appointmentRepository.findAll().stream().map(app -> { diff --git a/backend/Backend/src/main/java/com/securehealth/backend/service/ArchivalService.java b/backend/Backend/src/main/java/com/securehealth/backend/service/ArchivalService.java index 7d291fd9..0b12b2f9 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/service/ArchivalService.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/service/ArchivalService.java @@ -92,7 +92,14 @@ private void archiveUser(Login user) { } /** - * Admin action: restore an archived user. + * Restores a previously archived user account. + *

+ * Re-enables the core login account and removes the archival snapshot. + *

+ * + * @param archivedUserId the ID of the archive record + * @return the restored {@link Login} entity + * @throws RuntimeException if the archive or original user is not found */ @Transactional public Login restoreUser(Long archivedUserId) { @@ -112,7 +119,9 @@ public Login restoreUser(Long archivedUserId) { } /** - * Admin action: get all archived users. + * Retrieves a list of all archived user snapshots. + * + * @return a list of {@link ArchivedUser} entities */ public List getArchivedUsers() { return archivedUserRepository.findAllByOrderByArchivedAtDesc(); diff --git a/backend/Backend/src/main/java/com/securehealth/backend/service/AuthService.java b/backend/Backend/src/main/java/com/securehealth/backend/service/AuthService.java index 76970d80..166ed9dc 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/service/AuthService.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/service/AuthService.java @@ -98,6 +98,14 @@ public class AuthService { /** * Registers a new user and creates an initial profile if applicable. + *

+ * For patients, a basic profile is automatically generated using the + * information provided in the registration request. + *

+ * + * @param request the {@link RegistrationRequest} details + * @return the saved {@link Login} entity + * @throws RuntimeException if the email is already in use */ @Transactional public Login registerUser(RegistrationRequest request) { @@ -140,7 +148,18 @@ public Login registerUser(RegistrationRequest request) { } /** - * Authenticates user and generates tokens. + * Authenticates a user and generates access and refresh tokens. + *

+ * Includes multi-factor authentication (MFA) logic for staff roles, + * rate limiting for security, and session management. + *

+ * + * @param email the user's email + * @param rawPassword the user's plain-text password + * @param ipAddress the originating IP address for audit and security + * @param userAgent the user's browser agent for session tracking + * @return a {@link LoginResponse} containing tokens or MFA status + * @throws RuntimeException for invalid credentials or locked accounts */ public LoginResponse login(String email, String rawPassword, String ipAddress, String userAgent) { @@ -210,7 +229,14 @@ public LoginResponse login(String email, String rawPassword, String ipAddress, S } /** - * Verifies OTP and Completes Login (Generates Tokens). + * Verifies a multi-factor authentication (MFA) OTP and completes login. + * + * @param email the user's email + * @param otp the 6-digit one-time password provided by the user + * @param ipAddress the originating IP address + * @param userAgent the user's browser agent + * @return a {@link LoginResponse} containing generated tokens + * @throws RuntimeException if the OTP is invalid or expired */ public LoginResponse verifyOtp(String email, String otp, String ipAddress, String userAgent) { @@ -258,7 +284,10 @@ public LoginResponse verifyOtp(String email, String otp, String ipAddress, Strin } } /** - * Revokes a session (Logout). + * Revokes a user's session and blacklists the provided access token. + * + * @param accessToken the active JWT to blacklist + * @param refreshToken the refresh token to revoke */ @Transactional public void logout(String accessToken, String refreshToken) { @@ -293,7 +322,9 @@ public void logout(String accessToken, String refreshToken) { } /** - * Enables Two-Factor Authentication for a user (e.g. Patient). + * Enables Two-Factor Authentication for a user. + * + * @param email the email of the user to enable 2FA for */ @Transactional public void enableTwoFactorAuth(String email) { @@ -533,11 +564,17 @@ private String generateSecureToken() { } /** - * ROTATION LOGIC: - * 1. Validate the old Refresh Token. - * 2. Security: If it's already revoked? ALARM! Revoke everything (Theft - * detected). - * 3. If valid: Kill the old one, create a NEW one. + * Rotates a refresh token to generate new session tokens. + *

+ * Implements rotation logic to prevent token theft and session hijacking. + * Revokes all sessions if a reuse attempt is detected. + *

+ * + * @param oldRefreshToken the refresh token to rotate + * @param ipAddress the current IP address + * @param userAgent the current user agent + * @return a {@link LoginResponse} with new tokens + * @throws RuntimeException if the token is invalid or suspected theft occurs */ @Transactional public LoginResponse refreshToken(String oldRefreshToken, String ipAddress, String userAgent) { diff --git a/backend/Backend/src/main/java/com/securehealth/backend/service/BackupService.java b/backend/Backend/src/main/java/com/securehealth/backend/service/BackupService.java index 2afa842a..2ddf6edf 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/service/BackupService.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/service/BackupService.java @@ -45,7 +45,11 @@ public class BackupService { private String dbPassword; /** - * Runs on the configured cron schedule (default: 2:00 AM daily). + * Orchestrates the database backup process. + *

+ * Creates a timestamped {@code .sql} file using {@code pg_dump}, + * and triggers a cleanup of old backups based on the retention policy. + *

*/ @Scheduled(cron = "${backup.cron:0 0 2 * * *}") public void performBackup() { diff --git a/backend/Backend/src/main/java/com/securehealth/backend/service/ConsentService.java b/backend/Backend/src/main/java/com/securehealth/backend/service/ConsentService.java index 2f9b4f6d..79283d39 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/service/ConsentService.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/service/ConsentService.java @@ -23,7 +23,10 @@ public class ConsentService { @Autowired private PatientProfileRepository patientProfileRepository; /** - * Get all consents for the currently logged-in patient. + * Retrieves all consent records for the currently logged-in patient. + * + * @param patientEmail the email of the patient + * @return a list of {@link Consent} entities */ public List getMyConsents(String patientEmail) { PatientProfile profile = getPatientProfile(patientEmail); @@ -31,7 +34,12 @@ public List getMyConsents(String patientEmail) { } /** - * Grant consent for a provider to access a specific data type. + * Grants a provider access to a specific type of patient data. + * + * @param patientEmail the email of the patient granting consent + * @param payload a map containing 'grantedToId', 'consentType', 'reason', and optional 'expiresAt' + * @return the saved {@link Consent} entity + * @throws RuntimeException if the provider is not found or an active consent already exists */ public Consent grantConsent(String patientEmail, Map payload) { PatientProfile profile = getPatientProfile(patientEmail); @@ -66,7 +74,12 @@ public Consent grantConsent(String patientEmail, Map payload) { } /** - * Revoke a patient's consent by ID. + * Revokes an existing consent record. + * + * @param patientEmail the email of the patient revoking consent + * @param consentId the ID of the consent record to revoke + * @return the updated {@link Consent} entity + * @throws RuntimeException if the consent is not found, not owned by the patient, or already revoked */ public Consent revokeConsent(String patientEmail, Long consentId) { PatientProfile profile = getPatientProfile(patientEmail); @@ -90,8 +103,15 @@ public Consent revokeConsent(String patientEmail, Long consentId) { } /** - * Utility: Check if a provider has active consent for a specific data type. - * Can be called from other services to enforce consent checks. + * Validates if a healthcare provider has active consent for a patient's data. + *

+ * Checks for either the specific data type or a general "ALL" consent. + *

+ * + * @param patientProfileId the patient's profile ID + * @param providerUserId the provider's user ID + * @param consentType the type of data being accessed (e.g., "VITALS", "RECORDS") + * @return true if active consent is found, false otherwise */ public boolean hasConsent(Long patientProfileId, Long providerUserId, String consentType) { // Check for specific type OR "ALL" type diff --git a/backend/Backend/src/main/java/com/securehealth/backend/service/DoctorService.java b/backend/Backend/src/main/java/com/securehealth/backend/service/DoctorService.java index 47f6e41e..066c9d99 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/service/DoctorService.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/service/DoctorService.java @@ -10,12 +10,24 @@ import java.util.List; import java.util.stream.Collectors; +/** + * Service for managing doctor profiles and professional information. + *

+ * Handles retrieval of doctors by specialty or department, and allows + * doctors to update their own professional details and shift schedules. + *

+ */ @Service public class DoctorService { @Autowired private DoctorProfileRepository doctorProfileRepository; + /** + * Retrieves a list of all doctor profiles in the system. + * + * @return a list of {@link DoctorDTO} objects + */ @Transactional(readOnly = true) public List getAllDoctors() { return doctorProfileRepository.findAll().stream() @@ -23,6 +35,13 @@ public List getAllDoctors() { .collect(Collectors.toList()); } + /** + * Retrieves a specific doctor profile by its ID. + * + * @param id the ID of the doctor profile + * @return the {@link DoctorDTO} for the specified doctor + * @throws RuntimeException if the doctor is not found + */ @Transactional(readOnly = true) public DoctorDTO getDoctorById(Long id) { DoctorProfile profile = doctorProfileRepository.findById(id) @@ -30,6 +49,12 @@ public DoctorDTO getDoctorById(Long id) { return mapToDTO(profile); } + /** + * Filters doctor profiles by their medical specialty. + * + * @param specialty the specialty to filter by (case-insensitive) + * @return a list of matching {@link DoctorDTO} objects + */ @Transactional(readOnly = true) public List getDoctorsBySpecialty(String specialty) { return doctorProfileRepository.findBySpecialtyIgnoreCase(specialty).stream() @@ -37,6 +62,12 @@ public List getDoctorsBySpecialty(String specialty) { .collect(Collectors.toList()); } + /** + * Filters doctor profiles by their assigned department. + * + * @param department the department to filter by (case-insensitive) + * @return a list of matching {@link DoctorDTO} objects + */ @Transactional(readOnly = true) public List getDoctorsByDepartment(String department) { return doctorProfileRepository.findByDepartmentIgnoreCase(department).stream() @@ -44,6 +75,20 @@ public List getDoctorsByDepartment(String department) { .collect(Collectors.toList()); } + /** + * Updates an existing doctor profile. + *

+ * Enforces security by ensuring only the profile owner or an administrator + * can perform the update. + *

+ * + * @param id the ID of the profile to update + * @param dto the {@link DoctorDTO} containing updated information + * @param requesterEmail the email of the user requesting the update + * @param requesterRole the role of the user requesting the update + * @return the updated {@link DoctorDTO} + * @throws RuntimeException if the doctor is not found or access is forbidden + */ @Transactional public DoctorDTO updateDoctorProfile(Long id, DoctorDTO dto, String requesterEmail, String requesterRole) { DoctorProfile profile = doctorProfileRepository.findById(id) diff --git a/backend/Backend/src/main/java/com/securehealth/backend/service/FileStorageService.java b/backend/Backend/src/main/java/com/securehealth/backend/service/FileStorageService.java index 352f1ec0..b2e58fdb 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/service/FileStorageService.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/service/FileStorageService.java @@ -40,8 +40,16 @@ public class FileStorageService { private String encryptionKeyBase64; /** - * Stores an uploaded file with AES-256-GCM encryption. - * Returns the unique filename used for retrieval. + * Stores an uploaded file with AES-256-GCM encryption at rest. + *

+ * Validates the file extension against an allowlist and generates a + * unique filename for secure storage. + *

+ * + * @param file the {@link MultipartFile} to store + * @return the unique filename generated for the stored file + * @throws IOException if an I/O error occurs during storage + * @throws RuntimeException if the file is empty or the type is not allowed */ public String storeFile(MultipartFile file) throws IOException { // 1. Validate @@ -79,8 +87,12 @@ public String storeFile(MultipartFile file) throws IOException { } /** - * Retrieves and decrypts a stored file. - * Returns the decrypted bytes. + * Retrieves and decrypts a stored file based on its filename. + * + * @param filename the unique name of the encrypted file + * @return the decrypted byte array of the file content + * @throws IOException if an I/O error occurs during retrieval + * @throws RuntimeException if the file is not found or decryption fails */ public byte[] loadFile(String filename) throws IOException { Path filePath = Paths.get(uploadDir).resolve(filename); diff --git a/backend/Backend/src/main/java/com/securehealth/backend/service/LabTechnicianService.java b/backend/Backend/src/main/java/com/securehealth/backend/service/LabTechnicianService.java index 175f9f88..3f82bcfd 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/service/LabTechnicianService.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/service/LabTechnicianService.java @@ -13,6 +13,13 @@ import java.util.Map; import java.util.stream.Collectors; +/** + * Service for laboratory technician operations and workflow management. + *

+ * Handles the laboratory test lifecycle, including dashboard metrics, + * order list retrieval, status transitions, and final result/report uploads. + *

+ */ @Service @Transactional public class LabTechnicianService { @@ -20,6 +27,11 @@ public class LabTechnicianService { @Autowired private LabTestRepository labTestRepository; + /** + * Aggregates statistical overview data for the lab technician dashboard. + * + * @return a map containing status counts and recent test activity + */ public Map getDashboardOverview() { Map stats = new HashMap<>(); stats.put("pending", labTestRepository.countByStatusIgnoreCase("Pending")); @@ -33,6 +45,12 @@ public Map getDashboardOverview() { return stats; } + /** + * Retrieves a list of lab test orders, optionally filtered by status. + * + * @param status the optional status to filter by + * @return a list of {@link LabTestDTO} objects + */ public List getAllOrders(String status) { List labTests; if (status != null && !status.isEmpty()) { @@ -43,6 +61,14 @@ public List getAllOrders(String status) { return labTests.stream().map(this::mapToDTO).collect(Collectors.toList()); } + /** + * Updates the status of an existing lab test order. + * + * @param testId the ID of the lab test + * @param newStatus the new status to apply + * @return the updated {@link LabTestDTO} + * @throws RuntimeException if the lab test is not found + */ public LabTestDTO updateOrderStatus(Long testId, String newStatus) { LabTest labTest = labTestRepository.findById(testId) .orElseThrow(() -> new RuntimeException("Lab test not found with id: " + testId)); @@ -55,6 +81,19 @@ public LabTestDTO updateOrderStatus(Long testId, String newStatus) { return mapToDTO(labTest); } + /** + * Uploads the clinical results and optional report file for a lab test. + *

+ * Automatically transitions the test status to "Completed" upon upload. + *

+ * + * @param testId the ID of the lab test + * @param resultValue the clinical value recorded + * @param remarks optional professional remarks or interpretations + * @param fileUrl optional URL/path to the uploaded report file + * @return the updated and completed {@link LabTestDTO} + * @throws RuntimeException if the lab test is not found + */ public LabTestDTO uploadResults(Long testId, String resultValue, String remarks, String fileUrl) { LabTest labTest = labTestRepository.findById(testId) .orElseThrow(() -> new RuntimeException("Lab test not found with id: " + testId)); diff --git a/backend/Backend/src/main/java/com/securehealth/backend/service/LabTestService.java b/backend/Backend/src/main/java/com/securehealth/backend/service/LabTestService.java index 0fb3d2e2..dfe8b54b 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/service/LabTestService.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/service/LabTestService.java @@ -16,6 +16,13 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +/** + * Service for clinical lab test ordering and patient-facing lookups. + *

+ * Allows doctors to order new tests and patients to retrieve their existing + * test results and order history. + *

+ */ @Service public class LabTestService { @@ -23,6 +30,13 @@ public class LabTestService { @Autowired private LoginRepository loginRepository; @Autowired private PatientProfileRepository patientProfileRepository; + /** + * Creates a new lab test order for a patient. + * + * @param request the {@link LabTestRequest} details + * @param staffEmail the email of the healthcare professional ordering the test + * @return the saved {@link LabTest} entity + */ @Transactional public LabTest createLabTest(LabTestRequest request, String staffEmail) { Login staff = loginRepository.findByEmail(staffEmail) @@ -41,6 +55,12 @@ public LabTest createLabTest(LabTestRequest request, String staffEmail) { return labTestRepository.save(labTest); } + /** + * Retrieves all lab tests associated with a specific patient. + * + * @param patientId the ID of the patient + * @return a list of {@link LabTestDTO} objects + */ @Transactional(readOnly = true) public List getLabTestsByPatient(Long patientId) { return labTestRepository.findByPatient_ProfileId(patientId).stream().map(lt -> { @@ -62,6 +82,11 @@ public List getLabTestsByPatient(Long patientId) { }).collect(Collectors.toList()); } + /** + * Retrieves all lab test orders currently in "PENDING" status. + * + * @return a list of {@link LabTestDTO} objects + */ @Transactional(readOnly = true) public List getAllLabTests() { return labTestRepository.findAll().stream().map(lt -> { @@ -98,6 +123,12 @@ public List getPendingLabTests() { }).collect(Collectors.toList()); } + /** + * Permanently deletes a lab test order. + * + * @param id the ID of the lab test to delete + * @throws RuntimeException if the lab test is not found + */ @Transactional public void deleteLabTest(Long id) { if (!labTestRepository.existsById(id)) { diff --git a/backend/Backend/src/main/java/com/securehealth/backend/service/MedicalRecordService.java b/backend/Backend/src/main/java/com/securehealth/backend/service/MedicalRecordService.java index 01fa64dd..bb7bd7c1 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/service/MedicalRecordService.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/service/MedicalRecordService.java @@ -18,6 +18,13 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +/** + * Service for managing patients' clinical medical records. + *

+ * Handles the creation of encounter records by doctors, chronological + * retrieval for patients, and secure administrative deletion with auditing. + *

+ */ @Service public class MedicalRecordService { @@ -26,6 +33,16 @@ public class MedicalRecordService { @Autowired private PatientProfileRepository patientProfileRepository; @Autowired private AuditLogRepository auditLogRepository; + /** + * Creates a new clinical medical record for a patient. + *

+ * Automatically generates an audit log entry upon successful creation. + *

+ * + * @param request the {@link MedicalRecordRequest} details + * @param doctorEmail the email of the attending doctor + * @return the saved {@link MedicalRecord} entity + */ @Transactional public MedicalRecord createMedicalRecord(MedicalRecordRequest request, String doctorEmail) { Login doctor = loginRepository.findByEmail(doctorEmail) @@ -49,6 +66,12 @@ public MedicalRecord createMedicalRecord(MedicalRecordRequest request, String do return saved; } + /** + * Retrieves all medical records associated with a specific patient. + * + * @param patientId the ID of the patient + * @return a list of {@link MedicalRecordDTO} objects + */ @Transactional(readOnly = true) public List getMedicalRecordsByPatient(Long patientId) { return medicalRecordRepository.findByPatient_ProfileId(patientId).stream().map(mr -> { @@ -66,6 +89,16 @@ public List getMedicalRecordsByPatient(Long patientId) { }).collect(Collectors.toList()); } + /** + * Deletes a specific medical record. + *

+ * Restricted operation that triggers an audit log entry for accountability. + *

+ * + * @param id the ID of the medical record to delete + * @param adminEmail the email of the administrator performing the deletion + * @throws RuntimeException if the record is not found + */ @Transactional public void deleteMedicalRecord(Long id, String adminEmail) { MedicalRecord record = medicalRecordRepository.findById(id) diff --git a/backend/Backend/src/main/java/com/securehealth/backend/service/NurseService.java b/backend/Backend/src/main/java/com/securehealth/backend/service/NurseService.java index dad9203e..260705c1 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/service/NurseService.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/service/NurseService.java @@ -19,6 +19,14 @@ import java.util.Map; import java.util.Optional; +/** + * Service for nursing operations and clinical task management. + *

+ * Provides a dedicated dashboard for nurses to track assigned patients, + * monitor pending vitals and medications, manage shift handovers, and + * update nursing task statuses. + *

+ */ @Service @Transactional public class NurseService { @@ -34,6 +42,16 @@ private Login getAuthUser(String email) { .orElseThrow(() -> new RuntimeException("Nurse not found with email: " + email)); } + /** + * Aggregates clinical dashboard metrics for a specific nurse. + *

+ * Includes counts of assigned patients, pending/overdue tasks, + * and a countdown to the next scheduled medication. + *

+ * + * @param nurseEmail the email of the nurse + * @return a map containing various clinical activity metrics + */ public Map getDashboardOverview(String nurseEmail) { Login nurse = getAuthUser(nurseEmail); Long nurseId = nurse.getUserId(); @@ -75,16 +93,36 @@ public Map getDashboardOverview(String nurseEmail) { return stats; } + /** + * Retrieves a list of patients assigned to a specific nurse. + * + * @param nurseEmail the email of the nurse + * @return a list of {@link PatientProfile} entities + */ public List getAssignedPatients(String nurseEmail) { Login nurse = getAuthUser(nurseEmail); return patientProfileRepository.findByAssignedNurse(nurse); } + /** + * Retrieves all nursing tasks assigned to a specific nurse, ordered by due time. + * + * @param nurseEmail the email of the nurse + * @return a list of {@link NurseTask} entities + */ public List getTasks(String nurseEmail) { Login nurse = getAuthUser(nurseEmail); return nurseTaskRepository.findByAssignedNurse_UserIdOrderByDueTimeAsc(nurse.getUserId()); } + /** + * Toggles the completion status of a nursing task. + * + * @param taskId the ID of the task to toggle + * @param nurseEmail the email of the nurse performing the action (for authorization) + * @return a result map containing a success message and the updated task + * @throws RuntimeException if the task is not found or not assigned to the requester + */ public NurseTask createTask(Map payload, String nurseEmail) { Login nurse = getAuthUser(nurseEmail); @@ -138,6 +176,12 @@ public Map toggleTaskStatus(Long taskId, String nurseEmail) { return Map.of("message", "Task toggled successfully.", "task", task); } + /** + * Retrieves shift handover notes, separated by direction. + * + * @param nurseEmail the email of the nurse (currently unused for filtering) + * @return a map containing notes "fromPreviousShift" and "forNextShift" + */ public Map getHandoverNotes(String nurseEmail) { Login nurse = getAuthUser(nurseEmail); @@ -150,6 +194,13 @@ public Map getHandoverNotes(String nurseEmail) { ); } + /** + * Saves a new shift handover note. + * + * @param payload a map containing 'content', 'type', 'priority', 'direction', and optional 'patientId' + * @param nurseEmail the email of the nurse authoring the note + * @return the saved {@link HandoverNote} entity + */ public HandoverNote saveHandoverNote(Map payload, String nurseEmail) { Login nurse = getAuthUser(nurseEmail); diff --git a/backend/Backend/src/main/java/com/securehealth/backend/service/PatientService.java b/backend/Backend/src/main/java/com/securehealth/backend/service/PatientService.java index 7a9ebb76..4b39da85 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/service/PatientService.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/service/PatientService.java @@ -16,6 +16,13 @@ import java.util.List; import java.util.stream.Collectors; +/** + * Service for managing patient profiles and administrative directory lookups. + *

+ * Handles profile creation, secure retrieval with IDOR protection, and + * updates for personal and medical history data. + *

+ */ @Service public class PatientService { @@ -32,6 +39,17 @@ public class PatientService { * GET /patients * Only Doctors and Admins should be able to pull a full list of patients. */ + /** + * Retrieves a paginated list of all patients in the system. + *

+ * Restricted to healthcare professionals (DOCTOR/ADMIN). + *

+ * + * @param requesterRole the role of the user making the request + * @param pageable pagination and sorting information + * @return a page of {@link PatientDTO} objects + * @throws RuntimeException if the requester has insufficient privileges + */ @Transactional(readOnly = true) public Page getAllPatients(String requesterRole, Pageable pageable) { if (!requesterRole.equals("DOCTOR") && !requesterRole.equals("ADMIN")) { @@ -46,6 +64,19 @@ public Page getAllPatients(String requesterRole, Pageable pageable) * GET /patients/:id * SECURITY CORE: Prevents IDOR. */ + /** + * Retrieves a specific patient profile by its ID. + *

+ * Implements strict IDOR protection: Patients can only access their own + * profiles, while Doctors and Admins have general access. + *

+ * + * @param id the ID of the patient profile + * @param requesterEmail the email of the authenticated requester + * @param requesterRole the role of the authenticated requester + * @return the {@link PatientDTO} of the requested profile + * @throws RuntimeException if the patient is not found or access is forbidden + */ @Transactional(readOnly = true) public PatientDTO getPatientById(Long id, String requesterEmail, String requesterRole) { PatientProfile profile = patientProfileRepository.findById(id) @@ -69,6 +100,13 @@ public PatientDTO getPatientById(Long id, String requesterEmail, String requeste * GET /patients/me * SECURITY CORE: Gets the currently logged in patient's profile. */ + /** + * Retrieves the profile associated with a specific user email. + * + * @param email the user's email + * @return the {@link PatientDTO} of the profile + * @throws RuntimeException if the user or profile is not found + */ @Transactional(readOnly = true) public PatientDTO getPatientByEmail(String email) { Login user = loginRepository.findByEmail(email) @@ -82,6 +120,14 @@ public PatientDTO getPatientByEmail(String email) { * POST /patients * Creates a profile and links it to the logged-in user. */ + /** + * Creates a new patient profile for an existing user account. + * + * @param dto the profile details + * @param requesterEmail the email of the user to link the profile to + * @return the saved {@link PatientDTO} + * @throws RuntimeException if a profile already exists for the user + */ @Transactional public PatientDTO createPatientProfile(PatientDTO dto, String requesterEmail) { Login user = loginRepository.findByEmail(requesterEmail) @@ -107,6 +153,19 @@ public PatientDTO createPatientProfile(PatientDTO dto, String requesterEmail) { /** * PUT /patients/:id */ + /** + * Updates an existing patient profile. + *

+ * Enforces security by ensuring patients only update their own records. + *

+ * + * @param id the ID of the profile to update + * @param dto the {@link PatientDTO} with updated fields + * @param requesterEmail the email of the requester + * @param requesterRole the role of the requester + * @return the updated {@link PatientDTO} + * @throws RuntimeException if the profile is not found or access is forbidden + */ @Transactional public PatientDTO updatePatientProfile(Long id, PatientDTO dto, String requesterEmail, String requesterRole) { PatientProfile profile = patientProfileRepository.findById(id) @@ -125,6 +184,18 @@ public PatientDTO updatePatientProfile(Long id, PatientDTO dto, String requester * Retrieves a distinct list of all patients who have an active or completed * appointment with a specific doctor. */ + /** + * Retrieves a list of patients who have active or history with a specific doctor. + *

+ * Restricted to the doctor themselves or administrators. + *

+ * + * @param doctorId the ID of the doctor + * @param requesterEmail the email of the requester + * @param requesterRole the role of the requester + * @return a list of {@link PatientDTO} objects + * @throws RuntimeException if the doctor is not found or access is forbidden + */ @Transactional(readOnly = true) public List getPatientsByDoctor(Long doctorId, String requesterEmail, String requesterRole) { // Find the doctor to verify identity diff --git a/backend/Backend/src/main/java/com/securehealth/backend/service/PrescriptionService.java b/backend/Backend/src/main/java/com/securehealth/backend/service/PrescriptionService.java index 3e3e478f..a51572b9 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/service/PrescriptionService.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/service/PrescriptionService.java @@ -20,6 +20,13 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +/** + * Service for managing medication prescriptions. + *

+ * Handles the creation of prescriptions by doctors, chronological + * retrieval for patients, refill management, and administrative cleanup. + *

+ */ @Service public class PrescriptionService { @@ -28,6 +35,16 @@ public class PrescriptionService { @Autowired private PatientProfileRepository patientProfileRepository; @Autowired private AuditLogRepository auditLogRepository; + /** + * Issues a new medication prescription for a patient. + *

+ * Automatically captures the prescribing doctor and generates an audit log. + *

+ * + * @param request the {@link PrescriptionRequest} details + * @param doctorEmail the email of the issuing doctor + * @return the saved {@link Prescription} entity + */ @Transactional public Prescription createPrescription(PrescriptionRequest request, String doctorEmail) { Login doctor = loginRepository.findByEmail(doctorEmail) @@ -58,6 +75,12 @@ public Prescription createPrescription(PrescriptionRequest request, String docto return saved; } + /** + * Retrieves all prescriptions associated with a specific patient. + * + * @param patientId the ID of the patient + * @return a list of {@link PrescriptionDTO} objects + */ @Transactional(readOnly = true) public List getPrescriptionsByPatient(Long patientId) { return prescriptionRepository.findByPatient_ProfileId(patientId).stream().map(p -> { @@ -81,6 +104,12 @@ public List getPrescriptionsByPatient(Long patientId) { }).collect(Collectors.toList()); } + /** + * Retrieves only the current "ACTIVE" prescriptions for a specific patient. + * + * @param patientId the ID of the patient + * @return a list of {@link PrescriptionDTO} objects + */ @Transactional(readOnly = true) public List getActivePrescriptionsByPatient(Long patientId) { return prescriptionRepository.findByPatient_ProfileIdAndStatus(patientId, "ACTIVE") @@ -102,6 +131,14 @@ public List getActivePrescriptionsByPatient(Long patientId) { }).collect(Collectors.toList()); } + /** + * Decrements the refill count of an existing prescription. + * + * @param id the ID of the prescription to refill + * @param doctorEmail the email of the doctor authorizing the refill + * @return the updated {@link Prescription} entity + * @throws RuntimeException if the prescription is not found, unauthorized, or no refills remain + */ @Transactional public Prescription refillPrescription(Long id, String doctorEmail) { Prescription prescription = prescriptionRepository.findById(id) @@ -119,6 +156,16 @@ public Prescription refillPrescription(Long id, String doctorEmail) { return prescriptionRepository.save(prescription); } + /** + * Permanently deletes a prescription from the system. + *

+ * Restricted administrative action that generates an audit log entry. + *

+ * + * @param id the ID of the prescription to delete + * @param adminEmail the email of the administrator performing the deletion + * @throws RuntimeException if the prescription is not found + */ @Transactional public void deletePrescription(Long id, String adminEmail) { Prescription prescription = prescriptionRepository.findById(id) diff --git a/backend/Backend/src/main/java/com/securehealth/backend/service/RateLimiterService.java b/backend/Backend/src/main/java/com/securehealth/backend/service/RateLimiterService.java index b783668c..f112beeb 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/service/RateLimiterService.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/service/RateLimiterService.java @@ -8,6 +8,13 @@ import java.time.Duration; +/** + * Service for enforcing security rate limiting and account locking. + *

+ * Uses Redis to track failed login and OTP attempts, providing + * temporary lockouts to prevent brute-force attacks. + *

+ */ @Service public class RateLimiterService { @@ -17,6 +24,14 @@ public class RateLimiterService { @Autowired private AuditLogRepository auditLogRepository; + /** + * Validates that a user account is not currently locked due to failed attempts. + * + * @param email the user's email + * @param ipAddress original IP address for auditing + * @param userAgent original user agent for auditing + * @throws RuntimeException if the account is locked + */ public void checkLoginAttempts(String email, String ipAddress, String userAgent) { String lockKey = "auth:lock:" + email; if (Boolean.TRUE.equals(redisTemplate.hasKey(lockKey))) { @@ -26,6 +41,17 @@ public void checkLoginAttempts(String email, String ipAddress, String userAgent) } + /** + * Increments the failure count for a login attempt. + *

+ * Triggers a 30-minute account lock if the threshold is reached. + *

+ * + * @param email the user's email + * @param ipAddress originating IP address + * @param userAgent originating user agent + * @throws RuntimeException if the lockout threshold is reached + */ public void registerFailedLogin(String email, String ipAddress, String userAgent) { String failKey = "auth:fail:" + email; String lockKey = "auth:lock:" + email; @@ -47,11 +73,24 @@ public void registerFailedLogin(String email, String ipAddress, String userAgent } } + /** + * Resets the failed login counter for a user (e.g., after a successful login). + * + * @param email the user's email + */ public void resetLoginAttempts(String email) { redisTemplate.delete("auth:fail:" + email); } + /** + * Validates that a user has not exceeded the OTP verification attempt limit. + * + * @param email the user's email + * @param ipAddress originating IP address + * @param userAgent originating user agent + * @throws RuntimeException if the attempt limit is reached + */ public void checkOtpAttempts(String email, String ipAddress, String userAgent) { String key = "otp:attempt:" + email; String attemptsStr = redisTemplate.opsForValue().get(key); @@ -62,6 +101,14 @@ public void checkOtpAttempts(String email, String ipAddress, String userAgent) { } } + /** + * Increments the failure count for an OTP verification attempt. + * + * @param email the user's email + * @param ipAddress originating IP address + * @param userAgent originating user agent + * @throws RuntimeException if the attempt limit is reached + */ public void registerFailedOtp(String email, String ipAddress, String userAgent) { String key = "otp:attempt:" + email; @@ -78,6 +125,11 @@ public void registerFailedOtp(String email, String ipAddress, String userAgent) } } + /** + * Resets the OTP attempt counter for a user. + * + * @param email the user's email + */ public void resetOtpAttempts(String email) { redisTemplate.delete("otp:attempt:" + email); } diff --git a/backend/Backend/src/main/java/com/securehealth/backend/service/TokenBlacklistService.java b/backend/Backend/src/main/java/com/securehealth/backend/service/TokenBlacklistService.java index 0ebefe5d..11b500f9 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/service/TokenBlacklistService.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/service/TokenBlacklistService.java @@ -6,6 +6,20 @@ import java.time.Duration; +/** + * Service for managing JWT revocation and idle session tracking. + *

+ * Uses Redis to maintain a blacklist of revoked access tokens and + * tracks user activity to enforce idle session timeouts. + *

+ */ +/** + * Service for managing JWT revocation and idle session tracking. + *

+ * Uses Redis to maintain a blacklist of revoked access tokens and + * tracks user activity to enforce idle session timeouts. + *

+ */ @Service public class TokenBlacklistService { @@ -13,7 +27,10 @@ public class TokenBlacklistService { private StringRedisTemplate redisTemplate; /** - * Blacklists an Access Token until its natural expiration time. + * Blacklists an access token until its natural expiration time. + * + * @param token the JWT to blacklist + * @param remainingMillis duration in milliseconds until the token expires */ public void blacklistToken(String token, long remainingMillis) { if (remainingMillis > 0) { @@ -24,7 +41,10 @@ public void blacklistToken(String token, long remainingMillis) { } /** - * Checks if a token is in the blacklist. + * Checks if a specific token has been revoked and blacklisted. + * + * @param token the JWT to check + * @return true if the token is blacklisted, false otherwise */ public boolean isBlacklisted(String token) { String key = "jwt:blacklist:" + token; @@ -32,18 +52,50 @@ public boolean isBlacklisted(String token) { } + /** + * Updates the last active timestamp for a user's session. + * + * @param email the user's email + */ + /** + * Updates the last active timestamp for a user's session. + * + * @param email the user's email + */ public void updateLastActive(String email) { String key = "session:active:" + email; // Extend the idle timeout by 30 minutes on every request redisTemplate.opsForValue().set(key, "active", Duration.ofMinutes(30)); } + /** + * Checks if a user's session has been idle beyond the timeout threshold. + * + * @param email the user's email + * @return true if the session is considered idle, false otherwise + */ + /** + * Checks if a user's session has been idle beyond the timeout threshold. + * + * @param email the user's email + * @return true if the session is considered idle, false otherwise + */ public boolean isSessionIdle(String email) { String key = "session:active:" + email; // If the key doesn't exist, they have been idle for > 30 minutes return Boolean.FALSE.equals(redisTemplate.hasKey(key)); } + /** + * Clears the active session status for a user. + * + * @param email the user's email + */ + /** + * Clears the active session status for a user. + * + * @param email the user's email + */ public void clearIdleSession(String email) { redisTemplate.delete("session:active:" + email); } diff --git a/backend/Backend/src/main/java/com/securehealth/backend/service/VitalSignService.java b/backend/Backend/src/main/java/com/securehealth/backend/service/VitalSignService.java index 339e3aee..05b8a7aa 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/service/VitalSignService.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/service/VitalSignService.java @@ -11,6 +11,20 @@ import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; +/** + * Service for clinical tracking of patient vital signs. + *

+ * Handles the recording of vitals by nursing staff and provides + * chronological timelines/latest snapshots for clinical review. + *

+ */ +/** + * Service for clinical tracking of patient vital signs. + *

+ * Handles the recording of vitals by nursing staff and provides + * chronological timelines/latest snapshots for clinical review. + *

+ */ @Service public class VitalSignService { @@ -18,6 +32,20 @@ public class VitalSignService { @Autowired private LoginRepository loginRepository; @Autowired private PatientProfileRepository patientProfileRepository; + /** + * Records a new set of vital signs for a patient. + * + * @param request the {@link VitalSignRequest} details + * @param recorderEmail the email of the person recording the vitals + * @return the saved {@link VitalSign} entity + */ + /** + * Records a new set of vital signs for a patient. + * + * @param request the {@link VitalSignRequest} details + * @param recorderEmail the email of the person recording the vitals + * @return the saved {@link VitalSign} entity + */ @Transactional public VitalSign createVitalSign(VitalSignRequest request, String recorderEmail) { Login recorder = loginRepository.findByEmail(recorderEmail) @@ -41,12 +69,38 @@ public VitalSign createVitalSign(VitalSignRequest request, String recorderEmail) return vitalSignRepository.save(vitalSign); } + /** + * Retrieves a chronological history of vital signs for a specific patient. + * + * @param patientId the ID of the patient + * @return a list of {@link com.securehealth.backend.dto.VitalSignDTO} objects + */ + /** + * Retrieves a chronological history of vital signs for a specific patient. + * + * @param patientId the ID of the patient + * @return a list of {@link com.securehealth.backend.dto.VitalSignDTO} objects + */ @Transactional(readOnly = true) public java.util.List getVitalSignsByPatient(Long patientId) { return vitalSignRepository.findByPatient_ProfileIdOrderByRecordedAtDesc(patientId) .stream().map(this::mapToDTO).collect(java.util.stream.Collectors.toList()); } + /** + * Retrieves the most recent vital sign recording for a specific patient. + * + * @param patientId the ID of the patient + * @return the latest {@link com.securehealth.backend.dto.VitalSignDTO} + * @throws RuntimeException if no vital signs are found for the patient + */ + /** + * Retrieves the most recent vital sign recording for a specific patient. + * + * @param patientId the ID of the patient + * @return the latest {@link com.securehealth.backend.dto.VitalSignDTO} + * @throws RuntimeException if no vital signs are found for the patient + */ @Transactional(readOnly = true) public com.securehealth.backend.dto.VitalSignDTO getLatestVitalSignByPatient(Long patientId) { return vitalSignRepository.findFirstByPatient_ProfileIdOrderByRecordedAtDesc(patientId) @@ -54,6 +108,18 @@ public com.securehealth.backend.dto.VitalSignDTO getLatestVitalSignByPatient(Lon .orElseThrow(() -> new RuntimeException("404: No vital signs found for patient")); } + /** + * Permanently deletes a vital sign recording. + * + * @param id the ID of the recording to delete + * @throws RuntimeException if the recording is not found + */ + /** + * Permanently deletes a vital sign recording. + * + * @param id the ID of the recording to delete + * @throws RuntimeException if the recording is not found + */ @Transactional public void deleteVitalSign(Long id) { if (!vitalSignRepository.existsById(id)) { diff --git a/backend/Backend/src/main/java/com/securehealth/backend/util/JwtUtil.java b/backend/Backend/src/main/java/com/securehealth/backend/util/JwtUtil.java index f487983e..7a48574b 100644 --- a/backend/Backend/src/main/java/com/securehealth/backend/util/JwtUtil.java +++ b/backend/Backend/src/main/java/com/securehealth/backend/util/JwtUtil.java @@ -15,6 +15,13 @@ import java.util.UUID; import java.util.function.Function; +/** + * Utility class for handling JSON Web Tokens (JWT). + *

+ * This component provides methods for generating, extracting, and validating + * access tokens using the JJWT library (0.12.x syntax). + *

+ */ @Component public class JwtUtil { @@ -26,10 +33,23 @@ public class JwtUtil { // ================== READING TOKEN ================== + /** + * Extracts the subject (username/email) from a JWT. + * + * @param token the JWT + * @return the extracted username + */ public String extractUsername(String token) { return extractClaim(token, Claims::getSubject); } + /** + * Validates if a token belongs to the given user and is not expired. + * + * @param token the JWT + * @param userDetails the user details to validate against + * @return true if valid, false otherwise + */ public boolean validateToken(String token, UserDetails userDetails) { final String username = extractUsername(token); return (username.equals(userDetails.getUsername()) && !isTokenExpired(token)); @@ -37,6 +57,14 @@ public boolean validateToken(String token, UserDetails userDetails) { // ================== GENERATING TOKEN ================== + /** + * Generates a signed access token with custom claims. + * + * @param email the user's email (subject) + * @param role the user's assigned role + * @param userId the user's internal ID + * @return a signed JWT string + */ public String generateAccessToken(String email, String role, Long userId) { Map claims = new HashMap<>(); claims.put("role", role); @@ -44,12 +72,25 @@ public String generateAccessToken(String email, String role, Long userId) { return createToken(claims, email, jwtExpiration); } + /** + * Generates a random UUID-based refresh token. + * + * @return a unique refresh token string + */ public String generateRefreshToken() { return UUID.randomUUID().toString(); } // ================== HELPER METHODS (UPDATED FOR 0.12.x) ================== + /** + * Generic method to extract a specific claim from a token. + * + * @param the type of the claim + * @param token the JWT + * @param claimsResolver a function to extract the desired claim + * @return the extracted claim value + */ public T extractClaim(String token, Function claimsResolver) { final Claims claims = extractAllClaims(token); return claimsResolver.apply(claims); @@ -68,6 +109,12 @@ private Boolean isTokenExpired(String token) { return extractExpiration(token).before(new Date()); } + /** + * Extracts the expiration date from a JWT. + * + * @param token the JWT + * @return the expiration {@link Date} + */ public Date extractExpiration(String token) { return extractClaim(token, Claims::getExpiration); } diff --git a/frontend/app/public/index.html b/frontend/app/public/index.html index aa069f27..92d84be9 100644 --- a/frontend/app/public/index.html +++ b/frontend/app/public/index.html @@ -24,7 +24,7 @@ work correctly both with client-side routing and a non-root public URL. Learn how to configure a non-root public URL by running `npm run build`. --> - React App + Calyx