Ebene 2 ("Antrag stellen") als einseitiges Formular statt mehrseitigem
Assistenten — jede zusätzliche Seite kostet Zeit, und laut Spezifikation
wird ein Antrag umgangen, wenn er länger als fünf Minuten dauert.
- GET /antraege/neu: Fragebogen-Formular (Abschnitte A-D exakt nach
Spezifikation). Adaptive Folgefragen (C2: welche Art von Entscheidung,
C3: welche Art von Erkennung) werden rein per CSS :has() ein-/
ausgeblendet, kein JavaScript nötig — visuell mit Chromium-Screenshots
verifiziert (unchecked vs. checked).
- POST /antraege: legt an und reicht direkt ein (entwurf->eingereicht in
einem Schritt, kein Zwischenspeichern als Entwurf für v1). Die
antworten-JSON nutzt exakt dieselben Fakten-Schlüssel wie
rules/*.yaml (b1-b7, c1-c5, c2_folge, c3_art) — Schritt 3 kann sie
direkt auswerten, ohne Felder umzubenennen. "Unsicher" wird bewusst
NICHT zu "ja" normalisiert (das ist eine Auswertungsregel für Schritt
3, keine Speicherregel) — der Antrag hält fest, was der Mitarbeiter
tatsächlich geantwortet hat.
- GET /antraege: eigene Anträge (Ebene 2 sieht nur eigene, nicht die
des ganzen Mandanten — dafür neue Store-Methode
ListAntraegeForUser, getrennt von ListAntraegeForAccount für den
späteren Ebene-3-Posteingang).
- GET /antraege/{id}: Detail, fremder Antrag liefert 404 (nicht 403,
gleiches Muster wie überall sonst im Projekt).
- betreiber-Rolle wird von allen Antrags-Routen weggeleitet (Ebene 5
ist technisch getrennt vom Mandantenbereich).
rules/OPEN.md Punkt 3 (fehlende Fragebogen-Unterscheidung für die
"verboten"-Varianten) damit geklärt: c3_art existiert jetzt mit den
bereits in rules/kivo_einstufung.yaml erwarteten Werten.
Volle Testsuite inkl. echter Postgres-Tests grün; End-to-End gegen
einen laufenden Server verifiziert (Antrag anlegen, antworten-JSON in
der DB korrekt, Detail-/Listenansicht, Mandantentrennung).
24 KiB
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 (Textgenerierung/Übersetzung/ Code/Bild/Transkription/Recherche erkennen), 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ß.
Rechte werden als Prüfung an jeder Aktion durchgesetzt (Middleware je Handler), nicht als grob unterschiedene Seitenbereiche.
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).
Die Auswertung gegen echte Fragebogen-Antworten ist noch nicht
gebaut — das ist Schritt 3 der Baureihenfolge (siehe unten), bewusst
erst, wenn der Fragebogen (Schritt 2) die exakten Fakten-Feldnamen
festlegt.
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, Verarbeitungsort, Training-Opt-
out, Zertifizierungen) muss belegbar sein, sonst haftet Deklarix für
eine Aussage, die nicht nachweisbar ist. Einträge älter als 180 Tage
sollen im Ergebnis als "nicht aktuell geprüft" markiert werden (noch
nicht in der UI umgesetzt, siehe Offene Punkte).
CurrentKatalogVersion liefert eine reproduzierbare Kennung des
aktuellen Katalogzustands (Anzahl Einträge + letzte Änderung) — wird in
jeder Bewertung/Entscheidung eingefroren, damit im Audit nachvollziehbar
bleibt, mit welchem Katalogstand ein Vorschlag erzeugt wurde.
Bewertungslogik (geplant, Schritt 3+)
- K.-o.-Prüfung. Einstufung
verboten→ sofort Ablehnung (Art. 5 KI-VO), keine Werkzeugsuche. - Harte Filter. Werkzeuge aussortieren, die eine Pflichtanforderung nicht erfüllen — Grund je Werkzeug festhalten, auch aussortierte Werkzeuge werden im Ergebnis mit Begründung gezeigt.
- Zweckabgleich. Aus
beschreibung/ergebnisden Zweck ableiten (Textgenerierung, Übersetzung, Code, Bild, Transkription, Recherche) und gegengeeignete_zweckefiltern. - Rangfolge. Verbleibende Werkzeuge sortieren: EU-Verarbeitung, Training standardmäßig aus, kurze Aufbewahrung, Aktualität der Prüfung.
- Auflagen ableiten. Statt Ablehnung Bedingungen erzeugen (Pseudonymisierung, keine Klarnamen, Vier-Augen-Prüfung, Kennzeichnung, Aufbewahrung begrenzen).
- Vorschlag erzeugen. Empfehlung, Alternativen, Auflagen, vollständige Herleitung.
Jede Bewertung wird als eigene Zeile gespeichert (append-only, wie
finding/extraction im alten Produkt) — eine neue Bewertung ersetzt
nicht die alte, sie ergänzt sie, damit Nachvollziehbarkeit auch bei
mehrfacher Neubewertung eines Antrags erhalten bleibt.
Entscheidung, Register, Wiedervorlage (geplant, Schritt 5-7)
Der/die Verantwortliche wählt: genehmigt / genehmigt mit Auflagen / abgelehnt / Rückfrage. Begründungsfeld ist bei Abweichung vom Vorschlag Pflicht. Snapshot bei Entscheidung: Regelwerk-Version, Katalog- Version und der vollständige Werkzeugdatensatz werden eingefroren — ein späterer Katalog-Wandel darf nicht rückwirkend verändern, worauf eine Entscheidung beruhte.
Genehmigungen erhalten ein Ablaufdatum (Vorschlag: 12 Monate, bei
hochrisiko 6). Ändert sich im Katalog eine Eigenschaft, auf der eine
aktive Genehmigung beruht, wird der/die Verantwortliche benachrichtigt
(Wiedervorlage).
Jede Genehmigung erzeugt automatisch einen Registereintrag: Zweck, Abteilung, Werkzeug, Datenklasse, Einstufung, Auflagen, Verantwortliche/ r, Datum, Gültigkeit. Export als PDF und CSV.
Onboarding
Firma (Ebene 1, öffentlich, POST /register): Registrierungsformular
mit Firmendaten → Testzugang sofort aktiv → Freischaltung des
Bezahlbetriebs nach Prüfung durch den Betreiber (letzteres noch nicht
gebaut). Beim Anlegen entstehen automatisch: Account, erster Nutzer mit
Rolle admin (siehe Rollentabelle — vereinfacht v1: nicht zusätzlich
separat als verantwortlicher angelegt, siehe Offene Punkte),
leere Abteilungsliste, Werkzeugkatalog aus der Plattform vorbelegt
(noch nicht automatisiert — der zentrale Katalog ist aktuell leer, bis
Ebene 5/Betreiber-Pflege gebaut ist).
Mitarbeiter, geplante Reihenfolge: (1) Einladungslink (Sammellink, Selbstanmeldung, Abteilung beim ersten Antrag), (2) CSV- Import, (3) SSO (Entra ID/Google Workspace), (4) Antrag ganz ohne vorheriges Konto über Mandantenlink + E-Mail-Bestätigungscode (Konto entsteht nebenbei). Keins davon ist gebaut — aktuell nur Firma- Registrierung.
Abrechnung: nach vom Kunden angegebener Mitarbeiterzahl, nicht nach angelegten Nutzern — sonst entsteht der Anreiz, Mitarbeitende nicht anzulegen. Noch nicht gebaut (kein Abo-System).
Projektstruktur
/var/www/deklarix/
├── cmd/
│ └── deklarix/
│ └── main.go # Entry Point: Migration, Regelwerk laden, HTTP-Server
├── internal/
│ ├── auth/ # Passwort-Hashing, Session-Token (produktunabhängig)
│ ├── rules/ # Lädt/validiert Datenklasse-/Einstufungs-/Anforderungs-YAML
│ ├── store/ # Postgres, Migrationen
│ └── web/ # Handler, Templates
├── rules/ # YAML-Regelwerk + OPEN.md (offene fachliche Fragen)
├── design/
│ └── enterprise.css # Design-System (enconf-Basis, ungenutzt seit Pivot)
├── packaging/
│ └── DEBIAN/
│ └── control.tmpl # .deb Package-Control-Template
├── scripts/
│ ├── build.sh # Cross-Compile amd64 + arm64
│ ├── test.sh # Tests + vet + build-check
│ └── release.sh # Vollständiger Release-Prozess
├── go.mod
├── go.sum
└── CLAUDE.md
Datenmodell
account— ein Mandant (ein Unternehmen). Jeder Antrag gehört genau einem Account.app_user— ein Login innerhalb eines Accounts. Rolle ist eine vonmitarbeiter,verantwortlicher,pruefer,admin(alle vier Mandanten-bezogen) oderbetreiber(plattformweit, Ebene 5).session— eine angemeldete Sitzung (Token, Ablaufzeit); echte Tabelle statt zustandsloser signierter Tokens, damit Logout eine Sitzung wirklich beendet.audit_log— Protokoll (append-only): jede Antragsänderung, jede Bewertung, jede Entscheidung, jede Katalogänderung mit Zeitstempel und Akteur.abteilung— Stammdaten für Fragebogen-Feld A.abteilung, je Mandant.werkzeug— Katalogeintrag (siehe oben);account_idNULL = zentral, gesetzt = mandantenspezifische Ergänzung. NICHT append-only — der Katalog wird gepflegt, eine Entscheidung friert den zu ihrem Zeitpunkt gültigen Datensatz separat ein (geplant).werkzeug_sperre— Sperrung eines (auch zentralen) Katalogeintrags durch einen einzelnen Mandanten.antrag— das Vorhaben aus Fragebogen-Abschnitt A plus die vollständigen Antworten aus B/C/D als JSON (antworten, JSONB) — ein starres Spaltenschema könnte den adaptiven Fragebogen nicht abbilden. NICHT append-only (normale Zustandsänderungentwurf→eingereicht→entschieden, wiesubmissiones im alten Produkt war).bewertung,entscheidung,registereintrag— noch nicht gebaut, geplant für Schritt 5/6 der Baureihenfolge.
Append-only: kein UPDATE auf audit_log (Trigger forbid_update_delete,
wiederverwendet aus dem alten Produkt). bewertung/entscheidung/
registereintrag werden bei ihrer Einführung ebenfalls append-only.
Baureihenfolge
Datenmodell, Regelwerk als YAML, Katalogstruktur— erledigt (dieser Stand:account/app_user/session/audit_log/abteilung/werkzeug/werkzeug_sperre/antragin Postgres,internal/ruleslädt und validiert die drei YAML-Regelwerke, Web-Layer kompiliert mit Auth + Plattform-Bereich-Gerüst).Fragebogen mit adaptiver Logik— erledigt (GET /antraege/neueinseitiges Formular,POST /antraegelegt an und reicht direkt ein,GET /antraegeeigene Anträge,GET /antraege/{id}Detail. Adaptive Folgefragen C2/C3 rein per CSS:has()ein-/ausgeblendet, kein JavaScript.antworten-JSON nutzt exakt die Fakten-Schlüssel ausrules/*.yaml(b1-b7, c1-c5, c2_folge, c3_art) — das hat auch die OPEN.md-Frage zu den "verboten"-Fragebogen-Feldern final geklärt.)- Ableitungen und harte Filter (Auswertung gegen echte Antworten)
- Ergebnisdarstellung mit Herleitung
- Entscheidung, Snapshot, Audit-Log
- Registereintrag und Export
- Wiedervorlage und Katalog-Benachrichtigung
Nicht bauen (v1): automatische Genehmigung ohne Mensch, Erkennung tatsächlicher Werkzeug-Nutzung, Mitarbeiterüberwachung (nichts, was Nutzung einzelner Personen auswertet), konfigurierbare Rollen mit eigener Oberfläche, Konzernstrukturen mit Vererbung, mandantenspezifische Regelwerke, Workflow-Designer, SAML, Schnittstellen zu Fremdsystemen.
Go Commands
export PATH=$PATH:/usr/local/go/bin # Immer setzen!
# Entwickeln
go run ./cmd/deklarix/
# Tests
./scripts/test.sh
# oder direkt:
go test -race ./...
go vet ./...
# Build (amd64 + arm64)
./scripts/build.sh 1.0.0
# Build (nur amd64)
./scripts/build.sh 1.0.0 amd64
Build & Release-Prozess
Versioning (Semantic Versioning: MAJOR.MINOR.PATCH)
- MAJOR — Breaking changes, API-Inkompatibilitäten
- MINOR — Neue Features, rückwärtskompatibel
- PATCH — Bugfixes
Release-Schritte
# 1. Alle Änderungen committen
git add -p && git commit -m "feat: ..."
# 2. Release-Skript (macht Tests → .deb-Build → Gitea-Upload → Tag → Push)
./scripts/release.sh 1.2.0
# Danach liegt in dist/:
# deklarix_1.2.0_amd64.deb
# deklarix_1.2.0_arm64.deb
Was das Release-Skript tut
- Prüft: sauberer Git-Status (keine uncommitted changes)
- Führt
./scripts/test.shaus (vet + race tests + build-check, brauchtDATABASE_URL) - Baut
.deb-Pakete fürlinux/amd64undlinux/arm64(scripts/build.sh) - Lädt die Pakete in Giteas Debian-Paketregistrierung hoch (Kanal
testing, Suitesbookworm+trixie) — siehe „Deployment“ unten - Setzt Git-Tag
v<version>mit Annotierung - Pusht
main+ Tag nachorigin
Deployment (apt, Infrastruktur-Standard wie bei enconf)
Updates laufen ausschließlich über ein apt-Paket, nie über manuelles
Kopieren eines Binaries. .deb-Pakete landen in Giteas eingebauter
Debian-Paketregistrierung unter der Gitea-Org projekte (gleicher
Mechanismus wie beim Schwesterprojekt enconf-webpanel). Zielserver
richten sich einmalig ein:
sudo mkdir -p /etc/apt/keyrings
sudo curl -fsSL https://git.netcell-it.de/api/packages/projekte/debian/repository.key \
-o /etc/apt/keyrings/deklarix-gitea.asc
echo "deb [signed-by=/etc/apt/keyrings/deklarix-gitea.asc] https://git.netcell-it.de/api/packages/projekte/debian $(lsb_release -cs) testing" \
| sudo tee /etc/apt/sources.list.d/deklarix.list
sudo apt-get update && sudo apt-get install deklarix
Danach: apt upgrade für Updates, systemctl {start,stop,status} deklarix
für den Dienst. Konfiguration liegt in /etc/deklarix/deklarix.env
(aus deklarix.env.example beim Erstinstall kopiert, DATABASE_URL ist
dort absichtlich auskommentiert — der Dienst startet erst, wenn sie
gesetzt ist; postinst startet ihn sonst bewusst nicht, um keine
Crash-Restart-Schleife gegen einen Platzhalter-Host zu erzeugen).
Aktuell gibt es nur den Kanal testing (kein stable — es gibt noch
keine Kunden, für die eine Trennung nötig wäre).
Testing-Pattern & Qualitätssicherung
// Datei: internal/web/health_test.go
package web_test
import (
"net/http"
"net/http/httptest"
"testing"
)
func TestHealth(t *testing.T) {
req := httptest.NewRequest(http.MethodGet, "/health", nil)
w := httptest.NewRecorder()
HealthHandler(w, req)
if w.Code != http.StatusOK {
t.Fatalf("expected 200, got %d", w.Code)
}
}
- Tests liegen neben dem Code:
paket/foo_test.go - Package:
package foo_test(Black-Box-Test) oderpackage foo(White-Box) - Race-Detector immer an:
go test -race ./... - Tabellenbasierte Tests für mehrere Inputs
DATABASE_URL und Testsystem. internal/store hat Integrationstests
gegen echtes Postgres (u. a. die Append-only-Garantie). Ohne
DATABASE_URL überspringt go test diese Tests einfach — praktisch für
schnelle lokale Iteration ohne lokales Postgres. ./scripts/test.sh
(und damit release.sh) ist strenger: es bricht ohne DATABASE_URL mit
Fehler ab, statt die Append-only-Garantie still zu überspringen. Es
zieht dafür aber kein eigenes Postgres hoch (kein Docker-Zwang auf
dem lokalen Dev-Rechner) — das ist Aufgabe des dedizierten Testsystems,
dort muss DATABASE_URL vorkonfiguriert sein.
Leitplanken, die dauerhaft gelten
- Keine Rechtsdienstleistung. Deklarix bereitet eine Einstufung vor, entscheidet nicht. Keine Formulierung darf eine individuelle rechtliche Bewertung suggerieren oder Erfolgsaussichten behaupten.
- Keine erfundenen Einstufungen. Jede Ableitungsregel steht in einer
Regel-YAML und wurde dort von Hand geprüft; offene fachliche Fragen
stehen in
rules/OPEN.md, werden nicht geraten. - Werkzeugkatalog-Zusicherungen müssen belegbar sein.
quelleundletzte_pruefungsind Pflichtfelder, keine Ausnahme. - Keine Mitarbeiterüberwachung. Nichts im Produkt darf auswerten, welche einzelne Person welches Werkzeug wie oft nutzt — das widerspricht dem Vertrauensmodell, auf dem die freiwillige Antragstellung beruht.
- DSGVO und Hosting in der EU.
Wichtige Hinweise
Go PATH
# Immer setzen — ist nicht im Standard-PATH des Servers
export PATH=$PATH:/usr/local/go/bin
Git Push
git push origin main
# Remote: https://git.netcell-it.de/projekte/deklarix.git
Server-Prozess
# Dienst läuft über systemd (installiert per apt, siehe Deployment oben)
sudo systemctl start deklarix
sudo systemctl status deklarix
# Config: /etc/deklarix/deklarix.env (DATABASE_URL, PORT, RULES_DIR)
# Logs prüfen
journalctl -u deklarix -f
Bekannte Server
| Rolle | Host | Zugang |
|---|---|---|
Testsystem + app.deklarix.de (DB-Integrationstests, apt-Verifikation, nginx-Reverse-Proxy + Let's-Encrypt-TLS auf den lokalen Dienst) |
89.163.205.4 | SSH noroot, sudo passwortlos |
Installer-Endpoint (get.deklarix.com) |
89.163.205.110 | noch nicht eingerichtet |
Marketing-Site (deklarix.de/.com) |
89.163.205.80 | noch nicht eingerichtet |
Arbeitsweise für Claude Code
- Kleine Commits, ein Thema pro Commit
- Erst Test, dann Implementierung
- Keine neue Abhängigkeit ohne Rückfrage
- Fehler nicht verschlucken, keine stillen Fallbacks
- Bei fachlicher Unsicherheit: nicht raten, sondern als offene Frage in
rules/OPEN.mdnotieren
Vor Änderungen
go vet ./...— keine Fehler./scripts/test.sh— alle Tests grün- Bestehenden Code lesen — nicht raten
Nach Änderungen
./scripts/test.sh→ 0 Fehler./scripts/build.sh <version>→ erfolgreich- Commit mit semantischer Message:
feat:,fix:,refactor:,docs: - Bei Release:
./scripts/release.sh <version>
Offene Punkte
- Rangfolge der Datenklassen und Grenzfälle im Anforderungsprofil
(siehe
rules/OPEN.md) — vor Schritt 3 mit dem/der fachlich Verantwortlichen (z. B. Datenschutzbeauftragte/r) bestätigen. Genaue Fragebogen-Felder für die drei "verboten"-Varianten— erledigt in Schritt 2, C3 hat jetzt eine Folgefragec3_art. Weiterhin offen: ob die drei Varianten fachlich vollständig sind (sieherules/OPEN.md, Punkt 3).- Löschfristen je Datenklasse (konkrete Tageswerte für
loeschfrist_max_tage) — noch nicht fachlich festgelegt. - Mandantenisolation auf Datenbankebene (Postgres Row-Level Security)
— die Frontend-Spezifikation fordert das explizit ("nicht in der
Anwendungslogik"), aktuell ist Isolation ausschließlich
anwendungsseitig (Handler-Vergleich
AccountID). Umstellung auf RLS ist ein bewusst noch nicht getroffener Architektur-Entscheid — Aufwand und Zeitpunkt mit dem Nutzer klären, bevor mehr Tabellen entstehen, die sonst nachträglich migriert werden müssten. - "Admin und KI-Verantwortlicher" beim Firma-Onboarding — die
Spezifikation will, dass der erste Nutzer beide Rollen gleichzeitig
hat;
app_user.roleist aktuell ein einzelner Wert. Muss geklärt werden: zwei Rollen pro Nutzer zulassen (Datenmodell-Änderung) oder zweiapp_user-Zeilen für dieselbe Person? - Zentraler Werkzeugkatalog ist leer — "Werkzeugkatalog aus der Plattform vorbelegt" beim Onboarding ist nicht automatisiert, es gibt noch keine Ebene-5/Betreiber-UI zur Katalogpflege.
- Markenanmeldung Deklarix, sobald erster Kunde zahlt.