updating
This commit is contained in:
@@ -1,7 +1,5 @@
|
|||||||
package org.zaine.app.controller;
|
package org.zaine.app.controller;
|
||||||
import java.lang.System.Logger;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
import org.zaine.app.dto.CompetenciesDTO;
|
import org.zaine.app.dto.CompetenciesDTO;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.web.bind.annotation.GetMapping;
|
import org.springframework.web.bind.annotation.GetMapping;
|
||||||
@@ -17,7 +15,7 @@ import org.zaine.app.service.CompetenciesService;
|
|||||||
@RestController
|
@RestController
|
||||||
@RequestMapping("/api/competencies")
|
@RequestMapping("/api/competencies")
|
||||||
public class CompetenciesController {
|
public class CompetenciesController {
|
||||||
private static final Logger logger = System.getLogger(CompetenciesController.class.getName());
|
//private static final Logger logger = System.getLogger(CompetenciesController.class.getName());
|
||||||
|
|
||||||
@Autowired
|
@Autowired
|
||||||
private CompetenciesService competenciesService;
|
private CompetenciesService competenciesService;
|
||||||
|
|||||||
78
src/main/java/org/zaine/app/controller/WirdController.java
Normal file
78
src/main/java/org/zaine/app/controller/WirdController.java
Normal file
@@ -0,0 +1,78 @@
|
|||||||
|
package org.zaine.app.controller;
|
||||||
|
|
||||||
|
import java.lang.System.Logger;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.format.annotation.DateTimeFormat;
|
||||||
|
import org.springframework.http.ResponseEntity;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.zaine.app.dto.WirdEntryDTO;
|
||||||
|
import org.zaine.app.model.WirdEntry;
|
||||||
|
import org.zaine.app.service.WirdService;
|
||||||
|
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/wird")
|
||||||
|
public class WirdController {
|
||||||
|
|
||||||
|
private static final Logger logger = System.getLogger(WirdController.class.getName());
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private WirdService wirdService;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GET /api/wird/entries
|
||||||
|
* Returns all entries, newest first. Used by history table and today cards.
|
||||||
|
*/
|
||||||
|
@GetMapping("/entries")
|
||||||
|
public List<WirdEntry> getAllEntries() {
|
||||||
|
logger.log(Logger.Level.INFO, "Fetching all wird entries");
|
||||||
|
return wirdService.getAllEntries();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GET /api/wird/entries/today
|
||||||
|
* Convenience endpoint for today's entries only.
|
||||||
|
*/
|
||||||
|
@GetMapping("/entries/today")
|
||||||
|
public List<WirdEntry> getTodayEntries() {
|
||||||
|
return wirdService.getTodayEntries();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GET /api/wird/entries/range?from=2025-01-01&to=2025-01-31
|
||||||
|
* Used by trend chart to fetch a date window.
|
||||||
|
*/
|
||||||
|
@GetMapping("/entries/range")
|
||||||
|
public List<WirdEntry> getEntriesInRange(
|
||||||
|
@RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate from,
|
||||||
|
@RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate to) {
|
||||||
|
return wirdService.getEntriesInRange(from, to);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* GET /api/wird/entries/range?from=...&to=...&type=durood
|
||||||
|
* Filtered by wird type — useful if you want to extend the chart later.
|
||||||
|
*/
|
||||||
|
@GetMapping("/entries/type/{type}")
|
||||||
|
public List<WirdEntry> getEntriesByType(
|
||||||
|
@PathVariable String type,
|
||||||
|
@RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate from,
|
||||||
|
@RequestParam @DateTimeFormat(iso = DateTimeFormat.ISO.DATE) LocalDate to) {
|
||||||
|
return wirdService.getEntriesByTypeInRange(type, from, to);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* POST /api/wird/entries
|
||||||
|
* Body: { wirdType, date, value, notes }
|
||||||
|
* Creates a new log entry.
|
||||||
|
*/
|
||||||
|
@PostMapping("/entries")
|
||||||
|
public ResponseEntity<WirdEntry> createEntry(@RequestBody WirdEntryDTO dto) {
|
||||||
|
logger.log(Logger.Level.INFO, "Creating wird entry: {0} on {1}", dto.getWirdType(), dto.getDate());
|
||||||
|
WirdEntry saved = wirdService.createEntry(dto);
|
||||||
|
return ResponseEntity.ok(saved);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
20
src/main/java/org/zaine/app/dto/WirdEntryDTO.java
Normal file
20
src/main/java/org/zaine/app/dto/WirdEntryDTO.java
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
package org.zaine.app.dto;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
|
||||||
|
public class WirdEntryDTO {
|
||||||
|
private String wirdType;
|
||||||
|
private LocalDate date;
|
||||||
|
private BigDecimal value;
|
||||||
|
private String notes;
|
||||||
|
|
||||||
|
public String getWirdType() { return wirdType; }
|
||||||
|
public void setWirdType(String t) { this.wirdType = t; }
|
||||||
|
public LocalDate getDate() { return date; }
|
||||||
|
public void setDate(LocalDate d) { this.date = d; }
|
||||||
|
public BigDecimal getValue() { return value; }
|
||||||
|
public void setValue(BigDecimal v) { this.value = v; }
|
||||||
|
public String getNotes() { return notes; }
|
||||||
|
public void setNotes(String n) { this.notes = n; }
|
||||||
|
}
|
||||||
43
src/main/java/org/zaine/app/model/WirdEntry.java
Normal file
43
src/main/java/org/zaine/app/model/WirdEntry.java
Normal file
@@ -0,0 +1,43 @@
|
|||||||
|
package org.zaine.app.model;
|
||||||
|
|
||||||
|
import jakarta.persistence.*;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.time.OffsetDateTime;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "wird_entries")
|
||||||
|
public class WirdEntry {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@Column(name = "wird_type", nullable = false)
|
||||||
|
private String wirdType;
|
||||||
|
|
||||||
|
@Column(nullable = false)
|
||||||
|
private LocalDate date;
|
||||||
|
|
||||||
|
@Column(nullable = false, precision = 10, scale = 2)
|
||||||
|
private BigDecimal value;
|
||||||
|
|
||||||
|
@Column
|
||||||
|
private String notes;
|
||||||
|
|
||||||
|
@Column(name = "created_at", insertable = false, updatable = false)
|
||||||
|
private OffsetDateTime createdAt;
|
||||||
|
|
||||||
|
// ── Getters & Setters ─────────────────────────────────── //
|
||||||
|
|
||||||
|
public Long getId() { return id; }
|
||||||
|
public String getWirdType() { return wirdType; }
|
||||||
|
public void setWirdType(String t) { this.wirdType = t; }
|
||||||
|
public LocalDate getDate() { return date; }
|
||||||
|
public void setDate(LocalDate d) { this.date = d; }
|
||||||
|
public BigDecimal getValue() { return value; }
|
||||||
|
public void setValue(BigDecimal v) { this.value = v; }
|
||||||
|
public String getNotes() { return notes; }
|
||||||
|
public void setNotes(String n) { this.notes = n; }
|
||||||
|
public OffsetDateTime getCreatedAt() { return createdAt; }
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
package org.zaine.app.repositories;
|
||||||
|
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.data.jpa.repository.Query;
|
||||||
|
import org.springframework.data.repository.query.Param;
|
||||||
|
import org.springframework.stereotype.Repository;
|
||||||
|
import org.zaine.app.model.WirdEntry;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Repository
|
||||||
|
public interface WirdEntryRepository extends JpaRepository<WirdEntry, Long> {
|
||||||
|
|
||||||
|
// All entries ordered newest first (for history table)
|
||||||
|
List<WirdEntry> findAllByOrderByDateDescCreatedAtDesc();
|
||||||
|
|
||||||
|
// Entries for a specific date (today's cards)
|
||||||
|
List<WirdEntry> findByDateOrderByCreatedAtDesc(LocalDate date);
|
||||||
|
|
||||||
|
// Entries within a date range for a specific wird type (trend chart)
|
||||||
|
@Query("SELECT e FROM WirdEntry e WHERE e.wirdType = :type AND e.date BETWEEN :from AND :to ORDER BY e.date ASC")
|
||||||
|
List<WirdEntry> findByTypeAndDateRange(
|
||||||
|
@Param("type") String type,
|
||||||
|
@Param("from") LocalDate from,
|
||||||
|
@Param("to") LocalDate to
|
||||||
|
);
|
||||||
|
|
||||||
|
// All entries for a date range (bulk fetch for chart, avoids N+1)
|
||||||
|
@Query("SELECT e FROM WirdEntry e WHERE e.date BETWEEN :from AND :to ORDER BY e.date ASC, e.wirdType ASC")
|
||||||
|
List<WirdEntry> findByDateRange(
|
||||||
|
@Param("from") LocalDate from,
|
||||||
|
@Param("to") LocalDate to
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -32,6 +32,10 @@ public class CommentsService {
|
|||||||
|
|
||||||
public Comments getCommentById(Integer id) {
|
public Comments getCommentById(Integer id) {
|
||||||
logger.log(System.Logger.Level.INFO, "Entering getCommentById with id: " + id);
|
logger.log(System.Logger.Level.INFO, "Entering getCommentById with id: " + id);
|
||||||
|
if (id == null) {
|
||||||
|
logger.log(System.Logger.Level.WARNING, "Comment id is null. Operation aborted.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
return commentsRepository.findById(id).get();
|
return commentsRepository.findById(id).get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,10 @@ public class CompetenciesService {
|
|||||||
|
|
||||||
public Competencies getCompetencyById(Integer id) {
|
public Competencies getCompetencyById(Integer id) {
|
||||||
logger.log(System.Logger.Level.INFO, "Entering getCompetencyById with id: " + id);
|
logger.log(System.Logger.Level.INFO, "Entering getCompetencyById with id: " + id);
|
||||||
|
if (id == null) {
|
||||||
|
logger.log(System.Logger.Level.WARNING, "Competency id is null. Operation aborted.");
|
||||||
|
return null;
|
||||||
|
}
|
||||||
return competenciesRepository.findById(id).get();
|
return competenciesRepository.findById(id).get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
42
src/main/java/org/zaine/app/service/WirdService.java
Normal file
42
src/main/java/org/zaine/app/service/WirdService.java
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
package org.zaine.app.service;
|
||||||
|
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
import org.zaine.app.dto.WirdEntryDTO;
|
||||||
|
import org.zaine.app.model.WirdEntry;
|
||||||
|
import org.zaine.app.repositories.WirdEntryRepository;
|
||||||
|
|
||||||
|
import java.time.LocalDate;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Service
|
||||||
|
public class WirdService {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private WirdEntryRepository repo;
|
||||||
|
|
||||||
|
public List<WirdEntry> getAllEntries() {
|
||||||
|
return repo.findAllByOrderByDateDescCreatedAtDesc();
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<WirdEntry> getTodayEntries() {
|
||||||
|
return repo.findByDateOrderByCreatedAtDesc(LocalDate.now());
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<WirdEntry> getEntriesInRange(LocalDate from, LocalDate to) {
|
||||||
|
return repo.findByDateRange(from, to);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<WirdEntry> getEntriesByTypeInRange(String type, LocalDate from, LocalDate to) {
|
||||||
|
return repo.findByTypeAndDateRange(type, from, to);
|
||||||
|
}
|
||||||
|
|
||||||
|
public WirdEntry createEntry(WirdEntryDTO dto) {
|
||||||
|
WirdEntry entry = new WirdEntry();
|
||||||
|
entry.setWirdType(dto.getWirdType());
|
||||||
|
entry.setDate(dto.getDate() != null ? dto.getDate() : LocalDate.now());
|
||||||
|
entry.setValue(dto.getValue());
|
||||||
|
entry.setNotes(dto.getNotes());
|
||||||
|
return repo.save(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,8 +1,5 @@
|
|||||||
package org.zaine.app;
|
package org.zaine.app;
|
||||||
|
|
||||||
import static org.junit.jupiter.api.Assertions.assertTrue;
|
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
|
||||||
import org.junit.jupiter.api.Test;
|
|
||||||
|
|
||||||
public class ApplicationTest {
|
public class ApplicationTest {
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,8 @@ import static org.junit.jupiter.api.Assertions.*;
|
|||||||
import static org.mockito.Mockito.*;
|
import static org.mockito.Mockito.*;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.lang.System.Logger;
|
||||||
|
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import org.junit.jupiter.api.extension.ExtendWith;
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
import org.mockito.InjectMocks;
|
import org.mockito.InjectMocks;
|
||||||
@@ -14,6 +16,9 @@ import org.mockito.junit.jupiter.MockitoExtension;
|
|||||||
|
|
||||||
@ExtendWith(MockitoExtension.class)
|
@ExtendWith(MockitoExtension.class)
|
||||||
public class CommentsServiceTest {
|
public class CommentsServiceTest {
|
||||||
|
|
||||||
|
private static final Logger logger = System.getLogger(CompetenciesService.class.getName());
|
||||||
|
|
||||||
@InjectMocks
|
@InjectMocks
|
||||||
private CommentsService commentsService;
|
private CommentsService commentsService;
|
||||||
|
|
||||||
@@ -58,6 +63,10 @@ public class CommentsServiceTest {
|
|||||||
public void testGetCommentByIdReturnsComment() {
|
public void testGetCommentByIdReturnsComment() {
|
||||||
Comments comment = new Comments();
|
Comments comment = new Comments();
|
||||||
Integer id = comment.getId();
|
Integer id = comment.getId();
|
||||||
|
if (id == null) {
|
||||||
|
logger.log(System.Logger.Level.WARNING, "Comment id is null. Operation aborted.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
when(commentsRepository.findById(id)).thenReturn(java.util.Optional.of(comment));
|
when(commentsRepository.findById(id)).thenReturn(java.util.Optional.of(comment));
|
||||||
|
|
||||||
Comments result = commentsService.getCommentById(id);
|
Comments result = commentsService.getCommentById(id);
|
||||||
|
|||||||
@@ -11,12 +11,16 @@ import org.zaine.app.model.Competencies;
|
|||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
import static org.junit.jupiter.api.Assertions.*;
|
import static org.junit.jupiter.api.Assertions.*;
|
||||||
import static org.mockito.Mockito.*;
|
import static org.mockito.Mockito.*;
|
||||||
|
|
||||||
|
import java.lang.System.Logger;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
@ExtendWith(org.mockito.junit.jupiter.MockitoExtension.class)
|
@ExtendWith(org.mockito.junit.jupiter.MockitoExtension.class)
|
||||||
public class CompetenciesServiceTest {
|
public class CompetenciesServiceTest {
|
||||||
|
|
||||||
|
private static final Logger logger = System.getLogger(CompetenciesService.class.getName());
|
||||||
|
|
||||||
@InjectMocks
|
@InjectMocks
|
||||||
private CompetenciesService competenciesService;
|
private CompetenciesService competenciesService;
|
||||||
|
|
||||||
@@ -41,6 +45,10 @@ public class CompetenciesServiceTest {
|
|||||||
public void testGetCompetencyByIdReturnsCompetency() {
|
public void testGetCompetencyByIdReturnsCompetency() {
|
||||||
Competencies comp = new Competencies();
|
Competencies comp = new Competencies();
|
||||||
@NotNull Integer id = comp.getId();
|
@NotNull Integer id = comp.getId();
|
||||||
|
if (id == null) {
|
||||||
|
logger.log(System.Logger.Level.WARNING, "Competency id is null. Operation aborted.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
when(competenciesRepository.findById(id)).thenReturn(Optional.of(comp));
|
when(competenciesRepository.findById(id)).thenReturn(Optional.of(comp));
|
||||||
|
|
||||||
|
|
||||||
@@ -53,6 +61,10 @@ public class CompetenciesServiceTest {
|
|||||||
public void testUpdateCompetencyStatusUpdatesCorrectly() {
|
public void testUpdateCompetencyStatusUpdatesCorrectly() {
|
||||||
Competencies comp = new Competencies();
|
Competencies comp = new Competencies();
|
||||||
@NotNull Integer id = comp.getId();
|
@NotNull Integer id = comp.getId();
|
||||||
|
if (id == null) {
|
||||||
|
logger.log(System.Logger.Level.WARNING, "Competency id is null. Operation aborted.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
when(competenciesRepository.findById(id)).thenReturn(Optional.of(comp));
|
when(competenciesRepository.findById(id)).thenReturn(Optional.of(comp));
|
||||||
|
|
||||||
competenciesService.updateCompetencyState(id, "completed");
|
competenciesService.updateCompetencyState(id, "completed");
|
||||||
|
|||||||
Reference in New Issue
Block a user