Add data models and init data

This commit is contained in:
2025-11-06 12:21:50 +01:00
parent 6d1f2e00d9
commit c19d40e88c
16 changed files with 645 additions and 129 deletions

View File

@@ -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<Prescription> prescriptions = mapper.readValue(is, new TypeReference<>() {});
mongoTemplate.insertAll(prescriptions);
}
}
};
}
}

View File

@@ -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);
}
}
}

View File

@@ -10,7 +10,7 @@ import java.time.LocalDateTime;
import java.time.LocalTime; import java.time.LocalTime;
@Entity @Entity
@Table(name = "appointments") @Table(name = "appointments", uniqueConstraints = @UniqueConstraint(name = "doctor_patient_time_constraint", columnNames = {"doctor", "patient", "appointmentTime"}))
public class Appointment { public class Appointment {
@Id @Id

View File

@@ -1,12 +1,15 @@
package com.project.back_end.models; package com.project.back_end.models;
import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.persistence.*; import jakarta.persistence.*;
import jakarta.validation.constraints.Email; import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern; import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Size; import jakarta.validation.constraints.Size;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.List; import java.util.List;
@Entity @Entity
@@ -17,73 +20,71 @@ public class Doctor {
@GeneratedValue(strategy = GenerationType.IDENTITY) @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id; private Long id;
@NotNull
@OneToOne
@JsonIgnore
private User user;
@NotNull @NotNull
@Size(min = 3, max = 100) @Size(min = 3, max = 100)
@Column(unique=true)
private String name; private String name;
@NotNull @NotNull
@Size(min = 3, max = 50) @Email
private String specialization; @Column(unique=true)
private String email;
@NotNull @NotNull
@Email @JsonProperty(access = JsonProperty.Access.WRITE_ONLY)
private String emailAddress; @Size(min = 256,max = 256)
private String password;
@NotNull
@Size(min = 3, max = 50)
private String specialty;
@NotNull @NotNull
@Pattern(regexp = "^[0-9]{10}$") @Pattern(regexp = "^[0-9]{10}$")
private String phoneNumber; private String phone;
@OneToMany(fetch = FetchType.LAZY) @OneToMany(mappedBy = "doctor")
private List<Appointment> appointments; private List<Appointment> appointments;
@NotNull
@Size(min = 1)
@OneToMany(fetch = FetchType.LAZY)
private List<OfficeHour> officeHours;
@OneToMany(fetch = FetchType.LAZY)
private List<UnavailabilitySchedule> unavailabilitySchedules;
@NotNull
@JsonIgnore
private Boolean archived;
public Doctor() { public Doctor() {
} }
public Doctor(String name, User user, List<OfficeHour> officeHours) { public Doctor(String name, String email, String password) {
this.name = name; this.name = name;
this.user = user; this.email = email;
this.officeHours = officeHours; this.password = hashPassword(password);
} }
public Long getId() { public Long getId() {
return id; return id;
} }
public String getSpecialization() { public String getPassword() {
return specialization; return password;
} }
public void setSpecialization(String specialization) { public String getSpecialty() {
this.specialization = specialization; return specialty;
} }
public String getEmailAddress() { public void setSpecialty(String specialty) {
return emailAddress; this.specialty = specialty;
} }
public void setEmailAddress(String emailAddress) { public void setPassword(String password) {
this.emailAddress = emailAddress; this.password = hashPassword(password);
} }
public String getPhoneNumber() { public String getEmail() {
return phoneNumber; return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhone() {
return phone;
} }
public String getName() { public String getName() {
@@ -94,8 +95,8 @@ public class Doctor {
this.name = name; this.name = name;
} }
public void setPhoneNumber(String phoneNumber) { public void setPhone(String phone) {
this.phoneNumber = phoneNumber; this.phone = phone;
} }
public List<Appointment> getAppointments() { public List<Appointment> getAppointments() {
@@ -106,36 +107,11 @@ public class Doctor {
this.appointments = appointments; this.appointments = appointments;
} }
public List<OfficeHour> getOfficeHours() { private static String hashPassword(String rawPassword) {
return officeHours; try {
} return new String(MessageDigest.getInstance("SHA-256").digest(rawPassword.getBytes(StandardCharsets.UTF_8)));
} catch (NoSuchAlgorithmException e) {
public void setOfficeHours(List<OfficeHour> officeHours) { throw new RuntimeException(e);
this.officeHours = officeHours; }
}
public List<UnavailabilitySchedule> getUnavailabilitySchedules() {
return unavailabilitySchedules;
}
public void setUnavailabilitySchedules(List<UnavailabilitySchedule> 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;
} }
} }

View File

@@ -1,11 +1,15 @@
package com.project.back_end.models; package com.project.back_end.models;
import com.fasterxml.jackson.annotation.JsonProperty;
import jakarta.persistence.*; import jakarta.persistence.*;
import jakarta.validation.constraints.Email; import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Pattern; import jakarta.validation.constraints.Pattern;
import jakarta.validation.constraints.Size; import jakarta.validation.constraints.Size;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.List; import java.util.List;
@Entity @Entity
@@ -16,60 +20,64 @@ public class Patient {
@GeneratedValue(strategy = GenerationType.IDENTITY) @GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id; private Long id;
@NotNull
@OneToOne
private User user;
@NotNull @NotNull
@Size(min = 3, max = 100) @Size(min = 3, max = 100)
@Column(unique=true)
private String name; private String name;
@NotNull @NotNull
@Email @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 @NotNull
@Pattern(regexp = "^[0-9]{10}$") @Pattern(regexp = "^[0-9]{10}$")
private String phoneNumber; private String phone;
@NotNull @NotNull
@Size(max = 255) @Size(max = 255)
private String homeAddress; private String address;
@NotNull @OneToMany(mappedBy = "patient")
private Boolean archived; private List<Appointment> appointments;
@OneToMany(fetch = FetchType.LAZY)
public List<Appointment> appointments;
public Patient(){} public Patient(){}
public Patient(User user, String name, String emailAddress, String phoneNumber, String homeAddress) { public Patient(String name, String email, String password, String phone, String address) {
this.user = user;
this.name = name; this.name = name;
this.emailAddress = emailAddress; this.email = email;
this.phoneNumber = phoneNumber; this.phone = phone;
this.homeAddress = homeAddress; 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) { public void setName(String name) {
this.name = name; this.name = name;
} }
public void setEmailAddress(String emailAddress) { public void setEmail(String email) {
this.emailAddress = emailAddress; this.email = email;
} }
public void setPhoneNumber(String phoneNumber) { public void setPhone(String phone) {
this.phoneNumber = phoneNumber; this.phone = phone;
} }
public void setHomeAddress(String homeAddress) { public void setAddress(String address) {
this.homeAddress = homeAddress; this.address = address;
}
public void setArchived(Boolean archived) {
this.archived = archived;
} }
public void setAppointments(List<Appointment> appointments) { public void setAppointments(List<Appointment> appointments) {
@@ -80,36 +88,31 @@ public class Patient {
return id; return id;
} }
public User getUser() {
return user;
}
public String getName() { public String getName() {
return name; return name;
} }
public String getEmailAddress() { public String getEmail() {
return emailAddress; return email;
} }
public String getPhoneNumber() { public String getPhone() {
return phoneNumber; return phone;
} }
public String getHomeAddress() { public String getAddress() {
return homeAddress; return address;
}
public Boolean getArchived() {
return archived;
} }
public List<Appointment> getAppointments() { public List<Appointment> getAppointments() {
return appointments; return appointments;
} }
@PrePersist private static String hashPassword(String rawPassword) {
private void save() { try {
archived = false; return new String(MessageDigest.getInstance("SHA-256").digest(rawPassword.getBytes(StandardCharsets.UTF_8)));
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException(e);
}
} }
} }

View File

@@ -1,6 +1,8 @@
package com.project.back_end.models; package com.project.back_end.models;
import jakarta.persistence.Column;
import jakarta.persistence.Id; import jakarta.persistence.Id;
import jakarta.persistence.ManyToOne;
import jakarta.validation.constraints.NotNull; import jakarta.validation.constraints.NotNull;
import jakarta.validation.constraints.Size; import jakarta.validation.constraints.Size;
import org.springframework.data.mongodb.core.mapping.Document; import org.springframework.data.mongodb.core.mapping.Document;
@@ -14,10 +16,11 @@ public class Prescription {
private String id; private String id;
@NotNull @NotNull
private Long patientId; @Size(min = 3, max = 100)
private String patientName;
@NotNull @ManyToOne
private Long appointmentId; private Appointment appointment;
@NotNull @NotNull
@Size(min = 3, max = 100) @Size(min = 3, max = 100)
@@ -32,11 +35,11 @@ public class Prescription {
public Prescription() {} public Prescription() {}
public Prescription(Patient patient, Appointment appointment, String medication, String dosage, String doctorNotes) { public Prescription(Patient patient, Appointment appointment, String medication, String dosage, String doctorNotes) {
this.patientId = requireNonNull(patient).getId(); this.appointment = appointment;
this.appointmentId = requireNonNull(appointment).getId();
this.medication = medication; this.medication = medication;
this.dosage = dosage; this.dosage = dosage;
this.doctorNotes = doctorNotes; this.doctorNotes = doctorNotes;
this.patientName = requireNonNull(patient).getName();
} }
public String getId() { public String getId() {
@@ -67,11 +70,19 @@ public class Prescription {
this.doctorNotes = doctorNotes; this.doctorNotes = doctorNotes;
} }
public Long getAppointmentId() { public Appointment getAppointment() {
return appointmentId; return appointment;
} }
public Long getPatientId() { public void setAppointment(Appointment appointment) {
return patientId; this.appointment = appointment;
}
public String getPatientName() {
return patientName;
}
public void setPatientName(String patientName) {
this.patientName = patientName;
} }
} }

View File

@@ -1,16 +1,24 @@
spring.application.name=back-end spring.application.name=back-end
spring.datasource.url=jdbc:mysql://<mysql_host>/cms?usessl=false spring.datasource.url=jdbc:mysql://localhost:3306/cms?usessl=false
spring.datasource.username=root spring.datasource.username=root
spring.datasource.password=cms
spring.datasource.password=<mysql_password>
spring.jpa.hibernate.ddl-auto=update spring.jpa.hibernate.ddl-auto=update
spring.jpa.defer-datasource-initialization=true
spring.jpa.show-sql=true spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true spring.jpa.properties.hibernate.format_sql=true
spring.jpa.open-in-view=false spring.jpa.open-in-view=false
spring.data.mongodb.uri=mongodb://root:<mongodb_password>@<mongodb_host>: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.endpoint.health.show-details=always
management.health.db.enabled=true management.health.db.enabled=true
@@ -29,5 +37,5 @@ spring.web.resources.static-locations=classpath:/static/
spring.thymeleaf.prefix=classpath:/templates/ spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html spring.thymeleaf.suffix=.html
spring.thymeleaf.mode=HTML spring.thymeleaf.mode=HTML
spring.thymeleaf.cache=false spring.thymeleaf.cache=false
spring.thymeleaf.encoding=UTF-8 spring.thymeleaf.encoding=UTF-8

View File

@@ -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."
}
]

View File

@@ -0,0 +1,4 @@
INSERT INTO admins (username, password)
VALUES
('admin', SHA2('admin@1234',256))
ON DUPLICATE KEY UPDATE id = id; ^

View File

@@ -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; ^

View File

@@ -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; ^

View File

@@ -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; ^

View File

@@ -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;

View File

@@ -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;

View File

@@ -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;

View File

@@ -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: