Replaces the generic React/Vite/SQLite scaffold description with the actual Deklarix product spec: what it does, the two-stage extract/rules principle, the Postgres-based stack and cmd/deklarix structure, data model, evidence chain, legal guardrails (UWG, Versicherungsaufsicht, BRAO), QA via the golden-test suite, and the DATABASE_URL/test-system split for scripts/test.sh. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
345 lines
12 KiB
Markdown
345 lines
12 KiB
Markdown
# Deklarix
|
|
|
|
> Prüfung und Nachweis für Werbe-Content. Pre-Publish-Kennzeichnungsprüfung
|
|
> und revisionssichere Archivierung für Creator, Agenturen, Marken und
|
|
> Kanzleien. `deklarix.de` / `deklarix.com`
|
|
|
|
---
|
|
|
|
## Was das Projekt ist
|
|
|
|
Drei Funktionen, mehr nicht:
|
|
|
|
1. **Pre-Publish-Prüfung** — Caption, Standbild und Vertragslage rein,
|
|
Risikobewertung mit konkreten Korrekturvorschlägen raus.
|
|
2. **Beweissicherung** — jeder veröffentlichte Beitrag wird mit Hash und
|
|
Zeitstempel archiviert: Screenshot, Caption, sichtbare Kennzeichnung,
|
|
verknüpfter Vertrag, Briefing.
|
|
3. **Verantwortungsmatrix** — wer hat was vorgegeben, wer hat freigegeben,
|
|
wer schuldet welche Prüfung (Creator / Agentur / Marke).
|
|
|
|
**Wer nutzt es, wer zahlt:** Creator nutzen es täglich, zahlen wenig
|
|
(Reichweite/Referenz). Agenturen und Marken zahlen richtig — sie haften
|
|
über § 8 Abs. 2 UWG mit und brauchen Freigabe-Workflow plus
|
|
Nachweisarchiv. Kanzleien lizenzieren Deklarix als Whitelabel für ihre
|
|
Mandanten (zahlen für Software, nicht für Mandantenzugang); das
|
|
Kanzlei-Verzeichnis im Produkt bleibt kostenlos.
|
|
|
|
**Rollen von Anfang an.** Eine Submission gehört nicht einem Nutzer,
|
|
sondern hat Beteiligte mit Rollen (`creator`, `agentur`, `marke`,
|
|
`kanzlei`). Alle vier existieren im Datenmodell ab dem ersten Commit.
|
|
|
|
**Kein Demo-Shortcut.** Es wird direkt produktionsreif entwickelt —
|
|
keine reduzierte Zwischenstufe mit manuell eingetragenen Daten oder ohne
|
|
Login als Selbstzweck.
|
|
|
|
---
|
|
|
|
## Kernprinzip: das Modell entscheidet nicht
|
|
|
|
**Das LLM extrahiert Fakten. Das Regelwerk in Go fällt das Urteil.**
|
|
|
|
- **Stufe 1 — Extraktion (Claude API):** Eingabe Caption plus Bild/Video,
|
|
Ausgabe striktes JSON (Plattform, Gegenleistung, Kennzeichnung
|
|
vorhanden/Kanal/Wortlaut/Position, Produktkategorie, Verlinkungen, ...).
|
|
Ist die Extraktion unsicher, liefert sie `unklar` — nie eine geratene
|
|
Bewertung.
|
|
- **Stufe 2 — Bewertung (Go, deterministisch):** Regelwerk als
|
|
versionierte YAML-Dateien (`rules/`). Jedes Finding referenziert
|
|
Regel-ID und Version (z. B. `WK-004 v3`). Regeln sind
|
|
plattformunabhängig — UWG/MStV gelten überall gleich, nur
|
|
Darstellungsdetails unterscheiden sich; die gehören in
|
|
Regelbedingungen/Extraktion, nie in separate Regelsätze pro Plattform.
|
|
|
|
**Absolute Regel:** Das Modell nennt niemals selbst Normen, Urteile oder
|
|
Randnummern. Fundstellen stehen ausschließlich in den kuratierten
|
|
YAML-Regeln. Eine halluzinierte Fundstelle ist in diesem Markt ein
|
|
Totalschaden.
|
|
|
|
---
|
|
|
|
## Stack
|
|
|
|
Bewusst langweilig, ein Binary, lokal lauffähig:
|
|
|
|
| Bereich | Wahl |
|
|
|---|---|
|
|
| Sprache | Go 1.26, Standard-Library wo möglich |
|
|
| Web | `net/http` + `html/template` + htmx, kein Frontend-Build, kein React |
|
|
| Datenbank | PostgreSQL über `pgx`, Migrationen über `golang-migrate` |
|
|
| PDF | serverseitig erzeugt |
|
|
| Zeitstempel | RFC-3161 von einer öffentlichen TSA |
|
|
| Extraktion | Claude API (nur Fakten-Extraktion, siehe oben) |
|
|
| Design | `design/enterprise.css` (Enterprise Light Theme, enconf-Pattern, Primärfarbe `#1677ff`) |
|
|
|
|
Kein Docker für die App selbst, kein React, keine Queue. Neue
|
|
Abhängigkeiten nur nach Rückfrage.
|
|
|
|
**Warum Postgres statt SQLite:** Das Produkt läuft von Anfang an für
|
|
hunderte gleichzeitige Nutzer über mehrere Mandanten (Creator, Agentur,
|
|
Marke, Kanzlei). Ein revisionssicheres Beweisarchiv braucht robuste
|
|
Concurrent-Writes sowie Point-in-Time-Recovery/Replikation — das ist mit
|
|
SQLites Single-Writer-Modell nicht sauber zu bauen. Gehostet wird
|
|
Managed Postgres in der EU (DSGVO).
|
|
|
|
**Pfad:** `/var/www/deklarix` | **Git:** `https://git.netcell-it.de/projekte/deklarix` | **Branch:** `main`
|
|
|
|
---
|
|
|
|
## Projektstruktur
|
|
|
|
```
|
|
/var/www/deklarix/
|
|
├── cmd/
|
|
│ └── deklarix/
|
|
│ └── main.go # Entry Point, HTTP-Server
|
|
├── internal/
|
|
│ ├── extract/ # Claude-API-Aufruf, JSON-Schema, Validierung
|
|
│ ├── rules/ # YAML-Loader, Auswertung, Versionierung
|
|
│ ├── evidence/ # Hashing, Zeitstempel, Append-only-Log
|
|
│ ├── dossier/ # PDF-Erzeugung
|
|
│ ├── store/ # Postgres, Migrationen
|
|
│ └── web/ # Handler, Templates
|
|
├── rules/ # YAML-Regeln, versioniert im Git
|
|
├── testdata/
|
|
│ └── golden/ # Golden-Tests: Beispielbeiträge + erwartetes Ergebnis
|
|
├── design/
|
|
│ └── enterprise.css # Design-System (enconf-Basis)
|
|
├── 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
|
|
|
|
Fünf Tabellen, mehr braucht der MVP nicht:
|
|
|
|
- `submission` — ein eingereichter Beitrag, Status, Zeitpunkte
|
|
- `asset` — Bild oder Datei, Pfad, SHA-256
|
|
- `extraction` — das JSON aus Stufe 1, Modellversion, Prompt-Version
|
|
- `finding` — Ergebnis pro Regel: Regel-ID, Regel-Version, Schwere, Text
|
|
- `evidence_package` — Dossier, Hash, Zeitstempel-Token, erzeugt am
|
|
- `participant` — Beteiligter an einer Submission mit Rolle
|
|
(`creator`, `agentur`, `marke`, `kanzlei`) und Beitrag zur
|
|
Verantwortungsmatrix (wer hat vorgegeben, wer freigegeben)
|
|
|
|
**Append-only.** Kein UPDATE auf `finding`, `extraction` oder
|
|
`evidence_package`. Korrekturen sind neue Zeilen mit Verweis auf die alte.
|
|
Ein Beweisarchiv, in dem man Zeilen ändern kann, ist kein Beweisarchiv.
|
|
|
|
**Beweiskette:** SHA-256 über jedes Asset und über die kanonisierte
|
|
JSON-Repräsentation der Metadaten, RFC-3161-Zeitstempel über diesen Hash.
|
|
Dossier-PDF enthält Beitrag, Caption, Kennzeichnung, Findings mit
|
|
Fundstellen, Vertrags- und Briefing-Bezug, Verantwortungsmatrix, alle
|
|
Hashes und das Zeitstempel-Token. Vollständiger Export muss für den
|
|
Nutzer jederzeit möglich sein — wer kündigt, bekommt sein Archiv.
|
|
|
|
---
|
|
|
|
## Go Commands
|
|
|
|
```bash
|
|
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
|
|
```bash
|
|
# 1. Alle Änderungen committen
|
|
git add -p && git commit -m "feat: ..."
|
|
|
|
# 2. Release-Skript (macht Tests → Build → Tag → Push)
|
|
./scripts/release.sh 1.2.0
|
|
|
|
# Danach liegt in dist/:
|
|
# deklarix_1.2.0_amd64
|
|
# deklarix_1.2.0_arm64
|
|
```
|
|
|
|
### Was das Release-Skript tut
|
|
1. Prüft: sauberer Git-Status (keine uncommitted changes)
|
|
2. Führt `./scripts/test.sh` aus (vet + race tests + build-check)
|
|
3. Kompiliert für `linux/amd64` und `linux/arm64`
|
|
4. Setzt Git-Tag `v<version>` mit Annotierung
|
|
5. Pusht `main` + Tag nach `origin`
|
|
|
|
---
|
|
|
|
## Testing-Pattern & Qualitätssicherung
|
|
|
|
```go
|
|
// 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) oder `package 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.
|
|
|
|
**Golden-Test-Suite ist das eigentliche Asset des Projekts, nicht die
|
|
UI.** 30 bis 50 Beispielbeiträge in `testdata/golden/`, abgeleitet aus
|
|
veröffentlichten Urteilen und Beanstandungen der Medienanstalten, jeweils
|
|
mit erwarteten Findings. Jede Regeländerung läuft gegen die komplette
|
|
Suite. Eine Regeländerung, die ein Golden-Ergebnis kippt, wird nicht
|
|
gemerged, ohne dass der erwartete Wert bewusst und dokumentiert angepasst
|
|
wird. Extraktion wird separat getestet: fixierte Eingaben, geprüfte
|
|
JSON-Ausgabe.
|
|
|
|
---
|
|
|
|
## Leitplanken, die dauerhaft gelten
|
|
|
|
- **Keine Rechtsdienstleistung.** Deklarix ist ein Werkzeug, keine
|
|
Rechtsberatung. Keine Formulierung darf eine individuelle rechtliche
|
|
Bewertung suggerieren. Auf jedem Screen mit einem Ergebnis steht ein
|
|
entsprechender Hinweis. Keine Erfolgsaussichten-Aussagen.
|
|
- **Keine Versicherungssprache.** Nie „Abmahnschutz“, „abgesichert“,
|
|
„geschützt“, „Kostenübernahme“ — sonst erlaubnispflichtiges
|
|
Versicherungsgeschäft. Immer „Prüfung“, „Hinweis“, „Dokumentation“,
|
|
„Nachweis“.
|
|
- **Keine erfundenen Fundstellen.** Jede Norm und jedes Urteil steht in
|
|
einer Regel-YAML und wurde dort von Hand geprüft.
|
|
- **Nur eigene Inhalte.** Kein Scraping fremder Accounts, keine fremden
|
|
Posts als Demo-Material. Demo-Material ist synthetisch. Nutzerinhalte
|
|
kommen über eigenen OAuth-Zugang oder Datenexport.
|
|
- **DSGVO und Hosting in der EU.** Löschkonzept von Anfang an mitdenken,
|
|
aber Beweisarchiv und Löschpflicht sauber gegeneinander abgrenzen
|
|
(offener Punkt, siehe unten).
|
|
- **Berufsrecht der Anwälte (§ 49b Abs. 3 S. 1 BRAO).** Kein Routing
|
|
(kein Button, der einen Fall an eine Kanzlei übergibt — Nutzer wählt
|
|
selbst aus dem Verzeichnis), kein ergebnisabhängiger Preis, keine
|
|
Sachvorteile an gelistete Kanzleien, Verzeichnis bleibt kostenlos
|
|
(BGH IX ZR 89/23: entgeltliche Mandatsvermittlung ist nichtig). Vor dem
|
|
ersten Kanzlei-Vertrag: formlose Auskunft der zuständigen
|
|
Rechtsanwaltskammer einholen.
|
|
|
|
---
|
|
|
|
## Domains
|
|
|
|
| Domain | Verwendung |
|
|
|--------|-----------|
|
|
| deklarix.de | Primär |
|
|
| deklarix.com | Redirect / International |
|
|
|
|
---
|
|
|
|
## Wichtige Hinweise
|
|
|
|
### Go PATH
|
|
```bash
|
|
# Immer setzen — ist nicht im Standard-PATH des Servers
|
|
export PATH=$PATH:/usr/local/go/bin
|
|
```
|
|
|
|
### Git Push
|
|
```bash
|
|
git push origin main
|
|
# Remote: https://git.netcell-it.de/projekte/deklarix.git
|
|
```
|
|
|
|
### Server-Prozess
|
|
```bash
|
|
# Start (manuell)
|
|
PORT=8080 DATABASE_URL=postgres://... ANTHROPIC_API_KEY=... ./dist/deklarix_latest_amd64 &
|
|
|
|
# Logs prüfen
|
|
journalctl -u deklarix -f
|
|
```
|
|
|
|
---
|
|
|
|
## Arbeitsweise für Claude Code
|
|
|
|
- Kleine Commits, ein Thema pro Commit
|
|
- Erst Test oder Golden-Fall, dann Implementierung
|
|
- Keine neue Abhängigkeit ohne Rückfrage
|
|
- Keine Umbenennung von Regel-IDs; Regeln werden versioniert, nicht
|
|
ersetzt
|
|
- Fehler nicht verschlucken, keine stillen Fallbacks bei der Extraktion
|
|
- Bei Unsicherheit über eine Rechtsfrage: nicht raten, sondern als offene
|
|
Frage in `rules/OPEN.md` notieren
|
|
- Der Code-RAG dient der Orientierung im Bestand, nicht als Nachweis von
|
|
Korrektheit. Verifiziert wird durch Compiler, Tests und die
|
|
Golden-Suite.
|
|
|
|
## Vor Änderungen
|
|
|
|
1. `go vet ./...` — keine Fehler
|
|
2. `./scripts/test.sh` — alle Tests grün
|
|
3. Bestehenden Code lesen — nicht raten
|
|
|
|
## Nach Änderungen
|
|
|
|
1. `./scripts/test.sh` → 0 Fehler
|
|
2. `./scripts/build.sh <version>` → erfolgreich
|
|
3. Commit mit semantischer Message: `feat:`, `fix:`, `refactor:`, `docs:`
|
|
4. Bei Release: `./scripts/release.sh <version>`
|
|
|
|
---
|
|
|
|
## Offene Punkte
|
|
|
|
- Umfang des Regelsatzes für den ersten Pilotkunden festlegen
|
|
- Welche TSA für die Zeitstempel
|
|
- Löschkonzept versus Beweisarchiv sauber ausformulieren
|
|
- Markenanmeldung Deklarix, sobald erster Kunde zahlt
|