From 4bf78102069b91ee1ecaf2c66626ee07d5b347e0 Mon Sep 17 00:00:00 2001 From: Zaine Date: Wed, 10 Jun 2026 16:40:53 +0100 Subject: [PATCH] updates for zmanagement x4 --- .../app/controller/CheckinController.java | 13 +++++++ .../zaine/app/dto/EveningCheckinRequest.java | 3 ++ .../zaine/app/dto/MorningCheckinRequest.java | 3 ++ .../org/zaine/app/dto/TodayStatusDTO.java | 7 ++++ .../org/zaine/app/model/DailyCheckin.java | 30 ++++++++++++++++ .../repositories/DailyCheckinRepository.java | 2 ++ .../org/zaine/app/service/CheckinService.java | 34 +++++++++++++------ .../V4__daily_checkin_practice_fields.sql | 7 ++++ 8 files changed, 89 insertions(+), 10 deletions(-) create mode 100644 src/main/resources/db/migration/V4__daily_checkin_practice_fields.sql diff --git a/src/main/java/org/zaine/app/controller/CheckinController.java b/src/main/java/org/zaine/app/controller/CheckinController.java index 1768a93..5db4c86 100644 --- a/src/main/java/org/zaine/app/controller/CheckinController.java +++ b/src/main/java/org/zaine/app/controller/CheckinController.java @@ -2,17 +2,22 @@ package org.zaine.app.controller; import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.tags.Tag; +import org.springframework.format.annotation.DateTimeFormat; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import org.zaine.app.dto.EveningCheckinRequest; import org.zaine.app.dto.MorningCheckinRequest; import org.zaine.app.dto.TodayStatusDTO; import org.zaine.app.service.CheckinService; +import java.time.LocalDate; +import java.util.List; + @RestController @RequestMapping("/api/checkin") @Tag(name = "Check-in", description = "Daily morning and evening check-ins") @@ -30,6 +35,14 @@ public class CheckinController { return checkinService.getTodayStatus(); } + @Operation(summary = "Get check-in history") + @GetMapping("/history") + public List getHistory( + @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate from, + @RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate to) { + return checkinService.getHistory(from, to); + } + @Operation(summary = "Submit morning check-in") @PostMapping("/morning") public ResponseEntity submitMorning(@RequestBody MorningCheckinRequest request) { diff --git a/src/main/java/org/zaine/app/dto/EveningCheckinRequest.java b/src/main/java/org/zaine/app/dto/EveningCheckinRequest.java index df121db..291f7de 100644 --- a/src/main/java/org/zaine/app/dto/EveningCheckinRequest.java +++ b/src/main/java/org/zaine/app/dto/EveningCheckinRequest.java @@ -6,6 +6,9 @@ public record EveningCheckinRequest( LocalDate date, Integer mood, Integer stressLevel, + Boolean duties, + Boolean zikr, + Boolean salah, String reflection, String bestThingToday) { } diff --git a/src/main/java/org/zaine/app/dto/MorningCheckinRequest.java b/src/main/java/org/zaine/app/dto/MorningCheckinRequest.java index 5f19e5e..5c12a6e 100644 --- a/src/main/java/org/zaine/app/dto/MorningCheckinRequest.java +++ b/src/main/java/org/zaine/app/dto/MorningCheckinRequest.java @@ -8,5 +8,8 @@ public record MorningCheckinRequest( BigDecimal sleepHours, Integer energyLevel, Integer mood, + Boolean fajr, + Boolean quran, + Boolean exercise, String note) { } diff --git a/src/main/java/org/zaine/app/dto/TodayStatusDTO.java b/src/main/java/org/zaine/app/dto/TodayStatusDTO.java index 24fe5f5..8765817 100644 --- a/src/main/java/org/zaine/app/dto/TodayStatusDTO.java +++ b/src/main/java/org/zaine/app/dto/TodayStatusDTO.java @@ -13,6 +13,13 @@ public record TodayStatusDTO( Integer morningMoodLevel, Integer eveningMoodLevel, Integer stressLevel, + Boolean fajr, + Boolean quran, + Boolean exercise, + Boolean duties, + Boolean zikr, + Boolean salah, + String reflection, OffsetDateTime morningCompletedAt, OffsetDateTime eveningCompletedAt) { } diff --git a/src/main/java/org/zaine/app/model/DailyCheckin.java b/src/main/java/org/zaine/app/model/DailyCheckin.java index 813ad16..149f2de 100644 --- a/src/main/java/org/zaine/app/model/DailyCheckin.java +++ b/src/main/java/org/zaine/app/model/DailyCheckin.java @@ -36,6 +36,15 @@ public class DailyCheckin { @Column(name = "morning_note") private String morningNote; + @Column(name = "fajr") + private Boolean fajr; + + @Column(name = "quran") + private Boolean quran; + + @Column(name = "exercise") + private Boolean exercise; + @Column(name = "morning_completed_at") private OffsetDateTime morningCompletedAt; @@ -51,6 +60,15 @@ public class DailyCheckin { @Column(name = "best_thing_today") private String bestThingToday; + @Column(name = "duties") + private Boolean duties; + + @Column(name = "zikr") + private Boolean zikr; + + @Column(name = "salah") + private Boolean salah; + @Column(name = "evening_completed_at") private OffsetDateTime eveningCompletedAt; @@ -83,6 +101,12 @@ public class DailyCheckin { public void setMorningMoodLevel(Integer morningMoodLevel) { this.morningMoodLevel = morningMoodLevel; } public String getMorningNote() { return morningNote; } public void setMorningNote(String morningNote) { this.morningNote = morningNote; } + public Boolean getFajr() { return fajr; } + public void setFajr(Boolean fajr) { this.fajr = fajr; } + public Boolean getQuran() { return quran; } + public void setQuran(Boolean quran) { this.quran = quran; } + public Boolean getExercise() { return exercise; } + public void setExercise(Boolean exercise) { this.exercise = exercise; } public OffsetDateTime getMorningCompletedAt() { return morningCompletedAt; } public void setMorningCompletedAt(OffsetDateTime morningCompletedAt) { this.morningCompletedAt = morningCompletedAt; } public Integer getEveningMoodLevel() { return eveningMoodLevel; } @@ -93,6 +117,12 @@ public class DailyCheckin { public void setReflection(String reflection) { this.reflection = reflection; } public String getBestThingToday() { return bestThingToday; } public void setBestThingToday(String bestThingToday) { this.bestThingToday = bestThingToday; } + public Boolean getDuties() { return duties; } + public void setDuties(Boolean duties) { this.duties = duties; } + public Boolean getZikr() { return zikr; } + public void setZikr(Boolean zikr) { this.zikr = zikr; } + public Boolean getSalah() { return salah; } + public void setSalah(Boolean salah) { this.salah = salah; } public OffsetDateTime getEveningCompletedAt() { return eveningCompletedAt; } public void setEveningCompletedAt(OffsetDateTime eveningCompletedAt) { this.eveningCompletedAt = eveningCompletedAt; } public OffsetDateTime getCreatedAt() { return createdAt; } diff --git a/src/main/java/org/zaine/app/repositories/DailyCheckinRepository.java b/src/main/java/org/zaine/app/repositories/DailyCheckinRepository.java index 90be9f3..daac2e7 100644 --- a/src/main/java/org/zaine/app/repositories/DailyCheckinRepository.java +++ b/src/main/java/org/zaine/app/repositories/DailyCheckinRepository.java @@ -4,8 +4,10 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.zaine.app.model.DailyCheckin; import java.time.LocalDate; +import java.util.List; import java.util.Optional; public interface DailyCheckinRepository extends JpaRepository { Optional findByDate(LocalDate date); + List findByDateBetweenOrderByDateDesc(LocalDate from, LocalDate to); } diff --git a/src/main/java/org/zaine/app/service/CheckinService.java b/src/main/java/org/zaine/app/service/CheckinService.java index d57157e..d48ff0d 100644 --- a/src/main/java/org/zaine/app/service/CheckinService.java +++ b/src/main/java/org/zaine/app/service/CheckinService.java @@ -12,6 +12,7 @@ import org.zaine.app.repositories.DailyCheckinRepository; import java.math.BigDecimal; import java.time.LocalDate; import java.time.OffsetDateTime; +import java.util.List; @Service public class CheckinService { @@ -26,16 +27,27 @@ public class CheckinService { return toStatus(getOrCreate(LocalDate.now())); } + public List getHistory(LocalDate from, LocalDate to) { + if (to.isBefore(from)) { + throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "to must be on or after from"); + } + return dailyCheckinRepository.findByDateBetweenOrderByDateDesc(from, to) + .stream() + .map(this::toStatus) + .toList(); + } + public TodayStatusDTO saveMorning(MorningCheckinRequest request) { LocalDate date = request.date() == null ? LocalDate.now() : request.date(); - validateScore(request.energyLevel(), "energyLevel"); - validateScore(request.mood(), "mood"); validateSleepHours(request.sleepHours()); DailyCheckin checkin = getOrCreate(date); checkin.setSleepHours(request.sleepHours()); checkin.setMorningEnergyLevel(request.energyLevel()); checkin.setMorningMoodLevel(request.mood()); + checkin.setFajr(request.fajr()); + checkin.setQuran(request.quran()); + checkin.setExercise(request.exercise()); checkin.setMorningNote(blankToNull(request.note())); checkin.setMorningCompletedAt(OffsetDateTime.now()); @@ -44,12 +56,13 @@ public class CheckinService { public TodayStatusDTO saveEvening(EveningCheckinRequest request) { LocalDate date = request.date() == null ? LocalDate.now() : request.date(); - validateScore(request.mood(), "mood"); - validateScore(request.stressLevel(), "stressLevel"); DailyCheckin checkin = getOrCreate(date); checkin.setEveningMoodLevel(request.mood()); checkin.setStressLevel(request.stressLevel()); + checkin.setDuties(request.duties()); + checkin.setZikr(request.zikr()); + checkin.setSalah(request.salah()); checkin.setReflection(blankToNull(request.reflection())); checkin.setBestThingToday(blankToNull(request.bestThingToday())); checkin.setEveningCompletedAt(OffsetDateTime.now()); @@ -75,16 +88,17 @@ public class CheckinService { checkin.getMorningMoodLevel(), checkin.getEveningMoodLevel(), checkin.getStressLevel(), + checkin.getFajr(), + checkin.getQuran(), + checkin.getExercise(), + checkin.getDuties(), + checkin.getZikr(), + checkin.getSalah(), + checkin.getReflection(), checkin.getMorningCompletedAt(), checkin.getEveningCompletedAt()); } - private void validateScore(Integer value, String fieldName) { - if (value == null || value < 1 || value > 10) { - throw new ResponseStatusException(HttpStatus.BAD_REQUEST, fieldName + " must be between 1 and 10"); - } - } - private void validateSleepHours(BigDecimal sleepHours) { if (sleepHours == null || sleepHours.compareTo(BigDecimal.ZERO) < 0 || sleepHours.compareTo(new BigDecimal("24")) > 0) { throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "sleepHours must be between 0 and 24"); diff --git a/src/main/resources/db/migration/V4__daily_checkin_practice_fields.sql b/src/main/resources/db/migration/V4__daily_checkin_practice_fields.sql new file mode 100644 index 0000000..ebac15e --- /dev/null +++ b/src/main/resources/db/migration/V4__daily_checkin_practice_fields.sql @@ -0,0 +1,7 @@ +ALTER TABLE daily_checkins + ADD COLUMN IF NOT EXISTS fajr BOOLEAN, + ADD COLUMN IF NOT EXISTS quran BOOLEAN, + ADD COLUMN IF NOT EXISTS exercise BOOLEAN, + ADD COLUMN IF NOT EXISTS duties BOOLEAN, + ADD COLUMN IF NOT EXISTS zikr BOOLEAN, + ADD COLUMN IF NOT EXISTS salah BOOLEAN;