diff --git a/backend/pom.xml b/backend/pom.xml
index ad068e07..a5eddab8 100644
--- a/backend/pom.xml
+++ b/backend/pom.xml
@@ -148,7 +148,7 @@
true
- dev
+ dev,e2e
diff --git a/backend/src/main/java/org/raddatz/familienarchiv/config/DataInitializer.java b/backend/src/main/java/org/raddatz/familienarchiv/config/DataInitializer.java
index 25f69894..f101f5a1 100644
--- a/backend/src/main/java/org/raddatz/familienarchiv/config/DataInitializer.java
+++ b/backend/src/main/java/org/raddatz/familienarchiv/config/DataInitializer.java
@@ -49,7 +49,7 @@ public class DataInitializer {
// 1. Admin Gruppe erstellen
UserGroup adminGroup = UserGroup.builder()
.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();
groupRepository.save(adminGroup);
@@ -84,8 +84,24 @@ public class DataInitializer {
TagRepository tagRepo,
PasswordEncoder passwordEncoder) {
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) {
- log.info("E2E seed: Daten bereits vorhanden, überspringe.");
+ log.info("E2E seed: Personendaten bereits vorhanden, überspringe Dokument-Seed.");
return;
}
@@ -166,19 +182,6 @@ public class DataInitializer {
.receivers(Set.of(otto))
.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.",
personRepo.count(), tagRepo.count(), docRepo.count(), userRepository.count());
};
diff --git a/docker-compose.yml b/docker-compose.yml
index 16fef739..7ceabc66 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -98,6 +98,7 @@ services:
S3_SECRET_KEY: ${MINIO_ROOT_PASSWORD}
S3_BUCKET_NAME: ${MINIO_DEFAULT_BUCKETS}
S3_REGION: us-east-1
+ SPRING_PROFILES_ACTIVE: dev,e2e
APP_BASE_URL: ${APP_BASE_URL:-http://localhost:3000}
# Defaults to the local Mailpit catcher — override in .env for production SMTP
MAIL_HOST: ${MAIL_HOST:-mailpit}