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();
|
UUID getDocumentId();
|
||||||
Instant getHappenedAt();
|
Instant getHappenedAt();
|
||||||
boolean isYouMentioned();
|
boolean isYouMentioned();
|
||||||
|
int getCount();
|
||||||
|
Instant getHappenedAtUntil();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -39,7 +39,9 @@ public interface AuditLogQueryRepository extends JpaRepository<AuditLog, UUID> {
|
|||||||
a.document_id AS documentId,
|
a.document_id AS documentId,
|
||||||
a.happened_at AS happened_at,
|
a.happened_at AS happened_at,
|
||||||
(a.kind = 'MENTION_CREATED'
|
(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
|
FROM audit_log a
|
||||||
LEFT JOIN users u ON u.id = a.actor_id
|
LEFT JOIN users u ON u.id = a.actor_id
|
||||||
WHERE a.kind IN ('TEXT_SAVED','FILE_UPLOADED','ANNOTATION_CREATED','COMMENT_ADDED','MENTION_CREATED')
|
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) UUID documentId,
|
||||||
@Schema(requiredMode = Schema.RequiredMode.REQUIRED) String documentTitle,
|
@Schema(requiredMode = Schema.RequiredMode.REQUIRED) String documentTitle,
|
||||||
@Schema(requiredMode = Schema.RequiredMode.REQUIRED) OffsetDateTime happenedAt,
|
@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())
|
? new ActivityActorDTO(row.getActorInitials(), row.getActorColor(), row.getActorName())
|
||||||
: null;
|
: null;
|
||||||
String docTitle = titleCache.getOrDefault(row.getDocumentId(), "");
|
String docTitle = titleCache.getOrDefault(row.getDocumentId(), "");
|
||||||
|
OffsetDateTime happenedAtUntil = row.getHappenedAtUntil() != null
|
||||||
|
? row.getHappenedAtUntil().atOffset(ZoneOffset.UTC)
|
||||||
|
: null;
|
||||||
return new ActivityFeedItemDTO(
|
return new ActivityFeedItemDTO(
|
||||||
org.raddatz.familienarchiv.audit.AuditKind.valueOf(row.getKind()),
|
org.raddatz.familienarchiv.audit.AuditKind.valueOf(row.getKind()),
|
||||||
actor,
|
actor,
|
||||||
row.getDocumentId(),
|
row.getDocumentId(),
|
||||||
docTitle,
|
docTitle,
|
||||||
row.getHappenedAt().atOffset(ZoneOffset.UTC),
|
row.getHappenedAt().atOffset(ZoneOffset.UTC),
|
||||||
row.isYouMentioned()
|
row.isYouMentioned(),
|
||||||
|
row.getCount(),
|
||||||
|
happenedAtUntil
|
||||||
);
|
);
|
||||||
}).toList();
|
}).toList();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,6 +56,8 @@ class AuditLogQueryRepositoryIntegrationTest {
|
|||||||
assertThat(rows.get(0).getKind()).isEqualTo("ANNOTATION_CREATED");
|
assertThat(rows.get(0).getKind()).isEqualTo("ANNOTATION_CREATED");
|
||||||
assertThat(rows.get(0).getDocumentId()).isEqualTo(DOC_ID);
|
assertThat(rows.get(0).getDocumentId()).isEqualTo(DOC_ID);
|
||||||
assertThat(rows.get(0).getHappenedAt()).isNotNull();
|
assertThat(rows.get(0).getHappenedAt()).isNotNull();
|
||||||
|
assertThat(rows.get(0).getCount()).isEqualTo(1);
|
||||||
|
assertThat(rows.get(0).getHappenedAtUntil()).isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -104,6 +104,8 @@ class DashboardServiceTest {
|
|||||||
public UUID getDocumentId() { return docId; }
|
public UUID getDocumentId() { return docId; }
|
||||||
public Instant getHappenedAt() { return Instant.now(); }
|
public Instant getHappenedAt() { return Instant.now(); }
|
||||||
public boolean isYouMentioned() { return false; }
|
public boolean isYouMentioned() { return false; }
|
||||||
|
public int getCount() { return 1; }
|
||||||
|
public Instant getHappenedAtUntil() { return null; }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user