diff --git a/pom.xml b/pom.xml index e24a531..9b52e9c 100644 --- a/pom.xml +++ b/pom.xml @@ -84,7 +84,6 @@ org.projectlombok lombok - annotationProcessor org.springframework.security @@ -108,6 +107,18 @@ + + org.apache.maven.plugins + maven-compiler-plugin + + + + org.projectlombok + lombok + + + + org.springframework.boot spring-boot-maven-plugin diff --git a/src/main/java/org/example/projektarendehantering/application/service/CaseMapper.java b/src/main/java/org/example/projektarendehantering/application/service/CaseMapper.java index 80128e9..2a32d4a 100644 --- a/src/main/java/org/example/projektarendehantering/application/service/CaseMapper.java +++ b/src/main/java/org/example/projektarendehantering/application/service/CaseMapper.java @@ -4,12 +4,20 @@ import org.example.projektarendehantering.presentation.dto.CaseDTO; import org.springframework.stereotype.Component; +import java.util.stream.Collectors; + @Component public class CaseMapper { + private final CaseNoteMapper caseNoteMapper; + + public CaseMapper(CaseNoteMapper caseNoteMapper) { + this.caseNoteMapper = caseNoteMapper; + } + public CaseDTO toDTO(CaseEntity entity) { if (entity == null) return null; - return new CaseDTO( + CaseDTO dto = new CaseDTO( entity.getId(), entity.getStatus(), entity.getTitle(), @@ -17,6 +25,12 @@ public CaseDTO toDTO(CaseEntity entity) { entity.getCreatedAt(), entity.getPatient() != null ? entity.getPatient().getId() : null ); + if (entity.getNotes() != null) { + dto.setNotes(entity.getNotes().stream() + .map(caseNoteMapper::toDTO) + .collect(Collectors.toList())); + } + return dto; } public CaseEntity toEntity(CaseDTO dto) { diff --git a/src/main/java/org/example/projektarendehantering/application/service/CaseNoteMapper.java b/src/main/java/org/example/projektarendehantering/application/service/CaseNoteMapper.java new file mode 100644 index 0000000..a6a8f41 --- /dev/null +++ b/src/main/java/org/example/projektarendehantering/application/service/CaseNoteMapper.java @@ -0,0 +1,29 @@ +package org.example.projektarendehantering.application.service; + +import org.example.projektarendehantering.infrastructure.persistence.CaseNoteEntity; +import org.example.projektarendehantering.presentation.dto.CaseNoteDTO; +import org.springframework.stereotype.Component; + +@Component +public class CaseNoteMapper { + + public CaseNoteDTO toDTO(CaseNoteEntity entity) { + if (entity == null) return null; + return new CaseNoteDTO( + entity.getId(), + entity.getContent(), + entity.getAuthor(), + entity.getCreatedAt() + ); + } + + public CaseNoteEntity toEntity(CaseNoteDTO dto) { + if (dto == null) return null; + CaseNoteEntity entity = new CaseNoteEntity(); + entity.setId(dto.getId()); + entity.setContent(dto.getContent()); + entity.setAuthor(dto.getAuthor()); + entity.setCreatedAt(dto.getCreatedAt()); + return entity; + } +} diff --git a/src/main/java/org/example/projektarendehantering/application/service/CaseService.java b/src/main/java/org/example/projektarendehantering/application/service/CaseService.java index 37f428b..6b5c11c 100644 --- a/src/main/java/org/example/projektarendehantering/application/service/CaseService.java +++ b/src/main/java/org/example/projektarendehantering/application/service/CaseService.java @@ -4,6 +4,8 @@ import org.example.projektarendehantering.common.NotAuthorizedException; import org.example.projektarendehantering.common.Role; import org.example.projektarendehantering.infrastructure.persistence.CaseEntity; +import org.example.projektarendehantering.infrastructure.persistence.CaseNoteEntity; +import org.example.projektarendehantering.infrastructure.persistence.CaseNoteRepository; import org.example.projektarendehantering.infrastructure.persistence.CaseRepository; import org.example.projektarendehantering.infrastructure.persistence.EmployeeEntity; import org.example.projektarendehantering.infrastructure.persistence.EmployeeRepository; @@ -29,20 +31,31 @@ public class CaseService { private final CaseRepository caseRepository; private final CaseMapper caseMapper; private final PatientRepository patientRepository; + private final CaseNoteRepository caseNoteRepository; private final EmployeeRepository employeeRepository; - public CaseService( - CaseRepository caseRepository, - CaseMapper caseMapper, - PatientRepository patientRepository, - EmployeeRepository employeeRepository - ) { + public CaseService(CaseRepository caseRepository, CaseMapper caseMapper, PatientRepository patientRepository, CaseNoteRepository caseNoteRepository, EmployeeRepository employeeRepository) { this.caseRepository = caseRepository; this.caseMapper = caseMapper; this.patientRepository = patientRepository; + this.caseNoteRepository = caseNoteRepository; this.employeeRepository = employeeRepository; } + @Transactional + public void addNote(UUID caseId, String content, String author) { + CaseEntity caseEntity = caseRepository.findById(caseId) + .orElseThrow(() -> new ResponseStatusException(HttpStatus.NOT_FOUND, "Case not found")); + + CaseNoteEntity note = new CaseNoteEntity(); + note.setCaseEntity(caseEntity); + note.setContent(content); + note.setAuthor(author); + note.setCreatedAt(Instant.now()); + + caseNoteRepository.save(note); + } + @Transactional public CaseDTO createCase(Actor actor, CaseDTO caseDTO) { if (!canCreate(actor)) { diff --git a/src/main/java/org/example/projektarendehantering/infrastructure/persistence/CaseEntity.java b/src/main/java/org/example/projektarendehantering/infrastructure/persistence/CaseEntity.java index d90cab0..d423460 100644 --- a/src/main/java/org/example/projektarendehantering/infrastructure/persistence/CaseEntity.java +++ b/src/main/java/org/example/projektarendehantering/infrastructure/persistence/CaseEntity.java @@ -2,6 +2,8 @@ import jakarta.persistence.*; import java.time.Instant; +import java.util.ArrayList; +import java.util.List; import java.util.UUID; @Entity @@ -23,9 +25,13 @@ public class CaseEntity { @JoinColumn(name = "patient_id", nullable = true) // Optional because the patient can be null private PatientEntity patient; + @OneToMany(mappedBy = "caseEntity", cascade = CascadeType.ALL, orphanRemoval = true) + @OrderBy("createdAt DESC") + private List notes = new ArrayList<>(); + public CaseEntity() {} - public CaseEntity(UUID id, String status, UUID ownerId, String title, String description, Instant createdAt, PatientEntity patient) { + public CaseEntity(UUID id, String status, UUID ownerId, String title, String description, Instant createdAt, PatientEntity patient, List notes) { this.id = id; this.status = status; this.ownerId = ownerId; @@ -33,6 +39,7 @@ public CaseEntity(UUID id, String status, UUID ownerId, String title, String des this.description = description; this.createdAt = createdAt; this.patient = patient; + this.notes = notes != null ? notes : new ArrayList<>(); } public UUID getId() { return id; } @@ -61,4 +68,7 @@ public CaseEntity(UUID id, String status, UUID ownerId, String title, String des public PatientEntity getPatient() { return patient; } public void setPatient(PatientEntity patient) { this.patient = patient; } + + public List getNotes() { return notes; } + } diff --git a/src/main/java/org/example/projektarendehantering/infrastructure/persistence/CaseNoteEntity.java b/src/main/java/org/example/projektarendehantering/infrastructure/persistence/CaseNoteEntity.java new file mode 100644 index 0000000..1eac7a2 --- /dev/null +++ b/src/main/java/org/example/projektarendehantering/infrastructure/persistence/CaseNoteEntity.java @@ -0,0 +1,35 @@ +package org.example.projektarendehantering.infrastructure.persistence; + +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; + +import java.time.Instant; +import java.util.UUID; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Entity +@Table(name = "case_notes") +public class CaseNoteEntity { + + @Id + @GeneratedValue(strategy = GenerationType.UUID) + private UUID id; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "case_id") + private CaseEntity caseEntity; + + private String content; + + private String author; + + private Instant createdAt; + + +} diff --git a/src/main/java/org/example/projektarendehantering/infrastructure/persistence/CaseNoteRepository.java b/src/main/java/org/example/projektarendehantering/infrastructure/persistence/CaseNoteRepository.java new file mode 100644 index 0000000..b443d74 --- /dev/null +++ b/src/main/java/org/example/projektarendehantering/infrastructure/persistence/CaseNoteRepository.java @@ -0,0 +1,10 @@ +package org.example.projektarendehantering.infrastructure.persistence; + +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.UUID; + +@Repository +public interface CaseNoteRepository extends JpaRepository { +} diff --git a/src/main/java/org/example/projektarendehantering/presentation/dto/CaseDTO.java b/src/main/java/org/example/projektarendehantering/presentation/dto/CaseDTO.java index e0c306e..9ecfed4 100644 --- a/src/main/java/org/example/projektarendehantering/presentation/dto/CaseDTO.java +++ b/src/main/java/org/example/projektarendehantering/presentation/dto/CaseDTO.java @@ -1,8 +1,8 @@ package org.example.projektarendehantering.presentation.dto; -import jakarta.validation.constraints.NotNull; - import java.time.Instant; +import java.util.ArrayList; +import java.util.List; import java.util.UUID; public class CaseDTO { @@ -12,9 +12,8 @@ public class CaseDTO { private String title; private String description; private Instant createdAt; - - @NotNull private UUID patientId; + private List notes = new ArrayList<>(); public CaseDTO() {} @@ -44,4 +43,7 @@ public CaseDTO(UUID id, String status, String title, String description, Instant public UUID getPatientId() { return patientId; } public void setPatientId(UUID patientId) { this.patientId = patientId; } + + public List getNotes() { return notes; } + public void setNotes(List notes) { this.notes = notes; } } diff --git a/src/main/java/org/example/projektarendehantering/presentation/dto/CaseNoteDTO.java b/src/main/java/org/example/projektarendehantering/presentation/dto/CaseNoteDTO.java new file mode 100644 index 0000000..2f5660c --- /dev/null +++ b/src/main/java/org/example/projektarendehantering/presentation/dto/CaseNoteDTO.java @@ -0,0 +1,33 @@ +package org.example.projektarendehantering.presentation.dto; + +import java.time.Instant; +import java.util.UUID; + +public class CaseNoteDTO { + + private UUID id; + private String content; + private String author; + private Instant createdAt; + + public CaseNoteDTO() {} + + public CaseNoteDTO(UUID id, String content, String author, Instant createdAt) { + this.id = id; + this.content = content; + this.author = author; + this.createdAt = createdAt; + } + + public UUID getId() { return id; } + public void setId(UUID id) { this.id = id; } + + public String getContent() { return content; } + public void setContent(String content) { this.content = content; } + + public String getAuthor() { return author; } + public void setAuthor(String author) { this.author = author; } + + public Instant getCreatedAt() { return createdAt; } + public void setCreatedAt(Instant createdAt) { this.createdAt = createdAt; } +} diff --git a/src/main/java/org/example/projektarendehantering/presentation/web/UiController.java b/src/main/java/org/example/projektarendehantering/presentation/web/UiController.java index 2a65746..611e38f 100644 --- a/src/main/java/org/example/projektarendehantering/presentation/web/UiController.java +++ b/src/main/java/org/example/projektarendehantering/presentation/web/UiController.java @@ -12,8 +12,10 @@ import org.springframework.web.bind.annotation.ModelAttribute; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestParam; import jakarta.validation.Valid; +import java.security.Principal; import java.util.UUID; @Controller @@ -29,6 +31,13 @@ public UiController(CaseService caseService, PatientService patientService, Head this.currentUserAdapter = currentUserAdapter; } + @PostMapping("/ui/cases/{caseId}/notes") + public String addNote(@PathVariable UUID caseId, @RequestParam("content") String content, Principal principal) { + String author = principal != null ? principal.getName() : "Anonymous"; + caseService.addNote(caseId, content, author); + return "redirect:/ui/cases/" + caseId; + } + @GetMapping("/") public String index() { return "index"; diff --git a/src/main/resources/templates/cases/detail.html b/src/main/resources/templates/cases/detail.html index 1179be7..7968275 100644 --- a/src/main/resources/templates/cases/detail.html +++ b/src/main/resources/templates/cases/detail.html @@ -25,6 +25,30 @@

Case

Date
+ +
+

Notes

+
+

Note content

+
+ Author - + Date +
+
+

No notes yet.

+ +
+ +

Add Note

+
+ +
+ +
+
+

Error

Case not found.