fix(document): tie-break equal-date DATE sort by title asc, not createdAt
Some checks failed
CI / Unit & Component Tests (pull_request) Failing after 3m2s
CI / OCR Service Tests (pull_request) Successful in 24s
CI / Backend Unit Tests (pull_request) Failing after 3m54s
CI / fail2ban Regex (pull_request) Successful in 47s
CI / Semgrep Security Scan (pull_request) Successful in 20s
CI / Compose Bucket Idempotency (pull_request) Successful in 1m6s
Some checks failed
CI / Unit & Component Tests (pull_request) Failing after 3m2s
CI / OCR Service Tests (pull_request) Successful in 24s
CI / Backend Unit Tests (pull_request) Failing after 3m54s
CI / fail2ban Regex (pull_request) Successful in 47s
CI / Semgrep Security Scan (pull_request) Successful in 20s
CI / Compose Bucket Idempotency (pull_request) Successful in 1m6s
Owner decision (#668): when two documents share a meta_date, order them by title ascending instead of createdAt ascending. title is @Column(nullable=false) so it is always present, giving a deterministic, human-meaningful total order. Only the DATE-sort fast path changes; the in-memory SENDER/RECEIVER/RELEVANCE comparators are untouched. ORDER BY meta_date <dir> NULLS LAST, title ASC Tests assert title-asc tiebreaking for same-date rows in BOTH directions, with a fixture whose title order is the OPPOSITE of insertion (createdAt) order so the test fails if the tiebreaker reverts to createdAt. The integration test drives the production resolveSort against real Postgres. Refs #668
This commit is contained in:
@@ -839,11 +839,12 @@ public class DocumentService {
|
||||
// Undated documents (null documentDate) must order last regardless of
|
||||
// direction — Postgres puts NULLs FIRST on ASC by default, which would
|
||||
// surface the undated pile at the top with no explanation (issue #668).
|
||||
// The createdAt tiebreaker gives a stable total order when every row is
|
||||
// The title tiebreaker gives a stable total order when every row is
|
||||
// null-dated (the "Nur undatierte" filter), so pagination is deterministic.
|
||||
// title is @Column(nullable=false), so it is always present.
|
||||
return Sort.by(
|
||||
new Sort.Order(direction, "documentDate").nullsLast(),
|
||||
Sort.Order.asc("createdAt"));
|
||||
Sort.Order.asc("title"));
|
||||
}
|
||||
// SENDER and RECEIVER are sorted in-memory before this method is called
|
||||
return switch (sort) {
|
||||
|
||||
Reference in New Issue
Block a user