Background
Letter case is ignored only where identity and finding things are concerned: generated ids, natural-key matching that prevents duplicate content, and search and the endpoints built on it. Imported data must be able to correct an existing value even when the only change is its casing (developer decision, 2026-09-19).
The import does the opposite. FieldMergeResolver.ValuesEqual compares every imported field case-insensitively for every entity, so a case-only correction is treated as unchanged and silently dropped; #374 exempted only a quote's quoteText and character, and excluded source on purpose. A quote's character and source are the names of its linked Character and Source rows, which are matched case-insensitively for identity — so a correction has to be staged on those rows, not only on the quote. CLAUDE.md and #181's reasoning state case-insensitive comparison as the default.
What needs to be done
- An ADR records the rule, superseding the case-insensitive default for imported values.
- Every imported field value compares exactly, for every entity type; identity and natural-key matching, and search, stay case-insensitive.
- A case-only change to a Source title, Character name, Person name, Series name or Universe name is staged against that row, so deciding it writes the new casing.
CLAUDE.md states the rule.
Expected tests
To be written when the issue starts — per entity type, a case-only change is staged and, once decided, stored; identity matching still resolves the differently-cased value to the existing row; and an automated-test document that imports a case-only correction and reads the new casing back.
| Test class / document |
Test method / what it verifies |
Starts |
| To be written |
— |
❌ |
Definition of done
Background
Letter case is ignored only where identity and finding things are concerned: generated ids, natural-key matching that prevents duplicate content, and search and the endpoints built on it. Imported data must be able to correct an existing value even when the only change is its casing (developer decision, 2026-09-19).
The import does the opposite.
FieldMergeResolver.ValuesEqualcompares every imported field case-insensitively for every entity, so a case-only correction is treated as unchanged and silently dropped; #374 exempted only a quote'squoteTextandcharacter, and excludedsourceon purpose. A quote'scharacterandsourceare the names of its linked Character and Source rows, which are matched case-insensitively for identity — so a correction has to be staged on those rows, not only on the quote.CLAUDE.mdand #181's reasoning state case-insensitive comparison as the default.What needs to be done
CLAUDE.mdstates the rule.Expected tests
To be written when the issue starts — per entity type, a case-only change is staged and, once decided, stored; identity matching still resolves the differently-cased value to the existing row; and an automated-test document that imports a case-only correction and reads the new casing back.
Definition of done