Globale Such-API
Die globale Suche findet Vorgänge, Wissen und Bestand über neun Entitätstypen hinweg in einer Abfrage — die Datenquelle der Befehlspalette (Strg+K) und der Suchseite. Sie ist ein Übersichts-Endpunkt: Zähler je Typ plus eine kurze Vorschau. Die gefilterte, seitenweise Suche läuft über die Listen-Endpunkte der jeweiligen Entität.
Die Trennung ist wichtig für eigene Clients: dieser Endpunkt beantwortet „wo gibt es überhaupt Treffer und wie viele" — er kennt weder Seiten noch Filter noch Sortierung. Sobald es um eine vollständige, gefilterte Ergebnisliste geht, ist der Listen-Endpunkt der Entität die richtige Adresse (/api/tickets?q=…, /api/incidents?q=…, jeweils mit der FilterSpec-Abfragesyntax). Die Suchseite der Anwendung ist genau das: eine Klammer über diese neun Listen.
Endpunkt
| Method | Endpoint | Beschreibung |
|---|---|---|
GET | /api/search?q= | Übersicht über neun Entitätstypen (Zähler + Top-3-Vorschau). Nur eingeloggte Benutzer; API-Keys erreichen die Route nicht. |
Query-Parameter
| Parameter | Typ | Beschreibung |
|---|---|---|
q | String, 2–200 Zeichen, Pflicht | Suchbegriff (Groß-/Kleinschreibung egal). Wird vor der Längenprüfung getrimmt: fehlend, kürzer als zwei Zeichen oder nur Leerzeichen ergibt 400 VALIDATION_ERROR mit path ["q"]. |
Weitere Parameter gibt es nicht: die Vorschau ist fest auf drei Zeilen je Entitätstyp begrenzt.
Durchsuchbare Entitäten (9)
| Entität | Durchsuchte Felder | Permission |
|---|---|---|
tickets | ticketNumber, title, description, customer.name | tickets.viewAll ‖ viewOwn |
incidents | number, title, description, businessImpact | incidents.viewAll ‖ viewOwn |
problems | problemNumber, title, description | problems.viewAll ‖ viewOwn |
changes | number, title, description | changes.viewAll ‖ viewPendingApprovals ‖ viewOwn |
articles | title, summary, content, Tag-Namen (Volltext) | immer durchsuchbar — Treffer richten sich nach Sichtbarkeit und Status des Artikels |
assets | assetTag, name, serialNumber, description | assets.viewAll ‖ viewOwn |
contracts | contractNumber, name, vendor, publisher, description | contracts.viewAll ‖ viewOwn |
licenses | name, description, serialNumber, Produktname, Herausgeber | licenses.viewAll ‖ viewOwn |
elibrary | title, publisher | elibrary.view (archivierte Dokumente bleiben ausgeblendet) |
Eine Quelle für Suche und Liste: Suchfelder UND Zeilensicht kommen aus dem FilterSpec-Schema der jeweiligen Entität — dasselbe Schema, das der Listen-Endpunkt nutzt. Der Zähler in der Übersicht zeigt deshalb genau so viele Treffer, wie der Benutzer im Entitäts-Tab wiederfindet: Rechte wie viewOwn wirken in beiden Fällen gleich.
Beispiel-Abfrage
// Global search across all entities
const response = await fetch('/api/search?q=laptop', {
credentials: 'include'
});
const results = await response.json();
// {
// "typeCounts": {
// "tickets": 15, "incidents": 0, "problems": 0, "changes": 0,
// "articles": 3, "assets": 8,
// "contracts": 0, "licenses": 0, "elibrary": 0
// },
// "preview": {
// "tickets": [
// {
// "id": "ticket-uuid",
// "entityType": "tickets",
// "number": "TKT-000123",
// "title": "Laptop won't start",
// "status": "IN_PROGRESS",
// "priority": "HIGH",
// "category": "Hardware",
// "customerName": "John Doe",
// "assigneeName": "Jane Smith",
// "updatedAt": "2026-01-28T10:00:00Z"
// }
// ],
// "assets": [
// {
// "id": "asset-uuid",
// "entityType": "assets",
// "number": "00042",
// "title": "Dell XPS 15 Laptop",
// "status": "DEPLOYED",
// "assetTypeName": "Notebook",
// "category": "Hardware",
// "locationName": "Erdgeschoss",
// "assigneeName": "John Doe",
// "updatedAt": "2026-01-28T09:12:00Z"
// }
// ]
// },
// "totalResults": 26
// }
typeCounts— trägt immer alle neun Schlüssel; ein Typ ohne Leserecht steht auf 0.preview— nur Typen MIT Treffern, je höchstens drei Zeilen, sortiert nach letzter Änderung.status,priority,changeType— als Enum-Werte der jeweiligen Entität in Großbuchstaben, identisch mit den Listen-Endpunkten.- Feld je Fachbegriff:
assetTypeName(Asset-Typ, bei Assets immer gesetzt),changeType(Change-Art),vendor(Verträge) bzw.publisher(Lizenzen, Dokumente).
Verhalten & Performance
- Nebenläufige Ausführung: die Teilabfragen laufen in zwei Blöcken zu je fünf, damit der Verbindungspool nicht ausgereizt wird
- Fehler-Isolation: fällt eine Teilabfrage aus, liefert sie 0 Treffer — die übrigen Entitätstypen antworten normal
- Volltext für die Wissensdatenbank: PostgreSQL-tsvector (Konfiguration german, GIN-Index) mit Stammformen und Umlaut-Behandlung; die übrigen acht Typen vergleichen Teilstrings ohne Beachtung der Groß-/Kleinschreibung
- Soft-Delete-Filter: gelöschte Zeilen sind automatisch ausgeschlossen
Verwandte Seiten
- API-Übersicht — die FilterSpec-Abfragesyntax der Listen-Endpunkte, über die die gefilterte Suche läuft
- Permissions & RBAC — die Leserechte und Sichtbarkeitsregeln, die bestimmen, welche Zeilen ein Treffer sein können
- Wissensdatenbank — Sichtbarkeit, Status und Tags der durchsuchbaren Artikel
- Gespeicherte Ansichten — gespeicherte Listen-Zuschnitte samt Freigaben und Trefferzähler
- Settings — Systemeinstellungen, Nummernkreise, Integrationen