fix(review): resolve all review blockers and concerns

- Delete frontend/e2e/nl-search.spec.ts (was left alive; would have
  crashed CI when Playwright couldn't find the deleted SmartModeToggle)
- Fix docs/DEPLOYMENT.md: remove NLP service arrow + key-facts bullet
  that were accidentally added instead of removed in the prior commit
- Clean docs/GLOSSARY.md: remove keyword→tag resolution, PersonHint,
  TagHint, theme chip entries; trim NameMatches to drop the
  NlQueryParserService reference
- Remove @ConfigurationPropertiesScan from FamilienarchivApplication
  (all remaining @ConfigurationProperties beans carry @Component)
- Remove 12 orphaned i18n keys from de/en/es message files
  (search_loading_nl, search_chip_*, search_disambiguation_*, etc.)
- Fix SearchFilterBar.svelte input padding: pr-20 → pr-4 (SmartModeToggle
  that justified the right padding is gone)
- Delete docs/superpowers/plans/2026-06-07-remove-nlp-search.md
  (scaffolding artefact; plan files belong in Gitea issues, not the repo)
- Add docs/adr/034-remove-nl-search.md documenting the removal decision
  (supersedes deleted ADR-028 ×2, ADR-034-ollama, ADR-035)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Marcel
2026-06-07 19:50:48 +02:00
committed by marcel
parent 75c9dc4be9
commit acc73fd3e1
10 changed files with 56 additions and 934 deletions

View File

@@ -165,16 +165,7 @@ _See also [Chronik](#chronik-internal)._
**Domain** — a Tier-1 bounded context with its own entities, controller, service, repository, and DTOs. Backend domains: `document`, `person`, `tag`, `user`, `geschichte`, `notification`, `ocr`, `audit`, `dashboard`. Frontend domains mirror this structure under `src/lib/`.
**keyword→tag resolution** — the post-Ollama step in `NlQueryParserService` where each LLM-extracted keyword is substring-matched against the tag taxonomy via `TagService.findByNameContaining()`. Keywords that hit one or more tags are removed from the FTS text list and become an OR-union tag filter; keywords with no match remain as FTS text. Matching is case-insensitive and traverses the tag hierarchy via the recursive CTE `findDescendantIdsByName`. See ADR-033.
**PersonHint** — a lightweight `{id, displayName}` pair used in `NlQueryInterpretation` to describe a resolved or ambiguous person without exposing the full `Person` entity to the frontend.
**NameMatches** — the Person-domain result of `PersonService.resolveByName(name)`: candidate persons split by name-match strength into `direct` and `partial`. A match is **direct** when every query token is a whole-token match (order-independent, alias/maiden-name aware) across all of a person's name components (`firstName`, `lastName`, `alias`, each `PersonNameAlias` first+last, `title`); a **partial** matched the substring fetch but is not direct (e.g. "Cram" → "Clara Cramer"). The vocabulary is deliberately match strength, not the search layer's resolved/ambiguous buckets — `NlQueryParserService` maps one direct → resolved (auto-select), ≥2 direct → ambiguous, partial-only → ambiguous suggestions ("Meintest du …?"), and no candidates → folded into full-text search.
**TagHint** — a lightweight `{id, name, color?}` triple used in `NlQueryInterpretation.resolvedTags` to describe a tag matched by keyword→tag resolution. `color` is the tag's effective color (one-level inheritance from parent when the tag has no own color), or null if neither tag nor parent has a color.
**theme chip** `[frontend]` — a removable chip rendered in `InterpretationChipRow` for each entry in `NlQueryInterpretation.resolvedTags` when `tagsApplied` is `true`. Displays "Thema: {tag.name}" (prefix varies by locale). Clicking × removes the tag from the OR-union filter and navigates to `/documents?tag=…&tagOp=OR` with remaining tag and person parameters preserved.
**NameMatches** — the Person-domain result of `PersonService.resolveByName(name)`: candidate persons split by name-match strength into `direct` and `partial`. A match is **direct** when every query token is a whole-token match (order-independent, alias/maiden-name aware) across all of a person's name components (`firstName`, `lastName`, `alias`, each `PersonNameAlias` first+last, `title`); a **partial** matched the substring fetch but is not direct (e.g. "Cram" → "Clara Cramer").
---