Real IMAP connection via imapflow library: - Connects to IMAP server (IMAPFlow, TLS on port 993) - Fetches recent messages (configurable limit, default 20) - Extracts: from, fromEmail, subject, date, snippet (200 chars) - Thread-to-contact matching (PRD §6.1): 1. Match sender email against persons table 2. If no person match, extract domain and match against company.website 3. Returns matchedCompany + matchedPerson for each email - Audit-logged (action: crm.mailsync:imap) - Zod validated (host, port, user, password, folder, limit) - 502 on IMAP connection failure with detail - 400 on validation failure Tested: invalid creds → 502 'IMAP connection failed', missing host → 400
72 lines
2.8 KiB
Bash
Executable File
72 lines
2.8 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
# Test the AI explanation generation (Leads Finder "Explain" stage via z-ai-web-dev-sdk).
|
|
set -u
|
|
cd /home/z/my-project
|
|
BASE=http://127.0.0.1:3000
|
|
|
|
echo "=== Start server ==="
|
|
pkill -f "next dev" 2>/dev/null; sleep 1
|
|
bun run dev > dev.log 2>&1 &
|
|
SRV=$!
|
|
for i in $(seq 1 90); do curl -s -o /dev/null "$BASE/" 2>/dev/null && break; sleep 1; done
|
|
echo " ready after ${i}s"; sleep 2
|
|
|
|
echo "=== Direct API test: explain endpoint ==="
|
|
# get first lead id
|
|
LEAD_ID=$(curl -s "$BASE/api/aos/leads" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d['leads'][0]['id'])" 2>/dev/null)
|
|
echo " lead id: $LEAD_ID"
|
|
echo " calling /api/aos/leads/explain (max 60s)…"
|
|
RESP=$(curl -s -m 70 -X POST "$BASE/api/aos/leads/explain" -H 'content-type: application/json' -d "{\"leadId\":\"$LEAD_ID\"}")
|
|
echo " response (first 500 chars):"
|
|
echo "$RESP" | head -c 500
|
|
echo ""
|
|
echo ""
|
|
|
|
echo "=== Browser flow: select lead, click Neu generieren ==="
|
|
agent-browser open "$BASE/" >/dev/null 2>&1
|
|
agent-browser wait --load networkidle >/dev/null 2>&1 || true
|
|
agent-browser wait 2000 >/dev/null 2>&1
|
|
# go to leads
|
|
agent-browser find text "Leads Finder" click >/dev/null 2>&1
|
|
agent-browser wait 2000 >/dev/null 2>&1
|
|
# click second lead to ensure a fresh selection
|
|
agent-browser snapshot -i >/tmp/snap.txt 2>&1
|
|
LEAD2=$(grep -i "Ostsee Catering" /tmp/snap.txt | head -1 | grep -oE 'ref=e[0-9]+' | head -1)
|
|
echo " Ostsee Catering lead ref: $LEAD2"
|
|
[ -n "$LEAD2" ] && agent-browser click "$LEAD2" >/dev/null 2>&1
|
|
agent-browser wait 1500 >/dev/null 2>&1
|
|
# find Neu generieren / Erzeugen
|
|
agent-browser snapshot -i >/tmp/snap2.txt 2>&1
|
|
GEN=$(grep -iE "Erzeugen|Neu generieren" /tmp/snap2.txt | head -1 | grep -oE 'ref=e[0-9]+' | head -1)
|
|
echo " generate button ref: $GEN"
|
|
if [ -n "$GEN" ]; then
|
|
agent-browser click "$GEN" >/dev/null 2>&1
|
|
echo " clicked; waiting up to 30s for toast/response…"
|
|
for w in $(seq 1 30); do
|
|
agent-browser wait 1000 >/dev/null 2>&1
|
|
# check if a toast appeared
|
|
toast=$(agent-browser eval "document.querySelector('[data-sonner-toast]')?.textContent || ''" 2>/dev/null | tail -1)
|
|
if echo "$toast" | grep -qi "erklärung\|generiert\|fehlgeschlagen"; then
|
|
echo " toast after ${w}s: $toast"
|
|
break
|
|
fi
|
|
done
|
|
agent-browser screenshot --full /home/z/my-project/aos-shots/v2-ai-explain.png >/dev/null 2>&1 && echo " screenshot saved"
|
|
# read the explanation text from the detail panel
|
|
echo " --- explanation panel text ---"
|
|
agent-browser eval "document.querySelector('[class*=rounded-md]')?.innerText?.slice(0,400) || 'n/a'" 2>/dev/null | tail -3
|
|
else
|
|
echo " no generate button found"
|
|
fi
|
|
|
|
echo ""
|
|
echo "=== Errors ==="
|
|
agent-browser errors 2>&1 | head -10
|
|
echo "--- console last 6 ---"
|
|
agent-browser console 2>&1 | tail -6
|
|
|
|
echo ""
|
|
agent-browser close >/dev/null 2>&1
|
|
kill $SRV 2>/dev/null
|
|
echo "=== done ==="
|