Files
ICON-CRM/docs/10-api.md
T
schakal00783andClaude Opus 5.5 cbac02a96a KI: Modellauswahl als Dropdown + Abgleich mit Produktionsstand
Einstellungen -> KI: statt freiem Modellnamen ein Dropdown mit den
Chat-Modellen, die der hinterlegte OpenAI-Schluessel nutzen darf.

- Backend: listAiModels() fragt OpenAI GET /v1/models, filtert auf
  Chat-Modelle (gpt-*, o*, chatgpt-*; ohne Embedding/Audio/Bild/Instruct
  usw.), neueste zuerst, 10 min im Speicher (Schluesselwechsel laedt neu)
- Neuer Endpunkt GET /api/ai/models (admin)
- Frontend: aktives Modell bleibt waehlbar, auch wenn nicht mehr gelistet;
  Rueckfall auf Textfeld, wenn die Liste nicht abrufbar ist
- Doku: 05-ki (Modellauswahl mit Ablaufdiagramm), 10-api, 08-anleitung

Zieht ausserdem den bereits live laufenden, bisher nicht eingecheckten
Stand nach (perinco-Kontaktabgleich/MergeDialog, Projektmargen,
Whisper-Anpassungen u. a.). Repo entspricht damit icrm.icon-experts.de.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-23 10:26:30 +02:00

6.3 KiB
Raw Blame History

10 API-Referenz

Alles unter /api, Antworten sind JSON. Zugriff mit Authorization: Bearer <token>, sofern nicht anders vermerkt. Bei 401 verwirft das Frontend das Token und zeigt den Anmeldeschirm; 403 bedeutet fehlende Rolle.

Vermerk Bedeutung
offen ohne Anmeldung erreichbar
admin nur Rolle admin
Token fester Token statt JWT (Systemschnittstelle)

Gesundheit

Endpunkt
GET /api/health offen – {"ok":true,"db":"up"}

Anmeldung – /api/auth

Endpunkt Zweck
POST /login offen – { identifier, password } → { token, user }; SHA-256-Hashes des Altbestands werden dabei auf bcrypt umgeschrieben
GET /me angemeldeter Benutzer
PATCH /me Farbe, Foto, Design, hell/dunkel
POST /change-password { currentPassword, newPassword }

Benutzer – /api/users

Endpunkt Zweck
GET /directory Liste für Erwähnungen, Zuständigkeiten, Historie – jede Rolle, nie mit Hashes
GET / admin – vollständige Liste
POST /, PATCH /:id, DELETE /:id admin – anlegen, ändern, löschen

Der letzte aktive Administrator lässt sich nicht degradieren, deaktivieren oder löschen.

Unternehmen – /api/companies

Endpunkt Zweck
GET / Liste mit Filtern
GET /options Namen und Gruppen für Auswahlfelder
GET /:id Karte samt Kontakten, Werdegang, Gesprächen, Historie
POST /, PATCH /:id, DELETE /:id anlegen, ändern, löschen
POST /:id/interviews Gespräch festhalten

Kontakte – /api/contacts

Endpunkt Zweck
GET / Liste mit Filtern
GET /last-employers frühere Arbeitgeber je Kontakt (für „Ehemalige")
GET /:id Karte samt Werdegang, Gesprächen, Verbindungen, Historie
POST /, PATCH /:id, DELETE /:id anlegen, ändern, löschen
POST /:id/interviews Gespräch festhalten
POST /:id/employments Station im Werdegang anlegen (company oder company_id)
PATCH /employments/:employmentId Station ändern
DELETE /employments/:employmentId Station entfernen
GET /:id/cv hochgelegten Lebenslauf herunterladen (Bearer nötig)
POST /linkedin-photo Profilfoto aus der öffentlichen Open-Graph-Vorschau

Ausschreibungen – /api/tenders

GET /, GET /:id, POST /, PATCH /:id, DELETE /:id. Über PATCH laufen auch Phasenwechsel, der Schalter online und die Zuweisung von Kontakten.

Projekte – /api/projects

GET /, POST /, PATCH /:id, DELETE /:id.

GET / liefert zu jedem Projekt zusätzlich contact_rate_onsite und contact_rate_remote – die Stundensätze des zugeordneten Beraters. Sie sind nur für die Margen-Anzeige da und nicht über PATCH änderbar; gepflegt werden sie am Kontakt.

Leads – /api/leads

Endpunkt Zweck
GET / Pipeline; archived entscheidet über Kanban oder Archiv
GET /reminders fällige Erinnerungen – vom ReminderWatcher beim Anmelden und stündlich
GET /:id Karte samt ToDos und Historie
POST /, PATCH /:id, DELETE /:id anlegen, ändern (auch Spalte und Reihenfolge), löschen
POST /:id/acknowledge Erinnerung quittieren: erledigt oder in n Tagen erneut
POST /:id/todos, PATCH /todos/:todoId, DELETE /todos/:todoId Checkliste

CV-Import – /api/cvs

Endpunkt Zweck
GET / Eingang, Screening, Auswahl
POST / hochladen (mehrere, je 15 MB)
POST /:id/analyze auslesen lassen – der einzige Schritt, der die KI ruft; liefert zusätzlich das gefundene Foto
GET /:id/photo das gefundene Bewerbungsfoto, unverändert (die Liste trägt nur has_photo)
POST /:id/accept Vorschlag bestätigen → Kontakt anlegen
POST /:id/reject verwerfen
GET /:id/file Datei herunterladen
DELETE /:id Eintrag entfernen

KI – /api/ai

Endpunkt Zweck
GET /status { configured, model } – steuert, ob die Knöpfe erscheinen
POST /text Schreibhilfe: { task, text, prompt }
GET /config admin – Zustand der Einrichtung; der Schlüssel nur verkürzt
GET /models admin – { models: [{ id, created }] }, Chat-Modelle des hinterlegten Schlüssels, neueste zuerst (10 min zwischengespeichert)
PATCH /config admin – { key?, model? }; key: '' entfernt ihn wieder
POST /test admin – Miniaufruf gegen das Modell

Suche – /api/search

Endpunkt Zweck
GET /?q= normale Suche über alle Bereiche, LIKE
GET /mentions?q= Vorschläge für @
POST /ai erweiterte Suche: { question } → { answer, refs, model, truncated }

Netzwerk, Verbindungen, Historie, Stammdaten, Dashboard

Endpunkt Zweck
GET /api/network Knoten und Kanten für die Netzwerkansicht
GET/POST/PATCH/DELETE /api/connections „kennt"-Verbindungen zwischen Kontakten
GET /api/history, POST /api/history, DELETE /api/history/:id Verlauf lesen, Notiz schreiben, Eintrag entfernen
GET/POST/PATCH/DELETE /api/options Stammdaten (Schreiben admin)
GET /api/dashboard Kennzahlen und letzte Tätigkeiten

perinco – /api/perinco

Endpunkt Zweck
GET /status { configured, url } – ohne Einrichtung bleibt das Häkchen unsichtbar
GET /contacts Kontakte des perinco CRM, gelesen über einen gemeinsamen Zwischenspeicher; wirft nie, sondern liefert im Fehlerfall eine leere Liste

Systemschnittstelle – /api/integrations

Endpunkt Zweck
GET /contacts Token – die ICON-Kontakte für das perinco CRM. Nur Lesen, PERINCO_INBOUND_TOKEN, Vergleich mit timingSafeEqual

Öffentlich – /api/public

Endpunkt Zweck
GET /tenders offen – Ausschreibungen mit online = 1 und status <> 'Archiviert', neueste zuerst
GET /tenders/:id offen – eine davon

Beide antworten mit Access-Control-Allow-Origin: * und Cache-Control: public, max-age=60 und liefern nur id, title, status, notes, created_at, updated_at.