Kansho/docs/architecture/technical/backend_and_api.md
2026-08-29 11:04:34 +02:00

11 KiB
Raw Blame History

title version status date product_family document_role parent_document
Kanshō Backend und API 0.1 Arbeitsstand 2026-08-19 Jinkendo Technical Chapter / Backend / API technische_zielarchitektur.md

Kanshō Backend und API

Kanonisches Home für FastAPI-Struktur, Router-Schnitt und API-Vertrag. Mitai-Referenz: .claude/rules/ARCHITECTURE.md §1, backend/main.py, backend/routers/.

1. Prinzipien

Herkunft: Mitai-Architekturregeln, als Rahmen übernommen.

1.1 Ein Modul = ein Router

Jedes fachliche Modul besitzt genau eine Router-Datei unter backend/routers/. Endpoints liegen nicht in main.py außer Health/Status.

Neue Module = neue Datei, Registrierung via app.include_router(..., prefix="/api").

Rahmen-Module (erste erwartbare Dateien, keine vollständige Liste):

  • auth
  • profiles
  • später: Dialog, Memory, Journal-Handoff, Gateway-Audit-Metadaten, Admin-Diagnose

Domänenrouter für Mitai-Tracking werden nicht angelegt.

1.2 API-First

Jede vom UI benötigte Funktion ist zuerst ein Endpoint. Das Frontend spricht ausschließlich diese API (Mitai: utils/api.js). Keine fachliche Berechnung, kein Context-Building und kein Privacy-Demasking im Browser.

1.3 Fehlerformat

HTTPException → {"detail": "menschenlesbare Meldung"}

Keine parallelen Formate (error, success: false). Herkunft: Mitai.

1.4 Auth an der Grenze

Geschützte Routen nutzen Depends(require_auth) bzw. require_admin. Ressourcenfilter immer über Session-profile_id. Siehe auth_identity_and_roles.md.

2. Schichten im Backend

Bevorzugte innere Trennung, analog Mitai plus Kanshō-spezifische Gateway-Schicht:

routers/          HTTP, Validierung, Auth-Depends
services/         fachliche Orchestrierung (später)
privacy_gateway/  Minimierung, Pseudonymisierung, Egress, Validation
data/             PostgreSQL-Zugriff

Status: bevorzugte Richtung für Ordnernamen. Kein Zwang, Mitai-Dateibaum 1:1 zu klonen, wenn die Trennlinie Router / Gateway / Persistenz klar bleibt.

Privacy Gateway darf nicht umgangen werden, indem ein Router den Provider direkt aufruft. KI-Ausführung nur über die Prompt-Engine (platform_extensibility.md), Callback = Gateway.

3. Versionierung

Mitai führt backend/version.py mit APP_VERSION und MODULE_VERSIONS.

Status: bevorzugte Richtung gleiches Muster für Kanshō, sobald Code existiert. Semantic Versioning.

4. Health und Betrieb

Ein ungeschützter oder schwach geschützter Status-Endpoint für Deploy-Healthchecks analog Mitai /api/auth/status bzw. Health nach Container-Start.

Konkreter Pfad: offen, Muster übernommen.

5. Entscheidungsstand

Thema Stand Status
FastAPI + ein Router je Modul ja entschieden
API-First, keine Business-Logik im Frontend ja entschieden
Fehlerkörper {detail} ja entschieden
Direktaufruf externer LLMs aus Routern verboten entschieden
OpenAPI als dokumentierter Vertrag später offen
Interne service-Schicht vs. fette Router service-Schicht bevorzugte Richtung

5.1 Implementierungsstand (MVP-Journal-API)

Status: Code vorhanden. Router: backend/routers/journal.py, Prefix /api/journal. Zusammenhängende Umsetzung: mvp_implementation.md.

Produkt-Endpunkte hinter Session-Auth, Isolation über profile_id:

  • Spaces: GET/POST /spaces, GET/PATCH /spaces/{id}, POST /spaces/{id}/days, GET /spaces/{id}/entries, GET /spaces/{id}/trash
  • Days: GET /days/{id} inkl. Conversations, Current Draft, Entries, consolidation_offer
  • Start: GET /continuity
  • Dialog: POST /days/{id}/conversations (erster Impuls), POST /conversations/{id}/turn (ein Modell-Call, bei Erzähler-Fortsetzung einmal Korrektur), GET /conversations/{id}, DELETE /conversations/{id} (Profil-isoliert; Nachrichten und Derived dieser Conversation gehen mit)
  • Status: GET /egress-status (Provider bereit / fail-closed)
  • Derselbe Zug auch unter POST /api/dialogue/conversations/{id}/turn
  • Admin-Antwort zusätzlich decision und trace (Testphase)
  • Generate: POST /days/{id}/generate nur explizit; optionale conversation_ids; include_existing nur nach ausdrücklicher UI-Auswahl; ohne Auswahl kein stilles Mergen; optionaler generation_policy-Snapshot und remember_generation_policy
  • Generation Policy: GET /generation-settings — profilbezogene Defaults der vier Journal-Ausgabeeinstellungen, nicht Writing Profile. Die Anweisungstexte kommen aus generation_instruction_fragments, nicht aus dem Nutzerregler.
  • Additiv 2026-08-27: Generate sendet generation_selection (transformation_id, detail_id, voice_id, narrative_id) und remember_generation_selection (Default false). GET /generation-settings liefert selection, aktive options ohne Promptanweisung und System-defaults. Unbekannte oder nicht aktive IDs: 400 invalid_generation_selection. Der gespeicherte Entwurf enthält generation_snapshot und generation_summary.
  • Additiv 2026-08-28: Ungültige generation_selection bricht vor Detect- und Generate-Provideraufrufen ab. Preview nutzt denselben compile_selection-Pfad. Katalog-Publish/Default ändert gespeicherte Profilauswahl nicht.

5.3 Implementierungsstand (Generierungsrichtlinien)

Status: Code vorhanden. Admin-Session. Purpose zunächst journal_generate.

  • GET /api/admin/generation-instructions/{purpose}
  • PUT /api/admin/generation-instructions/{purpose} — vollständiger Satz, transaktional, ungültige Teilstände werden abgelehnt
  • POST /api/admin/generation-instructions/{purpose}/reset
  • POST /api/admin/generation-instructions/{purpose}/preview — lokal, kein Provider, keine persönlichen Quellen

Additiv 2026-08-27 (benannte Ausprägungen): Der numerische Katalog-PUT entfällt. Übersicht ohne Promptkörper. Detail, Klon, Draft-Update, Veröffentlichen, Archivieren, Standard und Löschen nur für unverwendete Drafts:

  • GET /api/admin/generation-instructions/{purpose} — Kartenfelder, keine Anweisungstexte
  • GET /api/admin/generation-instructions/{purpose}/{id}
  • POST /api/admin/generation-instructions/{purpose} — neuer Draft
  • PUT /api/admin/generation-instructions/{purpose}/{id} — nur Draft
  • POST .../{id}/clone|publish|archive|default
  • DELETE .../{id} — nur ungenutzter Draft
  • POST .../reset — neue Seed-Drafts, keine Überschreibung historischer Varianten
  • POST .../preview — lokal gerenderter Prompt, Dummy-Kontext, kein Provider

UI: /admin/generation mit getrennten Dimensionen, Karten und einem Editor nach „Öffnen“. Source Modes eigener Abschnitt. Keine Seed-Dateipfade in der normalen Adminbeschreibung.

Additiv 2026-08-27 (kein Source Mode): Preview und Admin-UI verwalten nur die vier Gestaltungsdimensionen. source_mode ist kein Request-Feld mehr. Ein Custom-Prompt mit veraltetem Platzhalter: 409 prompt_contract_incompatible, kein Provideraufruf, kein Draft.

  • Entries: POST /entries, GET /entries/{id}, Versionen, Versions-Restore, Soft-Delete, POST /entries/{id}/undelete, POST /entries/{id}/purge. Speichern aus einem Entwurf mit entry_id + origin=accepted_draft legt eine neue Version desselben Entry an.
  • Media: Upload/GET/DELETE; Bilder und einzelne Videos; Position/Unterschrift im Entry-Body als Markdown ![…](kansho-media:<id>)
  • Tagesstichpunkte: PATCH /days/{id}/scratch — lokal, nicht Context-Builder
  • Writing Profile: GET /writing-profile, Import (optional occurred_at, context_hint), Korpus GET/POST /writing-profile/corpus, Rebuild, PATCH Governance, Facet-Edit/Lock, Trait-Edit PATCH /writing-profile/traits/{slug}, Vorschläge annehmen/verwerfen. Brief ist eine abgeleitete Sicht aus Traits und zeitgestempelten Quellen. Media-Token werden vor dem Brief entfernt. JSON-Export/Restore: GET /writing-profile/export, POST /writing-profile/restore. Review: GET /writing-profile/review, POST /writing-profile/review/paste, POST /writing-profile/review/api, POST /writing-profile/review/import, POST /writing-profile/review/accept, POST /writing-profile/review/reject. Initial Build: POST /writing-profile/initial-build/paste, POST /writing-profile/initial-build/api. API und Copy/Paste nutzen denselben Vertrag kansho.profile_analysis_package / kansho.profile_analysis_result (mode initial_build|review, corpus, existing_before_new, expected_result). Legacy-kind kansho.profile_review_* bleibt lesbar. Import erzeugt ein Proposal, kein Current Profile; Übernahme erst nach Accept. Der Current Brief ist kein Import-/Exportformat.
  • Interaction Profile: GET /interaction-profile, PATCH Governance und Präferenzen, Vorschläge annehmen/verwerfen. Keine Ableitung aus Nicht-Widersprechen. Der Slot liegt unter /api/journal nur als Settings-Nachbar, nicht als Journal-Artefakt. JSON-Export/Restore: GET /interaction-profile/export, POST /interaction-profile/restore.
  • Beide Profile: GET /profiles/export, POST /profiles/restore (kind: kansho.profiles). Journal-Backup ist local_backup.py, nicht dieser Profil-Export.

/api/dialogue/* bleibt Low-Level-Source und Admin-Diagnose, nicht die Produkt-IA. Context Builder und Retrieval liegen nicht im Frontend.

5.2 Implementierungsstand (Provider-Admin)

Status: Code vorhanden. GET /api/admin/providers, PUT /api/admin/providers/{generate|detect}. Session-Admin. Body darf einen write-only key enthalten; die Antwort enthält ihn nicht. Persistenz: URL/Modell/Flags in provider_settings, Key in backend/.env.

5.4 Implementierungsstand (Debug-Persistenz)

Additiv 2026-08-28. Session-Admin. Default aus. Nur eigenes Profil in Liste/Export.

  • GET/PUT /api/admin/debug — Schalter persist_enabled
  • GET /api/admin/debug/tree — Space / Tag / Gespräche / Schritte
  • GET /api/admin/debug/latest?journal_day_id=&purpose= — letzter passender Lauf
  • GET /api/admin/debug/runs, GET/DELETE /api/admin/debug/runs/{id}, POST /api/admin/debug/runs/clear
  • GET /api/admin/debug/export?format=json|markdown — optional conversation_id, journal_day_id, purpose. kansho.debug_export v2

UI: /admin/debug (Baum). Im Dialog bei angeschalteter Persistenz: Gesprächs-JSON. Am Journal-Entwurf: sichtbare Testspur und Entwurf-JSON. Kein Gateway-Bypass. Mapping-Labels nicht in der Payload. Keine Live-Testspur unter der Konversation.

6. Offene Fragen

  1. Internes API für mindnet/Kairo: synchron REST vs. Events? → integrations_technical.md
  2. Idempotenz-Keys für Offline-Sync-Queue? → memory_storage_and_offline.md
  3. Rate Limits außer Auth: welche Dialog-Endpoints?

7. Querverweise

  • Technisch: auth_identity_and_roles.md, privacy_gateway.md, runtime_and_deploy.md
  • Mitai: ARCHITECTURE.md §1, INTERNAL_API_REFERENCE.md