feat(geschichten): blog-like family memory stories (closes #381) #382

Merged
marcel merged 30 commits from feat/issue-381-geschichten into main 2026-05-04 15:02:45 +02:00
2 changed files with 51 additions and 0 deletions
Showing only changes of commit b7a2f6c2fe - Show all commits

View File

@@ -0,0 +1,21 @@
package org.raddatz.familienarchiv.dto;
import lombok.Data;
import org.raddatz.familienarchiv.model.GeschichteStatus;
import java.util.List;
import java.util.UUID;
/**
* Used for both create and update of a Geschichte. All fields are optional;
* the service applies whatever is non-null. {@code body} is rich-text HTML and
* is sanitised against an allow-list before persistence.
*/
@Data
public class GeschichteUpdateDTO {
private String title;
private String body;
private GeschichteStatus status;
private List<UUID> personIds;
private List<UUID> documentIds;
}

View File

@@ -0,0 +1,30 @@
package org.raddatz.familienarchiv.repository;
import org.raddatz.familienarchiv.model.Geschichte;
import org.raddatz.familienarchiv.model.GeschichteStatus;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.UUID;
@Repository
public interface GeschichteRepository extends JpaRepository<Geschichte, UUID>, JpaSpecificationExecutor<Geschichte> {
@Query("""
SELECT g FROM Geschichte g
WHERE (:status IS NULL OR g.status = :status)
AND (:personId IS NULL OR :personId IN (SELECT p.id FROM g.persons p))
AND (:documentId IS NULL OR :documentId IN (SELECT d.id FROM g.documents d))
ORDER BY COALESCE(g.publishedAt, g.updatedAt) DESC
""")
List<Geschichte> search(
@Param("status") GeschichteStatus status,
@Param("personId") UUID personId,
@Param("documentId") UUID documentId,
Pageable pageable);
}