Zum Hauptinhalt springen

Architekturübersicht (Frontend-Anwendung)

Für Entwickler

Dies ist technische Dokumentation für Entwickler. Wenn Sie ein Geschäftsanwender sind, lesen Sie stattdessen den Erste Schritte-Leitfaden.

Dieses Dokument beschreibt die technische Architektur der Frontend-Anwendung hanc-app-frontend - des Client-Teils der Plattform für Sprachdialoge. Die Anwendung basiert auf Next.js (React) und bietet eine Web-Oberfläche zur Konfiguration und Überwachung von KI-Agenten (Telefon-Assistenten). Im Folgenden werden die Komponenten, Module und Integrationen des Frontends detailliert beschrieben.


1. Einführung

Das Frontend ist eine Single Page Application (SPA) auf Basis von Next.js, die im Browser mit Unterstützung für Server-Side Rendering (SSR) ausgeführt wird. Die Client-Anwendung ist der zentrale Interaktionspunkt für Benutzer mit der Plattform.

1.1 Zweck

Das Frontend bietet eine Oberfläche für:

  • Erstellung und Konfiguration von KI-Agenten;
  • Verwaltung der Wissensdatenbank der Agenten;
  • Anzeige von Anrufverlauf und Analytics;
  • Verwaltung von Abonnement und Abrechnung;
  • Verknüpfung und Verwaltung von Telefonnummern.

Benutzer (Endkunden und Agenturen) nutzen das Frontend zur Konfiguration der Plattform und Steuerung der KI-Agenten.

1.2 Benutzertypen

Die Anwendung wird von zwei Hauptbenutzertypen verwendet:

1.2.1 Endkunde

Ein Benutzer, der sein eigenes Konto und seinen KI-Agenten verwaltet.

Verfügbare Funktionen:

  • Konfiguration des KI-Agenten;
  • Hochladen der Wissensdatenbank;
  • Anzeige von Anrufverlauf und Analytics;
  • Verwaltung des Abonnements;
  • Verknüpfung von Telefonnummern.

1.2.2 Agentur

Ein Benutzer mit erweiterten Rechten, der mehrere Kundenkonten (Customer) oder Arbeitsbereiche (Workspace) verwaltet.

Zusätzlich verfügbare Bereiche:

  • Agency — Verwaltung von Kundenkonten;
  • Team — Verwaltung von Benutzern und Rollen innerhalb der Organisation.

2. Externe Integrationen und Vertrauensgrenzen

Das Frontend fungiert als Vermittler zwischen dem Benutzer und externen Diensten. Jeder Dienst bildet eine separate Vertrauensgrenze, die explizite Authentifizierung und Zugriffskontrolle erfordert.

2.1 HANC Core API

Das Frontend interagiert mit der HANC Core API über RESTful HTTP(S)-Anfragen.

Konfiguration:

  • Basis-URL der API wird über NEXT_PUBLIC_API_URL festgelegt (z.B. https://api.hanc.me/v1/...)
  • API-Version ist explizit in der URL enthalten (/v1)
  • Transport: HTTPS
  • Authentifizierung: Firebase ID Token (Bearer Token)

Implementierung:

  • Alle Anfragen erfordern ein gültiges Firebase ID Token oder API-Key
  • Interaktion erfolgt über Axios mit automatischem Hinzufügen des Authorization-Headers
  • Bei Autorisierungsfehlern initiiert das Frontend eine erneute Benutzeranmeldung

Die vollständige Beschreibung aller API-Endpoints ist unter https://api.hanc.me/api-docs verfügbar, sowie im JSON-Format unter https://api.hanc.me/api-docs/json

Trust boundary: HANC Backend.

2.2 Firebase Authentication

Firebase wird zur Benutzerauthentifizierung auf der Frontend-Seite verwendet.

Funktionen:

  • Unterstützte Methoden: OAuth (Google), E-Mail/Passwort
  • Konfiguration wird über NEXT_PUBLIC_FIREBASE_* übergeben
  • Firebase stellt ID-Tokens aus, die für den Zugriff auf die Core API verwendet werden
  • Firebase wird serverseitig im Frontend (Firebase Admin SDK) für Session-Verwaltung eingesetzt

Vertrauensgrenzen:

  • Firebase ist verantwortlich für Ausstellung und Validierung von Benutzerausweisen
  • Das Backend prüft Signatur und Gültigkeitsdauer der ID-Tokens
  • Für SSR wird Firebase Admin SDK und Session Cookies verwendet

Bei SSR-Anfragen verwendet das Frontend Firebase Session Cookies zur Bestimmung des Authentifizierungsstatus.

Trust boundary: Google Firebase-Infrastruktur.

2.3 Voice Service / LiveKit

Das Frontend integriert sich direkt mit dem LiveKit Client SDK zur Herstellung und Verwaltung von WebRTC-Sprachsitzungen zwischen Benutzer und KI-Agent.

Funktionen:

  • Vor der Verbindung fragt die Anwendung den externen Voice Service unter der öffentlichen URL NEXT_PUBLIC_VOICE_SERVICE_URL ab, um einen temporären Token und Verbindungsparameter zu erhalten
  • Frontend ruft POST /create-room-token auf
  • Der erhaltene Token wird zur Verbindung mit dem WebRTC-Raum über LiveKit SDK verwendet
  • Der Medienstream läuft direkt zwischen Frontend und LiveKit Server

Trust boundary: Voice Service und LiveKit.

2.4 Stripe

Stripe wird für Zahlungsabwicklung und Abonnementverwaltung verwendet.

Frontend-Funktionen:

  • Initiiert Erstellung von Checkout Session und Billing Portal über externe API;
  • Leitet Benutzer zum Stripe-Hosting weiter;
  • Zeigt Operationsergebnis nach Benutzerrückkehr an.

Das Frontend integriert sich nicht mit dem Stripe SDK und verarbeitet keine Zahlungsdaten.

Vertrauensgrenzen:

  • Erstellung von Checkout Session und Billing Portal erfolgt über Core API
  • Stripe Webhooks werden ausschließlich serverseitig verarbeitet
  • Alle sensiblen Zahlungsoperationen liegen außerhalb des Frontends

Trust boundary: Stripe und Core API.

2.5 Twilio

Das Frontend interagiert nicht direkt mit der Twilio API.

Frontend-Funktionen:

  • UI zur Eingabe von Twilio Account SID und Auth Token;
  • Verwaltung von Telefonnummern und deren Status.

Vertrauensgrenzen:

  • Alle Twilio-Operationen (Verifizierung, Import, Nummernkauf, SIP-Einstellungen) erfolgen über Core API
  • Versand und Prüfung von SMS-Codes erfolgt serverseitig
  • Import und Kauf von Telefonnummern erfolgen über API
  • SID und Auth Token werden nicht auf Frontend-Seite gespeichert

Trust boundary: Twilio Verification und Voice Services.

2.6 PostHog Analytics

Das Frontend nutzt PostHog JavaScript SDK zur Erfassung von Analytics.

  • Schlüssel wird über NEXT_PUBLIC_POSTHOG_KEY übergeben
  • Analytics beeinflusst nicht die Geschäftslogik der Plattform

Trust boundary: externes Telemetriesystem.


3. Struktur der Codebasis

3.1 Dateistruktur

Das Projekt ist nach funktionalen Verzeichnissen organisiert, was die Navigation im Code erleichtert. Im Folgenden die Hauptordner und Dateien:

3.1.1 Routenverzeichnis src/app/

  • (auth)/ – Routengruppen für Authentifizierung (Login-, Registrierungs-, Passwortwiederherstellungsseiten usw.). Beispielsweise binden login/page.tsx (Login-Bildschirm) und signup/page.tsx (Registrierungsbildschirm) entsprechende Bildschirmkomponenten aus dem Verzeichnis screens/Auth ein.
  • (...panel)/ – geschützte Routen der Hauptanwendung (Benutzer-Panel). Hier sind Bereiche nach Funktionen organisiert: agency/, dashboard/, settings/ usw., jeweils mit eigener Seite (page.tsx) und manchmal verschachteltem layout.tsx.
  • (public)/ – öffentliche Routen (z.B. Demo-Seiten).

3.1.2 Bildschirmkomponenten src/screens/

Hier befinden sich die UI-Implementierungen für Routen:

  • Auth/ – Authentifizierungsbildschirme. Z.B. LoginScreen/ (Komponenten für Login-Seite) und RegisterScreen/ (Komponenten für Registrierungsseite, einschließlich RegisterScreen.tsx mit Formularlogik und server.ts mit Server-Aktionen für Registrierung).
  • Weitere Bildschirme – z.B. Dashboard/ (Dashboard-Bildschirm), KnowledgeBase/ (Wissensdatenbank-Bildschirm) usw., oft aufgeteilt in Unterkomponenten (components/) und Hilfs-Submodule (z.B. stores/ für State oder providers/ für Context).

3.1.3 UI-Komponenten src/components/

  • ui/ – Basis-UI-Komponenten (Buttons, Eingabefelder, Modals, Tabellen, Icons usw.).
  • features/ – komplexere funktionale Komponenten oder Wrapper (z.B. ReactQueryWrapper für React Query-Initialisierung, Notifications für Benachrichtigungen).
  • widgets/ – spezialisierte Widgets für Seiten (z.B. UserProfileInfo/, CreateAgentModal/, TeamTable/ und andere Komponenten, die Geschäftsdaten im UI anzeigen).

3.1.4 API-Client src/gen/

Automatisch generierter API-Client in TypeScript mit Swagger:

  • http-client.ts – Basis-HTTP-Client, HttpClient-Klasse basierend auf Axios zur Ausführung von Anfragen. Er erstellt eine Axios-Instanz mit angegebener Basis-URL (z.B. aus Umgebungsvariable NEXT_PUBLIC_API_URL) und stellt die request()-Methode zur Anfragenübermittlung bereit.
  • API-Client-Dateien nach Entitäten: User.ts, Agency.ts, Voice.ts usw. – in jeder ist eine Klasse definiert (z.B. UserApi oder ähnlich), die von HttpClient erbt. Diese Klassen enthalten Methoden zum Aufruf spezifischer REST-Endpoints. Beispielsweise führt die Methode userControllerCreateUserV1 in User.ts eine POST-Anfrage an /v1/user zur Benutzerregistrierung aus.

3.1.5 React Query Hooks src/queries/

Für jede Entität sind Funktionen definiert, die @tanstack/react-query verwenden. Z.B. enthält user.ts Hooks zum Abrufen/Ändern von Benutzerdaten, die Methoden aus dem generierten API-Client aufrufen. Dies ist eine Abstraktion über direkte API-Aufrufe, die die Wiederverwendung der Anfragelogik vereinfacht.

3.1.6 Utilities src/utils/

  • validations/ – Schemata und Validierungsfunktionen für Formulare. Hier sind Zod-Schemata für verschiedene Formulare definiert (z.B. LoginFormSchema, SignUpFormSchema usw.) sowie zusammengesetzte Validatoren (E-Mail, Passwort, Captcha usw.).
  • firebase/Firebase-Einstellungen für Authentifizierung: firebaseConfig.ts (Firebase SDK-Konfiguration auf Client-Seite), firebaseAdminConfig.ts (admin SDK-Initialisierung auf Server-Seite) und Hilfsfunktionen (firebaseServer.ts enthält Firebase-Backend-Integrationsmethoden).
  • weitere Utilities – z.B. Datenformatierung, Pfade, clsx.

3.1.7 Weitere Verzeichnisse

  • public/ – statische Dateien (Bilder, Audio usw.).
  • Konfigurationsdateien im Wurzelverzeichnis – next.config.ts, docker-compose.yml, .env.example (Beispiel für Umgebungsvariablen mit API URL und Firebase-Schlüsseln) usw.

3.2 Anwendungsrouten

Das Frontend ist auf Next.js 15 mit App Router (Verzeichnis src/app) implementiert. Der Code ist nach funktionalen Zonen organisiert, unter Verwendung von Routengruppen und verschachtelten Layouts. Dies ermöglicht die Trennung von Anwendungsbereichen, Zugriffsverwaltung (öffentliche vs. geschützte Seiten) und Wiederverwendung von UI-Vorlagen.

3.2.1 (auth) – öffentlicher Bereich für Authentifizierung

Zugänglich ohne Login:

  • /login – Benutzer-Login-Seite (mit E-Mail/Passwort- und Google OAuth-Unterstützung).
  • /signup – Registrierung neuer Benutzer.
  • /forgot-password – Passwortwiederherstellung (E-Mail-Eingabeformular zum Zurücksetzen).

Diese Seiten verwenden ein gemeinsames minimalistisches Layout. Nach erfolgreichem Login wird der Benutzer zu /dashboard weitergeleitet. Wenn bereits autorisiert und /login, /signup aufgerufen wird, leitet die Middleware zum Dashboard weiter.

3.2.2 (public) – öffentliche Seiten

Erfordern keine Autorisierung:

  • /demo-agent-call/[id] – Demo-Seite für Agenten-Anruf. Ermöglicht jedem Besucher, mit einem Demo-Agenten des Web-Clients zu sprechen. Der Benutzer klickt auf die Anruf-Schaltfläche und initiiert eine WebRTC-Verbindung mit dem Agenten. Diese Seite ist für Marketing-/Demonstrationszwecke gedacht, damit potenzielle Kunden den Sprachagenten ausprobieren können.

3.2.3 (...panel) – geschützte Seiten

Zugänglich nach Autorisierung.

Übersicht (/dashboard)

Haupt-Panel nach dem Einloggen. Hier werden zusammenfassende Informationen angezeigt:

Wichtige Metriken und Statistiken: Gesamtzahl der Anrufe, Gesamtgesprächszeit, Durchschnittsdauer. Das Dashboard verwendet üblicherweise ein gemeinsames Layout für geschützte Bereiche (Navigationsleiste links, Header). Es gibt eine Schaltfläche zum Erstellen eines neuen Agenten Create Voice Agent, die je nach Anzahl erstellter Agenten und Tarif deaktiviert sein kann. Ruft POST /v1/agent auf. Verwendet zwei Informationsquellen: GET /v1/call/general-metrics, GET /v1/call/daily-metrics

Voice Agents (/voice-agents)

Bereich zur Verwaltung von KI-Sprachagenten. Dieser Bereich ist im Wesentlichen der wichtigste, er ermöglicht dem Benutzer maximale Anpassung des Agenten für seine Bedürfnisse und umfasst eine umfangreiche Liste von Einstellungen, die unten dargestellt werden

Es gibt eine Schaltfläche zum Erstellen eines neuen Agenten Create Voice Agent, die je nach Anzahl erstellter Agenten und Tarif deaktiviert sein kann. Ruft POST /v1/agent auf. Bestehende Agenten zeigen an, ob eine Nummer für Outbound und/oder Inbound verknüpft ist, sowie zwei Einstellungen: Delete (DELETE /v1/agent/:agent_id) und Duplicate (POST /v1/agent). Für jeden neuen Agenten wird auch POST /v1/llm mit einer neuen Sprachmodell-Instanz aufgerufen.

  • Agent-Details: Seite /voice-agents/[agentID] – Bearbeitung der Agent-Einstellungen. Enthält:

    • Overview: Bereich mit Schnellaktionen und Agentenverwaltung, enthält:

      • Quick Actions: Schnellaktionen wie:
        • Talk to agent: Initiiert Gespräch mit Agent über Web durch Aufruf von POST /v1/create-room-token, Erstellung eines Raums und Verbindung von Benutzer und Voice-Service des Agenten (siehe Abschnitt 7)
        • Demo: Leitet zu /demo-agent-call/:agent_id weiter, wo Agent im Demo-Modus verbunden wird.
        • Call Agent: Um einen Telefonanruf zu testen, muss eine Telefonnummer verknüpft sein, dann erhält der Benutzer bei Klick auf POST /v1/configuration/frontend/list zwei Telefonnummern aus einem Dropdown, durch Anruf kann er die Funktionsfähigkeit des Agenten über Mobilfunk prüfen.
        • Copy AgentID: Agent-ID kopieren.
      • Management: Zusätzliche Funktionen wie Duplicate (Agent duplizieren), Rename (Agent umbenennen), Delete (Agent löschen), sowie Request feature (leitet zur lokalen E-Mail mit Hanc-Kontakt für Funktionsvorschläge weiter)
    • Dashboard: Zeigt Anrufanzahl aus GET /v1/call/daily-metrics/:agent_id, mit Möglichkeit zur sofortigen Aktualisierung und Zeitraumauswahl, enthält auch Stimmungsinformationen der Benutzer aus GET /v1/sentiment-stats/:agent_id.

    • Model: Modellkonfiguration, enthält folgende Bereiche:

      • Knowledge base: Verknüpfung der Wissensdatenbank (Dokumente) mit dem Agenten. Hier können eine oder mehrere Knowledge Bases ausgewählt werden, die der Agent zur Beantwortung von Fragen verwendet.

      • First message: Erste Nachricht, die der Agent zu Beginn des Gesprächs sagt.

      • Agent prompt: Detaillierte Einstellung des Agentenverhaltens, enthält RichTextEditor aus der mantine-Bibliothek.

        Alle Änderungen werden über PATCH /v1/llm/:agent_id gepatcht.

    • Settings: Allgemeine Einstellungen, enthält:

      • Language: Anfängliche Begrüßungssprache, danach wechselt der Agent zur Sprache des Gesprächspartners.

      • Voice: Stimmauswahl (Tonalität, Geschlecht, praktische Anwendungsbereiche).

      • End call after silence: Automatische Anrufbeendigung nach Timeout bei Stille.

      • End-Call timeout (sec): Timeout in Sekunden, wenn ecas aktiviert ist.

      • Reminder timeout (sec): Zeit, nach der die Nachricht bei Stille wiederholt wird.

      • Max reminders: Anzahl der Nachrichten, die der Agent bei Stille sagen kann.

      • Sentiment analysis: Stimmungsanalyse des Anrufers, erfasst als positive | neutral | negative.

      • Call summary: Generiert eine Kurzübersicht des Dialogs mit Schlüsselphrasen und Aktionen.

        Alle Änderungen werden über PATCH /v1/agent/:agent_id gepatcht.

    • Tools: Zusätzliche Werkzeuge:

      • Call Forwarding: Anrufweiterleitungsfunktion, enthält:
        • Name: Name des Account Managers.

        • Forwarding number: Nummer für Weiterleitung.

        • Global condition: Globale Bedingung für Anrufweiterleitung.

          Nach Speichern: POST /v1/agent/:agent_id/tools. Nummer erscheint im Tab Tools mit Möglichkeit zu deaktivieren, ändern (PATCH /v1/agent/:agent_id/tools/:_id), löschen (DELETE /v1/agent/:agent_id/tools/:_id).

      • Book Appointment: Kunden planen und eintragen mit Cal.com-Planer
        • Name: Name des Beratungsplaners,

        • General Condition: Bedingung für Kundeneintragung.

        • API KEY: API-Schlüssel von cal.com.

        • Event ID: Ereignis-ID.

        • Book an appointment: Wenn deaktiviert, prüft nur Verfügbarkeit.

        • Confirmation: Standardmäßig no confirmation, Option mit SMS-Bestätigung.

          Nach Speichern: POST /v1/agent/:agent_id/tools. Tool erscheint im Tab Tools mit Möglichkeit zu deaktivieren, ändern (PATCH /v1/agent/:agent_id/tools/:_id), löschen (DELETE /v1/agent/:agent_id/tools/:_id).

      • API tool RAG: Tool ermöglicht Verbindung zu externem API für Echtzeit-Wissensdatenbank-Anbindung.
        • Name: Tool-Name.

        • General Condition: Bedingung für Anfrage an externes API.

        • Execution message: Nachricht während API-Anfrage.

        • API Endpoint URL: Endpoint für Anfrage.

        • Enthält auch alle Anfrageeinstellungen (Method, Headers, Query Params, mit definiertem Body-Schema (JSON)), sowie Request-Timeout-Einstellung.

          Nach Speichern: POST /v1/agent/:agent_id/tools. Tool erscheint im Tab Tools mit Möglichkeit zu deaktivieren, ändern (PATCH /v1/agent/:agent_id/tools/:_id), löschen (DELETE /v1/agent/:agent_id/tools/:_id).

    • Actions: Tab enthält Satz benutzerdefinierter Variablen für aus dem Dialog extrahierte Werte sowie Aktionen, die aktiviert und mit Variablen interagiert werden können.

      • Retrieval Variables: Extrahierte Variablen, enthält:

        • Text, Number, Boolean, Selector: Name und Beschreibung, nach der LLM Wert in Variable extrahiert.

          Nach Speichern: PATCH /v1/agent/:agent_id. Tool erscheint im Tab Actions/Retrieval Variables mit Möglichkeit zu ändern (PATCH /v1/agent/:agent_id), löschen (PATCH /v1/agent/:agent_id).

      • Actions: Ausführbare Aktionen:

        • Send Email: E-Mail-Versand benötigter Daten:
          • Name: Action-Name.
          • Subject: Nachrichtenbetreff.
          • Message: Beschreibung für LLM der zu extrahierenden Daten. Neben vorgefertigten können benutzerdefinierte Variablen aus Retrieval Variables hinzugefügt werden.
          • General Condition: Bedingung für E-Mail-Versand, bei leerem Feld immer Versand.
          • Recipient Email(s): Empfänger-E-Mail(s).
        • Send SMS: Analog zu E-Mail-Versand, nur ohne subject und Versand per SMS.
        • API Call: Datenversand per API:
          • Name: Action-Name.
          • Condition: Sendebedingung, bei leer immer Versand.
          • API Endpoint URL: Ziel-Endpoint.
          • Satz von Methoden, Parametern, Headern für Versand.

        Nach Speichern: POST /v1/agent/:agent_id/actions. Tool erscheint im Tab Actions mit Möglichkeit zu deaktivieren, ändern (PATCH /v1/agent/:agent_id/actions/:_id), löschen (DELETE /v1/agent/:agent_id/actions/:_id).

    • Widgets: Tab enthält Informationen zur schnellen Widget-Einbettung in beliebige Anwendungen:

      • Floating Widget: Floating-Widget, eingebettet per <script><script/>, erfordert agent-id-Attribut, befindet sich außerhalb des Layout Tree.
      • Inline Widget: Direkt in Seiteninhalt eingebettet, ebenfalls per <script><script/>, erfordert ebenfalls agent-id.
    • Call Logs: Enthält detaillierte Logs mit Export-Funktion in xlsx.

      • Hat viele Metriken: Start Time Duration Direction Source From To Sentiment Variables Status

Call Logs (/call-logs)

Logs aller Anrufe von allen Agenten über bestimmte Zeit, enthält Statistiken:

  • Agent Name: Agentenname.
  • Start time: Anrufstartzeit.
  • Duration: Anrufdauer.
  • Direction: Eingehend oder ausgehend.
  • Source: Quelle.
  • From: Anrufernummer.
  • To: Empfängernummer.
  • Sentiment: Stimmung.
  • Variables: Mögliche Variablen, siehe Voice Agents -> Actions -> Retrieval Variables.
  • Status: Anrufstatus.

Interface ermöglicht Zeitraumauswahl und sofortige Aktualisierung (GET /v1/call/list). Export-Option in xlsx-Format verfügbar.

Knowledge Base (/knowledge-base)

Bereich zur Verwaltung von Wissensdatenbanken für Agenten. Ermöglicht Hochladen und Speichern von Dateien für Retrieval-Augmented Generation.

  • Knowledge Base-Liste: Seite zeigt alle Wissensdatenbanken des aktuellen Benutzers. Jeder Eintrag enthält Name und Dateiliste.
  • Neue KB erstellen: Create-Button öffnet Formular für Name, Prompt und Dateianhang. Prompt ermöglicht klare Angabe, wann auf KB zugegriffen werden soll. Formularabsendung: POST /v1/knowledge-base.
  • Löschen: DELETE /v1/knowledge-base/:_id.
  • Bearbeitung ermöglicht Änderung von Informationen oder Datei, oder Hinzufügen weiterer Dateien (POST /v1/knowledge-base/:_id/files). Datei löschen: DELETE /v1/knowledge-base/:_id/file.

Phone Numbers (/phone-numbers)

Verwaltung verbundener Telefonnummern. Ermöglicht Verbinden, Anzeigen und Löschen von Telefonnummern für Agenten. Zeigt alle aktiven Nummern des aktuellen Workspace:

  • Telefonnummer (internationales Format)
  • Typ
  • Agent für eingehende Anrufe
  • Agent für ausgehende Anrufe

Ohne Abonnement nur Upgrade now-Button verfügbar, der zu /settings/billing weiterleitet.

Mit Abonnement: Möglichkeit zum Importieren von Nummern aus Twilio (erfordert Twilio-Integration), Nummer kaufen Buy number, sowie Connect SIP Trunk (erfordert E-Mail-Kontakt).

Integrations (/integrations)

Einrichtung externer Integrationen:

  • Twilio-Integration über Twilio SID, Twilio Auth Token. Speichern: POST /v1/integration/twilio.
  • Token-Generierung für HANC API-Nutzung

Team (/team)

Team- und Einladungsverwaltung. Ermöglicht Verwaltung von Teammitgliedern des Workspace. Mitgliederliste mit Feldern Name, Email

Invite User-Button öffnet Modal zur E-Mail-Eingabe. Formularabsendung: POST /v1/workspace/invite-member.

Teammitglied entfernen: DELETE /v1/workspace/remove-member/:member_id.

Agency (/agency)

Agenturverwaltung (für Multi-Workspace-Kunden). Enthält zwei Bereiche:

  • Customers: Nur mit Agency-Plan verfügbar, Create Customer-Button öffnet Modal:

    • Name: Anzeigename. Primary contact: Hauptkontakt
    • Full Name: Vollständiger Name.
    • Email: E-Mail.
    • Set initial password: Anfangspasswort setzen.

    Absenden: POST /v1/customer.

  • Account: Agentur-Account, hat zwei Bereiche:

    • Profile:

      • Agenturinformationen.
      • Invite Team Member: Neues Mitglied per E-Mail hinzufügen (POST /v1/agency/invite-user).
    • Domain:

      • CNAME-Record-Verknüpfung möglich, nach manueller DNS-Verknüpfung wird SSL-Zertifikat aktiviert und White-Label eingeschaltet, Benutzer muss per E-Mail für Abschluss kontaktiert werden (PATCH /v1/agency).

Settings (/settings)

Bearbeitbare Benutzerinformationen + Plan & Billing.

  • /settings/profile — Bereich mit Grundinformationen: Full Name, E-mail, Phone Number, Password, Language, Time Zone. Alle Änderungen: POST /v1/user.

  • /settings/billing Bereich mit Downgrade/Upgrade-Plan-Möglichkeit

    • Aktuelle Plan-Informationen.
    • Verbleibende Credits.
    • Verschiedene Pläne und detaillierter Vergleich.

    Bei Klick auf Subscribe: PUT /v1/stripe/subscriptions → Weiterleitung zu Stripe Checkout. Mit Abonnement: Manage billing info-Button (POST /v1/stripe/billing-portal) und Cancel subscription-Button unten.


4. State Management

4.1 Zustand

Für globales UI-State-Management wird Zustand verwendet (Verzeichnis src/store). State umfasst:

  • Benutzerdaten (user)
  • Abonnementstatus
  • WebRTC-Zustände
  • Modal-Verwaltung
  • Auswahl des aktuellen Agenten oder Workspace

4.2 React Query

Für Anfragenverwaltung wird React Query (@tanstack/react-query) verwendet:

  • Cacht Anfragen
  • Aktualisiert Daten per Trigger
  • Verwaltet Zustände: isLoading, isError, isSuccess

Details in Abschnitt 6.


5. UI: Formulare und Validierung

Die Anwendung nutzt intensiv kontrollierte Formulare mit Mantine-Bibliothek und Zod-Validierungsschemata. Für jedes Formular wird ein form-Objekt über useForm-Hook aus @mantine/form erstellt, mit initialValues und Parameter validate: zodResolver(schema). Beispielsweise wird für Login LoginFormSchema verwendet, für Kundenerstellung CreateCustomerFormSchema. Zod ermöglicht strikte Regeln: .string().email({message:'Invalid email'}) oder .string().min(6,{message:'...'}), mit automatischer Fehleranzeige unter Feldern gemäß Mantine-Dokumentation.

5.1 Validierungsschemata

Im Ordner src/utils/validations/ liegen Schema-Dateien mit Zod-beschriebenen Validierungsregeln für Formulare (Feldnamen, Formate, Längen). Diese Schemata werden in Formularkomponenten importiert und an zodResolver übergeben.

5.2 Formularbesipiele

Registrierungsformular (RegisterScreen) enthält E-Mail-, Passwort- und weitere Felder, verbunden mit RegisterFormSchema; Modal-Formulare (z.B. CreateCustomerModal, InviteTeamMemberModal) nutzen analog useForm mit zodResolver und Mantine-Komponenten. Nach Validierung werden Submit-Events durch Mutations-Funktionsaufrufe verarbeitet.

5.3 Fehler und Benachrichtigungen

Bei ungültiger Eingabe wird dem Benutzer die in Zod-Schema definierte Nachricht angezeigt. Bei erfolgreicher/fehlgeschlagener Anfrage wird das gemeinsame Benachrichtigungssystem (Notification) aufgerufen, das Toast für Erfolg oder Misserfolg anzeigt.


6. Data Flow (von UI bis HTTP-Client)

Wenn der Benutzer ein Formular ausfüllt und absendet, initiiert die oberste React-Komponente eine Ereigniskette, die mit einem HTTP-Request an das Backend API endet. Beispiel mit Benutzerregistrierung:

6.1 Initiierung in Komponente

Bei Formular-Submit in RegisterScreen wird onSubmit-Handler aufgerufen. Handler sammelt Formulardaten (Name, E-Mail, Passwort) und startet Registrierungsmutation. Für Serveroperationen wird React Query verwendet – z.B. gibt Hook useRegisterUserQuery() Funktion mutateAsync für Registrierung zurück. Komponente ruft registerUserQuery.mutateAsync(formData) mit Formulardaten auf.

6.2 Anfragefunktionsaufruf (React Query)

In useRegisterUserQuery ist mutationFn definiert, die API-Request ausführt. Sie nutzt generierten User-API-Client. Am Dateianfang wird User-Klasseninstanz (generiert in src/gen/User.ts) mit Basis-URL des API-Servers (aus process.env.NEXT_PUBLIC_API_URL) erstellt. So weiß user-Objekt, wohin es sich wenden soll. Dann ruft mutationFn API-Client-Methode auf: user.userControllerCreateUserV1(data), wobei data Formularobjekt mit Feldern als erforderliches DTO (z.B. CreateUserDto) ist. Diese Methode – Teil der generierten User-Klasse – ist für Registrierungs-Endpoint-Aufruf zuständig.

6.3 Generierter API-Client

Methode userControllerCreateUserV1 in User-Klasse ist vom Generator vordefiniert. Gemäß Swagger-Spezifikation führt sie POST-Request an URL /v1/user (relativ zur Basis-URL) mit Benutzerdaten im Request-Body aus. Request ist als secure markiert (erfordert Autorisierung, hier möglicherweise JWT-Token wenn Benutzer bereits autorisiert, oder nicht verwendet für offene Registrierung). Diese Methode ruft intern universelle request()-Methode der HttpClient-Basisklasse auf.

6.4 HTTP-Client (unterste Ebene)

HttpClient.request() bildet und sendet HTTP-Request mit Axios. Er kombiniert Basis-URL und Pfad (/v1/user), setzt Header (z.B. Content-Type: application/json), serialisiert Request-Body und ruft axios.instance.request(...) auf. Wenn in Client-Konfiguration secure-Flag gesetzt ist, kann vor Request securityWorker ausgeführt werden – Funktion, die Autorisierungsdaten (z.B. Token) zu Request-Parametern hinzufügt. Bei Registrierung hat neuer Benutzer noch keinen Token, daher wird Request ohne Authorization-Header gesendet.

6.5 Backend-Interaktion

Request erreicht Backend (URL und Methode entsprechen Swagger-Dokumentation). Backend erstellt neuen Benutzer und gibt Antwort zurück (z.B. erstellte Benutzerdaten). HTTP-Client erhält Antwort (Axios gibt Promise mit AxiosResponse zurück).

6.6 Ergebnisverarbeitung im Frontend

Nach erfolgreicher Mutation registerUserQuery setzt Registrierungskomponente Logik fort: z.B. wird in unserem Projekt direkt nach Benutzererstellung zusätzlicher Schritt – Authentifizierung des neuen Benutzers – ausgeführt.

Bei Google-Registrierung hat Anwendung bereits userCredential von Firebase. Bei normaler Registrierung (E-Mail/Passwort) loggt Frontend selbst Benutzer in Firebase per signInWithEmailAndPassword ein, direkt nach Backend-Account-Erstellung wird verknüpftes Konto in Firebase Auth erstellt und Login durchgeführt.

Dann wird Funktion authUserOnServer(userCredential) aufgerufen, die Client-Autorisierung mit Server-Session verknüpft. Diese Methode (definiert in firebaseServer.ts) nimmt Token von Firebase für eingeloggten Benutzer und sendet Request an internes Next.js API: POST /api/auth/login mit Header Authorization: Bearer <firebase_id_token>. In unserer Anwendung prüft diese interne Route Token über Firebase Admin SDK und setzt Session-Cookie, damit Benutzer als eingeloggt gilt. Bei 200-Status von /api/auth/login betrachtet Frontend Benutzer als autorisiert.

6.7 Flow-Abschluss

Nach erfolgreicher Registrierung und Login Redirect zu geschützter Seite (per router.push(toHome()). Bei Fehlern auf beliebiger Stufe werden diese behandelt: z.B. bei fehlgeschlagenem Request an /v1/user oder /api/auth/login zeigt UI Fehlermeldung an.

6.8 Analoger Flow für Login

Analoger Flow ist für Login implementiert, bei Login-Formular-Submit ruft Komponente signInWithEmailAndPassword (Firebase) mit eingegebenen Daten auf. Bei erfolgreicher Firebase-Authentifizierung wird authUserOnServer(userCred) für Server-Session-Erstellung aufgerufen. Nach erfolgreicher Antwort von /api/auth/login erfolgt Übergang zur Panel-Startseite. Bei fehlgeschlagenem Login (falsche Credentials) setzt Komponente Formularfehler und zeigt Login-Fehlerbenachrichtigung.

6.9 Zusammenfassung

So initiieren obere Schichten (React-Komponenten und Hooks) Netzwerkanfragen, arbeiten aber nicht direkt mit URLs. Sie nutzen generierte API-Client-Methoden, die Anfragedetails kapseln. Diese Methoden nutzen wiederum gemeinsamen HttpClient auf Axios-Basis für HTTP-Requests an externes Backend-API. Zusätzlich werden für Firebase-Integration Funktionen verwendet, die Requests an interne Next.js-API-Routen senden (z.B. für Auth-Cookie-Setzung nach Login) – dies koordiniert globalen Authentifizierungszustand zwischen Frontend und Backend.

6.10 Middleware

Abschließende Stufe in unserem Fall wird durch Prüfung aus src/middleware.ts abgeschlossen. Bei jedem Request auf geschützte Routen prüfen wir Session-Token-Gültigkeit über firebase-admin. Bei Misserfolg wird Cookie gelöscht und Benutzer zu /login weitergeleitet.


7. Schlüsselszenarien: Arbeit mit Audio-Anrufen

Eine der Schlüsselfunktionen - Organisation von Direktanrufen zum Agenten, sowohl über Telefonnetz als auch über Browser. Frontend stellt WebRTC-Verbindung her und überträgt Audio.

7.1 Szenario 1: Testanruf über Web (WebRTC call)

Diese Funktion ist für Benutzer mit beliebigen Privilegien verfügbar, um ihren Agenten direkt über Browser anzurufen, ohne echten Anruf, z.B. zum Testen von Szenarien oder zur Agenten-Demonstration. Auf Agenten-Seite Demo. Bei Klick startet spezieller Hook useLiveKitCall. Ablauf:

7.1.1 Raum-Initiierung

Hook erstellt neues LiveKit Room-Objekt mit Client-Bibliothek livekit-client. Dies ist lokales Konferenzobjekt.

7.1.2 Event-Listener-Setup

Vor Verbindung registriert Hook Handler für Raum-Events – z.B. RoomEvent.ParticipantConnected, ParticipantDisconnected, neue Audio-Tracks usw. ParticipantConnected-Handler prüft identity, und wenn Agent erkannt wird, setzt Flag agentConnected = true und startet Wiedergabe des Agenten-Begrüßungs-Audios (wenn Agent-Track eintrifft).

7.1.3 Raum-Token-Anfrage

Frontend fragt Voice-Service unter separater Domain (NEXT_PUBLIC_VOICE_SERVICE_URL) ab. POST /create-room-token mit JSON-Body: { metadata: { agent_id: <Agent-ID>, timestamp: <Date.now()> } }. Dieser Request teilt Voice-Service mit, dass Token für Raum mit diesem Agenten benötigt wird.

7.1.4 Antwort erhalten

Voice-Service gibt Objekt mit Konferenzparametern zurück:

  • urlLiveKit-Server-Adresse (z.B. wss://voice.hanc.aiWebSocket URL für Verbindung).
  • tokenJWT Zugriffstoken für Raumverbindung. Token enthält identity des aktuellen Benutzers.
  • room_name – eindeutiger Sitzungsname (vom Service generiert).
  • user_identity – Identity des Anrufers, damit Frontend weiß, wie er auf Server identifiziert ist.

room_name und user_identity werden lokal gespeichert.

7.1.5 LiveKit-Verbindung

await room.connect(url, token) wird aufgerufen, WebRTC-Verbindung zum LiveKit-Server hergestellt. Browser fragt dabei Mikrofon-Zugriff (wenn nicht vorher erteilt).

7.1.6 Audio-Veröffentlichung

Nach erfolgreicher Verbindung wechselt Anrufstatus zu 'connected'. Hook ruft enableMicrophone(room) auf – aktiviert Mikrofon-Audio-Capture und veröffentlicht als Audio-Track im Raum. Benutzer spricht – Stimme wird an LiveKit-Server in diesen Raum gesendet.

7.1.7 KI-Agent-Verbindung

Parallel fügt Voice-Service zweiten Teilnehmer in selben Raum hinzu - den Agenten. Zwei mögliche Wege:

  • Wenn Agent mit Telefonnummer verknüpft, könnte Service ausgehenden Anruf über Twilio (Call API) auf SIP-Trunk LiveKit mit Raumverbindung initiieren. Aber für Web-Anruf ist Twilio nicht nötig, Voice-Service startet selbst KI-Bot-Instanz.

Voice-Service nutzt LiveKit Server SDK oder spezielle Komponente (Media Gateway), um virtuellen Teilnehmer in Raum zu verbinden. Dieser Teilnehmer repräsentiert Agenten: erhält Benutzer-Audio, führt durch Speech-To-Text (STT), dann durch LLM (Dialog-Logik-Kern), Ergebnis durch Text-To-Speech (TTS) – und veröffentlicht generiertes Audio zurück in Raum. Diese Pipeline ermöglicht bidirektionales Echtzeit-Gespräch.

  • Alternative – Twilio SIP: Twilio-Anruf -> SIP -> LiveKit.

Wenn Agent Raum betritt, erhält Frontend ParticipantConnected-Event. useLiveKitCall-Hook erkennt Agent. UI setzt agentConnected-Flag, kann z.B. "Agent joined"-Status anzeigen und auf Agent-Audio warten. Wenn Agent Audio-Track veröffentlicht (synthetisierte Sprache), erhält Frontend über LiveKit SDK Event über neuen Track und startet Wiedergabe (möglicherweise automatisch, oder erfordert "Unmute audio"-Klick wegen Browser-Autoplay-Richtlinien).

7.1.8 Dialog

Benutzer und Agent tauschen Repliken aus. Benutzerstimme geht zum Bot, Bot antwortet – Antwort erklingt im Frontend. Anrufdauer kann unbegrenzt sein, nur durch Minutenguthaben begrenzt.

7.1.9 Anrufende

Benutzer kann end call klicken, oder wenn Agent Verbindung schließt, endet Anruf. Hook verarbeitet RoomEvent.Disconnected, entfernt Listener, gibt Mikrofon-Ressourcen frei. Frontend-UI kehrt in Ausgangszustand zurück.

7.2 Szenario 2: Ein-/ausgehender Anruf über Telefonnetz

Hier ist Frontend nicht direkt am Audio beteiligt, stellt aber Infrastruktur bereit:

7.2.1 Eingehender Anruf

Wenn externer Anrufer erworbene Twilio-Nummer anruft, leitet Twilio über SIP-Trunk Anruf in LiveKit-Raum. Architektur: für jeden Telefonanruf erstellt Backend eindeutigen LiveKit-Raum, verbindet Agenten, verbindet Anruferstimme (über Twilio SIP Gateway) mit selbem Raum. Letztendlich spricht echter Anrufer mit virtuellem Agenten. Frontend ist hier nicht direkt involviert: erfährt nicht von Anruf in Echtzeit. Nach Anrufende landet Aufnahme in Call Logs.

7.2.2 Ausgehender Anruf

Derzeit ist Outbound-Call-Funktion nicht implementiert.

7.3 LiveKit Security

Frontend erhält Token nur für eigene Rolle, kennt Agenten-Token nicht – Voice-Service erstellt ihn selbst. Tokens sind einmalig und kurzlebig. Kommunikation läuft über verschlüsseltes WebRTC. So hat Frontend keinen Zugriff auf Agenten-Audio außerhalb des Raums und vertraut Voice-Service, richtigen Bot zu verbinden.

7.4 Fazit

Frontend-Benutzer kann jederzeit seinen Sprachagenten über Web-Interface testen. Dies vereinfacht Dialog-Debugging ohne echten Anruf. Alle Komplexitäten sind für Benutzer unsichtbar, Frontend stellt qualitative Verbindung sicher. Bei Problemen kann Frontend Session trennen und Fehlermeldung anzeigen.


8. Entwicklung und Debugging

8.1 Lokaler Start

Für lokalen Anwendungsstart ist .env-Datei mit allen nötigen Variablen erforderlich, dann npm run dev starten, für Umgebungstest docker compose build -> docker compose up.

8.2 Logging

Für potenzielle Fehlererfassung sind console.log(...)-Ausgaben vorgesehen, vorher Prüfung auf isDev() NODE_ENV !== 'production', so werden Fehler in Dev erfasst und unnötige console.log in Production ausgeschlossen.

8.3 API-Dokumentation

Für vollständige Hanc Core API-Übersicht, beschrieben per Swagger: https://api.hanc.me/api-docs, sowie https://api.hanc.me/api-docs/json im JSON-Format. Hier sind alle existierenden Endpoints, Method, Headers, Body, erfolgreiche und erfolglose Response-Varianten sowie Operationsname und Typisierung vollständig beschrieben.