feat(user): add deterministic avatar color to AppUser

Adds color field assigned from an 8-colour palette keyed on the user's UUID
hash (Math.abs(id.hashCode()) % 8). Fires via @PrePersist/@PreUpdate/@PostLoad
so both new and existing users get the correct colour at runtime.

V47 migration adds the column and fixes the V46 REVOKE bug that hardcoded
role name 'app_user' instead of CURRENT_USER.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-04-19 16:33:27 +02:00
parent 428c63a2f2
commit cb02dc84f6
3 changed files with 72 additions and 0 deletions

View File

@@ -0,0 +1,38 @@
package org.raddatz.familienarchiv.model;
import org.junit.jupiter.api.Test;
import java.util.List;
import java.util.UUID;
import static org.assertj.core.api.Assertions.assertThat;
class AppUserTest {
private static final List<String> EXPECTED_PALETTE = List.of(
"#7a4f9a", "#5a8a6a", "#3060b0", "#a0522d", "#c0446e", "#c17a00", "#0e7490", "#1d4ed8"
);
@Test
void computeColor_returnsDeterministicPaletteColor() {
UUID id = UUID.fromString("12345678-1234-1234-1234-123456789abc");
String color = AppUser.computeColor(id);
assertThat(EXPECTED_PALETTE).contains(color);
assertThat(AppUser.computeColor(id)).isEqualTo(color);
}
@Test
void computeColor_isStableAcrossCalls() {
UUID id = UUID.randomUUID();
assertThat(AppUser.computeColor(id)).isEqualTo(AppUser.computeColor(id));
}
@Test
void computeColor_variesAcrossDifferentIds() {
long distinct = java.util.stream.IntStream.range(0, 100)
.mapToObj(i -> AppUser.computeColor(UUID.randomUUID()))
.distinct()
.count();
assertThat(distinct).isGreaterThan(1);
}
}