2026-09-15 14:14:54 +01:00

137 lines
3.5 KiB
Java

package com.voidsoftware.map02.entities;
import com.voidsoftware.map02.models.Gender;
import com.voidsoftware.map02.models.MediaEntity;
import jakarta.persistence.*;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.Instant;
import java.time.LocalDate;
import java.util.UUID;
@Entity
@Table(name = "patient", indexes = {
@Index(name = "idx_patient_email", columnList = "email", unique = true),
@Index(name = "idx_patient_professional_id", columnList = "professional_id"),
@Index(name = "idx_patient_user_id", columnList = "user_id"),
// Directory pagination order, not case-insensitive substring filtering.
@Index(name = "idx_patient_name_id", columnList = "name, id")
})
@Data
@NoArgsConstructor
public class Patient implements MediaEntity {
@Id
@GeneratedValue(strategy = GenerationType.UUID)
@Column(name = "id", nullable = false, updatable = false, columnDefinition = "uuid")
private UUID id;
/**
* Full name of the patient.
*/
@Column(nullable = false)
private String name;
/**
* Date of birth, used to calculate age and check paediatric dosing rules.
*/
@Column(name = "date_of_birth")
private LocalDate dateOfBirth;
/**
* IANA timezone (e.g. Europe/Lisbon) used to convert scheduled UTC times to local display times.
*/
@Column(nullable = false)
private String timezone;
/**
* Soft-delete flag; inactive patients are excluded from dose generation and alerts.
*/
@Column(nullable = false)
private Boolean active = true;
/**
* Contact e-mail, also used as login identifier if the patient has an app account.
*/
// Uniqueness is already declared by idx_patient_email on the table.
@Column
private String email;
/**
* Mobile number for SMS notification delivery.
*/
@Column(name = "phone_number")
private String phoneNumber;
/**
* MALE, FEMALE, OTHER
*/
@Enumerated(EnumType.STRING)
@Column(name = "gender")
private Gender gender;
/**
* Residential address, used for home-delivery or home-visit workflows.
*/
@Column
private String address;
/**
* ABO/Rh blood type (e.g. A+), relevant for clinical decision support.
*/
@Column(name = "blood_type", length = 5)
private String bloodType;
/**
* Name of the person to contact in a medical emergency.
*/
@Column(name = "emergency_contact_name")
private String emergencyContactName;
/**
* Phone number of the emergency contact.
*/
@Column(name = "emergency_contact_phone")
private String emergencyContactPhone;
/**
* Free-text clinical notes visible only to the assigned professional.
*/
@Column(columnDefinition = "text")
private String notes;
/**
* Professional responsible for this patient's care.
*/
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "professional_id")
private Professional professional;
@Column(name = "created_at", nullable = false, updatable = false)
private Instant createdAt;
@Column(name = "updated_at", nullable = false)
private Instant updatedAt;
@Column(name = "user_id", columnDefinition = "uuid")
private UUID userId;
@Column(columnDefinition = "uuid")
private UUID resourceId;
@PrePersist
public void prePersist() {
Instant now = Instant.now();
this.createdAt = now;
this.updatedAt = now;
}
@PreUpdate
public void preUpdate() {
this.updatedAt = Instant.now();
}
}