Files
familienarchiv/docs/date-label-fixtures.json
Marcel f2a74a6064 feat(frontend): add precision-aware document date formatter
Adds formatDocumentDate — a pure, branch-per-precision label function that
renders a document date at exactly the precision the data claims (DAY → full
date, MONTH → "Juni 1916", SEASON → localized season word, YEAR → "1916",
APPROX → "ca. 1916", RANGE with collapse/expand/open-ended, UNKNOWN → "Datum
unbekannt"). Delegates to the existing date.ts helpers (shared T12:00:00
convention) and routes every localized word through Paraglide.

A shared docs/date-label-fixtures.json table is asserted by this spec and will
be asserted by the Java title formatter, as the drift guard requested in
review (Markus/Sara). Adds de/en/es precision/season/edit-form i18n keys.

Assumption: SEASON structured label is localized per locale (Decision 4),
with the verbatim raw cell preserved as a separate secondary line by callers.

Refs #666

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-27 11:43:32 +02:00

102 lines
3.2 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{
"_comment": "Single source of truth for the honest date-label rule set shared by the TS formatDocumentDate (frontend/src/lib/shared/utils/documentDate.ts) and the Java formatTitleDate (backend importing/DocumentTitleFormatter.java). Both test suites assert against THIS table so the two implementations cannot drift (en-dash vs hyphen, 'ca.' vs 'circa', season words, range collapse). Expected labels are the GERMAN (de) canonical form: import titles are always German, and the TS formatter defaults to the de locale. Do not edit one side's expectation without editing this file and both tests. See issue #666 and the Markus/Sara drift-guard decision.",
"cases": [
{
"name": "DAY renders a full long date",
"precision": "DAY",
"anchor": "1943-12-24",
"end": null,
"raw": null,
"expected": "24. Dezember 1943"
},
{
"name": "MONTH renders month and year only — never a fabricated day",
"precision": "MONTH",
"anchor": "1916-06-01",
"end": null,
"raw": "Juni 1916",
"expected": "Juni 1916"
},
{
"name": "SEASON renders the season word from raw",
"precision": "SEASON",
"anchor": "1916-06-01",
"end": null,
"raw": "Sommer 1916",
"expected": "Sommer 1916"
},
{
"name": "SEASON with null raw derives the season from the anchor month",
"precision": "SEASON",
"anchor": "1916-04-01",
"end": null,
"raw": null,
"expected": "Frühling 1916"
},
{
"name": "YEAR renders the year only — suppresses month and day",
"precision": "YEAR",
"anchor": "1916-06-15",
"end": null,
"raw": null,
"expected": "1916"
},
{
"name": "APPROX renders a ca. prefix before the year",
"precision": "APPROX",
"anchor": "1920-01-01",
"end": null,
"raw": null,
"expected": "ca. 1920"
},
{
"name": "RANGE in the same month collapses the shared month and year",
"precision": "RANGE",
"anchor": "1917-01-10",
"end": "1917-01-11",
"raw": null,
"expected": "10.11. Jan. 1917"
},
{
"name": "RANGE across months expands both months, sharing the year",
"precision": "RANGE",
"anchor": "1917-01-30",
"end": "1917-02-02",
"raw": null,
"expected": "30. Jan. 2. Feb. 1917"
},
{
"name": "RANGE across a year boundary expands both full dates",
"precision": "RANGE",
"anchor": "1916-12-30",
"end": "1917-01-02",
"raw": null,
"expected": "30. Dez. 1916 2. Jan. 1917"
},
{
"name": "RANGE where end equals start collapses to a single day",
"precision": "RANGE",
"anchor": "1917-01-10",
"end": "1917-01-10",
"raw": null,
"expected": "10. Jan. 1917"
},
{
"name": "RANGE with a null end renders an open-range indicator, never a fabricated end",
"precision": "RANGE",
"anchor": "1917-01-10",
"end": null,
"raw": null,
"expected": "ab 10. Jan. 1917"
},
{
"name": "UNKNOWN renders the unknown label regardless of anchor",
"precision": "UNKNOWN",
"anchor": null,
"end": null,
"raw": "?",
"expected": "Datum unbekannt"
}
]
}