feat(transcription): person @mention sidecar + rename propagation (PR-A backend, #362) #366

Merged
marcel merged 40 commits from feat/person-mentions-issue-362-backend into main 2026-04-28 23:54:40 +02:00
Showing only changes of commit 13e0801b30 - Show all commits

View File

@@ -45,19 +45,12 @@ public class PersonMentionPropagationListener {
String oldNeedle = "@" + event.oldDisplayName();
String newNeedle = "@" + event.newDisplayName();
// Match @OldName only at a token boundary: not followed by a letter/digit/hyphen
// (catches @Hans-Peter when renaming Hans) AND not followed by " <Uppercase>"
// (catches @Hans Müller when renaming the single-name @Hans). False negatives —
// e.g. "@Hans Bekam" where Bekam is sentence-initial — are accepted as the
// conservative trade-off; the alternative (corruption) is irrecoverable.
Pattern boundary = Pattern.compile(
Pattern.quote(oldNeedle) + "(?![\\p{L}0-9\\-]| (?=\\p{Lu}))");
String replacement = Matcher.quoteReplacement(newNeedle);
for (TranscriptionBlock block : blocks) {
if (block.getText() != null) {
block.setText(boundary.matcher(block.getText()).replaceAll(replacement));
}
rewriteBlockText(block, boundary, replacement);
for (PersonMention mention : block.getMentionedPersons()) {
if (mention.getPersonId().equals(event.personId())) {
mention.setDisplayName(event.newDisplayName());
@@ -70,4 +63,15 @@ public class PersonMentionPropagationListener {
log.info("Propagated rename {} → {} across {} block(s) for person {}",
event.oldDisplayName(), event.newDisplayName(), blocks.size(), event.personId());
}
// Match @OldName only at a token boundary: not followed by a letter/digit/hyphen
// (catches @Hans-Peter when renaming Hans) AND not followed by " <Uppercase>"
// (catches @Hans Müller when renaming the single-name @Hans). False negatives —
// e.g. "@Hans Bekam" where Bekam is sentence-initial — are accepted as the
// conservative trade-off; the alternative (corruption) is irrecoverable.
private void rewriteBlockText(TranscriptionBlock block, Pattern boundary, String replacement) {
if (block.getText() != null) {
block.setText(boundary.matcher(block.getText()).replaceAll(replacement));
}
}
}