refactor(audit): extend activity feed row/DTO with count and happenedAtUntil (singletons default)
Prepares the activity feed data shape for session-style rollup (#285). Adds two new fields that carry null-operation defaults for the existing hour-truncated dedupe query: - count: int (required) — always 1 for singleton rows - happenedAtUntil: OffsetDateTime (nullable) — end-of-session timestamp for future rollup rows; null for singletons No behavioral change yet — the rollup SQL rewrite lands in a follow-up commit. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -12,4 +12,6 @@ public interface ActivityFeedRow {
|
||||
UUID getDocumentId();
|
||||
Instant getHappenedAt();
|
||||
boolean isYouMentioned();
|
||||
int getCount();
|
||||
Instant getHappenedAtUntil();
|
||||
}
|
||||
|
||||
@@ -39,7 +39,9 @@ public interface AuditLogQueryRepository extends JpaRepository<AuditLog, UUID> {
|
||||
a.document_id AS documentId,
|
||||
a.happened_at AS happened_at,
|
||||
(a.kind = 'MENTION_CREATED'
|
||||
AND a.payload->>'mentionedUserId' = :currentUserId) AS youMentioned
|
||||
AND a.payload->>'mentionedUserId' = :currentUserId) AS youMentioned,
|
||||
1 AS count,
|
||||
CAST(NULL AS TIMESTAMPTZ) AS happenedAtUntil
|
||||
FROM audit_log a
|
||||
LEFT JOIN users u ON u.id = a.actor_id
|
||||
WHERE a.kind IN ('TEXT_SAVED','FILE_UPLOADED','ANNOTATION_CREATED','COMMENT_ADDED','MENTION_CREATED')
|
||||
|
||||
@@ -14,5 +14,7 @@ public record ActivityFeedItemDTO(
|
||||
@Schema(requiredMode = Schema.RequiredMode.REQUIRED) UUID documentId,
|
||||
@Schema(requiredMode = Schema.RequiredMode.REQUIRED) String documentTitle,
|
||||
@Schema(requiredMode = Schema.RequiredMode.REQUIRED) OffsetDateTime happenedAt,
|
||||
@Schema(requiredMode = Schema.RequiredMode.REQUIRED) boolean youMentioned
|
||||
@Schema(requiredMode = Schema.RequiredMode.REQUIRED) boolean youMentioned,
|
||||
@Schema(requiredMode = Schema.RequiredMode.REQUIRED) int count,
|
||||
@Nullable OffsetDateTime happenedAtUntil
|
||||
) {}
|
||||
|
||||
@@ -130,13 +130,18 @@ public class DashboardService {
|
||||
? new ActivityActorDTO(row.getActorInitials(), row.getActorColor(), row.getActorName())
|
||||
: null;
|
||||
String docTitle = titleCache.getOrDefault(row.getDocumentId(), "");
|
||||
OffsetDateTime happenedAtUntil = row.getHappenedAtUntil() != null
|
||||
? row.getHappenedAtUntil().atOffset(ZoneOffset.UTC)
|
||||
: null;
|
||||
return new ActivityFeedItemDTO(
|
||||
org.raddatz.familienarchiv.audit.AuditKind.valueOf(row.getKind()),
|
||||
actor,
|
||||
row.getDocumentId(),
|
||||
docTitle,
|
||||
row.getHappenedAt().atOffset(ZoneOffset.UTC),
|
||||
row.isYouMentioned()
|
||||
row.isYouMentioned(),
|
||||
row.getCount(),
|
||||
happenedAtUntil
|
||||
);
|
||||
}).toList();
|
||||
}
|
||||
|
||||
@@ -56,6 +56,8 @@ class AuditLogQueryRepositoryIntegrationTest {
|
||||
assertThat(rows.get(0).getKind()).isEqualTo("ANNOTATION_CREATED");
|
||||
assertThat(rows.get(0).getDocumentId()).isEqualTo(DOC_ID);
|
||||
assertThat(rows.get(0).getHappenedAt()).isNotNull();
|
||||
assertThat(rows.get(0).getCount()).isEqualTo(1);
|
||||
assertThat(rows.get(0).getHappenedAtUntil()).isNull();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
||||
@@ -104,6 +104,8 @@ class DashboardServiceTest {
|
||||
public UUID getDocumentId() { return docId; }
|
||||
public Instant getHappenedAt() { return Instant.now(); }
|
||||
public boolean isYouMentioned() { return false; }
|
||||
public int getCount() { return 1; }
|
||||
public Instant getHappenedAtUntil() { return null; }
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user