Skip to content

Feat/medical record repo - #6

Merged
annikaholmqvist94 merged 4 commits into
mainfrom
feat/medical-record-repo
Mar 26, 2026
Merged

Feat/medical record repo#6
annikaholmqvist94 merged 4 commits into
mainfrom
feat/medical-record-repo

Conversation

@annikaholmqvist94

@annikaholmqvist94 annikaholmqvist94 commented Mar 26, 2026

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

  • New Features
    • Added comprehensive medical record management system to track and organize pet medical histories.
    • Medical records are now connected to pets, clinics, owners, and assigned veterinarians for improved coordinated care.
    • Introduced status tracking with four workflow states: Open, In Progress, Awaiting Info, and Closed.

@coderabbitai

coderabbitai Bot commented Mar 26, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

A new medical records feature is introduced, consisting of a JPA entity MedicalRecord with UUID-based persistence, status tracking via enum, timestamp lifecycle management, and relationships to pets, users, and clinics. A supporting repository interface provides derived queries for filtering records across multiple dimensions.

Changes

Cohort / File(s) Summary
Medical Record Entity & Status
src/main/java/org/example/vet1177/entities/MedicalRecord.java, src/main/java/org/example/vet1177/entities/RecordStatus.java
New MedicalRecord entity with UUID primary key, title/description fields, enum-based status tracking, multiple lazy-loaded @ManyToOne relationships (Pet, User, Clinic), and @PrePersist/@PreUpdate lifecycle callbacks for timestamp management. Companion RecordStatus enum with four states: OPEN, IN_PROGRESS, AWAITING_INFO, CLOSED.
Medical Record Repository
src/main/java/org/example/vet1177/repository/MedicalRecordRepository.java
Spring Data JPA repository interface offering derived query methods to retrieve MedicalRecord instances by pet, owner, veterinarian, clinic, and status filters, including a combined clinic-and-status query.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~28 minutes

Poem

🐰 A medical record hops into place,
With timestamps and statuses keeping pace,
Pet, vet, and owner all linked with care,
Queries spring forth from the repository lair,
Health data organized, fair and square! 🏥✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 27.27% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'Feat/medical record repo' accurately describes the main change: adding a new medical record repository and related JPA entity with enum support.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/medical-record-repo

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
src/main/java/org/example/vet1177/entities/MedicalRecord.java (2)

76-77: Avoid public mutation of generated primary key.

Line 77 exposes a public setter for a generated ID. This makes accidental identity mutation possible and can cause persistence-context inconsistencies.

Suggested tightening
 public UUID getId() { return id; }
-    public void setId(UUID id) { this.id = id; }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/org/example/vet1177/entities/MedicalRecord.java` around lines
76 - 77, The class exposes a public setter for the generated primary key (method
setId(UUID) in MedicalRecord), which allows external mutation; remove or tighten
this setter to prevent identity changes — either delete the public setId(UUID)
entirely or change its visibility to protected or package-private so only the
ORM or same-package test code can set it (keep getId() public). Update any tests
or framework usage to rely on the ORM reflection/constructors rather than
calling the public setId(UUID).

51-55: Align timestamp column nullability with required persistence contract.

Line 51 and Line 54 should explicitly declare nullable = false to match required timestamp behavior and tighten schema/entity consistency.

Suggested annotation update
-    `@Column`(name = "created_at", updatable = false)
+    `@Column`(name = "created_at", nullable = false, updatable = false)
     private Instant createdAt;
@@
-    `@Column`(name = "updated_at")
+    `@Column`(name = "updated_at", nullable = false)
     private Instant updatedAt;
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/org/example/vet1177/entities/MedicalRecord.java` around lines
51 - 55, The MedicalRecord entity's timestamp columns lack explicit nullability
which can mismatch the persistence contract; update the `@Column` annotations on
the createdAt and updatedAt fields in class MedicalRecord to include nullable =
false (i.e., `@Column`(name = "created_at", updatable = false, nullable = false)
and `@Column`(name = "updated_at", nullable = false)) so the JPA mapping and DB
schema enforce non-null timestamps.
src/main/java/org/example/vet1177/repository/MedicalRecordRepository.java (1)

15-30: Consider paginated query variants and matching DB indexes for these filters.

Line 15–Line 30 currently expose only unbounded List fetches. For medical records, these result sets can grow quickly and create avoidable memory pressure. Add paginated variants and ensure indexes exist for pet_id, owner_id, assigned_vet_id, clinic_id, and (clinic_id, status).

Suggested repository additions
+import org.springframework.data.domain.Page;
+import org.springframework.data.domain.Pageable;
+
+    Page<MedicalRecord> findByPetId(UUID petId, Pageable pageable);
+    Page<MedicalRecord> findByOwnerId(UUID ownerId, Pageable pageable);
+    Page<MedicalRecord> findByAssignedVetId(UUID vetId, Pageable pageable);
+    Page<MedicalRecord> findByClinicId(UUID clinicId, Pageable pageable);
+    Page<MedicalRecord> findByStatus(RecordStatus status, Pageable pageable);
+    Page<MedicalRecord> findByClinicIdAndStatus(UUID clinicId, RecordStatus status, Pageable pageable);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/org/example/vet1177/repository/MedicalRecordRepository.java`
around lines 15 - 30, Replace the unbounded List fetch methods with or add
paginated overloads that accept Pageable and return Page<MedicalRecord> (e.g.,
add findByPetId(UUID petId, Pageable p) -> Page<MedicalRecord>,
findByOwnerId(UUID ownerId, Pageable p), findByAssignedVetId(UUID vetId,
Pageable p), findByClinicId(UUID clinicId, Pageable p),
findByStatus(RecordStatus status, Pageable p), and findByClinicIdAndStatus(UUID
clinicId, RecordStatus status, Pageable p)); update callers to use paging; and
ensure DB indexes exist on pet_id, owner_id, assigned_vet_id, clinic_id and a
composite index on (clinic_id, status) in the schema/migration so these paged
queries are efficient.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/main/java/org/example/vet1177/entities/MedicalRecord.java`:
- Around line 85-109: MedicalRecord allows inconsistent states between status
and closedAt; update the setters in MedicalRecord to enforce the invariant: in
setStatus(RecordStatus status) if status == RecordStatus.CLOSED ensure closedAt
is non-null (either set closedAt = Instant.now() when currently null or throw
IllegalStateException per project policy), and if changing from CLOSED to any
other status clear closedAt (set to null); in setClosedAt(Instant closedAt) if
closedAt != null set status = RecordStatus.CLOSED (or validate it already is),
and if closedAt == null ensure status != RecordStatus.CLOSED (or change status
accordingly). Apply this logic to any construction/path that mutates these
fields (e.g., constructors or builders) to keep status and closedAt consistent.

---

Nitpick comments:
In `@src/main/java/org/example/vet1177/entities/MedicalRecord.java`:
- Around line 76-77: The class exposes a public setter for the generated primary
key (method setId(UUID) in MedicalRecord), which allows external mutation;
remove or tighten this setter to prevent identity changes — either delete the
public setId(UUID) entirely or change its visibility to protected or
package-private so only the ORM or same-package test code can set it (keep
getId() public). Update any tests or framework usage to rely on the ORM
reflection/constructors rather than calling the public setId(UUID).
- Around line 51-55: The MedicalRecord entity's timestamp columns lack explicit
nullability which can mismatch the persistence contract; update the `@Column`
annotations on the createdAt and updatedAt fields in class MedicalRecord to
include nullable = false (i.e., `@Column`(name = "created_at", updatable = false,
nullable = false) and `@Column`(name = "updated_at", nullable = false)) so the JPA
mapping and DB schema enforce non-null timestamps.

In `@src/main/java/org/example/vet1177/repository/MedicalRecordRepository.java`:
- Around line 15-30: Replace the unbounded List fetch methods with or add
paginated overloads that accept Pageable and return Page<MedicalRecord> (e.g.,
add findByPetId(UUID petId, Pageable p) -> Page<MedicalRecord>,
findByOwnerId(UUID ownerId, Pageable p), findByAssignedVetId(UUID vetId,
Pageable p), findByClinicId(UUID clinicId, Pageable p),
findByStatus(RecordStatus status, Pageable p), and findByClinicIdAndStatus(UUID
clinicId, RecordStatus status, Pageable p)); update callers to use paging; and
ensure DB indexes exist on pet_id, owner_id, assigned_vet_id, clinic_id and a
composite index on (clinic_id, status) in the schema/migration so these paged
queries are efficient.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 02c8b03e-1c6f-4666-bdca-040bdcde5ce0

📥 Commits

Reviewing files that changed from the base of the PR and between ceece24 and 5b08aab.

📒 Files selected for processing (3)
  • src/main/java/org/example/vet1177/entities/MedicalRecord.java
  • src/main/java/org/example/vet1177/entities/RecordStatus.java
  • src/main/java/org/example/vet1177/repository/MedicalRecordRepository.java

Comment on lines +85 to +109
public RecordStatus getStatus() { return status; }
public void setStatus(RecordStatus status) { this.status = status; }

public Pet getPet() { return pet; }
public void setPet(Pet pet) { this.pet = pet; }

public User getOwner() { return owner; }
public void setOwner(User owner) { this.owner = owner; }

public Clinic getClinic() { return clinic; }
public void setClinic(Clinic clinic) { this.clinic = clinic; }

public User getAssignedVet() { return assignedVet; }
public void setAssignedVet(User assignedVet) { this.assignedVet = assignedVet; }

public User getCreatedBy() { return createdBy; }
public void setCreatedBy(User createdBy) { this.createdBy = createdBy; }

public User getUpdatedBy() { return updatedBy; }
public void setUpdatedBy(User updatedBy) { this.updatedBy = updatedBy; }

public Instant getCreatedAt() { return createdAt; }
public Instant getUpdatedAt() { return updatedAt; }
public Instant getClosedAt() { return closedAt; }
public void setClosedAt(Instant closedAt) { this.closedAt = closedAt; }

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Enforce statusclosedAt consistency to prevent invalid record states.

Line 86 and Line 109 allow RecordStatus.CLOSED with closedAt == null (and vice versa), which creates inconsistent medical record states.

Suggested invariant handling in setters
 public RecordStatus getStatus() { return status; }
-    public void setStatus(RecordStatus status) { this.status = status; }
+    public void setStatus(RecordStatus status) {
+        this.status = status;
+        if (status == RecordStatus.CLOSED && this.closedAt == null) {
+            this.closedAt = Instant.now();
+        } else if (status != RecordStatus.CLOSED) {
+            this.closedAt = null;
+        }
+    }
@@
 public Instant getClosedAt() { return closedAt; }
-    public void setClosedAt(Instant closedAt) { this.closedAt = closedAt; }
+    public void setClosedAt(Instant closedAt) {
+        this.closedAt = closedAt;
+        if (closedAt != null) {
+            this.status = RecordStatus.CLOSED;
+        }
+    }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/main/java/org/example/vet1177/entities/MedicalRecord.java` around lines
85 - 109, MedicalRecord allows inconsistent states between status and closedAt;
update the setters in MedicalRecord to enforce the invariant: in
setStatus(RecordStatus status) if status == RecordStatus.CLOSED ensure closedAt
is non-null (either set closedAt = Instant.now() when currently null or throw
IllegalStateException per project policy), and if changing from CLOSED to any
other status clear closedAt (set to null); in setClosedAt(Instant closedAt) if
closedAt != null set status = RecordStatus.CLOSED (or validate it already is),
and if closedAt == null ensure status != RecordStatus.CLOSED (or change status
accordingly). Apply this logic to any construction/path that mutates these
fields (e.g., constructors or builders) to keep status and closedAt consistent.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant