diff --git a/SmartClinicManagementSystem/app/src/main/java/com/project/back_end/config/MongoConfig.java b/SmartClinicManagementSystem/app/src/main/java/com/project/back_end/config/MongoConfig.java new file mode 100644 index 0000000..92c6549 --- /dev/null +++ b/SmartClinicManagementSystem/app/src/main/java/com/project/back_end/config/MongoConfig.java @@ -0,0 +1,29 @@ +package com.project.back_end.config; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.project.back_end.models.Prescription; +import org.springframework.boot.CommandLineRunner; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.data.mongodb.core.MongoTemplate; + +import java.io.InputStream; +import java.util.List; + +@Configuration +public class MongoConfig { + + @Bean + CommandLineRunner loadPrescriptions(MongoTemplate mongoTemplate, ObjectMapper mapper) { + return args -> { + if (mongoTemplate.getCollection("prescriptions").countDocuments() == 0) { + try (InputStream is = getClass().getResourceAsStream("/documents/prescriptions.json")) { + List prescriptions = mapper.readValue(is, new TypeReference<>() {}); + mongoTemplate.insertAll(prescriptions); + } + } + }; + } + +} \ No newline at end of file diff --git a/SmartClinicManagementSystem/app/src/main/java/com/project/back_end/models/Admin.java b/SmartClinicManagementSystem/app/src/main/java/com/project/back_end/models/Admin.java new file mode 100644 index 0000000..52b9fcc --- /dev/null +++ b/SmartClinicManagementSystem/app/src/main/java/com/project/back_end/models/Admin.java @@ -0,0 +1,57 @@ +package com.project.back_end.models; + +import com.fasterxml.jackson.annotation.JsonProperty; +import jakarta.persistence.*; +import jakarta.validation.constraints.NotNull; +import jakarta.validation.constraints.Size; + +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; + +@Entity +@Table(name = "admins") +public class Admin { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @NotNull + @Column(unique = true) + private String username; + + @NotNull + @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) + @Size(min = 256, max = 256) + private String password; + + public Admin(String username, String password) { + this.username = username; + this.password = hashPassword(password); + } + + public String getUsername() { + return username; + } + + public void setUsername(String username) { + this.username = username; + } + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + private static String hashPassword(String rawPassword) { + try { + return new String(MessageDigest.getInstance("SHA-256").digest(rawPassword.getBytes(StandardCharsets.UTF_8))); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException(e); + } + } +} \ No newline at end of file diff --git a/SmartClinicManagementSystem/app/src/main/java/com/project/back_end/models/Appointment.java b/SmartClinicManagementSystem/app/src/main/java/com/project/back_end/models/Appointment.java index 50ae24f..232ed32 100644 --- a/SmartClinicManagementSystem/app/src/main/java/com/project/back_end/models/Appointment.java +++ b/SmartClinicManagementSystem/app/src/main/java/com/project/back_end/models/Appointment.java @@ -10,7 +10,7 @@ import java.time.LocalDateTime; import java.time.LocalTime; @Entity -@Table(name = "appointments") +@Table(name = "appointments", uniqueConstraints = @UniqueConstraint(name = "doctor_patient_time_constraint", columnNames = {"doctor", "patient", "appointmentTime"})) public class Appointment { @Id diff --git a/SmartClinicManagementSystem/app/src/main/java/com/project/back_end/models/Doctor.java b/SmartClinicManagementSystem/app/src/main/java/com/project/back_end/models/Doctor.java index c7e4e6c..b52cfce 100644 --- a/SmartClinicManagementSystem/app/src/main/java/com/project/back_end/models/Doctor.java +++ b/SmartClinicManagementSystem/app/src/main/java/com/project/back_end/models/Doctor.java @@ -1,12 +1,15 @@ package com.project.back_end.models; -import com.fasterxml.jackson.annotation.JsonIgnore; +import com.fasterxml.jackson.annotation.JsonProperty; import jakarta.persistence.*; import jakarta.validation.constraints.Email; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Pattern; import jakarta.validation.constraints.Size; +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; import java.util.List; @Entity @@ -17,73 +20,71 @@ public class Doctor { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @NotNull - @OneToOne - @JsonIgnore - private User user; - @NotNull @Size(min = 3, max = 100) + @Column(unique=true) private String name; @NotNull - @Size(min = 3, max = 50) - private String specialization; + @Email + @Column(unique=true) + private String email; @NotNull - @Email - private String emailAddress; + @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) + @Size(min = 256,max = 256) + private String password; + + @NotNull + @Size(min = 3, max = 50) + private String specialty; @NotNull @Pattern(regexp = "^[0-9]{10}$") - private String phoneNumber; + private String phone; - @OneToMany(fetch = FetchType.LAZY) + @OneToMany(mappedBy = "doctor") private List appointments; - @NotNull - @Size(min = 1) - @OneToMany(fetch = FetchType.LAZY) - private List officeHours; - - @OneToMany(fetch = FetchType.LAZY) - private List unavailabilitySchedules; - - @NotNull - @JsonIgnore - private Boolean archived; - public Doctor() { } - public Doctor(String name, User user, List officeHours) { + public Doctor(String name, String email, String password) { this.name = name; - this.user = user; - this.officeHours = officeHours; + this.email = email; + this.password = hashPassword(password); } public Long getId() { return id; } - public String getSpecialization() { - return specialization; + public String getPassword() { + return password; } - public void setSpecialization(String specialization) { - this.specialization = specialization; + public String getSpecialty() { + return specialty; } - public String getEmailAddress() { - return emailAddress; + public void setSpecialty(String specialty) { + this.specialty = specialty; } - public void setEmailAddress(String emailAddress) { - this.emailAddress = emailAddress; + public void setPassword(String password) { + this.password = hashPassword(password); } - public String getPhoneNumber() { - return phoneNumber; + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } + + public String getPhone() { + return phone; } public String getName() { @@ -94,8 +95,8 @@ public class Doctor { this.name = name; } - public void setPhoneNumber(String phoneNumber) { - this.phoneNumber = phoneNumber; + public void setPhone(String phone) { + this.phone = phone; } public List getAppointments() { @@ -106,36 +107,11 @@ public class Doctor { this.appointments = appointments; } - public List getOfficeHours() { - return officeHours; - } - - public void setOfficeHours(List officeHours) { - this.officeHours = officeHours; - } - - public List getUnavailabilitySchedules() { - return unavailabilitySchedules; - } - - public void setUnavailabilitySchedules(List unavailabilitySchedules) { - this.unavailabilitySchedules = unavailabilitySchedules; - } - - public User getUser() { - return user; - } - - public Boolean getArchived() { - return archived; - } - - public void setArchived(Boolean archived) { - this.archived = archived; - } - - @PrePersist - private void save() { - archived = false; + private static String hashPassword(String rawPassword) { + try { + return new String(MessageDigest.getInstance("SHA-256").digest(rawPassword.getBytes(StandardCharsets.UTF_8))); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException(e); + } } } \ No newline at end of file diff --git a/SmartClinicManagementSystem/app/src/main/java/com/project/back_end/models/Patient.java b/SmartClinicManagementSystem/app/src/main/java/com/project/back_end/models/Patient.java index 20ab11b..109ca74 100644 --- a/SmartClinicManagementSystem/app/src/main/java/com/project/back_end/models/Patient.java +++ b/SmartClinicManagementSystem/app/src/main/java/com/project/back_end/models/Patient.java @@ -1,11 +1,15 @@ package com.project.back_end.models; +import com.fasterxml.jackson.annotation.JsonProperty; import jakarta.persistence.*; import jakarta.validation.constraints.Email; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Pattern; import jakarta.validation.constraints.Size; +import java.nio.charset.StandardCharsets; +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; import java.util.List; @Entity @@ -16,60 +20,64 @@ public class Patient { @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; - @NotNull - @OneToOne - private User user; - @NotNull @Size(min = 3, max = 100) + @Column(unique=true) private String name; @NotNull @Email - private String emailAddress; + @Column(unique=true) + private String email; + + @NotNull + @JsonProperty(access = JsonProperty.Access.WRITE_ONLY) + @Size(min = 256,max = 256) + private String password; @NotNull @Pattern(regexp = "^[0-9]{10}$") - private String phoneNumber; + private String phone; @NotNull @Size(max = 255) - private String homeAddress; + private String address; - @NotNull - private Boolean archived; - - @OneToMany(fetch = FetchType.LAZY) - public List appointments; + @OneToMany(mappedBy = "patient") + private List appointments; public Patient(){} - public Patient(User user, String name, String emailAddress, String phoneNumber, String homeAddress) { - this.user = user; + public Patient(String name, String email, String password, String phone, String address) { this.name = name; - this.emailAddress = emailAddress; - this.phoneNumber = phoneNumber; - this.homeAddress = homeAddress; + this.email = email; + this.phone = phone; + this.address = address; + this.password = hashPassword(password); + } + + public void setPassword(String password) { + this.password = hashPassword(password); + } + + public String getPassword() { + return password; } public void setName(String name) { this.name = name; } - public void setEmailAddress(String emailAddress) { - this.emailAddress = emailAddress; + public void setEmail(String email) { + this.email = email; } - public void setPhoneNumber(String phoneNumber) { - this.phoneNumber = phoneNumber; + public void setPhone(String phone) { + this.phone = phone; } - public void setHomeAddress(String homeAddress) { - this.homeAddress = homeAddress; - } - - public void setArchived(Boolean archived) { - this.archived = archived; + public void setAddress(String address) { + this.address = address; } public void setAppointments(List appointments) { @@ -80,36 +88,31 @@ public class Patient { return id; } - public User getUser() { - return user; - } - public String getName() { return name; } - public String getEmailAddress() { - return emailAddress; + public String getEmail() { + return email; } - public String getPhoneNumber() { - return phoneNumber; + public String getPhone() { + return phone; } - public String getHomeAddress() { - return homeAddress; - } - - public Boolean getArchived() { - return archived; + public String getAddress() { + return address; } public List getAppointments() { return appointments; } - @PrePersist - private void save() { - archived = false; + private static String hashPassword(String rawPassword) { + try { + return new String(MessageDigest.getInstance("SHA-256").digest(rawPassword.getBytes(StandardCharsets.UTF_8))); + } catch (NoSuchAlgorithmException e) { + throw new RuntimeException(e); + } } } \ No newline at end of file diff --git a/SmartClinicManagementSystem/app/src/main/java/com/project/back_end/models/Prescription.java b/SmartClinicManagementSystem/app/src/main/java/com/project/back_end/models/Prescription.java index 54f97dc..797be4b 100644 --- a/SmartClinicManagementSystem/app/src/main/java/com/project/back_end/models/Prescription.java +++ b/SmartClinicManagementSystem/app/src/main/java/com/project/back_end/models/Prescription.java @@ -1,6 +1,8 @@ package com.project.back_end.models; +import jakarta.persistence.Column; import jakarta.persistence.Id; +import jakarta.persistence.ManyToOne; import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.Size; import org.springframework.data.mongodb.core.mapping.Document; @@ -14,10 +16,11 @@ public class Prescription { private String id; @NotNull - private Long patientId; + @Size(min = 3, max = 100) + private String patientName; - @NotNull - private Long appointmentId; + @ManyToOne + private Appointment appointment; @NotNull @Size(min = 3, max = 100) @@ -32,11 +35,11 @@ public class Prescription { public Prescription() {} public Prescription(Patient patient, Appointment appointment, String medication, String dosage, String doctorNotes) { - this.patientId = requireNonNull(patient).getId(); - this.appointmentId = requireNonNull(appointment).getId(); + this.appointment = appointment; this.medication = medication; this.dosage = dosage; this.doctorNotes = doctorNotes; + this.patientName = requireNonNull(patient).getName(); } public String getId() { @@ -67,11 +70,19 @@ public class Prescription { this.doctorNotes = doctorNotes; } - public Long getAppointmentId() { - return appointmentId; + public Appointment getAppointment() { + return appointment; } - public Long getPatientId() { - return patientId; + public void setAppointment(Appointment appointment) { + this.appointment = appointment; + } + + public String getPatientName() { + return patientName; + } + + public void setPatientName(String patientName) { + this.patientName = patientName; } } \ No newline at end of file diff --git a/SmartClinicManagementSystem/app/src/main/resources/application.properties b/SmartClinicManagementSystem/app/src/main/resources/application.properties index b6b721a..bc2e1b0 100644 --- a/SmartClinicManagementSystem/app/src/main/resources/application.properties +++ b/SmartClinicManagementSystem/app/src/main/resources/application.properties @@ -1,16 +1,24 @@ spring.application.name=back-end -spring.datasource.url=jdbc:mysql:///cms?usessl=false +spring.datasource.url=jdbc:mysql://localhost:3306/cms?usessl=false spring.datasource.username=root +spring.datasource.password=cms -spring.datasource.password= spring.jpa.hibernate.ddl-auto=update - +spring.jpa.defer-datasource-initialization=true spring.jpa.show-sql=true spring.jpa.properties.hibernate.format_sql=true spring.jpa.open-in-view=false -spring.data.mongodb.uri=mongodb://root:@:27017/prescriptions?authSource=admin" +spring.data.mongodb.uri=mongodb://root:cms@localhost:27017/prescriptions?authSource=admin + +logging.level.org.springframework.jdbc.datasource.init=DEBUG +spring.sql.init.mode=always +spring.sql.init.data-locations=classpath:sql/data_*.sql +spring.sql.init.schema-locations=classpath:sql/proc_*.sql +spring.sql.init.platform=mysql +spring.sql.init.separator=^ +spring.sql.init.encoding=utf-8 management.endpoint.health.show-details=always management.health.db.enabled=true @@ -29,5 +37,5 @@ spring.web.resources.static-locations=classpath:/static/ spring.thymeleaf.prefix=classpath:/templates/ spring.thymeleaf.suffix=.html spring.thymeleaf.mode=HTML -spring.thymeleaf.cache=false +spring.thymeleaf.cache=false spring.thymeleaf.encoding=UTF-8 \ No newline at end of file diff --git a/SmartClinicManagementSystem/app/src/main/resources/documents/prescriptions.json b/SmartClinicManagementSystem/app/src/main/resources/documents/prescriptions.json new file mode 100644 index 0000000..a753f51 --- /dev/null +++ b/SmartClinicManagementSystem/app/src/main/resources/documents/prescriptions.json @@ -0,0 +1,170 @@ +[ + { + "patientName": "John Smith", + "appointmentId": 51, + "medication": "Paracetamol", + "dosage": "500mg", + "doctorNotes": "Take 1 tablet every 6 hours." + }, + { + "patientName": "Emily Rose", + "appointmentId": 52, + "medication": "Aspirin", + "dosage": "300mg", + "doctorNotes": "Take 1 tablet after meals." + }, + { + "patientName": "Michael Jordan", + "appointmentId": 53, + "medication": "Ibuprofen", + "dosage": "400mg", + "doctorNotes": "Take 1 tablet every 8 hours." + }, + { + "patientName": "Olivia Moon", + "appointmentId": 54, + "medication": "Antihistamine", + "dosage": "10mg", + "doctorNotes": "Take 1 tablet daily before bed." + }, + { + "patientName": "Liam King", + "appointmentId": 55, + "medication": "Vitamin C", + "dosage": "1000mg", + "doctorNotes": "Take 1 tablet daily." + }, + { + "patientName": "Sophia Lane", + "appointmentId": 56, + "medication": "Antibiotics", + "dosage": "500mg", + "doctorNotes": "Take 1 tablet every 12 hours." + }, + { + "patientName": "Noah Brooks", + "appointmentId": 57, + "medication": "Paracetamol", + "dosage": "500mg", + "doctorNotes": "Take 1 tablet every 6 hours." + }, + { + "patientName": "Ava Daniels", + "appointmentId": 58, + "medication": "Ibuprofen", + "dosage": "200mg", + "doctorNotes": "Take 1 tablet every 8 hours." + }, + { + "patientName": "William Harris", + "appointmentId": 59, + "medication": "Aspirin", + "dosage": "300mg", + "doctorNotes": "Take 1 tablet after meals." + }, + { + "patientName": "Mia Green", + "appointmentId": 60, + "medication": "Vitamin D", + "dosage": "1000 IU", + "doctorNotes": "Take 1 tablet daily with food." + }, + { + "patientName": "James Brown", + "appointmentId": 61, + "medication": "Antihistamine", + "dosage": "10mg", + "doctorNotes": "Take 1 tablet every morning." + }, + { + "patientName": "Amelia Clark", + "appointmentId": 62, + "medication": "Paracetamol", + "dosage": "500mg", + "doctorNotes": "Take 1 tablet every 6 hours." + }, + { + "patientName": "Ben Johnson", + "appointmentId": 63, + "medication": "Ibuprofen", + "dosage": "400mg", + "doctorNotes": "Take 1 tablet every 8 hours." + }, + { + "patientName": "Ella Monroe", + "appointmentId": 64, + "medication": "Vitamin C", + "dosage": "1000mg", + "doctorNotes": "Take 1 tablet daily." + }, + { + "patientName": "Lucas Turner", + "appointmentId": 65, + "medication": "Aspirin", + "dosage": "300mg", + "doctorNotes": "Take 1 tablet after meals." + }, + { + "patientName": "Grace Scott", + "appointmentId": 66, + "medication": "Paracetamol", + "dosage": "500mg", + "doctorNotes": "Take 1 tablet every 6 hours." + }, + { + "patientName": "Ethan Hill", + "appointmentId": 67, + "medication": "Ibuprofen", + "dosage": "400mg", + "doctorNotes": "Take 1 tablet every 8 hours." + }, + { + "patientName": "Ruby Ward", + "appointmentId": 68, + "medication": "Vitamin D", + "dosage": "1000 IU", + "doctorNotes": "Take 1 tablet daily with food." + }, + { + "patientName": "Jack Baker", + "appointmentId": 69, + "medication": "Antibiotics", + "dosage": "500mg", + "doctorNotes": "Take 1 tablet every 12 hours." + }, + { + "patientName": "Mia Hall", + "appointmentId": 70, + "medication": "Paracetamol", + "dosage": "500mg", + "doctorNotes": "Take 1 tablet every 6 hours." + }, + { + "patientName": "Owen Thomas", + "appointmentId": 71, + "medication": "Ibuprofen", + "dosage": "200mg", + "doctorNotes": "Take 1 tablet every 8 hours." + }, + { + "patientName": "Ivy Jackson", + "appointmentId": 72, + "medication": "Antihistamine", + "dosage": "10mg", + "doctorNotes": "Take 1 tablet every morning." + }, + { + "patientName": "Leo Martin", + "appointmentId": 73, + "medication": "Vitamin C", + "dosage": "1000mg", + "doctorNotes": "Take 1 tablet daily." + }, + { + "patientName": "Ella Moore", + "appointmentId": 74, + "medication": "Aspirin", + "dosage": "300mg", + "doctorNotes": "Take 1 tablet after meals." + } +] \ No newline at end of file diff --git a/SmartClinicManagementSystem/app/src/main/resources/sql/data_1_admins.sql b/SmartClinicManagementSystem/app/src/main/resources/sql/data_1_admins.sql new file mode 100644 index 0000000..1d653f2 --- /dev/null +++ b/SmartClinicManagementSystem/app/src/main/resources/sql/data_1_admins.sql @@ -0,0 +1,4 @@ +INSERT INTO admins (username, password) +VALUES + ('admin', SHA2('admin@1234',256)) +ON DUPLICATE KEY UPDATE id = id; ^ \ No newline at end of file diff --git a/SmartClinicManagementSystem/app/src/main/resources/sql/data_2_doctors.sql b/SmartClinicManagementSystem/app/src/main/resources/sql/data_2_doctors.sql new file mode 100644 index 0000000..f82c1e9 --- /dev/null +++ b/SmartClinicManagementSystem/app/src/main/resources/sql/data_2_doctors.sql @@ -0,0 +1,28 @@ +INSERT INTO doctors (email, name, password, phone, specialty) +VALUES + ('dr.adams@example.com', 'Dr. Emily Adams', SHA2('pass12345', 256), '555-101-2020', 'Cardiologist'), + ('dr.johnson@example.com', 'Dr. Mark Johnson', SHA2('secure4567', 256), '555-202-3030', 'Neurologist'), + ('dr.lee@example.com', 'Dr. Sarah Lee', SHA2('leePass987', 256), '555-303-4040', 'Orthopedist'), + ('dr.wilson@example.com', 'Dr. Tom Wilson', SHA2('w!ls0nPwd', 256), '555-404-5050', 'Pediatrician'), + ('dr.brown@example.com', 'Dr. Alice Brown', SHA2('brownie123', 256), '555-505-6060', 'Dermatologist'), + ('dr.taylor@example.com', 'Dr. Taylor Grant', SHA2('taylor321', 256), '555-606-7070', 'Cardiologist'), + ('dr.white@example.com', 'Dr. Sam White', SHA2('whiteSecure1', 256), '555-707-8080', 'Neurologist'), + ('dr.clark@example.com', 'Dr. Emma Clark', SHA2('clarkPass456', 256), '555-808-9090', 'Orthopedist'), + ('dr.davis@example.com', 'Dr. Olivia Davis', SHA2('davis789', 256), '555-909-0101', 'Pediatrician'), + ('dr.miller@example.com', 'Dr. Henry Miller', SHA2('millertime!', 256), '555-010-1111', 'Dermatologist'), + ('dr.moore@example.com', 'Dr. Ella Moore', SHA2('ellapass33', 256), '555-111-2222', 'Cardiologist'), + ('dr.martin@example.com', 'Dr. Leo Martin', SHA2('martinpass', 256), '555-222-3333', 'Neurologist'), + ('dr.jackson@example.com', 'Dr. Ivy Jackson', SHA2('jackson11', 256), '555-333-4444', 'Orthopedist'), + ('dr.thomas@example.com', 'Dr. Owen Thomas', SHA2('thomasPWD', 256), '555-444-5555', 'Pediatrician'), + ('dr.hall@example.com', 'Dr. Ava Hall', SHA2('hallhall', 256), '555-555-6666', 'Dermatologist'), + ('dr.green@example.com', 'Dr. Mia Green', SHA2('greenleaf', 256), '555-666-7777', 'Cardiologist'), + ('dr.baker@example.com', 'Dr. Jack Baker', SHA2('bakeitup', 256), '555-777-8888', 'Neurologist'), + ('dr.walker@example.com', 'Dr. Nora Walker', SHA2('walkpass12', 256), '555-888-9999', 'Orthopedist'), + ('dr.young@example.com', 'Dr. Liam Young', SHA2('young123', 256), '555-999-0000', 'Pediatrician'), + ('dr.king@example.com', 'Dr. Zoe King', SHA2('kingkong1', 256), '555-000-1111', 'Dermatologist'), + ('dr.scott@example.com', 'Dr. Lily Scott', SHA2('scottish', 256), '555-111-2223', 'Cardiologist'), + ('dr.evans@example.com', 'Dr. Lucas Evans', SHA2('evansEv1', 256), '555-222-3334', 'Neurologist'), + ('dr.turner@example.com', 'Dr. Grace Turner', SHA2('turnerBurner', 256), '555-333-4445', 'Orthopedist'), + ('dr.hill@example.com', 'Dr. Ethan Hill', SHA2('hillclimb', 256), '555-444-5556', 'Pediatrician'), + ('dr.ward@example.com', 'Dr. Ruby Ward', SHA2('wardWard', 256), '555-555-6667', 'Dermatologist') +ON DUPLICATE KEY UPDATE id = id; ^ \ No newline at end of file diff --git a/SmartClinicManagementSystem/app/src/main/resources/sql/data_3_patients.sql b/SmartClinicManagementSystem/app/src/main/resources/sql/data_3_patients.sql new file mode 100644 index 0000000..b6b88ab --- /dev/null +++ b/SmartClinicManagementSystem/app/src/main/resources/sql/data_3_patients.sql @@ -0,0 +1,28 @@ +INSERT INTO patients (address, email, name, password, phone) +VALUES + ('101 Oak St, Cityville', 'jane.doe@example.com', 'Jane Doe', SHA2('passJane1', 256), '888-111-1111'), + ('202 Maple Rd, Townsville', 'john.smith@example.com', 'John Smith', SHA2('smithSecure', 256), '888-222-2222'), + ('303 Pine Ave, Villageton', 'emily.rose@example.com', 'Emily Rose', SHA2('emilyPass99', 256), '888-333-3333'), + ('404 Birch Ln, Metropolis', 'michael.j@example.com', 'Michael Jordan', SHA2('airmj23', 256), '888-444-4444'), + ('505 Cedar Blvd, Springfield', 'olivia.m@example.com', 'Olivia Moon', SHA2('moonshine12', 256), '888-555-5555'), + ('606 Spruce Ct, Gotham', 'liam.k@example.com', 'Liam King', SHA2('king321', 256), '888-666-6666'), + ('707 Aspen Dr, Riverdale', 'sophia.l@example.com', 'Sophia Lane', SHA2('sophieLane', 256), '888-777-7777'), + ('808 Elm St, Newtown', 'noah.b@example.com', 'Noah Brooks', SHA2('noahBest!', 256), '888-888-8888'), + ('909 Willow Way, Star City', 'ava.d@example.com', 'Ava Daniels', SHA2('avaSecure8', 256), '888-999-9999'), + ('111 Chestnut Pl, Midvale', 'william.h@example.com', 'William Harris', SHA2('willH2025', 256), '888-000-0000'), + ('112 Redwood St, Fairview', 'mia.g@example.com', 'Mia Green', SHA2('miagreen1', 256), '889-111-1111'), + ('113 Cypress Rd, Edgewater', 'james.b@example.com', 'James Brown', SHA2('jamiebrown', 256), '889-222-2222'), + ('114 Poplar Ave, Crestwood', 'amelia.c@example.com', 'Amelia Clark', SHA2('ameliacool', 256), '889-333-3333'), + ('115 Sequoia Dr, Elmwood', 'ben.j@example.com', 'Ben Johnson', SHA2('bennyJ', 256), '889-444-4444'), + ('116 Palm Blvd, Harborview', 'ella.m@example.com', 'Ella Monroe', SHA2('ellam123', 256), '889-555-5555'), + ('117 Cottonwood Ct, Laketown', 'lucas.t@example.com', 'Lucas Turner', SHA2('lucasTurn', 256), '889-666-6666'), + ('118 Sycamore Ln, Hilltop', 'grace.s@example.com', 'Grace Scott', SHA2('graceful', 256), '889-777-7777'), + ('119 Magnolia Pl, Brookside', 'ethan.h@example.com', 'Ethan Hill', SHA2('hill2025', 256), '889-888-8888'), + ('120 Fir St, Woodland', 'ruby.w@example.com', 'Ruby Ward', SHA2('rubypass', 256), '889-999-9999'), + ('121 Beech Way, Lakeside', 'jack.b@example.com', 'Jack Baker', SHA2('bakerjack', 256), '889-000-0000'), + ('122 Alder Ave, Pinehill', 'mia.h@example.com', 'Mia Hall', SHA2('hallMia', 256), '890-111-1111'), + ('123 Hawthorn Blvd, Meadowbrook', 'owen.t@example.com', 'Owen Thomas', SHA2('owen123', 256), '890-222-2222'), + ('124 Dogwood Dr, Summit', 'ivy.j@example.com', 'Ivy Jackson', SHA2('ivyIvy', 256), '890-333-3333'), + ('125 Juniper Ct, Greenwood', 'leo.m@example.com', 'Leo Martin', SHA2('leopass', 256), '890-444-4444'), + ('126 Olive Rd, Ashville', 'ella.moore@example.com', 'Ella Moore', SHA2('ellamoore', 256), '890-555-5555') +ON DUPLICATE KEY UPDATE id = id; ^ \ No newline at end of file diff --git a/SmartClinicManagementSystem/app/src/main/resources/sql/data_4_appointments.sql b/SmartClinicManagementSystem/app/src/main/resources/sql/data_4_appointments.sql new file mode 100644 index 0000000..9d49e0d --- /dev/null +++ b/SmartClinicManagementSystem/app/src/main/resources/sql/data_4_appointments.sql @@ -0,0 +1,133 @@ +INSERT INTO appointments (appointment_time, status, doctor_id, patient_id) +VALUES + ('2025-05-01 09:00:00.000000', 0, 1, 1), + ('2025-05-02 10:00:00.000000', 0, 1, 2), + ('2025-05-03 11:00:00.000000', 0, 1, 3), + ('2025-05-04 14:00:00.000000', 0, 1, 4), + ('2025-05-05 15:00:00.000000', 0, 1, 5), + ('2025-05-06 13:00:00.000000', 0, 1, 6), + ('2025-05-07 09:00:00.000000', 0, 1, 7), + ('2025-05-08 16:00:00.000000', 0, 1, 8), + ('2025-05-09 11:00:00.000000', 0, 1, 9), + ('2025-05-10 10:00:00.000000', 0, 1, 10), + ('2025-05-11 12:00:00.000000', 0, 1, 11), + ('2025-05-12 15:00:00.000000', 0, 1, 12), + ('2025-05-13 13:00:00.000000', 0, 1, 13), + ('2025-05-14 10:00:00.000000', 0, 1, 14), + ('2025-05-15 11:00:00.000000', 0, 1, 15), + ('2025-05-16 14:00:00.000000', 0, 1, 16), + ('2025-05-17 09:00:00.000000', 0, 1, 17), + ('2025-05-18 12:00:00.000000', 0, 1, 18), + ('2025-05-19 13:00:00.000000', 0, 1, 19), + ('2025-05-20 16:00:00.000000', 0, 1, 20), + ('2025-05-21 14:00:00.000000', 0, 1, 21), + ('2025-05-22 10:00:00.000000', 0, 1, 22), + ('2025-05-23 11:00:00.000000', 0, 1, 23), + ('2025-05-24 15:00:00.000000', 0, 1, 24), + ('2025-05-25 09:00:00.000000', 0, 1, 25), + ('2025-05-01 10:00:00.000000', 0, 2, 1), + ('2025-05-02 11:00:00.000000', 0, 3, 2), + ('2025-05-03 14:00:00.000000', 0, 4, 3), + ('2025-05-04 15:00:00.000000', 0, 5, 4), + ('2025-05-05 10:00:00.000000', 0, 6, 5), + ('2025-05-06 11:00:00.000000', 0, 7, 6), + ('2025-05-07 14:00:00.000000', 0, 8, 7), + ('2025-05-08 15:00:00.000000', 0, 9, 8), + ('2025-05-09 10:00:00.000000', 0, 10, 9), + ('2025-05-10 14:00:00.000000', 0, 11, 10), + ('2025-05-11 13:00:00.000000', 0, 12, 11), + ('2025-05-12 14:00:00.000000', 0, 13, 12), + ('2025-05-13 15:00:00.000000', 0, 14, 13), + ('2025-05-14 10:00:00.000000', 0, 15, 14), + ('2025-05-15 11:00:00.000000', 0, 16, 15), + ('2025-05-16 14:00:00.000000', 0, 17, 16), + ('2025-05-17 10:00:00.000000', 0, 18, 17), + ('2025-05-18 13:00:00.000000', 0, 19, 18), + ('2025-05-19 14:00:00.000000', 0, 20, 19), + ('2025-05-20 11:00:00.000000', 0, 21, 20), + ('2025-05-21 13:00:00.000000', 0, 22, 21), + ('2025-05-22 14:00:00.000000', 0, 23, 22), + ('2025-05-23 10:00:00.000000', 0, 24, 23), + ('2025-05-24 15:00:00.000000', 0, 25, 24), + ('2025-05-25 13:00:00.000000', 0, 25, 25), + ('2025-04-01 10:00:00.000000', 1, 1, 2), + ('2025-04-02 11:00:00.000000', 1, 2, 3), + ('2025-04-03 14:00:00.000000', 1, 3, 4), + ('2025-04-04 15:00:00.000000', 1, 4, 5), + ('2025-04-05 10:00:00.000000', 1, 5, 6), + ('2025-04-06 11:00:00.000000', 1, 6, 7), + ('2025-04-07 14:00:00.000000', 1, 7, 8), + ('2025-04-08 15:00:00.000000', 1, 8, 9), + ('2025-04-09 10:00:00.000000', 1, 9, 10), + ('2025-04-10 14:00:00.000000', 1, 10, 11), + ('2025-04-11 13:00:00.000000', 1, 11, 12), + ('2025-04-12 14:00:00.000000', 1, 12, 13), + ('2025-04-13 15:00:00.000000', 1, 13, 14), + ('2025-04-14 10:00:00.000000', 1, 14, 15), + ('2025-04-15 11:00:00.000000', 1, 15, 16), + ('2025-04-16 14:00:00.000000', 1, 16, 17), + ('2025-04-17 10:00:00.000000', 1, 17, 18), + ('2025-04-18 13:00:00.000000', 1, 18, 19), + ('2025-04-19 14:00:00.000000', 1, 19, 20), + ('2025-04-20 11:00:00.000000', 1, 20, 21), + ('2025-04-21 13:00:00.000000', 1, 21, 22), + ('2025-04-22 14:00:00.000000', 1, 22, 23), + ('2025-04-23 10:00:00.000000', 1, 23, 24), + ('2025-04-24 15:00:00.000000', 1, 24, 25), + ('2025-04-25 13:00:00.000000', 1, 25, 25), + ('2025-04-01 09:00:00.000000', 1, 1, 1), + ('2025-04-02 10:00:00.000000', 1, 1, 2), + ('2025-04-03 11:00:00.000000', 1, 1, 3), + ('2025-04-04 14:00:00.000000', 1, 1, 4), + ('2025-04-05 10:00:00.000000', 1, 1, 5), + ('2025-04-10 10:00:00.000000', 1, 1, 6), + ('2025-04-11 09:00:00.000000', 1, 1, 7), + ('2025-04-14 13:00:00.000000', 1, 1, 8), + ('2025-04-01 10:00:00.000000', 1, 2, 1), + ('2025-04-01 11:00:00.000000', 1, 2, 2), + ('2025-04-02 09:00:00.000000', 1, 2, 3), + ('2025-04-02 10:00:00.000000', 1, 2, 4), + ('2025-04-03 11:00:00.000000', 1, 2, 5), + ('2025-04-03 12:00:00.000000', 1, 2, 6), + ('2025-04-04 14:00:00.000000', 1, 2, 7), + ('2025-04-04 15:00:00.000000', 1, 2, 8), + ('2025-04-05 10:00:00.000000', 1, 2, 9), + ('2025-04-05 11:00:00.000000', 1, 2, 10), + ('2025-04-06 13:00:00.000000', 1, 2, 11), + ('2025-04-06 14:00:00.000000', 1, 2, 12), + ('2025-04-07 09:00:00.000000', 1, 2, 13), + ('2025-04-07 10:00:00.000000', 1, 2, 14), + ('2025-04-08 11:00:00.000000', 1, 2, 15), + ('2025-04-08 12:00:00.000000', 1, 2, 16), + ('2025-04-09 13:00:00.000000', 1, 2, 17), + ('2025-04-09 14:00:00.000000', 1, 2, 18), + ('2025-04-10 11:00:00.000000', 1, 2, 19), + ('2025-04-10 12:00:00.000000', 1, 2, 20), + ('2025-04-11 14:00:00.000000', 1, 2, 21), + ('2025-04-11 15:00:00.000000', 1, 2, 22), + ('2025-04-12 10:00:00.000000', 1, 2, 23), + ('2025-04-12 11:00:00.000000', 1, 2, 24), + ('2025-04-13 13:00:00.000000', 1, 2, 25), + ('2025-04-13 14:00:00.000000', 1, 2, 1), + ('2025-04-14 09:00:00.000000', 1, 2, 2), + ('2025-04-14 10:00:00.000000', 1, 2, 3), + ('2025-04-15 12:00:00.000000', 1, 2, 4), + ('2025-04-15 13:00:00.000000', 1, 2, 5), + ('2025-04-01 12:00:00.000000', 1, 3, 1), + ('2025-04-02 11:00:00.000000', 1, 3, 2), + ('2025-04-03 13:00:00.000000', 1, 3, 3), + ('2025-04-04 15:00:00.000000', 1, 3, 4), + ('2025-04-05 12:00:00.000000', 1, 3, 5), + ('2025-04-08 13:00:00.000000', 1, 3, 6), + ('2025-04-09 10:00:00.000000', 1, 3, 7), + ('2025-04-10 14:00:00.000000', 1, 3, 8), + ('2025-04-11 13:00:00.000000', 1, 3, 9), + ('2025-04-12 09:00:00.000000', 1, 3, 10), + ('2025-04-01 14:00:00.000000', 1, 4, 1), + ('2025-04-02 12:00:00.000000', 1, 4, 2), + ('2025-04-03 14:00:00.000000', 1, 4, 3), + ('2025-04-04 16:00:00.000000', 1, 4, 4), + ('2025-04-05 14:00:00.000000', 1, 4, 5), + ('2025-04-09 11:00:00.000000', 1, 4, 6), + ('2025-04-10 13:00:00.000000', 1, 4, 7) +ON DUPLICATE KEY UPDATE id = id; ^ \ No newline at end of file diff --git a/SmartClinicManagementSystem/app/src/main/resources/sql/proc_GetDailyAppointmentReportByDoctor.sql b/SmartClinicManagementSystem/app/src/main/resources/sql/proc_GetDailyAppointmentReportByDoctor.sql new file mode 100644 index 0000000..9ddf092 --- /dev/null +++ b/SmartClinicManagementSystem/app/src/main/resources/sql/proc_GetDailyAppointmentReportByDoctor.sql @@ -0,0 +1,16 @@ +DROP PROCEDURE IF EXISTS GetDailyAppointmentReportByDoctor; ^ +CREATE PROCEDURE GetDailyAppointmentReportByDoctor(IN report_date DATE) +BEGIN + SELECT + d.name AS doctor_name, + a.appointment_time, + a.status, + p.name AS patient_name, + p.phone AS patient_phone + FROM appointments a + JOIN doctors d ON a.doctor_id = d.id + JOIN patients p ON a.patient_id = p.id + WHERE DATE(a.appointment_time) = report_date + ORDER BY d.name, a.appointment_time; +END; ^ +SELECT 1; \ No newline at end of file diff --git a/SmartClinicManagementSystem/app/src/main/resources/sql/proc_GetDoctorWithMostPatientsByMonth.sql b/SmartClinicManagementSystem/app/src/main/resources/sql/proc_GetDoctorWithMostPatientsByMonth.sql new file mode 100644 index 0000000..86f8be7 --- /dev/null +++ b/SmartClinicManagementSystem/app/src/main/resources/sql/proc_GetDoctorWithMostPatientsByMonth.sql @@ -0,0 +1,13 @@ +DROP PROCEDURE IF EXISTS GetDoctorWithMostPatientsByMonth; ^ +CREATE PROCEDURE GetDoctorWithMostPatientsByMonth(IN input_month INT,IN input_year INT) +BEGIN + SELECT + doctor_id, + COUNT(patient_id) AS patients_seen + FROM appointments + WHERE MONTH(appointment_time) = input_month AND YEAR(appointment_time) = input_year + GROUP BY doctor_id + ORDER BY patients_seen DESC + LIMIT 1; +END; ^ +SELECT 1; \ No newline at end of file diff --git a/SmartClinicManagementSystem/app/src/main/resources/sql/proc_GetDoctorWithMostPatientsByYear.sql b/SmartClinicManagementSystem/app/src/main/resources/sql/proc_GetDoctorWithMostPatientsByYear.sql new file mode 100644 index 0000000..0e2cbf2 --- /dev/null +++ b/SmartClinicManagementSystem/app/src/main/resources/sql/proc_GetDoctorWithMostPatientsByYear.sql @@ -0,0 +1,13 @@ +DROP PROCEDURE IF EXISTS GetDoctorWithMostPatientsByYear; ^ +CREATE PROCEDURE GetDoctorWithMostPatientsByYear(IN input_year INT) +BEGIN + SELECT + doctor_id, + COUNT(patient_id) AS patients_seen + FROM appointments + WHERE YEAR(appointment_time) = input_year + GROUP BY doctor_id + ORDER BY patients_seen DESC + LIMIT 1; +END; ^ +SELECT 1; \ No newline at end of file diff --git a/SmartClinicManagementSystem/docker-compose.yml b/SmartClinicManagementSystem/docker-compose.yml new file mode 100644 index 0000000..e243b12 --- /dev/null +++ b/SmartClinicManagementSystem/docker-compose.yml @@ -0,0 +1,27 @@ +services: + mysql: + image: mysql:8.0 + container_name: mysql + environment: + MYSQL_ROOT_PASSWORD: cms + MYSQL_DATABASE: cms + volumes: + - mysql-data:/var/lib/mysql + ports: + - "3306:3306" + + mongo: + image: mongo:8.2.1 + container_name: mongo + environment: + MONGO_INITDB_ROOT_USERNAME: root + MONGO_INITDB_ROOT_PASSWORD: cms + MONGO_INITDB_DATABASE: cms + volumes: + - mongodb-data:/data/db + ports: + - "27017:27017" + +volumes: + mysql-data: + mongodb-data: \ No newline at end of file