Let the employee list be sorted A-Z or Z-A
Some checks failed
CI / Lint, Typen, Tests, Build (push) Failing after 6m12s
CI / Integrationstests (echtes Postgres) (push) Failing after 5m29s

Sorting lives in the URL, not the browser. The list is built on the
server and fetched a page at a time, so a client-side sort would only
reorder the fifteen rows on screen — with 867 people that promises an
alphabetical list and delivers something else on page 2.

The sort key is the surname, because that is how the column reads:
"Aigner, Manuel", and whoever looks for someone looks under A. Postgres
runs with the Austrian collation, so Ö sorts with O rather than at the
end of the alphabet.

Only the surname reverses. The id stays ascending: it decides nothing
except ties, and it exists to keep the order total across page
boundaries. Reversing it too would still be deterministic but would flip
the fourteen Winklers relative to each other for no reason anyone asked
for.

The select sits in the filter bar rather than in a clickable column
header — a header would suggest it sorts what is on screen.

Verified: compiled SQL is `order by last_name desc, id` for Z-A; the
parse and direction rules are covered by tests that were mutation-checked
(breaking each rule turns them red). Not verified in the browser — the
login goes through the company account, and the Supabase instance no
longer resolves.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
2026-09-07 10:02:15 +02:00
parent af947f094d
commit 5c310c3a58
4 changed files with 112 additions and 2 deletions

40
lib/employee-sort.ts Normal file
View File

@@ -0,0 +1,40 @@
// Wie die Mitarbeiterliste sortiert wird.
//
// Wie die Filter steht auch die Sortierung in der Adresse und nicht im
// Browser: die Liste wird auf dem Server gebaut und seitenweise geholt. Wer
// im Browser sortierte, ordnete nur die fünfzehn Zeilen der aktuellen Seite
// um — bei 867 Personen wäre das eine Sortierung, die nach dem Blättern
// etwas anderes zeigt als versprochen.
//
// Sortiert wird nach dem **Nachnamen**, weil die Liste danach gelesen wird:
// die Spalte zeigt „Aigner, Manuel", und wer jemanden sucht, sucht ihn unter
// A. Postgres läuft mit österreichischer Sortierregel, deshalb steht Ö bei O
// und nicht am Ende des Alphabets.
export const SORTIERUNGEN = [
{ value: "az", label: "Name A–Z" },
{ value: "za", label: "Name Z–A" },
] as const;
export type Sortierung = (typeof SORTIERUNGEN)[number]["value"];
export const STANDARD_SORTIERUNG: Sortierung = "az";
/** Alles, was nicht in der Liste steht, führt auf den Standard zurück. */
export function parseSortierung(wert: string | undefined): Sortierung {
return SORTIERUNGEN.some((s) => s.value === wert) ? (wert as Sortierung) : STANDARD_SORTIERUNG;
}
/**
* Die Richtung für die Abfrage.
*
* Nur der Nachname dreht sich. Das zweite Kriterium — die Kennung — bleibt
* aufsteigend: es entscheidet nur bei gleichem Nachnamen und dient allein
* dazu, die Reihenfolge über die Seitengrenzen hinweg eindeutig zu halten.
* Drehte es mit, wäre die Sortierung immer noch eindeutig, aber die vierzehn
* Winkler stünden in umgekehrter Reihenfolge zueinander, ohne dass jemand
* das verlangt hätte.
*/
export function richtung(sortierung: Sortierung): "asc" | "desc" {
return sortierung === "za" ? "desc" : "asc";
}