feat: PDF annotations for documents (#40) #54

Merged
marcel merged 10 commits from feat/40-pdf-annotations into main 2026-03-24 10:00:28 +01:00
3 changed files with 20 additions and 16 deletions
Showing only changes of commit ea1c097ae0 - Show all commits

View File

@@ -148,7 +148,7 @@
<activeByDefault>true</activeByDefault> <activeByDefault>true</activeByDefault>
</activation> </activation>
<properties> <properties>
<spring.profiles.active>dev</spring.profiles.active> <spring.profiles.active>dev,e2e</spring.profiles.active>
</properties> </properties>
</profile> </profile>
<profile> <profile>

View File

@@ -49,7 +49,7 @@ public class DataInitializer {
// 1. Admin Gruppe erstellen // 1. Admin Gruppe erstellen
UserGroup adminGroup = UserGroup.builder() UserGroup adminGroup = UserGroup.builder()
.name("Administrators") .name("Administrators")
.permissions(Set.of("ADMIN", "READ_ALL", "WRITE_ALL", "ADMIN_USER", "ADMIN_TAG", "ADMIN_PERMISSION")) .permissions(Set.of("ADMIN", "READ_ALL", "WRITE_ALL", "ANNOTATE_ALL", "ADMIN_USER", "ADMIN_TAG", "ADMIN_PERMISSION"))
.build(); .build();
groupRepository.save(adminGroup); groupRepository.save(adminGroup);
@@ -84,8 +84,24 @@ public class DataInitializer {
TagRepository tagRepo, TagRepository tagRepo,
PasswordEncoder passwordEncoder) { PasswordEncoder passwordEncoder) {
return args -> { return args -> {
// Always ensure the read-only test user exists, even when seed data was already loaded.
if (userRepository.findByUsername("reader").isEmpty()) {
log.info("E2E seed: Erstelle 'reader'-Testbenutzer...");
UserGroup leserGroup = groupRepository.findByName("Leser").orElseGet(() ->
groupRepository.save(UserGroup.builder()
.name("Leser")
.permissions(Set.of("READ_ALL"))
.build()));
userRepository.save(AppUser.builder()
.username("reader")
.password(passwordEncoder.encode("reader123"))
.groups(Set.of(leserGroup))
.build());
log.info("E2E seed: 'reader'-Testbenutzer erstellt.");
}
if (personRepo.count() > 0) { if (personRepo.count() > 0) {
log.info("E2E seed: Daten bereits vorhanden, überspringe."); log.info("E2E seed: Personendaten bereits vorhanden, überspringe Dokument-Seed.");
return; return;
} }
@@ -166,19 +182,6 @@ public class DataInitializer {
.receivers(Set.of(otto)) .receivers(Set.of(otto))
.build()); .build());
// ── Read-only user (for permissions E2E tests) ───────────────────
// Username: reader / Password: reader123
// Has only READ_ALL — used to assert write controls are absent.
UserGroup leserGroup = groupRepository.save(UserGroup.builder()
.name("Leser")
.permissions(Set.of("READ_ALL"))
.build());
userRepository.save(AppUser.builder()
.username("reader")
.password(passwordEncoder.encode("reader123"))
.groups(Set.of(leserGroup))
.build());
log.info("E2E seed: {} Personen, {} Tags, {} Dokumente, {} Benutzer erstellt.", log.info("E2E seed: {} Personen, {} Tags, {} Dokumente, {} Benutzer erstellt.",
personRepo.count(), tagRepo.count(), docRepo.count(), userRepository.count()); personRepo.count(), tagRepo.count(), docRepo.count(), userRepository.count());
}; };

View File

@@ -98,6 +98,7 @@ services:
S3_SECRET_KEY: ${MINIO_ROOT_PASSWORD} S3_SECRET_KEY: ${MINIO_ROOT_PASSWORD}
S3_BUCKET_NAME: ${MINIO_DEFAULT_BUCKETS} S3_BUCKET_NAME: ${MINIO_DEFAULT_BUCKETS}
S3_REGION: us-east-1 S3_REGION: us-east-1
SPRING_PROFILES_ACTIVE: dev,e2e
APP_BASE_URL: ${APP_BASE_URL:-http://localhost:3000} APP_BASE_URL: ${APP_BASE_URL:-http://localhost:3000}
# Defaults to the local Mailpit catcher — override in .env for production SMTP # Defaults to the local Mailpit catcher — override in .env for production SMTP
MAIL_HOST: ${MAIL_HOST:-mailpit} MAIL_HOST: ${MAIL_HOST:-mailpit}