# Remove NLP/Smart Search Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** Remove the NLP/smart-search feature entirely from the codebase — backend search package, frontend components, i18n keys, infrastructure config, and the nlp-service microservice. **Architecture:** Pure deletion + targeted edits. No new code. Each task deletes a self-contained layer, then verifies compilation passes before committing. Order: backend first (most isolated), then frontend, then infrastructure, then docs. **Tech Stack:** Spring Boot 4 (Java 21, Maven), SvelteKit 2 / Svelte 5, Docker Compose, Paraglide i18n. --- ## File Map ### Delete entirely - `backend/src/main/java/org/raddatz/familienarchiv/search/` — 14 Java source files - `backend/src/test/java/org/raddatz/familienarchiv/search/` — 6 Java test files - `frontend/src/routes/search/SmartModeToggle.svelte` + `.spec.ts` - `frontend/src/routes/search/SmartSearchStatus.svelte` + `.spec.ts` - `frontend/src/routes/search/InterpretationChipRow.svelte` + `.spec.ts` - `frontend/src/routes/search/DisambiguationPicker.svelte` + `.spec.ts` - `frontend/src/routes/search/chip-types.ts` - `frontend/src/routes/documents/theme-chip-removal.ts` + `.spec.ts` - `infra/observability/grafana/provisioning/dashboards/ollama.json` - `nlp-service/` (entire directory) - `docs/adr/028-nl-search-ollama.md` - `docs/adr/028-ollama-docker-compose-service.md` - `docs/adr/034-ollama-production-deployment-and-keep-alive.md` - `docs/adr/035-rule-based-nlp-service.md` ### Modify - `backend/src/main/java/org/raddatz/familienarchiv/exception/ErrorCode.java` — remove 2 enum values - `backend/src/main/resources/application.yaml` — remove `nlp` + `nl-search` config blocks - `backend/src/main/resources/application-dev.yaml` — remove `nlp` config block - `frontend/src/routes/SearchFilterBar.svelte` — remove SmartModeToggle, smartMode prop, smart callbacks - `frontend/src/routes/SearchFilterBar.svelte.spec.ts` — remove smart-mode describe block - `frontend/src/routes/documents/+page.svelte` — remove all NL state, functions, template block - `frontend/src/lib/shared/errors.ts` — remove 2 error codes + their switch cases - `frontend/messages/de.json` — remove 8 smart-search keys - `frontend/messages/en.json` — remove 8 smart-search keys - `frontend/messages/es.json` — remove 8 smart-search keys - `docker-compose.yml` — remove nlp-service block + backend depends_on + env var - `docker-compose.prod.yml` — remove nlp-service block + backend depends_on + env var - `infra/observability/prometheus/prometheus.yml` — remove ollama scrape job - `CLAUDE.md` — remove search package reference + error code entries - `backend/CLAUDE.md` — no change needed (search package already absent from structure) - `frontend/CLAUDE.md` — update routes/search/ description --- ### Task 1: Delete backend search package **Files:** - Delete: `backend/src/main/java/org/raddatz/familienarchiv/search/` (14 files) - Delete: `backend/src/test/java/org/raddatz/familienarchiv/search/` (6 files) - [ ] **Step 1: Delete all source files** ```bash rm -rf backend/src/main/java/org/raddatz/familienarchiv/search rm -rf backend/src/test/java/org/raddatz/familienarchiv/search ``` - [ ] **Step 2: Verify backend compiles** ```bash cd backend && . ~/.sdkman/candidates/java/current/bin/../.. && source ~/.sdkman/bin/sdkman-init.sh && ./mvnw compile -q ``` Expected: BUILD SUCCESS with no errors. - [ ] **Step 3: Commit** ```bash git add -A git commit -m "refactor(search): delete backend NLP search package" ``` --- ### Task 2: Remove ErrorCode entries and backend config **Files:** - Modify: `backend/src/main/java/org/raddatz/familienarchiv/exception/ErrorCode.java:138-142` - Modify: `backend/src/main/resources/application.yaml:133-138` - Modify: `backend/src/main/resources/application-dev.yaml:15-17` - [ ] **Step 1: Remove NL Search enum values from ErrorCode.java** Remove these lines (138–142): ```java // --- NL Search --- /** Ollama is unreachable or timed out. 503 */ SMART_SEARCH_UNAVAILABLE, /** NL search rate limit exceeded (5 requests per user per minute). 429 */ SMART_SEARCH_RATE_LIMITED, ``` The block between `TAG_MERGE_INVALID_TARGET,` and `// --- Generic ---` becomes empty. - [ ] **Step 2: Remove nlp and nl-search config from application.yaml** Remove these lines (133–138): ```yaml nlp: base-url: http://nlp-service:8001 nl-search: rate-limit: max-requests-per-minute: 20 ``` - [ ] **Step 3: Remove nlp config from application-dev.yaml** Remove these lines (15–17): ```yaml app: nlp: base-url: http://localhost:8001 ``` Note: only remove the `nlp:` sub-key under `app:`, preserving any other `app:` config above it. - [ ] **Step 4: Verify backend still compiles** ```bash cd backend && source ~/.sdkman/bin/sdkman-init.sh && ./mvnw compile -q ``` Expected: BUILD SUCCESS. - [ ] **Step 5: Commit** ```bash git add backend/src/main/java/org/raddatz/familienarchiv/exception/ErrorCode.java \ backend/src/main/resources/application.yaml \ backend/src/main/resources/application-dev.yaml git commit -m "refactor(search): remove NLP error codes and application config" ``` --- ### Task 3: Delete frontend NL search components and utilities **Files:** - Delete: `frontend/src/routes/search/SmartModeToggle.svelte` + `.spec.ts` - Delete: `frontend/src/routes/search/SmartSearchStatus.svelte` + `.spec.ts` - Delete: `frontend/src/routes/search/InterpretationChipRow.svelte` + `.spec.ts` - Delete: `frontend/src/routes/search/DisambiguationPicker.svelte` + `.spec.ts` - Delete: `frontend/src/routes/search/chip-types.ts` - Delete: `frontend/src/routes/documents/theme-chip-removal.ts` + `.spec.ts` - [ ] **Step 1: Delete all NL search components, specs, and utilities** ```bash rm frontend/src/routes/search/SmartModeToggle.svelte \ frontend/src/routes/search/SmartModeToggle.svelte.spec.ts \ frontend/src/routes/search/SmartSearchStatus.svelte \ frontend/src/routes/search/SmartSearchStatus.svelte.spec.ts \ frontend/src/routes/search/InterpretationChipRow.svelte \ frontend/src/routes/search/InterpretationChipRow.svelte.spec.ts \ frontend/src/routes/search/DisambiguationPicker.svelte \ frontend/src/routes/search/DisambiguationPicker.svelte.spec.ts \ frontend/src/routes/search/chip-types.ts \ frontend/src/routes/documents/theme-chip-removal.ts \ frontend/src/routes/documents/theme-chip-removal.spec.ts ``` - [ ] **Step 2: Commit** ```bash git add -A git commit -m "refactor(search): delete frontend NLP search components and utilities" ``` --- ### Task 4: Remove NL search from SearchFilterBar **Files:** - Modify: `frontend/src/routes/SearchFilterBar.svelte` - Modify: `frontend/src/routes/SearchFilterBar.svelte.spec.ts:199-233` - [ ] **Step 1: Rewrite SearchFilterBar.svelte** Replace the entire ` ``` - [ ] **Step 2: Update the search input element in the template** Replace the `` element (lines 92–105) with: ```svelte ``` - [ ] **Step 3: Remove the SmartModeToggle component from the template** Delete this line (135): ```svelte ``` - [ ] **Step 4: Remove smart-mode describe block from SearchFilterBar.svelte.spec.ts** Delete lines 199–233 (the entire final `describe` block): ```typescript describe('SearchFilterBar – smart-mode chip lifecycle hooks', () => { // ... }); ``` - [ ] **Step 5: Run the SearchFilterBar tests to verify they pass** ```bash cd frontend && source ~/.nvm/nvm.sh && npm run test -- --project=client src/routes/SearchFilterBar.svelte.spec.ts ``` Expected: all tests pass, no failures. - [ ] **Step 6: Commit** ```bash git add frontend/src/routes/SearchFilterBar.svelte \ frontend/src/routes/SearchFilterBar.svelte.spec.ts git commit -m "refactor(search): remove smart mode from SearchFilterBar" ``` --- ### Task 5: Remove NL search from documents/+page.svelte **Files:** - Modify: `frontend/src/routes/documents/+page.svelte` This is the largest edit. Remove all NL search state, derived values, functions, and the NL results template block. - [ ] **Step 1: Remove NL search imports (lines 11–16, 23–27)** Remove these import lines: ```typescript import SmartSearchStatus from '../search/SmartSearchStatus.svelte'; import InterpretationChipRow from '../search/InterpretationChipRow.svelte'; import type { ChipType } from '../search/chip-types.js'; import { buildThemeRemovalUrl } from './theme-chip-removal.js'; import DisambiguationPicker from '../search/DisambiguationPicker.svelte'; ``` Remove these type aliases: ```typescript type NlQueryInterpretation = components['schemas']['NlQueryInterpretation']; type NlSearchResponse = components['schemas']['NlSearchResponse']; type DocumentSearchResult = components['schemas']['DocumentSearchResult']; type PersonHint = components['schemas']['PersonHint']; type SmartSearchErrorCode = 'SMART_SEARCH_UNAVAILABLE' | 'SMART_SEARCH_RATE_LIMITED'; ``` Also remove the `import { csrfFetch } from '$lib/shared/cookies';` line — it is only used by `runSmartSearch`. - [ ] **Step 2: Remove all NL state and derived values (lines 51–70)** Remove these declarations: ```typescript // Smart (NL) search — UI-local state, resets on real page navigation (away + back). let smartMode = $state(false); let nlSubmitted = $state(false); let nlLoading = $state(false); let nlError = $state(null); let nlInterpretation = $state(null); let nlResult = $state(null); const showNlView = $derived(smartMode && nlSubmitted); const nlHasResults = $derived((nlResult?.items.length ?? 0) > 0); const ambiguousPersons = $derived(nlInterpretation?.ambiguousPersons ?? []); const nlIsAmbiguous = $derived(ambiguousPersons.length > 0); const disambiguationHeading = $derived( ambiguousPersons.length === 1 ? m.search_disambiguation_did_you_mean({ name: ambiguousPersons[0].displayName }) : m.search_disambiguation_heading() ); const showDisambiguationCue = $derived(ambiguousPersons.length >= 2); ``` - [ ] **Step 3: Remove all NL search functions (lines 202–318)** Remove these functions entirely: - `resetNlState()` - `onModeToggle()` - `runSmartSearch()` - `switchToKeywordMode()` - `applyResolvedAndSearch()` - `paramsFromInterpretation()` - `removeChip()` - `selectDisambiguated()` - [ ] **Step 4: Update SearchFilterBar usage in the template** Replace the SearchFilterBar call with (removing `bind:smartMode`, `onSmartSearch`, `onModeToggle`): ```svelte (qFocused = true)} onblur={() => (qFocused = false)} /> ``` - [ ] **Step 5: Remove the NL results template block** Replace the entire `{#if showNlView}...{:else}...{/if}` block with just the content of the `{:else}` branch — the `