From a15b5ebf17f6b4e6149cf19baa0df4193e88c440 Mon Sep 17 00:00:00 2001 From: Marcel Date: Wed, 15 Apr 2026 15:30:53 +0200 Subject: [PATCH] feat(search): add MatchOffset record for character-level highlight positions Co-Authored-By: Claude Sonnet 4.6 --- .../familienarchiv/dto/MatchOffset.java | 14 ++++++++++++ .../familienarchiv/dto/MatchOffsetTest.java | 22 +++++++++++++++++++ 2 files changed, 36 insertions(+) create mode 100644 backend/src/main/java/org/raddatz/familienarchiv/dto/MatchOffset.java create mode 100644 backend/src/test/java/org/raddatz/familienarchiv/dto/MatchOffsetTest.java diff --git a/backend/src/main/java/org/raddatz/familienarchiv/dto/MatchOffset.java b/backend/src/main/java/org/raddatz/familienarchiv/dto/MatchOffset.java new file mode 100644 index 00000000..65d72918 --- /dev/null +++ b/backend/src/main/java/org/raddatz/familienarchiv/dto/MatchOffset.java @@ -0,0 +1,14 @@ +package org.raddatz.familienarchiv.dto; + +import io.swagger.v3.oas.annotations.media.Schema; + +/** + * Character-level offset of a highlighted term within a text field. + * Offsets are Java {@code String} character positions (UTF-16 code units), + * which are identical to JavaScript string positions — consistent end-to-end + * for all German BMP characters (ä, ö, ü, ß, etc.). + */ +public record MatchOffset( + @Schema(requiredMode = Schema.RequiredMode.REQUIRED) int start, + @Schema(requiredMode = Schema.RequiredMode.REQUIRED) int length +) {} diff --git a/backend/src/test/java/org/raddatz/familienarchiv/dto/MatchOffsetTest.java b/backend/src/test/java/org/raddatz/familienarchiv/dto/MatchOffsetTest.java new file mode 100644 index 00000000..2021a640 --- /dev/null +++ b/backend/src/test/java/org/raddatz/familienarchiv/dto/MatchOffsetTest.java @@ -0,0 +1,22 @@ +package org.raddatz.familienarchiv.dto; + +import org.junit.jupiter.api.Test; + +import static org.assertj.core.api.Assertions.assertThat; + +class MatchOffsetTest { + + @Test + void should_hold_start_and_length() { + MatchOffset offset = new MatchOffset(6, 5); + + assertThat(offset.start()).isEqualTo(6); + assertThat(offset.length()).isEqualTo(5); + } + + @Test + void should_implement_value_equality() { + assertThat(new MatchOffset(0, 3)).isEqualTo(new MatchOffset(0, 3)); + assertThat(new MatchOffset(0, 3)).isNotEqualTo(new MatchOffset(0, 4)); + } +}