# Deklarix > KI-Antragsprüfung für Unternehmen: Mitarbeitende beschreiben ein > KI-Vorhaben in eigenen Worten, das System leitet Datenklasse, > KI-VO-Einstufung und Anforderungsprofil ab, gleicht sie gegen einen > gepflegten Werkzeugkatalog ab und erzeugt einen begründeten > Entscheidungsvorschlag. Ein Mensch entscheidet, das System bereitet > nur vor. --- ## Produktwechsel (2026-08-28) Deklarix war ursprünglich eine Pre-Publish-Kennzeichnungsprüfung für Werbe-Content (UWG/MStV) für Creator, Agenturen, Marken und Kanzleien. Dieser Scope wurde **komplett verworfen** und durch das oben beschriebene Produkt ersetzt — kein Feature-Zusatz, ein Produktwechsel. Wiederverwendet wurden nur produktunabhängige Bausteine: Auth/Session/ Account-Mandantentrennung, das Prinzip "Regelwerk als versionierte YAML-Dateien, kein ML für die Bewertung", die apt/systemd/Gitea- Deployment-Pipeline und das Design-System. Alles Werberecht-Spezifische (Kennzeichnungsregeln, Beweisarchiv für Social-Media-Posts, Instagram/ TikTok-OAuth, Insights-Erinnerung) wurde entfernt, nicht nur ersetzt — siehe Migration `0008_pivot_ki_antragspruefung` für den genauen Schnitt. --- ## Grundregel **Das System entscheidet nicht. Es bereitet vor.** Der/die Verantwortliche bestätigt, ändert oder überschreibt einen Bewertungsvorschlag — mit Begründungsfeld bei Abweichung. Jede Entscheidung wird als Registereintrag protokolliert. Die Bewertung wird **nie** ohne ihre vollständige Herleitung angezeigt (welche Antwort welche Anforderung ausgelöst hat) — ohne das ist ein Vorschlag im Audit wertlos. Regelbasiert, nicht ML: die Ableitungsregeln (Datenklasse, KI-VO- Einstufung, Anforderungsprofil) liegen als versionierte YAML-Dateien vor, nicht im Code — ein fachlich Verantwortlicher soll sie anpassen können, ohne Go-Code anzufassen. Ein LLM ist v1 höchstens optional zur Zweckerkennung aus dem Freitext vorgesehen (die zwölf Zweck-Kategorien erkennen, siehe `gueltigeZwecke` weiter unten), nie für die Einstufung selbst — und auch dort nur als Vorschlag, den der Mensch bestätigt. --- ## Fünf Ebenen, fünf Rollen Die Oberfläche gliedert sich in fünf Ebenen mit steigender Sensibilität. Vier Mandanten-Rollen sind eine Voreinstellung, kein fest verdrahtetes Modell (spätere Ausbaustufe: konfigurierbare Rollen) — `betreiber` ist technisch getrennt vom Mandantenbereich, keine Voreinstellung. | Ebene | Zugang | Rolle(n) | Zweck | |---|---|---|---| | 1 — Öffentlich | ohne Konto | — | Anmeldung, Passwort zurücksetzen, Einladung annehmen, Antrag über Mandantenlink | | 2 — Mitarbeiter | Konto nötig | `mitarbeiter` | Antrag stellen, eigene Anträge verfolgen, Rückfragen beantworten, freigegebene Werkzeuge einsehen. Bewusst schlank — dauert der Antrag zu lange, wird er umgangen | | 3 — Fachebene | Konto nötig | `verantwortlicher` (Entscheidungsrecht), `pruefer` (identische Sicht, kein Entscheidungsrecht) | Posteingang offener Anträge, Bewertungsvorschlag mit Herleitung, entscheiden, Register, Berichte/Exporte, Audit-Log lesend | | 4 — Mandanten-Verwaltung | Konto nötig | `admin` | Nutzer/Rollen, Abteilungen, Anmeldeverfahren, eigene Werkzeug-Freigaben/-Sperrungen, Rechnungsdaten — bezogen auf GENAU EINEN Mandanten | | 5 — Plattform | Konto nötig, technisch getrennt | `betreiber` | Werkzeugkatalog, Regelwerk-Versionierung, Mandantenverwaltung/Freischaltung, Nutzungssicht — Netcell-IT-Personal, plattformweit über alle Mandanten | **Funktionstrennung bleibt bestehen**, auch wenn in kleinen Firmen dieselbe Person Admin und Verantwortlicher ist — das sind zwei Rollen auf demselben Menschen, keine verschmolzene Rolle. `admin` (Ebene 4, Mandanten-Verwaltung für den eigenen Account) und `betreiber` (Ebene 5, Plattform-Betrieb für Netcell-IT über alle Mandanten) sind nicht dasselbe, auch wenn beide "Admin"-artige Rechte haben — nur `betreiber` ist der Nachfolger dessen, was früher (vor dem Produktwechsel) `admin` hieß. **Praktische Umsetzung dieser Doppelrolle:** `admin` bekommt zusätzlich dieselben Fachebene-Rechte wie `verantwortlicher` (siehe `requireFachebene`/`hatEntscheidungsrecht`) — pragmatisch gelöst ohne Datenmodell-Umbau, siehe Offene Punkte weiter unten. Rechte werden **als Prüfung an jeder Aktion** durchgesetzt (Middleware je Handler), nicht als grob unterschiedene Seitenbereiche. **Ebene 4 ist inzwischen zu großen Teilen umgesetzt** (Anspruch: alles, was im Datenmodell existiert, muss über das Frontend steuerbar sein, nicht nur einsehbar — Deklarix soll ein buchbarer Service werden, ein reiner Anzeige-Screen reicht nicht): - **Nutzerverwaltung** (`internal/web/admin_handlers.go`, Middleware `requireAdmin`): `GET /verwaltung/nutzer` listet alle Logins des eigenen Mandanten mit Status (aktiv/deaktiviert), `GET/POST /verwaltung/nutzer/neu` legt einen weiteren Login mit einer der vier Mandanten-Rollen an (`mitarbeiter`, `verantwortlicher`, `pruefer`, `admin` — `betreiber` kann kein Mandanten-Admin vergeben, das ist Ebene 5). Es gibt noch **keine** Einladungsmail — der Admin setzt das Initialpasswort direkt im Formular. Nutzer werden **nicht gelöscht** (`app_user` wird von `antrag`/`entscheidung`/`audit_log` per Foreign Key referenziert — ein Hard-Delete würde die Historie zerstören), sondern über `POST /verwaltung/nutzer/{id}/deaktivieren` bzw. `.../aktivieren` (de-)aktiviert (Spalte `app_user.active`, Migration 0012). Ein deaktivierter Login kann sich nicht mehr anmelden (`handleLogin` prüft `Active` erst NACH der Passwortprüfung, um keine Kontoexistenz zu verraten) und verliert eine bereits laufende Sitzung sofort (`authenticate`-Middleware prüft `Active` bei jedem Request). Ein Admin kann sich nicht selbst deaktivieren (Aussperr-Schutz). - **Abteilungen** (`GET /verwaltung/abteilungen`, anlegen + löschen): reine Stammdaten für das Fragebogen-Feld "Abteilung" — ohne diese Seite blieb die Abteilung-Auswahl im Fragebogen faktisch leer und unbenutzbar, das war kein Komfort-, sondern ein Funktionsdefizit. - **Eigene Werkzeug-Sperrungen und -Einträge** (`internal/web/mandant_werkzeug_handlers.go`, `GET /verwaltung/werkzeuge`): ein Mandant kann einen zentralen Katalogeintrag für sich sperren/entsperren (`werkzeug_sperre`), ohne den zentralen Katalog selbst zu verändern — das bleibt Sache der Plattform (Ebene 5, `betreiber_werkzeug_handlers.go`). Zusätzlich kann ein Mandant eigene, nur für sich sichtbare Katalogeinträge anlegen/ bearbeiten/löschen (`GET/POST /verwaltung/werkzeuge/neu`, `GET/POST /verwaltung/werkzeuge/{id}`, `POST /verwaltung/werkzeuge/{id}/loeschen` — `werkzeug.account_id` = der eigene Account). Nutzt dasselbe Formular wie der zentrale Katalog (`werkzeugFormData`/`betreiber-werkzeug-form.html`, ein `ActionBase`-Feld unterscheidet Betreiber- von Mandanten-Ziel-URL) — ein zentraler oder fremder Eintrag ist über diese Route nicht erreichbar (404). **Support-Login (Ebene 5, `betreiber`) ist umgesetzt** — auf `GET /betreiber/accounts/{id}` kann sich der Betreiber über `POST .../nutzer/{userID}/anmelden-als` als ein aktiver Kunden-Nutzer anmelden, ohne dessen Passwort zu kennen (`handleBetreiberLoginAls` in `betreiber_handlers.go`, `store.CreateImpersonatedSession`, Migration 0014). Nicht für deaktivierte Nutzer möglich. Die neue Sitzung ersetzt die eigene Betreiber-Sitzung (kein Sitzungs-Stack/"Zurück zum Betreiber" — der Betreiber meldet sich danach mit den eigenen Zugangsdaten neu an). Jede Nutzung erzeugt einen `audit_log`-Eintrag (Action `betreiber_login_als_nutzer`); während der gesamten Sitzung zeigt die Nav einen auffälligen Banner ("Support-Zugriff durch ...", siehe `currentImpersonator` in `middleware.go`), damit nie unklar ist, im Kontext eines fremden Kontos zu handeln. **Firmen-CRUD für den Betreiber ist umgesetzt:** `GET/POST /betreiber/accounts/neu` legt eine Firma samt erstem `admin`-Login an (dasselbe Ergebnis wie die öffentliche Registrierung, nur vom Betreiber ausgelöst — z. B. für vertriebsunterstütztes Onboarding oder Testkonten), `POST /betreiber/accounts/{id}/umbenennen` korrigiert den Firmennamen (`store.UpdateAccount`). Jede Firmenanlage erzeugt einen `audit_log`-Eintrag. Bewusst **kein** Löschen — ein Hard-Delete würde gegen die Fremdschlüssel aus `antrag`/`app_user`/`audit_log` laufen und Historie zerstören (dasselbe Muster wie bei Nutzern: deaktivieren statt löschen, aber ein Sperren/Deaktivieren-Zustand für Accounts existiert noch nicht, siehe unten). **Weiterhin nicht gebaut:** Anmeldeverfahren-Konfiguration, das Abo-System. **Wichtige Korrektur (2026-08-31):** die eigentliche Zahlungsabwicklung/Rechnungsstellung läuft über ein **anderes, externes System** — Deklarix baut dafür **kein Stripe/Zahlungs-SDK**. Deklarix bildet nur den **Subskriptionsstatus** ab (Plan, gebuchte Mitarbeiterzahl, Status wie `test`/`aktiv`/`gekündigt`, Ablaufdatum), der von außen gesetzt wird — noch offen, wie genau ("von außen" heißt aktuell: manuell durch den Betreiber, eine Schnittstelle zum externen Abrechnungssystem ist nicht spezifiziert). Das Preismodell selbst (3 €/Mitarbeiter/Monat, Mindestabnahme 10 Mitarbeiter, 14 Tage Testphase) bleibt als Orientierung gültig, nur der Stripe-Teil der Empfehlung vom 2026-08-29 entfällt. Sperren/Deaktivieren eines Accounts durch den Betreiber hängt weiter an dieser (jetzt kleineren) Subskriptions-Architektur (siehe Offene Punkte: `account.verified` wurde beim Produktwechsel sogar entfernt). **Mandantenfähigkeit:** jede Tabelle trägt `account_id`. Aktuell wird Isolation in der Anwendungsschicht erzwungen (Handler vergleichen `AccountID` gegen den angemeldeten Account, wie bisher) — die Zielvorgabe "Isolation auf Datenbankebene erzwungen" (Postgres Row- Level Security) ist eine bewusst noch nicht getroffene Entscheidung, siehe Offene Punkte unten. --- ## Fragebogen (Ebene 2, "Antrag stellen") Adaptiv: Folgefragen erscheinen nur, wenn die Antwort sie auslöst. Alltagssprache, keine Fachbegriffe — die stehen nur in der Ableitung. **A — Vorhaben:** `titel`, `beschreibung` (Freitext: was soll die KI tun?), `ergebnis` (Freitext: was soll herauskommen?), `haeufigkeit` (einmalig/gelegentlich/täglich/automatisiert), `abteilung` (aus Stammdaten). **B — Daten** (bestimmt die Datenklasse). Mehrfachauswahl Ja/Nein/ Unsicher, "Unsicher" zählt wie "Ja": Namen/E-Mail/Personenangaben (B1), Gesundheit/Religion/Herkunft/Gewerkschaft/Sexualleben (B2), Patienten-/ Mandanten-/Versichertendaten (B3), Bewerbungs-/Personal-/ Leistungsdaten Beschäftigter (B4), von Kunden anvertraute Daten (B5), Konstruktions-/Kalkulations-/Vertragsunterlagen (B6), nur allgemein zugängliche/erfundene Inhalte (B7). **C — Verwendung des Ergebnisses** (bestimmt die KI-VO-Einstufung): geht das Ergebnis unverändert nach außen (C1)? beeinflusst es eine Entscheidung über einen Menschen (C2, Folgefrage: Einstellung/ Beförderung/Kündigung, Kreditwürdigkeit, Leistungsbewilligung, Zugang zu Bildung, medizinische Beurteilung, keins davon)? erkennt/bewertet es Emotionen, Verhalten oder biometrische Merkmale (C3)? läuft es ohne menschliche Prüfung (C4)? merkt der Empfänger, dass es von einer KI stammt (C5)? **D — Werkzeug:** ggf. schon ein Werkzeug im Sinn (optional, Freitext), Firmen- oder privater Zugang, Firmen- oder Privatgerät. --- ## Ableitungen (`rules/*.yaml`, `internal/rules`) **Datenklasse** (`rules/datenklasse.yaml`) — höchste zutreffende Stufe gewinnt: `oeffentlich` (B7) < `intern` (B6) < `auftragsdaten` (B5) < `personenbezogen` (B1, B4) < `berufsgeheimnis` (B3, § 203 StGB) < `besondere_kategorie` (B2, Art. 9 DSGVO). **Die Rangfolge ist eine Annahme** (Spezifikation nennt keine expliziten Ränge) — siehe `rules/OPEN.md`, vor Produktiveinsatz mit dem/der Datenschutz- beauftragten bestätigen. **KI-VO-Einstufung** (`rules/kivo_einstufung.yaml`) — Prüfreihenfolge, erste zutreffende Stufe gewinnt: `verboten` (Art. 5 KI-VO: C3 mit Emotionserkennung am Arbeitsplatz, Social Scoring oder biometrischer Kategorisierung) → `hochrisiko` (C2 mit Beschäftigung/Kreditwürdigkeit/ Leistungsbewilligung/Bildung/Gesundheit) → `transparenzpflicht` (C1 ja und C5 nein) → `minimal` (alles übrige). Die genauen Fragebogen-Felder für die drei "verboten"-Varianten sind noch nicht abschließend spezifiziert — siehe `rules/OPEN.md`. **Anforderungsprofil** (`rules/anforderungen.yaml`) — aus Datenklasse und/oder Einstufung abgeleitete Menge von Anforderungen an ein Werkzeug: `avv_erforderlich`, `eu_verarbeitung`, `kein_training_auf_eingabe`, `loeschfrist_max_tage`, `menschliche_aufsicht`, `kennzeichnungspflicht`, `dsfa_erforderlich`. `internal/rules` lädt und validiert diese drei Dateien (eindeutige IDs, eindeutige Ränge, jede Anforderung braucht mindestens einen Auslöser) und wertet sie seit Schritt 3 auch aus: `EvaluateDatenklasse`, `EvaluateEinstufung`, `IstVerboten`, `DeriveAnforderungen` operieren auf `rules.Antworten` (geparst aus `antrag.antworten` via `ParseAntworten`) — reine, für sich getestete Funktionen ohne DB-/Web-Zugriff. `FilterWerkzeuge`/`ErfuelltAnforderung` filtern einen Werkzeugkatalog hart gegen die abgeleiteten Anforderungen (`WerkzeugEigenschaften` ist ein schlanker, von `store.Werkzeug` unabhängiger Typ, damit `internal/rules` weiterhin ohne `internal/store` auskommt). Seit Schritt 4 wird das auch tatsächlich aufgerufen: `POST /antraege` berechnet nach dem Einreichen sofort eine `bewertung` (append-only, `internal/web/antrag_handlers.go:bewerteAntrag`) — bei `verboten` (K.-o.-Prüfung) ohne Werkzeugsuche — und `GET /antraege/{id}` zeigt sie inklusive Herleitung, RegelwerkVersion/KatalogVersion und dem Pflicht-Hinweis "Das System entscheidet nicht. Es bereitet vor." --- ## Werkzeugkatalog (`werkzeug`, `werkzeug_sperre`) Der eigentliche Wert des Produkts. Zentral gepflegt (Ebene 5, `account_id IS NULL`), für alle Mandanten identisch sichtbar; jeder Mandant kann zusätzlich eigene Einträge (`account_id` gesetzt) und Sperrungen zentraler Einträge (`werkzeug_sperre`) führen, ohne den zentralen Katalog zu verändern. **Pflicht:** `letzte_pruefung` und `quelle` sind NOT NULL — jede Zusicherung im Katalog (AVV verfügbar, Verarbeitungsländer, Training-Opt- out, Zertifizierungen) muss belegbar sein, sonst haftet Deklarix für eine Aussage, die nicht nachweisbar ist. Beide Katalogansichten zeigen eine dreistufige Ampel zum Prüfalter (`pruefStatus()` in `betreiber_werkzeug_handlers.go`, CSS-Klassen `status-niedrig`/ `-mittel`/`-hoch`, dieselben Farbtoken wie die KI-VO-Risikoampel): **aktuell** (grün, < 150 Tage), **bald fällig** (gelb, 150–180 Tage — dasselbe 30-Tage-Vorwarnfenster wie bei der Wiedervorlage), **abgelaufen** (rot, > 180 Tage). `aufbewahrung_tage` ist NULLABLE (Migration 0015) — `NULL` bedeutet "vom Anbieter nicht beziffert" und ist bewusst von `0` ("belegte Zusicherung: sofortige Löschung", z. B. DeepL) unterschieden. Vorher war die Spalte `NOT NULL DEFAULT 0`, wodurch beide Fälle identisch aussahen — `formatAufbewahrung()` zeigt entsprechend "unbekannt" statt "0 Tage". `geeignete_zwecke` ist seit derselben Migration ein kontrolliertes Vokabular statt Freitext: das Formular zeigt Checkboxen statt eines Freitextfelds (`gueltigeZwecke` in `betreiber_werkzeug_handlers.go`, serverseitig validiert via `istGueltigerZweck`). Grund: ein künftiger automatischer Zweckabgleich (Bewertungslogik Schritt 3, weiterhin nicht gebaut) würde an inkonsistentem Freitext ("Text" statt "Textgenerierung") scheitern. Am 2026-08-31 von sechs auf zwölf Kategorien erweitert, nachdem der Nutzer zurecht einwandte, dass sechs Kategorien die tatsächliche Bandbreite an Einsatzgebieten nicht abdecken: Textgenerierung, Übersetzung, Code, Bild, Transkription, Recherche, **Datenanalyse, Video, Audio/Sprache, Kundenservice/Chatbot, Präsentation/Design, Automatisierung/Agenten**. Es gibt keinen einheitlichen Branchenstandard für KI-Funktions- kategorien (regulatorische Taxonomien wie die KI-VO selbst oder OECD/ NIST klassifizieren nach Risiko, nicht nach Funktion; Marktplatz- Kategorien wie bei G2 sind Marketing, kein Standard) — diese zwölf sind Deklarix' eigene, bewusst begrenzte Liste für den künftigen Zweckabgleich, keine allgemeine KI-Taxonomie. Neues Feld `subprozessoren` (TEXT[], Migration 0015) macht Unterauftragsverarbeiter (z. B. Anthropic bei Microsoft 365 Copilot, AWS bei DeepL) als eigenes, durchsuchbares Feld sichtbar statt nur als Freitext in `einschraenkungen` — das ist oft der Grund, warum ein scheinbar EU-verarbeitetes Werkzeug die USA doch nicht ausschließt. Sowohl der zentrale Katalog (`GET /betreiber/werkzeuge`) als auch die mandantenseitige Sicht (`GET /verwaltung/werkzeuge`) zeigen den Katalog als Tabelle (Name, Anbieter, Verarbeitungsländer, DPF, AVV, Training aus, Aufbewahrung, Zertifizierungen, Geeignete Zwecke, Zuletzt geprüft) statt als Liste — vorher waren nur Name/Anbieter/Ort auf einen Blick sichtbar, der Rest war erst nach Klick auf den Detaileintrag zu sehen. **Filter & Paginierung** (seit 2026-08-31, `pagination.go` + `werkzeugFilter` in `betreiber_werkzeug_handlers.go`): beide Katalog-Tabellen haben eine Filterleiste (Freitext über Name/Anbieter/ Verarbeitungsländer, Dropdown über die zwölf Zweck-Kategorien) und serverseitige Paginierung (20 Einträge/Seite, `page`-Query-Parameter). Alles über ein einziges GET-Formular, ohne JavaScript — Prev/Next- Buttons setzen `page` per `