updates for zmanagement x4
All checks were successful
Build Org Backend / build (push) Successful in 17s
All checks were successful
Build Org Backend / build (push) Successful in 17s
This commit is contained in:
@@ -2,17 +2,22 @@ package org.zaine.app.controller;
|
|||||||
|
|
||||||
import io.swagger.v3.oas.annotations.Operation;
|
import io.swagger.v3.oas.annotations.Operation;
|
||||||
import io.swagger.v3.oas.annotations.tags.Tag;
|
import io.swagger.v3.oas.annotations.tags.Tag;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
import org.springframework.http.ResponseEntity;
|
import org.springframework.http.ResponseEntity;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
import org.springframework.web.bind.annotation.PostMapping;
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
import org.springframework.web.bind.annotation.RequestBody;
|
import org.springframework.web.bind.annotation.RequestBody;
|
||||||
import org.springframework.web.bind.annotation.RequestMapping;
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestParam;
|
||||||
import org.springframework.web.bind.annotation.RestController;
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
import org.zaine.app.dto.EveningCheckinRequest;
|
import org.zaine.app.dto.EveningCheckinRequest;
|
||||||
import org.zaine.app.dto.MorningCheckinRequest;
|
import org.zaine.app.dto.MorningCheckinRequest;
|
||||||
import org.zaine.app.dto.TodayStatusDTO;
|
import org.zaine.app.dto.TodayStatusDTO;
|
||||||
import org.zaine.app.service.CheckinService;
|
import org.zaine.app.service.CheckinService;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/checkin")
|
@RequestMapping("/api/checkin")
|
||||||
@Tag(name = "Check-in", description = "Daily morning and evening check-ins")
|
@Tag(name = "Check-in", description = "Daily morning and evening check-ins")
|
||||||
@@ -30,6 +35,14 @@ public class CheckinController {
|
|||||||
return checkinService.getTodayStatus();
|
return checkinService.getTodayStatus();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Operation(summary = "Get check-in history")
|
||||||
|
@GetMapping("/history")
|
||||||
|
public List<TodayStatusDTO> 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")
|
@Operation(summary = "Submit morning check-in")
|
||||||
@PostMapping("/morning")
|
@PostMapping("/morning")
|
||||||
public ResponseEntity<TodayStatusDTO> submitMorning(@RequestBody MorningCheckinRequest request) {
|
public ResponseEntity<TodayStatusDTO> submitMorning(@RequestBody MorningCheckinRequest request) {
|
||||||
|
|||||||
@@ -6,6 +6,9 @@ public record EveningCheckinRequest(
|
|||||||
LocalDate date,
|
LocalDate date,
|
||||||
Integer mood,
|
Integer mood,
|
||||||
Integer stressLevel,
|
Integer stressLevel,
|
||||||
|
Boolean duties,
|
||||||
|
Boolean zikr,
|
||||||
|
Boolean salah,
|
||||||
String reflection,
|
String reflection,
|
||||||
String bestThingToday) {
|
String bestThingToday) {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,5 +8,8 @@ public record MorningCheckinRequest(
|
|||||||
BigDecimal sleepHours,
|
BigDecimal sleepHours,
|
||||||
Integer energyLevel,
|
Integer energyLevel,
|
||||||
Integer mood,
|
Integer mood,
|
||||||
|
Boolean fajr,
|
||||||
|
Boolean quran,
|
||||||
|
Boolean exercise,
|
||||||
String note) {
|
String note) {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,13 @@ public record TodayStatusDTO(
|
|||||||
Integer morningMoodLevel,
|
Integer morningMoodLevel,
|
||||||
Integer eveningMoodLevel,
|
Integer eveningMoodLevel,
|
||||||
Integer stressLevel,
|
Integer stressLevel,
|
||||||
|
Boolean fajr,
|
||||||
|
Boolean quran,
|
||||||
|
Boolean exercise,
|
||||||
|
Boolean duties,
|
||||||
|
Boolean zikr,
|
||||||
|
Boolean salah,
|
||||||
|
String reflection,
|
||||||
OffsetDateTime morningCompletedAt,
|
OffsetDateTime morningCompletedAt,
|
||||||
OffsetDateTime eveningCompletedAt) {
|
OffsetDateTime eveningCompletedAt) {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,6 +36,15 @@ public class DailyCheckin {
|
|||||||
@Column(name = "morning_note")
|
@Column(name = "morning_note")
|
||||||
private String morningNote;
|
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")
|
@Column(name = "morning_completed_at")
|
||||||
private OffsetDateTime morningCompletedAt;
|
private OffsetDateTime morningCompletedAt;
|
||||||
|
|
||||||
@@ -51,6 +60,15 @@ public class DailyCheckin {
|
|||||||
@Column(name = "best_thing_today")
|
@Column(name = "best_thing_today")
|
||||||
private String bestThingToday;
|
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")
|
@Column(name = "evening_completed_at")
|
||||||
private OffsetDateTime eveningCompletedAt;
|
private OffsetDateTime eveningCompletedAt;
|
||||||
|
|
||||||
@@ -83,6 +101,12 @@ public class DailyCheckin {
|
|||||||
public void setMorningMoodLevel(Integer morningMoodLevel) { this.morningMoodLevel = morningMoodLevel; }
|
public void setMorningMoodLevel(Integer morningMoodLevel) { this.morningMoodLevel = morningMoodLevel; }
|
||||||
public String getMorningNote() { return morningNote; }
|
public String getMorningNote() { return morningNote; }
|
||||||
public void setMorningNote(String morningNote) { this.morningNote = 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 OffsetDateTime getMorningCompletedAt() { return morningCompletedAt; }
|
||||||
public void setMorningCompletedAt(OffsetDateTime morningCompletedAt) { this.morningCompletedAt = morningCompletedAt; }
|
public void setMorningCompletedAt(OffsetDateTime morningCompletedAt) { this.morningCompletedAt = morningCompletedAt; }
|
||||||
public Integer getEveningMoodLevel() { return eveningMoodLevel; }
|
public Integer getEveningMoodLevel() { return eveningMoodLevel; }
|
||||||
@@ -93,6 +117,12 @@ public class DailyCheckin {
|
|||||||
public void setReflection(String reflection) { this.reflection = reflection; }
|
public void setReflection(String reflection) { this.reflection = reflection; }
|
||||||
public String getBestThingToday() { return bestThingToday; }
|
public String getBestThingToday() { return bestThingToday; }
|
||||||
public void setBestThingToday(String bestThingToday) { this.bestThingToday = 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 OffsetDateTime getEveningCompletedAt() { return eveningCompletedAt; }
|
||||||
public void setEveningCompletedAt(OffsetDateTime eveningCompletedAt) { this.eveningCompletedAt = eveningCompletedAt; }
|
public void setEveningCompletedAt(OffsetDateTime eveningCompletedAt) { this.eveningCompletedAt = eveningCompletedAt; }
|
||||||
public OffsetDateTime getCreatedAt() { return createdAt; }
|
public OffsetDateTime getCreatedAt() { return createdAt; }
|
||||||
|
|||||||
@@ -4,8 +4,10 @@ import org.springframework.data.jpa.repository.JpaRepository;
|
|||||||
import org.zaine.app.model.DailyCheckin;
|
import org.zaine.app.model.DailyCheckin;
|
||||||
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public interface DailyCheckinRepository extends JpaRepository<DailyCheckin, Long> {
|
public interface DailyCheckinRepository extends JpaRepository<DailyCheckin, Long> {
|
||||||
Optional<DailyCheckin> findByDate(LocalDate date);
|
Optional<DailyCheckin> findByDate(LocalDate date);
|
||||||
|
List<DailyCheckin> findByDateBetweenOrderByDateDesc(LocalDate from, LocalDate to);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import org.zaine.app.repositories.DailyCheckinRepository;
|
|||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
import java.time.OffsetDateTime;
|
import java.time.OffsetDateTime;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class CheckinService {
|
public class CheckinService {
|
||||||
@@ -26,16 +27,27 @@ public class CheckinService {
|
|||||||
return toStatus(getOrCreate(LocalDate.now()));
|
return toStatus(getOrCreate(LocalDate.now()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<TodayStatusDTO> 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) {
|
public TodayStatusDTO saveMorning(MorningCheckinRequest request) {
|
||||||
LocalDate date = request.date() == null ? LocalDate.now() : request.date();
|
LocalDate date = request.date() == null ? LocalDate.now() : request.date();
|
||||||
validateScore(request.energyLevel(), "energyLevel");
|
|
||||||
validateScore(request.mood(), "mood");
|
|
||||||
validateSleepHours(request.sleepHours());
|
validateSleepHours(request.sleepHours());
|
||||||
|
|
||||||
DailyCheckin checkin = getOrCreate(date);
|
DailyCheckin checkin = getOrCreate(date);
|
||||||
checkin.setSleepHours(request.sleepHours());
|
checkin.setSleepHours(request.sleepHours());
|
||||||
checkin.setMorningEnergyLevel(request.energyLevel());
|
checkin.setMorningEnergyLevel(request.energyLevel());
|
||||||
checkin.setMorningMoodLevel(request.mood());
|
checkin.setMorningMoodLevel(request.mood());
|
||||||
|
checkin.setFajr(request.fajr());
|
||||||
|
checkin.setQuran(request.quran());
|
||||||
|
checkin.setExercise(request.exercise());
|
||||||
checkin.setMorningNote(blankToNull(request.note()));
|
checkin.setMorningNote(blankToNull(request.note()));
|
||||||
checkin.setMorningCompletedAt(OffsetDateTime.now());
|
checkin.setMorningCompletedAt(OffsetDateTime.now());
|
||||||
|
|
||||||
@@ -44,12 +56,13 @@ public class CheckinService {
|
|||||||
|
|
||||||
public TodayStatusDTO saveEvening(EveningCheckinRequest request) {
|
public TodayStatusDTO saveEvening(EveningCheckinRequest request) {
|
||||||
LocalDate date = request.date() == null ? LocalDate.now() : request.date();
|
LocalDate date = request.date() == null ? LocalDate.now() : request.date();
|
||||||
validateScore(request.mood(), "mood");
|
|
||||||
validateScore(request.stressLevel(), "stressLevel");
|
|
||||||
|
|
||||||
DailyCheckin checkin = getOrCreate(date);
|
DailyCheckin checkin = getOrCreate(date);
|
||||||
checkin.setEveningMoodLevel(request.mood());
|
checkin.setEveningMoodLevel(request.mood());
|
||||||
checkin.setStressLevel(request.stressLevel());
|
checkin.setStressLevel(request.stressLevel());
|
||||||
|
checkin.setDuties(request.duties());
|
||||||
|
checkin.setZikr(request.zikr());
|
||||||
|
checkin.setSalah(request.salah());
|
||||||
checkin.setReflection(blankToNull(request.reflection()));
|
checkin.setReflection(blankToNull(request.reflection()));
|
||||||
checkin.setBestThingToday(blankToNull(request.bestThingToday()));
|
checkin.setBestThingToday(blankToNull(request.bestThingToday()));
|
||||||
checkin.setEveningCompletedAt(OffsetDateTime.now());
|
checkin.setEveningCompletedAt(OffsetDateTime.now());
|
||||||
@@ -75,16 +88,17 @@ public class CheckinService {
|
|||||||
checkin.getMorningMoodLevel(),
|
checkin.getMorningMoodLevel(),
|
||||||
checkin.getEveningMoodLevel(),
|
checkin.getEveningMoodLevel(),
|
||||||
checkin.getStressLevel(),
|
checkin.getStressLevel(),
|
||||||
|
checkin.getFajr(),
|
||||||
|
checkin.getQuran(),
|
||||||
|
checkin.getExercise(),
|
||||||
|
checkin.getDuties(),
|
||||||
|
checkin.getZikr(),
|
||||||
|
checkin.getSalah(),
|
||||||
|
checkin.getReflection(),
|
||||||
checkin.getMorningCompletedAt(),
|
checkin.getMorningCompletedAt(),
|
||||||
checkin.getEveningCompletedAt());
|
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) {
|
private void validateSleepHours(BigDecimal sleepHours) {
|
||||||
if (sleepHours == null || sleepHours.compareTo(BigDecimal.ZERO) < 0 || sleepHours.compareTo(new BigDecimal("24")) > 0) {
|
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");
|
throw new ResponseStatusException(HttpStatus.BAD_REQUEST, "sleepHours must be between 0 and 24");
|
||||||
|
|||||||
@@ -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;
|
||||||
Reference in New Issue
Block a user