Vier Befunde, die still falsche Ergebnisse lieferten
Some checks failed
CI / Migrationen auf leerer Datenbank (push) Has been cancelled
CI / Lint, Typen, Tests, Build (push) Successful in 11m17s

C.08 -- die Suche mit Bindestrich fand nichts. Das Feld wird per translate an
"-/:.," in Leerzeichen zerlegt, die Eingabe aber nicht: "Mueller-Weiss" erzeugte
das Muster mueller-weiss%, waehrend im Heuhaufen "mueller weiss" stand. Ohne
Bindestrich fand man dieselbe Person. Die Trennzeichen stehen jetzt einmal in
lib/employee-search.ts und werden von beiden Seiten des Vergleichs benutzt.

C.09 -- der Einheitenfilter verlor jede Person mit vorgemerktem Austritt.
"Laufend" war valid_to is null, aber terminate_employee setzt das Ende schon
beim Erfassen, Monate vor dem Tag. Jetzt zaehlt auch, was noch laeuft
(valid_to > heute). Bewusst ohne valid_from <= heute: ein geplanter Eintritt
gehoert in die Liste, sonst fiele er aus dem Filter, obwohl der Status
"Geplant" ihn ausdruecklich fuehrt.

E.07 -- nur die Kostenstelle zu aendern war unmoeglich. update_position weist
einen Aufruf ohne Aenderung ab, und die Umkontierung lief erst bei dessen
Erfolg. Sie wird jetzt uebersprungen, wenn sich an den Stammangaben nichts
geaendert hat.

H.06 -- jedes Speichern erzeugte zusaetzlich "Wochenstunden 30.0 -> 30". Der
Vergleich laeuft ueber Text, die Spalte ist numeric(4,1), und das Formular
schickt 30. Der Kommentar an der Zeile nannte die Absicht richtig, nur reicht
::numeric dafuer nicht -- es muss auf die Genauigkeit der Spalte gehen.
This commit is contained in:
2026-09-29 19:47:48 +02:00
parent a0b9f6dc80
commit cf5ed5c6c6
5 changed files with 182 additions and 15 deletions

View File

@@ -8,6 +8,24 @@
// verglichen wird gegen Vorname, Nachname und Position zusammengesetzt, mit
// Trennzeichen als Wortgrenze.
/**
* Die Zeichen, die im Namen als Wortgrenze zählen.
*
* Sie stehen hier und nicht in der Seite, weil **beide Seiten des Vergleichs**
* sie brauchen: das Feld wird per `translate` an diesen Zeichen in Leerzeichen
* zerlegt, und die Eingabe muss genauso zerlegt werden. Vorher tat es nur das
* Feld — wer „Müller-Weiß" mit Bindestrich suchte, erzeugte das Muster
* `müller-weiß%`, während im Heuhaufen „müller weiß" stand. Null Treffer,
* obwohl die Person da ist; ohne Bindestrich fand man sie. Gemeldet im Test
* vom 29.09. (C.08).
*/
export const TRENNZEICHEN = "-/:.,";
/** Für `translate(…, TRENNZEICHEN, TRENNZEICHEN_ERSATZ)`: gleich lang, nur Leerzeichen. */
export const TRENNZEICHEN_ERSATZ = " ".repeat(TRENNZEICHEN.length);
const WORTGRENZE = new RegExp(`[\\s${TRENNZEICHEN.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&")}]+`);
/** Nur Ziffern? Dann ist es eine Personalnummer und kein Name. */
export function istPersonalnummer(term: string): boolean {
return /^\d+$/.test(term.trim());
@@ -25,7 +43,10 @@ export function istPersonalnummer(term: string): boolean {
export function suchMuster(term: string): string[][] {
return term
.trim()
.split(/\s+/)
// An denselben Zeichen zerlegt wie das Feld, gegen das verglichen wird:
// „Müller-Weiß" wird zu zwei Wörtern, die beide am Wortanfang treffen
// müssen — genau wie „Müller Weiß".
.split(WORTGRENZE)
.filter(Boolean)
.map((wort) => {
// Die Platzhalter von LIKE entschärfen: wer „50 %" tippt, sucht Text.