Add autonomous compliance agent that fetches web documents (cookie banners, privacy policies), classifies them via Qwen/Ollama, assesses DSGVO compliance, assigns to the responsible role, and sends notification emails. Components: - ZeroClaw SOP (6-step workflow: fetch, classify, assess, summarize, assign, notify) - Backend: /api/compliance/agent/analyze (combined endpoint) - Backend: /api/compliance/agent/notify (standalone email) - Frontend: /sdk/agent page (Manager UI with URL input + results) - Helper scripts + E2E test Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
97 lines
3.6 KiB
Bash
Executable File
97 lines
3.6 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
#
|
|
# test_sop_workflow.sh — End-to-end test for the compliance-analyst SOP.
|
|
#
|
|
# Prerequisites:
|
|
# - Compliance SDK running on localhost:8093
|
|
# - Backend running on localhost:8002
|
|
# - Ollama running on localhost:11434 with qwen model
|
|
# - Mailpit running (SMTP on 1025, Web on 8025)
|
|
# - ZeroClaw installed
|
|
|
|
set -euo pipefail
|
|
|
|
SDK="http://localhost:8093"
|
|
BACKEND="http://localhost:8002"
|
|
OLLAMA="http://localhost:11434"
|
|
MAILPIT="http://localhost:8025"
|
|
TENANT="9282a473-5c95-4b3a-bf78-0ecc0ec71d3e"
|
|
USER_ID="00000000-0000-0000-0000-000000000001"
|
|
|
|
red() { printf '\033[31m✗ %s\033[0m\n' "$*"; }
|
|
green() { printf '\033[32m✓ %s\033[0m\n' "$*"; }
|
|
|
|
echo "═══ Compliance Agent SOP — E2E Test ═══"
|
|
echo ""
|
|
|
|
# Step 1: Health checks
|
|
echo "── Step 1: Service Health ──"
|
|
curl -sf "$SDK/health" >/dev/null && green "SDK healthy" || red "SDK unreachable"
|
|
curl -sf "$BACKEND/health" >/dev/null && green "Backend healthy" || red "Backend unreachable"
|
|
curl -sf "$OLLAMA/api/tags" >/dev/null && green "Ollama running" || red "Ollama unreachable"
|
|
|
|
# Step 2: Test document fetch
|
|
echo ""
|
|
echo "── Step 2: Document Fetch ──"
|
|
TEXT=$(bash "$(dirname "$0")/../scripts/fetch-and-analyze.sh" "https://www.google.com/intl/de/policies/privacy/" 2000)
|
|
CHARS=${#TEXT}
|
|
if [ "$CHARS" -gt 100 ]; then
|
|
green "Fetched $CHARS chars from Google Privacy Policy"
|
|
else
|
|
red "Fetch returned too little text ($CHARS chars)"
|
|
exit 1
|
|
fi
|
|
|
|
# Step 3: Test LLM classification
|
|
echo ""
|
|
echo "── Step 3: LLM Classification ──"
|
|
CLASSIFY_RESULT=$(curl -sf -X POST "$SDK/sdk/v1/llm/chat" \
|
|
-H "Content-Type: application/json" \
|
|
-H "X-Tenant-ID: $TENANT" \
|
|
-H "X-User-ID: $USER_ID" \
|
|
-d "{
|
|
\"messages\": [
|
|
{\"role\": \"system\", \"content\": \"Klassifiziere: privacy_policy, cookie_banner, terms_of_service, imprint, dpa, other. Antworte NUR mit dem Kategorienamen.\"},
|
|
{\"role\": \"user\", \"content\": $(echo "$TEXT" | head -c 1000 | python3 -c 'import json,sys; print(json.dumps(sys.stdin.read()))')}
|
|
]
|
|
}" 2>&1) || true
|
|
|
|
if echo "$CLASSIFY_RESULT" | grep -qi "privacy_policy\|cookie\|terms\|imprint\|dpa"; then
|
|
green "Classification: $(echo "$CLASSIFY_RESULT" | python3 -c 'import json,sys; d=json.load(sys.stdin); print(d.get("response","").strip()[:50])' 2>/dev/null || echo "$CLASSIFY_RESULT" | head -c 50)"
|
|
else
|
|
echo " Classification result: $(echo "$CLASSIFY_RESULT" | head -c 100)"
|
|
red "Classification did not return expected category (may still be valid)"
|
|
fi
|
|
|
|
# Step 4: Test notification endpoint
|
|
echo ""
|
|
echo "── Step 4: Agent Notification ──"
|
|
NOTIFY_RESULT=$(curl -sf -X POST "$BACKEND/api/compliance/agent/notify" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"recipient": "dsb@breakpilot.local",
|
|
"subject": "E2E Test: Compliance-Finding",
|
|
"body_html": "<h2>Test-Benachrichtigung</h2><p>Automatischer E2E-Test des Compliance-Agent SOP.</p>",
|
|
"role": "Datenschutzbeauftragter"
|
|
}' 2>&1) || true
|
|
|
|
if echo "$NOTIFY_RESULT" | grep -qi "sent\|success\|ok"; then
|
|
green "Notification sent"
|
|
else
|
|
echo " Notify result: $(echo "$NOTIFY_RESULT" | head -c 100)"
|
|
red "Notification endpoint returned unexpected result"
|
|
fi
|
|
|
|
# Step 5: Check Mailpit
|
|
echo ""
|
|
echo "── Step 5: Mailpit Check ──"
|
|
MAIL_COUNT=$(curl -sf "$MAILPIT/api/v1/messages" 2>/dev/null | python3 -c 'import json,sys; d=json.load(sys.stdin); print(d.get("total",0))' 2>/dev/null || echo "0")
|
|
if [ "$MAIL_COUNT" -gt 0 ]; then
|
|
green "Mailpit has $MAIL_COUNT message(s)"
|
|
else
|
|
red "No messages in Mailpit (check SMTP connectivity)"
|
|
fi
|
|
|
|
echo ""
|
|
echo "═══ E2E Test Complete ═══"
|