- Add icanhazstring/composer-unused as dev dependency for dependency hygiene checks - Add German documentation (docs/) covering architecture, conventions, workflows, and developer checklists - Add API layer (ApiAuth, ApiBootstrap, ApiResponse), audit, scheduler, custom fields, and SSO services - Add Microsoft OIDC SSO, API token management, and user lifecycle features - Add swagger-ui vendor integration and OpenAPI spec - Add production Docker setup and bin/ scripts - Update composer dependencies, config, templates, and frontend assets throughout Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
150 lines
4.9 KiB
Markdown
150 lines
4.9 KiB
Markdown
# Globale Suche erweitern
|
|
|
|
Letzte Aktualisierung: 2026-02-21
|
|
|
|
Diese Doku erklärt, wie neue Entitäten sauber in die globale Suche integriert werden.
|
|
|
|
## Überblick
|
|
|
|
Es gibt zwei Suchausgaben mit derselben Datenquelle:
|
|
|
|
1. **Aside-Preview** (`admin/search/data`)
|
|
- zeigt je Resource Count + bis zu 5 Preview-Einträge.
|
|
2. **Vollseite Suche** (`search/data` -> `/search`)
|
|
- zeigt gemischte Trefferliste über alle Resources.
|
|
|
|
Die zentrale Fassade liegt in:
|
|
|
|
- `/lib/Support/SearchConfig.php`
|
|
|
|
Die eigentliche Logik ist in Provider aufgeteilt:
|
|
|
|
- `/lib/Support/Search/SearchSqlResourceProvider.php`
|
|
- `/lib/Support/Search/SearchUiMetaProvider.php`
|
|
- `/lib/Support/Search/SearchItemMapperProvider.php`
|
|
- `/lib/Support/Search/SearchSpecialResourceProvider.php`
|
|
- `/lib/Support/Search/SearchQueryNormalizer.php`
|
|
|
|
## Relevante Dateien
|
|
|
|
- `/lib/Support/SearchConfig.php`
|
|
- stabile Orchestrierungs-Fassade (kompatible Methoden nach außen)
|
|
- `/lib/Support/Search/SearchSqlResourceProvider.php`
|
|
- Resource-Definitionen (SQL + Permission + Label) + Tenant-Filter
|
|
- `/lib/Support/Search/SearchUiMetaProvider.php`
|
|
- URL- und Icon-Mapping pro Resource-Key
|
|
- `/lib/Support/Search/SearchItemMapperProvider.php`
|
|
- Mapping SQL-Row -> Preview-/Result-Item
|
|
- `/lib/Support/Search/SearchSpecialResourceProvider.php`
|
|
- Spezialressourcen (`docs`, `hotkeys`)
|
|
- `/lib/Support/Search/SearchQueryNormalizer.php`
|
|
- Query-Normalisierung für LIKE/Score
|
|
- `/pages/admin/search/data().php`
|
|
- Aside-Preview API (Counts + Preview)
|
|
- `/pages/search/data().php`
|
|
- Volltext-Treffer API
|
|
- `/templates/partials/app-main-aside.phtml`
|
|
- Sichtbarer Eintrag im Such-Panel (`data-search-key=...`)
|
|
- `/web/js/components/app-global-search.js`
|
|
- Render-Logik (generisch; meist keine Anpassung nötig)
|
|
- `/lib/Service/Docs/DocsCatalogService.php`
|
|
- Zentrale Katalog-/Anchor-Logik für Entwicklerdoku (Single Source of Truth)
|
|
|
|
## Standard-Vorgehen für neue Resource
|
|
|
|
### 1) Resource in `SearchSqlResourceProvider::resources()` anlegen
|
|
|
|
Neue Struktur mit:
|
|
|
|
- `key` (z. B. `scheduled-jobs`)
|
|
- `label` (übersetzbar via `t(...)`)
|
|
- `permission` (z. B. `PermissionService::JOBS_VIEW`)
|
|
- `countSql` + `countParams`
|
|
- `previewSql` + `previewParams`
|
|
- `resultSql` + `resultParams`
|
|
|
|
Regeln:
|
|
|
|
- SQL immer mit `... like ? escape '\\'`.
|
|
- Bei tenant-sensitiven Entitäten `{{tenantFilter}}` nutzen und in `SearchSqlResourceProvider::tenantScopeFilters()` ergänzen.
|
|
- Preview-Query immer mit `limit ?`.
|
|
|
|
### 2) URL-/Icon-/Mapping ergänzen
|
|
|
|
- `SearchUiMetaProvider::iconForKey()` erweitern
|
|
- `SearchUiMetaProvider::listUrl()` erweitern
|
|
- `SearchItemMapperProvider::mapPreviewItem()` ergänzen (falls Spezialformat nötig)
|
|
- `SearchItemMapperProvider::mapResultItem()` ergänzen (falls Spezialformat nötig)
|
|
|
|
Ziel:
|
|
|
|
- Preview und Volltreffer sollen sprechende Labels zeigen.
|
|
- URLs sollen direkt auf sinnvolle Zielseiten gehen.
|
|
|
|
### 3) Eintrag im Aside-Search-Panel anlegen
|
|
|
|
In `/templates/partials/app-main-aside.phtml`:
|
|
|
|
- `<li data-search-key="..." data-search-base="...">` ergänzen
|
|
- Anzeige per Permission guarden (z. B. `$canViewJobs`)
|
|
|
|
Wichtig:
|
|
|
|
- `data-search-key` muss exakt dem `key` in `SearchConfig` entsprechen.
|
|
|
|
### 4) i18n prüfen
|
|
|
|
Neue Labels in:
|
|
|
|
- `/i18n/default_de.json`
|
|
- `/i18n/default_en.json`
|
|
|
|
## Sicherheits- und Qualitätsregeln
|
|
|
|
- Permission in `SearchConfig` setzen, nicht nur im Aside.
|
|
- Tenant-Scope für tenant-bezogene Daten nicht vergessen.
|
|
- Keine sensiblen Daten im Preview-Label.
|
|
- Bei optionalen Modulen nur dann Resource aktivieren, wenn Schema vorhanden ist (oder Migration als Pflicht voraussetzen).
|
|
|
|
## Kurzes Beispiel: `scheduled-jobs`
|
|
|
|
Integration umfasst:
|
|
|
|
- Resource in `SearchSqlResourceProvider::resources()`
|
|
- Mapping auf `admin/scheduled-jobs/edit/{id}`
|
|
- Icon `bi-calendar-check`
|
|
- Aside-Search-Item mit `data-search-key="scheduled-jobs"`
|
|
- Permission `jobs.view`
|
|
|
|
## Doku-Resource (`docs`) im System
|
|
|
|
Die Entwicklerdoku ist als eigene Search-Resource integriert:
|
|
|
|
- Key: `docs`
|
|
- Permission: `docs.view`
|
|
- Quelle: `docs/*.md` (über `DocsCatalogService`, kein `openapi.yaml`)
|
|
- Aside: eigener Block `Documentation` mit Count + Preview
|
|
- Vollsuche: Treffer vom Typ `Documentation`
|
|
- Ziel-URLs: `admin/docs/{slug}#anchor` (direkter Abschnitt)
|
|
|
|
Wichtig:
|
|
|
|
- Anchor-Ermittlung für Docs-Seite und Suche läuft über denselben Service.
|
|
- Dadurch bleiben Hash-Links stabil und konsistent.
|
|
|
|
## Checkliste vor Merge
|
|
|
|
1. `php -l /lib/Support/SearchConfig.php`
|
|
2. `php -l /lib/Support/Search/*.php`
|
|
3. `php -l /templates/partials/app-main-aside.phtml`
|
|
3. Global Search manuell testen:
|
|
- Sidebar-Suche zeigt Count + Preview
|
|
- Klick auf Resource öffnet richtige Liste
|
|
- `/search?search=...` zeigt Volltreffer
|
|
4. Permission-Test:
|
|
- ohne Permission kein Eintrag/keine Treffer
|
|
5. Tenant-Scope-Test (falls relevant)
|
|
6. Bei `docs` zusätzlich:
|
|
- Preview-Link springt auf richtigen Abschnitt
|
|
- Vollsuche zeigt `Documentation`-Treffer mit sinnvollem Snippet
|