Dev #18
@@ -1,6 +1,7 @@
|
|||||||
package de.zendric.app.xpensely_server.model;
|
package de.zendric.app.xpensely_server.model;
|
||||||
|
|
||||||
import java.time.LocalDate;
|
import java.time.LocalDate;
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
import com.fasterxml.jackson.annotation.JsonBackReference;
|
import com.fasterxml.jackson.annotation.JsonBackReference;
|
||||||
|
|
||||||
@@ -36,6 +37,7 @@ public class Expense {
|
|||||||
private Double otherPersonAmount;
|
private Double otherPersonAmount;
|
||||||
private String category;
|
private String category;
|
||||||
private LocalDate date;
|
private LocalDate date;
|
||||||
|
private LocalDateTime lastModified;
|
||||||
|
|
||||||
@ManyToOne
|
@ManyToOne
|
||||||
@JoinColumn(name = "expense_list_id", nullable = false)
|
@JoinColumn(name = "expense_list_id", nullable = false)
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
package de.zendric.app.xpensely_server.model;
|
||||||
|
|
||||||
|
import java.time.LocalDateTime;
|
||||||
|
|
||||||
|
import jakarta.persistence.Column;
|
||||||
|
import jakarta.persistence.Entity;
|
||||||
|
import jakarta.persistence.EnumType;
|
||||||
|
import jakarta.persistence.Enumerated;
|
||||||
|
import jakarta.persistence.GeneratedValue;
|
||||||
|
import jakarta.persistence.GenerationType;
|
||||||
|
import jakarta.persistence.Id;
|
||||||
|
import jakarta.persistence.Index;
|
||||||
|
import jakarta.persistence.JoinColumn;
|
||||||
|
import jakarta.persistence.ManyToOne;
|
||||||
|
import jakarta.persistence.Table;
|
||||||
|
import lombok.Getter;
|
||||||
|
import lombok.NoArgsConstructor;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
@NoArgsConstructor
|
||||||
|
@Entity
|
||||||
|
@Table(name = "expense_history_entry", indexes = @Index(name = "idx_history_list_timestamp", columnList = "expense_list_id, timestamp DESC"))
|
||||||
|
public class ExpenseHistoryEntry {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||||
|
private Long id;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
@JoinColumn(name = "expense_list_id", nullable = false)
|
||||||
|
private ExpenseList expenseList;
|
||||||
|
|
||||||
|
/** Plain column on purpose — no FK, so history survives expense deletion. */
|
||||||
|
private Long expenseId;
|
||||||
|
|
||||||
|
/** Denormalized so entries for deleted expenses still render. */
|
||||||
|
private String expenseTitle;
|
||||||
|
|
||||||
|
@ManyToOne
|
||||||
|
private AppUser actor;
|
||||||
|
|
||||||
|
@Enumerated(EnumType.STRING)
|
||||||
|
private HistoryEntryType type;
|
||||||
|
|
||||||
|
private LocalDateTime timestamp;
|
||||||
|
|
||||||
|
/** JSON array of FieldChange; null for CREATED/DELETED. */
|
||||||
|
@Column(columnDefinition = "TEXT")
|
||||||
|
private String changes;
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
package de.zendric.app.xpensely_server.model;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
||||||
|
public record FieldChange(
|
||||||
|
String field,
|
||||||
|
@JsonProperty("old") String oldValue,
|
||||||
|
@JsonProperty("new") String newValue) {
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
package de.zendric.app.xpensely_server.model;
|
||||||
|
|
||||||
|
public enum HistoryEntryType {
|
||||||
|
CREATED, UPDATED, DELETED
|
||||||
|
}
|
||||||
@@ -0,0 +1,18 @@
|
|||||||
|
package de.zendric.app.xpensely_server.repo;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.springframework.data.domain.Page;
|
||||||
|
import org.springframework.data.domain.Pageable;
|
||||||
|
import org.springframework.data.jpa.repository.JpaRepository;
|
||||||
|
import org.springframework.data.jpa.repository.Query;
|
||||||
|
|
||||||
|
import de.zendric.app.xpensely_server.model.ExpenseHistoryEntry;
|
||||||
|
|
||||||
|
public interface ExpenseHistoryRepository extends JpaRepository<ExpenseHistoryEntry, Long> {
|
||||||
|
|
||||||
|
Page<ExpenseHistoryEntry> findByExpenseListIdOrderByTimestampDescIdDesc(Long expenseListId, Pageable pageable);
|
||||||
|
|
||||||
|
@Query("select h.expenseId from ExpenseHistoryEntry h")
|
||||||
|
List<Long> findAllExpenseIds();
|
||||||
|
}
|
||||||
@@ -10,4 +10,6 @@ import de.zendric.app.xpensely_server.model.Expense;
|
|||||||
@Repository
|
@Repository
|
||||||
public interface ExpenseRepository extends JpaRepository<Expense, Long> {
|
public interface ExpenseRepository extends JpaRepository<Expense, Long> {
|
||||||
List<Expense> findAllByOrderByDateAsc();
|
List<Expense> findAllByOrderByDateAsc();
|
||||||
|
|
||||||
|
List<Expense> findByLastModifiedIsNull();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user