Skip to content

Commit fa17d2a

Browse files
refactor: update domain models and repository interfaces
1 parent fcb3e18 commit fa17d2a

6 files changed

Lines changed: 543 additions & 0 deletions

File tree

Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
package com.countyhospital.healthapi.encounter.domain;
2+
3+
import com.countyhospital.healthapi.patient.domain.Patient;
4+
5+
import jakarta.persistence.*;
6+
import jakarta.validation.constraints.*;
7+
import java.time.LocalDateTime;
8+
import java.util.Objects;
9+
10+
@Entity
11+
@Table(name = "encounters", indexes = {
12+
@Index(name = "idx_encounter_patient_id", columnList = "patient_id"),
13+
@Index(name = "idx_encounter_start_date", columnList = "startDateTime"),
14+
@Index(name = "idx_encounter_class", columnList = "encounterClass")
15+
})
16+
public class Encounter {
17+
18+
@Id
19+
@GeneratedValue(strategy = GenerationType.IDENTITY)
20+
private Long id;
21+
22+
@NotNull(message = "Patient is required")
23+
@ManyToOne(fetch = FetchType.LAZY)
24+
@JoinColumn(name = "patient_id", nullable = false)
25+
private Patient patient;
26+
27+
@NotNull(message = "Start date time is required")
28+
@Column(nullable = false)
29+
private LocalDateTime startDateTime;
30+
31+
@Column
32+
private LocalDateTime endDateTime;
33+
34+
@NotBlank(message = "Encounter class is required")
35+
@Pattern(regexp = "^(INPATIENT|OUTPATIENT|EMERGENCY|VIRTUAL)$",
36+
message = "Encounter class must be INPATIENT, OUTPATIENT, EMERGENCY, or VIRTUAL")
37+
@Column(name = "encounter_class", nullable = false, length = 20)
38+
private String encounterClass;
39+
40+
@Size(max = 500, message = "Description must not exceed 500 characters")
41+
@Column(length = 500)
42+
private String description;
43+
44+
@Column(name = "created_at", nullable = false, updatable = false)
45+
private LocalDateTime createdAt;
46+
47+
@Column(name = "updated_at", nullable = false)
48+
private LocalDateTime updatedAt;
49+
50+
// Default constructor for JPA
51+
public Encounter() {}
52+
53+
// Constructor for creating new encounters
54+
public Encounter(Patient patient, LocalDateTime startDateTime,
55+
LocalDateTime endDateTime, String encounterClass, String description) {
56+
this.patient = patient;
57+
this.startDateTime = startDateTime;
58+
this.endDateTime = endDateTime;
59+
this.encounterClass = encounterClass;
60+
this.description = description;
61+
this.createdAt = LocalDateTime.now();
62+
this.updatedAt = LocalDateTime.now();
63+
}
64+
65+
@PrePersist
66+
protected void onCreate() {
67+
createdAt = LocalDateTime.now();
68+
updatedAt = LocalDateTime.now();
69+
}
70+
71+
@PreUpdate
72+
protected void onUpdate() {
73+
updatedAt = LocalDateTime.now();
74+
}
75+
76+
// Business validation
77+
@AssertTrue(message = "End date time must be after start date time")
78+
public boolean isValidDateTimeRange() {
79+
return endDateTime == null || !endDateTime.isBefore(startDateTime);
80+
}
81+
82+
// Getters and setters
83+
public Long getId() { return id; }
84+
public void setId(Long id) { this.id = id; }
85+
86+
public Patient getPatient() { return patient; }
87+
public void setPatient(Patient patient) { this.patient = patient; }
88+
89+
public LocalDateTime getStartDateTime() { return startDateTime; }
90+
public void setStartDateTime(LocalDateTime startDateTime) { this.startDateTime = startDateTime; }
91+
92+
public LocalDateTime getEndDateTime() { return endDateTime; }
93+
public void setEndDateTime(LocalDateTime endDateTime) { this.endDateTime = endDateTime; }
94+
95+
public String getEncounterClass() { return encounterClass; }
96+
public void setEncounterClass(String encounterClass) { this.encounterClass = encounterClass; }
97+
98+
public String getDescription() { return description; }
99+
public void setDescription(String description) { this.description = description; }
100+
101+
public LocalDateTime getCreatedAt() { return createdAt; }
102+
public void setCreatedAt(LocalDateTime createdAt) { this.createdAt = createdAt; }
103+
104+
public LocalDateTime getUpdatedAt() { return updatedAt; }
105+
public void setUpdatedAt(LocalDateTime updatedAt) { this.updatedAt = updatedAt; }
106+
107+
// Equals and hashCode
108+
@Override
109+
public boolean equals(Object o) {
110+
if (this == o) return true;
111+
if (o == null || getClass() != o.getClass()) return false;
112+
Encounter encounter = (Encounter) o;
113+
return Objects.equals(id, encounter.id);
114+
}
115+
116+
@Override
117+
public int hashCode() {
118+
return Objects.hash(id);
119+
}
120+
121+
@Override
122+
public String toString() {
123+
return "Encounter{" +
124+
"id=" + id +
125+
", patientId=" + (patient != null ? patient.getId() : null) +
126+
", startDateTime=" + startDateTime +
127+
", endDateTime=" + endDateTime +
128+
", encounterClass='" + encounterClass + '\'' +
129+
'}';
130+
}
131+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
package com.countyhospital.healthapi.encounter.repository;
2+
3+
import com.countyhospital.healthapi.encounter.domain.Encounter;
4+
import com.countyhospital.healthapi.patient.domain.Patient;
5+
import org.springframework.data.jpa.repository.JpaRepository;
6+
import org.springframework.data.jpa.repository.Query;
7+
import org.springframework.data.repository.query.Param;
8+
import org.springframework.stereotype.Repository;
9+
10+
import java.time.LocalDateTime;
11+
import java.util.List;
12+
13+
@Repository
14+
public interface EncounterRepository extends JpaRepository<Encounter, Long> {
15+
16+
List<Encounter> findByPatient(Patient patient);
17+
18+
List<Encounter> findByPatientId(Long patientId);
19+
20+
List<Encounter> findByEncounterClass(String encounterClass);
21+
22+
List<Encounter> findByStartDateTimeBetween(LocalDateTime start, LocalDateTime end);
23+
24+
@Query("SELECT e FROM Encounter e WHERE e.patient.id = :patientId AND e.startDateTime BETWEEN :startDate AND :endDate")
25+
List<Encounter> findByPatientIdAndDateRange(
26+
@Param("patientId") Long patientId,
27+
@Param("startDate") LocalDateTime startDate,
28+
@Param("endDate") LocalDateTime endDate);
29+
30+
@Query("SELECT COUNT(e) FROM Encounter e WHERE e.patient.id = :patientId")
31+
long countByPatientId(@Param("patientId") Long patientId);
32+
33+
boolean existsByPatientAndStartDateTime(Patient patient, LocalDateTime startDateTime);
34+
}
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
package com.countyhospital.healthapi.observation.domain;
2+
3+
import com.countyhospital.healthapi.patient.domain.Patient;
4+
import com.countyhospital.healthapi.encounter.domain.Encounter;
5+
6+
import jakarta.persistence.*;
7+
import jakarta.validation.constraints.*;
8+
import java.time.LocalDateTime;
9+
import java.util.Objects;
10+
11+
@Entity
12+
@Table(name = "observations", indexes = {
13+
@Index(name = "idx_observation_patient_id", columnList = "patient_id"),
14+
@Index(name = "idx_observation_encounter_id", columnList = "encounter_id"),
15+
@Index(name = "idx_observation_effective_date", columnList = "effectiveDateTime"),
16+
@Index(name = "idx_observation_code", columnList = "code")
17+
})
18+
public class Observation {
19+
20+
@Id
21+
@GeneratedValue(strategy = GenerationType.IDENTITY)
22+
private Long id;
23+
24+
@NotNull(message = "Patient is required")
25+
@ManyToOne(fetch = FetchType.LAZY)
26+
@JoinColumn(name = "patient_id", nullable = false)
27+
private Patient patient;
28+
29+
@ManyToOne(fetch = FetchType.LAZY)
30+
@JoinColumn(name = "encounter_id")
31+
private Encounter encounter;
32+
33+
@NotBlank(message = "Observation code is required")
34+
@Size(max = 50, message = "Code must not exceed 50 characters")
35+
@Column(nullable = false, length = 50)
36+
private String code;
37+
38+
@NotBlank(message = "Display name is required")
39+
@Size(max = 200, message = "Display name must not exceed 200 characters")
40+
@Column(name = "display_name", nullable = false, length = 200)
41+
private String displayName;
42+
43+
@NotBlank(message = "Value is required")
44+
@Size(max = 500, message = "Value must not exceed 500 characters")
45+
@Column(nullable = false, length = 500)
46+
private String value;
47+
48+
@Size(max = 50, message = "Unit must not exceed 50 characters")
49+
@Column(length = 50)
50+
private String unit;
51+
52+
@NotNull(message = "Effective date time is required")
53+
@Column(nullable = false)
54+
private LocalDateTime effectiveDateTime;
55+
56+
@Column(name = "created_at", nullable = false, updatable = false)
57+
private LocalDateTime createdAt;
58+
59+
// Default constructor for JPA
60+
public Observation() {}
61+
62+
// Constructor for creating new observations
63+
public Observation(Patient patient, Encounter encounter, String code,
64+
String displayName, String value, String unit, LocalDateTime effectiveDateTime) {
65+
this.patient = patient;
66+
this.encounter = encounter;
67+
this.code = code;
68+
this.displayName = displayName;
69+
this.value = value;
70+
this.unit = unit;
71+
this.effectiveDateTime = effectiveDateTime;
72+
this.createdAt = LocalDateTime.now();
73+
}
74+
75+
@PrePersist
76+
protected void onCreate() {
77+
createdAt = LocalDateTime.now();
78+
}
79+
80+
// Getters and setters
81+
public Long getId() { return id; }
82+
public void setId(Long id) { this.id = id; }
83+
84+
public Patient getPatient() { return patient; }
85+
public void setPatient(Patient patient) { this.patient = patient; }
86+
87+
public Encounter getEncounter() { return encounter; }
88+
public void setEncounter(Encounter encounter) { this.encounter = encounter; }
89+
90+
public String getCode() { return code; }
91+
public void setCode(String code) { this.code = code; }
92+
93+
public String getDisplayName() { return displayName; }
94+
public void setDisplayName(String displayName) { this.displayName = displayName; }
95+
96+
public String getValue() { return value; }
97+
public void setValue(String value) { this.value = value; }
98+
99+
public String getUnit() { return unit; }
100+
public void setUnit(String unit) { this.unit = unit; }
101+
102+
public LocalDateTime getEffectiveDateTime() { return effectiveDateTime; }
103+
public void setEffectiveDateTime(LocalDateTime effectiveDateTime) { this.effectiveDateTime = effectiveDateTime; }
104+
105+
public LocalDateTime getCreatedAt() { return createdAt; }
106+
public void setCreatedAt(LocalDateTime createdAt) { this.createdAt = createdAt; }
107+
108+
// Equals and hashCode
109+
@Override
110+
public boolean equals(Object o) {
111+
if (this == o) return true;
112+
if (o == null || getClass() != o.getClass()) return false;
113+
Observation that = (Observation) o;
114+
return Objects.equals(id, that.id);
115+
}
116+
117+
@Override
118+
public int hashCode() {
119+
return Objects.hash(id);
120+
}
121+
122+
@Override
123+
public String toString() {
124+
return "Observation{" +
125+
"id=" + id +
126+
", patientId=" + (patient != null ? patient.getId() : null) +
127+
", encounterId=" + (encounter != null ? encounter.getId() : null) +
128+
", code='" + code + '\'' +
129+
", value='" + value + '\'' +
130+
", effectiveDateTime=" + effectiveDateTime +
131+
'}';
132+
}
133+
}

0 commit comments

Comments
 (0)