Files
nexarch/docs/INT-12-PRUEFPROTOKOLL.md
patrickandClaude Sonnet 5 358964415c
CI / Web-Barrierefreiheitspruefung (axe, Tastatur, Reflow, Textabstaende) (push) Canceled after 0s
CI / Web-Barrierefreiheitspruefung (axe, Tastatur, Reflow, Textabstaende) (pull_request) Canceled after 0s
CI / Web (dms-browser) (push) Canceled after 0s
CI / Core-Modul (Build/Vet/Test) (pull_request) Canceled after 0s
CI / DMS Security-Test-Gate (AC5, Merge-Gate) (pull_request) Canceled after 0s
CI / Connect Security-Test-Gate (QA-01 AC4, Merge-Gate) (pull_request) Canceled after 0s
AI-Pflichttest-Gate / pflichttest-gate (pull_request) Canceled after 0s
CI / Core-Modul (Build/Vet/Test) (push) Canceled after 0s
CI / DMS Security-Test-Gate (AC5, Merge-Gate) (push) Canceled after 0s
CI / Connect Security-Test-Gate (QA-01 AC4, Merge-Gate) (push) Canceled after 0s
CI / DMS-Modul Supply-Chain-Scan (govulncheck) (push) Canceled after 0s
CI / Web (pdf-viewer) (push) Canceled after 0s
CI / Web (shl) (push) Canceled after 0s
CI / DMS-Modul Supply-Chain-Scan (govulncheck) (pull_request) Canceled after 0s
CI / Web (dms-browser) (pull_request) Canceled after 0s
CI / Web (pdf-viewer) (pull_request) Canceled after 0s
CI / Web (shl) (pull_request) Canceled after 0s
Supply-Chain-Scan (Go) / govulncheck (push) Canceled after 0s
Core-Schnittstellen-Vertragstests / contract-tests (pull_request) Canceled after 0s
Supply-Chain-Scan (Go) / govulncheck (pull_request) Canceled after 0s
Supply-Chain-Scan (npm) / npm-audit (pull_request) Canceled after 0s
Core-Pflichttest-Gate / pflichttest-gate (pull_request) Canceled after 0s
RBAC-Rollenhierarchie-Pflichtgate / rbac-policy-invariant (pull_request) Canceled after 0s
CI / DMS-Modul (Lint/Build/Test/Coverage/Artefakt) (push) Canceled after 0s
CI / DMS-Modul (Lint/Build/Test/Coverage/Artefakt) (pull_request) Canceled after 0s
INT-12: AI-Anbindung Objekttyp-Registrierung (Kopplung AI GOV-01)
DMS registriert den Dokument-Objekttyp inkl. KI-relevanter Felder (Volltext,
Metadaten) beim Start automatisch bei AI GOV-01 - ueber eine neue HTTP-
Schnittstelle (ai/internal/moduletypeapi), da DMS ein getrenntes Go-Modul
ist und GOV-01s Go-Paket nicht importieren kann. Registrierung ist optional
(fehlt die AI-Basis-URL, startet DMS unveraendert) und fail-open (ein
unerreichbarer AI-Dienst blockiert den DMS-Start nie).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-10-15 20:54:31 +00:00

8.8 KiB

Prüfprotokoll INT-12 — AI-Anbindung: Objekttyp-Registrierung (Kopplung AI GOV-01)

Datum: 2026-10-15 Host: 192.168.1.204 (Wegwerf-Arbeitsverzeichnis) Branch: feature/int-12-ai-anbindung-objekttyp-registrierung-kopplung-ai-gov-01

Ausgangslage

  • DOC-01 (dms/internal/upload) liefert Upload/Chunk-Handling, aus dem die KI-relevanten Dokumentfelder stammen (Volltext aus OCR/SRC-05, Kernmetadaten aus MET-02/DOC-01).
  • GOV-01 (ai/internal/moduletype) existierte bereits als reines Go-Paket mit Registry.Register, Get, ListByModule gegen die Tabelle module_objecttypes, inkl. Tenant-Verifikation gegen Core TEN-01 (GOV-07, fail-closed) über das TenantVerifier-Interface.
  • Es gab keinen HTTP-Endpunkt für diese Registrierung — DMS ist ein physisch getrenntes Go-Modul (gitea.perlbach24.de/scripte/nexarch/dms) und kann ai/internal/moduletype nicht importieren. Diese Lücke musste als Teil von INT-12 geschlossen werden (minimal, im bestehenden Baustil von extractapi/residencyapi).

Umsetzung

AI-Modul (ai/)

  • Neu: ai/internal/moduletypeapi — HTTP-Bindung für moduletype.Registry:
    • POST /module-objecttypes (Service-Token-Pflicht über X-Service-Token, fail closed wie extractapi/residencyapi).
    • Antwort 403 bei moduletype.ErrUnknownTenant (GOV-07), 400 bei sonstigen Validierungsfehlern, 200 bei Erfolg.
  • ai/cmd/ai-app/main.go: neue Konfiguration NEXARCH_AI_APP_CORE_BASE_URL / NEXARCH_AI_APP_CORE_SERVICE_TOKEN. Der Endpunkt wird nur verdrahtet, wenn eine Core-Basis-URL konfiguriert ist — ohne Tenant-Verifikationsmöglichkeit bleibt die Registrierungsroute unverdrahtet statt eine Registrierung ohne GOV-07-Prüfung zuzulassen (fail-closed-Grundsatz von GOV-01/GOV-07 bleibt gewahrt).

DMS-Modul (dms/)

  • Neu: dms/internal/moduletypeclient — schlanker HTTP-Client (Muster wie dms/internal/retentionclient für Archive RET-05/DOC-16):
    • Register(ctx, tenantSlug, objectType, fields) → POST {baseURL}/module-objecttypes mit X-Service-Token.
    • DocumentFields() liefert die KI-relevanten Felder des Objekttyps document: fulltext, title, filename, mime_type, created_at, tags.
  • dms/cmd/app/main.go: neue Funktion setupAIObjectTypeRegistration(), aufgerufen beim Start aus main():
    • AK2 (optional/kein Fehler ohne AI-Modul): fehlt NEXARCH_DMS_APP_AI_BASE_URL (stellvertretend für "AI-Modul/Core-LIC-02 nicht aktiviert" — Ops setzt diese URL nur, wenn das AI-Modul lizenziert/aktiv ist, analog zum bestehenden RET-05/DOC-16-Muster in derselben Datei), wird die Registrierung übersprungen, nur eine Logzeile, kein Fehler, kein log.Fatal.
    • AK3 (fail open bei Registrierungsfehlern): jeder Fehler aus Register (Transport, Timeout, Nicht-200) wird nur geloggt (log.Printf), die Funktion kehrt zurück, main() läuft unverändert weiter — kein log.Fatal, kein Blockieren.
    • AK1: bei erfolgreicher Konfiguration wird der Objekttyp document mit den KI-relevanten Feldern automatisch beim Start registriert.

Bewusst nicht umgesetzt (Scope-Entscheidung)

  • Keine Deregistrierungs-/Lösch-Schnittstelle: Die Akzeptanzkriterien von INT-12 fordern nur die Registrierung beim Start; der Ticket-Hinweis zu "Löschfehler dürfen anders behandelt werden" beschreibt nur eine Abgrenzung zur Fail-Open-Regel, verlangt aber keine Deregistrierungsfunktion. Um nicht über das Ticket hinaus zu bauen, wurde keine Delete-Route/-Client ergänzt.
  • Kein eigener HTTP-Client für Core LIC-02 (Feature-Flag-Abfrage) auf DMS-Seite: Ein solcher modulübergreifender Flag-Abfrage-Client existiert im Code noch nirgends (auch nicht in anderen separaten Go-Modulen wie mail/connect/workflow). Stattdessen wird das etablierte, bereits im Code vorhandene Muster (RET-05/DOC-16 in dms/cmd/app/main.go) übernommen: Aktivierung/Deaktivierung wird über das Vorhandensein der Basis-URL-Umgebungsvariable abgebildet, die Ops nur setzt, wenn das Modul lizenziert ist. Diese Design-Entscheidung ist dokumentiert, falls ein künftiges Ticket einen generischen LIC-02-HTTP-Client für module-übergreifende Flag-Abfragen einführt.

Automatisierte Tests (real ausgeführt)

Testdatenbank (Wegwerf, eigens angelegt, nicht dms_dev/archivdms):

  • Rolle/DB int12_ai_test (Postgres 17, lokal auf 204).

AK1 — Registrierung erscheint bei AI

  • ai/internal/moduletypeapi/moduletypeapi_test.go::TestHandleRegister_ValidRequest_Registered — POST gegen echten httptest-Server + echte Postgres-DB, Nachweis per Registry.Get.
  • dms/internal/moduletypeclient/moduletypeclient_test.go::TestRegister_SendsExpectedPayloadAndAuth — Client sendet korrektes Payload/Token.
  • Realer End-to-End-Nachweis (Prüfung 1, siehe unten): echter ai-app-Prozess + echter DMS-Client-Aufruf, Ergebnis per direkter SQL-Abfrage verifiziert.

AK2 — AI-Modul nicht aktiviert → DMS startet unverändert

  • dms/cmd/app/aiobjecttype_test.go::TestSetupAIObjectTypeRegistration_NoBaseURL_SkipsWithoutPanic — keine NEXARCH_DMS_APP_AI_BASE_URL, Aufruf kehrt ohne Fehler zurück.
  • TestSetupAIObjectTypeRegistration_NoTenantSlug_SkipsWithoutPanic — zusätzliche Absicherung (fehlender Tenant-Kontext).

AK3 — Registrierungsfehler blockieren DMS-Start nie

  • dms/cmd/app/aiobjecttype_test.go::TestSetupAIObjectTypeRegistration_UnreachableEndpoint_DoesNotBlock — Basis-URL zeigt auf geschlossenen Port (127.0.0.1:1), Aufruf kehrt kontrolliert mit Logzeile zurück statt zu blockieren/abzustürzen.
  • dms/internal/moduletypeclient/moduletypeclient_test.go::TestRegister_UnreachableEndpoint_IsError / TestRegister_NonOKStatus_IsError — Client liefert Fehler statt stillschweigend zu akzeptieren (Aufrufer entscheidet über Fail-Open).
  • ai/internal/moduletypeapi/moduletypeapi_test.go::TestHandleRegister_MissingServiceToken_Rejected, TestHandleRegister_UnknownTenant_Rejected — AI-seitiges fail-closed bei Auth/Tenant bleibt erhalten.

Alle genannten Tests real ausgeführt und grün:

ok  ai/internal/moduletypeapi        0.539s   (3 Tests)
ok  ai/internal/moduletype           (unverändert grün)
ok  ai/cmd/ai-app                    (unverändert grün)
ok  dms/internal/moduletypeclient    (3 Tests)
ok  dms/cmd/app                      (alle Tests inkl. 3 neue INT-12-Tests)

Vollständiger go test ./... des ai-Moduls (alle ~50 Pakete) ebenfalls grün mit TEST_TENANT_DSN gegen int12_ai_test.

Prüfungen vor Abnahme (real durchgeführt, nicht nur behauptet)

Prüfung 1 — Registrierung gegen echte, laufende AI-Testinstanz

  1. Migrationen auf int12_ai_test angewendet (ai/internal/migrate, 16 Migrationen inkl. module_objecttypes).
  2. Core-TEN-01-Stub gestartet (127.0.0.1:19901): GET /tenants/mandant-int12 → 200, alles andere → 404 (einfacher, legitimer Stub für die fremde, bereits eigenständig vertragsgetestete Core-Schnittstelle — kein DB-Mocking).
  3. Echter ai-app-Prozess gestartet (go build → Binary, 127.0.0.1:19902), verbunden mit int12_ai_test und dem Core-Stub, NEXARCH_AI_APP_CORE_BASE_URL gesetzt → Route /module-objecttypes ist verdrahtet.
  4. Echter DMS-Client (moduletypeclient.Register) rief http://127.0.0.1:19902/module-objecttypes auf → Antwort 200 ok.
  5. Direkte SQL-Abfrage gegen int12_ai_test:
    select tenant_slug, module_name, object_type, fields from module_objecttypes where tenant_slug='mandant-int12';
    
    Ergebnis: ein Datensatz dms/document mit allen 6 KI-relevanten Feldern (fulltext, title, filename, mime_type, created_at, tags) — Objekttyp ist nachweislich bei AI registriert.
  6. Alle Testprozesse (ai-app, Core-Stub) anschließend beendet (pkill), keine Leichen.

Prüfung 2 — AI-Modul-Flag deaktiviert

  • TestSetupAIObjectTypeRegistration_NoBaseURL_SkipsWithoutPanic: NEXARCH_DMS_APP_AI_BASE_URL leer → setupAIObjectTypeRegistration() kehrt sofort zurück, nur eine Logzeile ("deaktiviert"), kein Fehler, kein Prozessabbruch. Entspricht dem Normalbetrieb ohne AI-Modul.

Prüfung 3 — AI-Endpunkt nicht erreichbar bei Registrierung

  • TestSetupAIObjectTypeRegistration_UnreachableEndpoint_DoesNotBlock: NEXARCH_DMS_APP_AI_BASE_URL=http://127.0.0.1:1 (verbindungsrefused) → Register liefert Fehler, setupAIObjectTypeRegistration() loggt ihn und kehrt zurück, main() würde unverändert weiterlaufen (kein log.Fatal im Pfad). Client-seitig zusätzlich durch TestRegister_UnreachableEndpoint_IsError abgesichert (Timeout über context.WithTimeout(10s) in setupAIObjectTypeRegistration, kein endloses Warten).

Aufräumen

  • Testprozesse (ai-app-Binary, Core-Stub) beendet.
  • Temporäre cmd/int12-*-tmp-Verzeichnisse (Migrations-Runner, E2E-Runner) nach Gebrauch wieder gelöscht.
  • Postgres-Rolle/DB int12_ai_test bleibt auf 204 als Wegwerf-Testartefakt stehen (keine Kollision mit dms_dev/archivdms), kann bei Bedarf gelöscht werden: DROP DATABASE int12_ai_test; DROP ROLE int12_ai_test;