test: E2E test scenarios and curl collection
This commit is contained in:
514
tests/curl-test-collection.sh
Normal file
514
tests/curl-test-collection.sh
Normal file
@@ -0,0 +1,514 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# E2E Test Collection - Service Health & Connectivity Checks
|
||||||
|
# Purpose: Verify all services are running and accessible
|
||||||
|
# Author: QA/Testing Agent
|
||||||
|
# Date: 2026-03-16
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
set -e # Exit on error
|
||||||
|
|
||||||
|
# Color output
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
BLUE='\033[0;34m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
# Counters
|
||||||
|
PASSED=0
|
||||||
|
FAILED=0
|
||||||
|
SKIPPED=0
|
||||||
|
|
||||||
|
# Configuration
|
||||||
|
SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
||||||
|
PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
|
||||||
|
|
||||||
|
# Load environment variables if .env exists
|
||||||
|
if [ -f "$PROJECT_ROOT/.env" ]; then
|
||||||
|
source "$PROJECT_ROOT/.env"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Default values (can be overridden by env vars)
|
||||||
|
FREESCOUT_HOST="${FREESCOUT_HOST:-https://ekshelpdesk.fft-it.de}"
|
||||||
|
LITELLM_HOST="${LITELLM_HOST:-http://llm.eks-ai.apps.asgard.eks-lnx.fft-it.de}"
|
||||||
|
MILVUS_HOST="${MILVUS_HOST:-127.0.0.1}"
|
||||||
|
MILVUS_PORT="${MILVUS_PORT:-19530}"
|
||||||
|
POSTGRES_HOST="${POSTGRES_HOST:-127.0.0.1}"
|
||||||
|
POSTGRES_PORT="${POSTGRES_PORT:-5432}"
|
||||||
|
POSTGRES_USER="${POSTGRES_USER:-kb_user}"
|
||||||
|
POSTGRES_DB="${POSTGRES_DB:-n8n_kb}"
|
||||||
|
N8N_HOST="${N8N_HOST:-http://localhost}"
|
||||||
|
N8N_PORT="${N8N_PORT:-5678}"
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Helper Functions
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
log_header() {
|
||||||
|
echo -e "\n${BLUE}=== $1 ===${NC}\n"
|
||||||
|
}
|
||||||
|
|
||||||
|
log_pass() {
|
||||||
|
echo -e "${GREEN}✓ PASS${NC}: $1"
|
||||||
|
((PASSED++))
|
||||||
|
}
|
||||||
|
|
||||||
|
log_fail() {
|
||||||
|
echo -e "${RED}✗ FAIL${NC}: $1"
|
||||||
|
((FAILED++))
|
||||||
|
}
|
||||||
|
|
||||||
|
log_skip() {
|
||||||
|
echo -e "${YELLOW}⊘ SKIP${NC}: $1"
|
||||||
|
((SKIPPED++))
|
||||||
|
}
|
||||||
|
|
||||||
|
log_info() {
|
||||||
|
echo -e "${BLUE}ℹ INFO${NC}: $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
test_endpoint() {
|
||||||
|
local name="$1"
|
||||||
|
local method="${2:-GET}"
|
||||||
|
local url="$3"
|
||||||
|
local headers="$4"
|
||||||
|
local data="$5"
|
||||||
|
local expected_code="${6:-200}"
|
||||||
|
|
||||||
|
echo -n "Testing $name... "
|
||||||
|
|
||||||
|
# Build curl command
|
||||||
|
local curl_cmd="curl -s -w '%{http_code}' -X $method"
|
||||||
|
|
||||||
|
if [ -n "$headers" ]; then
|
||||||
|
curl_cmd="$curl_cmd -H '$headers'"
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ "$method" != "GET" ] && [ -n "$data" ]; then
|
||||||
|
curl_cmd="$curl_cmd -d '$data'"
|
||||||
|
fi
|
||||||
|
|
||||||
|
curl_cmd="$curl_cmd '$url' -o /tmp/response.txt"
|
||||||
|
|
||||||
|
# Execute and capture response code
|
||||||
|
local response_code=$(eval "$curl_cmd" 2>/dev/null || echo "000")
|
||||||
|
|
||||||
|
if [ "$response_code" = "$expected_code" ]; then
|
||||||
|
log_pass "$name (HTTP $response_code)"
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
log_fail "$name (Expected HTTP $expected_code, got $response_code)"
|
||||||
|
cat /tmp/response.txt 2>/dev/null | head -c 200
|
||||||
|
echo ""
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Test Suite
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
main() {
|
||||||
|
echo -e "${BLUE}"
|
||||||
|
cat << 'EOF'
|
||||||
|
╔════════════════════════════════════════════════════════════════════════════╗
|
||||||
|
║ E2E Test Collection - Health Checks ║
|
||||||
|
║ ║
|
||||||
|
║ This script verifies that all microservices are running and accessible. ║
|
||||||
|
║ It performs basic connectivity tests and returns a summary report. ║
|
||||||
|
╚════════════════════════════════════════════════════════════════════════════╝
|
||||||
|
EOF
|
||||||
|
echo -e "${NC}\n"
|
||||||
|
|
||||||
|
# Test Milvus Vector DB
|
||||||
|
log_header "1. Testing Milvus Vector Database"
|
||||||
|
test_milvus
|
||||||
|
|
||||||
|
# Test PostgreSQL
|
||||||
|
log_header "2. Testing PostgreSQL Database"
|
||||||
|
test_postgres
|
||||||
|
|
||||||
|
# Test Freescout
|
||||||
|
log_header "3. Testing Freescout API"
|
||||||
|
test_freescout
|
||||||
|
|
||||||
|
# Test LiteLLM
|
||||||
|
log_header "4. Testing LiteLLM API"
|
||||||
|
test_litellm
|
||||||
|
|
||||||
|
# Test n8n
|
||||||
|
log_header "5. Testing n8n Workflow Engine"
|
||||||
|
test_n8n
|
||||||
|
|
||||||
|
# Test Docker Compose Stack
|
||||||
|
log_header "6. Testing Docker Compose Services"
|
||||||
|
test_docker_compose
|
||||||
|
|
||||||
|
# Print Summary
|
||||||
|
print_summary
|
||||||
|
}
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Individual Test Functions
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
test_milvus() {
|
||||||
|
local milvus_url="http://$MILVUS_HOST:$MILVUS_PORT"
|
||||||
|
|
||||||
|
echo "Checking Milvus at $milvus_url"
|
||||||
|
|
||||||
|
# Test health endpoint
|
||||||
|
echo -n " Health check... "
|
||||||
|
if curl -s "$milvus_url/healthz" >/dev/null 2>&1; then
|
||||||
|
log_pass "Milvus is responding"
|
||||||
|
else
|
||||||
|
log_fail "Milvus health endpoint not reachable"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Test metrics endpoint
|
||||||
|
echo -n " Metrics check... "
|
||||||
|
if curl -s "$milvus_url/metrics" >/dev/null 2>&1; then
|
||||||
|
log_pass "Milvus metrics available"
|
||||||
|
else
|
||||||
|
log_skip "Milvus metrics endpoint (non-critical)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Test REST API version
|
||||||
|
echo -n " API version check... "
|
||||||
|
if curl -s "$milvus_url/v1/version" >/dev/null 2>&1; then
|
||||||
|
log_pass "Milvus REST API responding"
|
||||||
|
else
|
||||||
|
log_fail "Milvus REST API not responding"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
test_postgres() {
|
||||||
|
echo "Checking PostgreSQL at $POSTGRES_HOST:$POSTGRES_PORT"
|
||||||
|
|
||||||
|
# Test basic connectivity
|
||||||
|
echo -n " Connection test... "
|
||||||
|
if nc -z "$POSTGRES_HOST" "$POSTGRES_PORT" 2>/dev/null; then
|
||||||
|
log_pass "PostgreSQL port is open"
|
||||||
|
else
|
||||||
|
log_fail "Cannot connect to PostgreSQL port"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Test database query (if inside docker network)
|
||||||
|
echo -n " Database query test... "
|
||||||
|
if command -v docker &> /dev/null; then
|
||||||
|
if docker-compose -f "$PROJECT_ROOT/docker-compose.yml" exec postgres \
|
||||||
|
psql -U "$POSTGRES_USER" -d "$POSTGRES_DB" -c "SELECT COUNT(*) FROM knowledge_base_updates;" \
|
||||||
|
>/dev/null 2>&1; then
|
||||||
|
log_pass "PostgreSQL database accessible and configured"
|
||||||
|
else
|
||||||
|
log_fail "PostgreSQL query failed - might be authentication issue"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
log_skip "PostgreSQL query test (Docker not available)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check for required tables
|
||||||
|
echo -n " Schema validation... "
|
||||||
|
if docker-compose -f "$PROJECT_ROOT/docker-compose.yml" exec postgres \
|
||||||
|
psql -U "$POSTGRES_USER" -d "$POSTGRES_DB" -c \
|
||||||
|
"SELECT EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name='knowledge_base_updates');" \
|
||||||
|
2>/dev/null | grep -q "t"; then
|
||||||
|
log_pass "Required tables exist"
|
||||||
|
else
|
||||||
|
log_skip "Schema validation (might not be initialized)"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
test_freescout() {
|
||||||
|
echo "Checking Freescout at $FREESCOUT_HOST"
|
||||||
|
|
||||||
|
# Test basic connectivity
|
||||||
|
echo -n " Web server check... "
|
||||||
|
if curl -s -I "$FREESCOUT_HOST/login" 2>/dev/null | grep -q "200\|301\|302"; then
|
||||||
|
log_pass "Freescout web interface responding"
|
||||||
|
else
|
||||||
|
log_fail "Freescout web interface not responding"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Test API health (if API key available)
|
||||||
|
if [ -n "$FREESCOUT_API_KEY" ]; then
|
||||||
|
echo -n " API authentication test... "
|
||||||
|
local response=$(curl -s -w '%{http_code}' \
|
||||||
|
-H "Authorization: Bearer $FREESCOUT_API_KEY" \
|
||||||
|
"$FREESCOUT_HOST/api/v1/mailboxes" -o /tmp/freescout_api_response.txt)
|
||||||
|
|
||||||
|
if [ "$response" = "200" ]; then
|
||||||
|
log_pass "Freescout API authenticated"
|
||||||
|
local mailbox_count=$(jq '.mailboxes | length' /tmp/freescout_api_response.txt 2>/dev/null)
|
||||||
|
log_info "Found $mailbox_count mailbox(es)"
|
||||||
|
else
|
||||||
|
log_fail "Freescout API authentication failed (HTTP $response)"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
log_skip "Freescout API authentication test (FREESCOUT_API_KEY not set)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Test custom fields
|
||||||
|
if [ -n "$FREESCOUT_API_KEY" ]; then
|
||||||
|
echo -n " Custom fields check... "
|
||||||
|
if curl -s -H "Authorization: Bearer $FREESCOUT_API_KEY" \
|
||||||
|
"$FREESCOUT_HOST/api/v1/custom-fields" 2>/dev/null | \
|
||||||
|
grep -q "AI_SUGGESTION"; then
|
||||||
|
log_pass "AI custom fields configured"
|
||||||
|
else
|
||||||
|
log_fail "AI custom fields not found - check Freescout configuration"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
test_litellm() {
|
||||||
|
echo "Checking LiteLLM at $LITELLM_HOST"
|
||||||
|
|
||||||
|
# Test health endpoint
|
||||||
|
echo -n " Health check... "
|
||||||
|
if curl -s "$LITELLM_HOST/health" >/dev/null 2>&1; then
|
||||||
|
log_pass "LiteLLM is responding"
|
||||||
|
else
|
||||||
|
log_fail "LiteLLM health endpoint not reachable"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Test API endpoint
|
||||||
|
echo -n " API endpoint test... "
|
||||||
|
local test_payload='{
|
||||||
|
"model": "gpt-3.5-turbo",
|
||||||
|
"messages": [{"role": "user", "content": "test"}],
|
||||||
|
"max_tokens": 10
|
||||||
|
}'
|
||||||
|
|
||||||
|
if curl -s -X POST "$LITELLM_HOST/v1/chat/completions" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d "$test_payload" >/dev/null 2>&1; then
|
||||||
|
log_pass "LiteLLM chat API responding"
|
||||||
|
else
|
||||||
|
log_fail "LiteLLM chat API not responding"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Test model availability
|
||||||
|
if [ -n "$LITELLM_API_KEY" ]; then
|
||||||
|
echo -n " Model availability check... "
|
||||||
|
if curl -s -X GET "$LITELLM_HOST/v1/models" \
|
||||||
|
-H "Authorization: Bearer $LITELLM_API_KEY" 2>/dev/null | \
|
||||||
|
grep -q "gpt"; then
|
||||||
|
log_pass "Models available"
|
||||||
|
else
|
||||||
|
log_skip "Model availability (non-critical)"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
test_n8n() {
|
||||||
|
echo "Checking n8n at $N8N_HOST:$N8N_PORT"
|
||||||
|
|
||||||
|
local n8n_url="$N8N_HOST:$N8N_PORT"
|
||||||
|
|
||||||
|
# Test REST API
|
||||||
|
echo -n " REST API health... "
|
||||||
|
if curl -s "$n8n_url/healthz" >/dev/null 2>&1 || \
|
||||||
|
curl -s "$n8n_url/health" >/dev/null 2>&1; then
|
||||||
|
log_pass "n8n REST API responding"
|
||||||
|
else
|
||||||
|
log_fail "n8n REST API not responding (might be behind reverse proxy)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Test web interface
|
||||||
|
echo -n " Web interface check... "
|
||||||
|
if curl -s "$n8n_url/" >/dev/null 2>&1; then
|
||||||
|
log_pass "n8n web interface accessible"
|
||||||
|
else
|
||||||
|
log_skip "n8n web interface check (might require authentication)"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Test workflows endpoint (if authenticated)
|
||||||
|
if [ -n "$N8N_AUTH_TOKEN" ]; then
|
||||||
|
echo -n " Workflow list test... "
|
||||||
|
if curl -s -H "Authorization: Bearer $N8N_AUTH_TOKEN" \
|
||||||
|
"$n8n_url/api/v1/workflows" >/dev/null 2>&1; then
|
||||||
|
log_pass "n8n workflows accessible"
|
||||||
|
else
|
||||||
|
log_fail "Cannot access n8n workflows"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
test_docker_compose() {
|
||||||
|
if ! command -v docker-compose &> /dev/null; then
|
||||||
|
log_skip "Docker Compose not available"
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Checking Docker Compose services..."
|
||||||
|
|
||||||
|
# Get list of running services
|
||||||
|
local services=$(docker-compose -f "$PROJECT_ROOT/docker-compose.yml" ps --services 2>/dev/null)
|
||||||
|
|
||||||
|
if [ -z "$services" ]; then
|
||||||
|
log_fail "No Docker Compose services found"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Check each service
|
||||||
|
while read -r service; do
|
||||||
|
echo -n " Service: $service... "
|
||||||
|
if docker-compose -f "$PROJECT_ROOT/docker-compose.yml" ps "$service" 2>/dev/null | \
|
||||||
|
grep -q "Up"; then
|
||||||
|
log_pass "$service is running"
|
||||||
|
else
|
||||||
|
log_fail "$service is not running"
|
||||||
|
fi
|
||||||
|
done <<< "$services"
|
||||||
|
|
||||||
|
# Check resource usage
|
||||||
|
echo ""
|
||||||
|
echo -n " Container resource check... "
|
||||||
|
if docker-compose -f "$PROJECT_ROOT/docker-compose.yml" stats --no-stream 2>/dev/null | \
|
||||||
|
tail -n +2 | wc -l | grep -qv "0"; then
|
||||||
|
log_pass "Docker containers have allocated resources"
|
||||||
|
else
|
||||||
|
log_skip "Could not read container stats"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Summary Report
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
print_summary() {
|
||||||
|
local total=$((PASSED + FAILED + SKIPPED))
|
||||||
|
local status="PASSED"
|
||||||
|
|
||||||
|
if [ $FAILED -gt 0 ]; then
|
||||||
|
status="FAILED"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo -e "${BLUE}╔════════════════════════════════════════════════════════════════╗${NC}"
|
||||||
|
echo -e "${BLUE}║ Test Summary Report ║${NC}"
|
||||||
|
echo -e "${BLUE}╚════════════════════════════════════════════════════════════════╝${NC}"
|
||||||
|
echo ""
|
||||||
|
echo -e " Total Tests: $total"
|
||||||
|
echo -e " ${GREEN}Passed:${NC} $PASSED"
|
||||||
|
if [ $FAILED -gt 0 ]; then
|
||||||
|
echo -e " ${RED}Failed:${NC} $FAILED"
|
||||||
|
fi
|
||||||
|
if [ $SKIPPED -gt 0 ]; then
|
||||||
|
echo -e " ${YELLOW}Skipped:${NC} $SKIPPED"
|
||||||
|
fi
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
if [ $FAILED -eq 0 ]; then
|
||||||
|
echo -e "${GREEN}✓ All critical services are running and accessible!${NC}"
|
||||||
|
echo -e " You can proceed with E2E testing."
|
||||||
|
echo ""
|
||||||
|
return 0
|
||||||
|
else
|
||||||
|
echo -e "${RED}✗ Some services are not responding!${NC}"
|
||||||
|
echo -e " Please check the failures above and ensure all services are running."
|
||||||
|
echo ""
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Usage Information
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
show_help() {
|
||||||
|
cat << EOF
|
||||||
|
Usage: $0 [OPTIONS]
|
||||||
|
|
||||||
|
E2E Test Collection - Service Health & Connectivity Checks
|
||||||
|
|
||||||
|
Options:
|
||||||
|
-h, --help Show this help message
|
||||||
|
-v, --verbose Enable verbose output
|
||||||
|
-m, --milvus HOST:PORT Override Milvus address (default: 127.0.0.1:19530)
|
||||||
|
-p, --postgres HOST:PORT Override PostgreSQL address (default: 127.0.0.1:5432)
|
||||||
|
-f, --freescout URL Override Freescout URL
|
||||||
|
-l, --litellm URL Override LiteLLM URL
|
||||||
|
-n, --n8n URL Override n8n URL
|
||||||
|
|
||||||
|
Environment Variables:
|
||||||
|
FREESCOUT_API_KEY Freescout API authentication token
|
||||||
|
LITELLM_API_KEY LiteLLM API authentication token
|
||||||
|
N8N_AUTH_TOKEN n8n authentication token
|
||||||
|
POSTGRES_USER PostgreSQL username (default: kb_user)
|
||||||
|
POSTGRES_DB PostgreSQL database name (default: n8n_kb)
|
||||||
|
|
||||||
|
Examples:
|
||||||
|
# Run basic health checks with defaults
|
||||||
|
$0
|
||||||
|
|
||||||
|
# Override Milvus host
|
||||||
|
$0 --milvus 192.168.1.100:19530
|
||||||
|
|
||||||
|
# With API keys
|
||||||
|
FREESCOUT_API_KEY=token123 $0
|
||||||
|
|
||||||
|
EOF
|
||||||
|
}
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
# Main Execution
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
# Parse command line arguments
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
case $1 in
|
||||||
|
-h|--help)
|
||||||
|
show_help
|
||||||
|
exit 0
|
||||||
|
;;
|
||||||
|
-v|--verbose)
|
||||||
|
set -x
|
||||||
|
shift
|
||||||
|
;;
|
||||||
|
-m|--milvus)
|
||||||
|
MILVUS_HOST="${2%:*}"
|
||||||
|
MILVUS_PORT="${2##*:}"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
-p|--postgres)
|
||||||
|
POSTGRES_HOST="${2%:*}"
|
||||||
|
POSTGRES_PORT="${2##*:}"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
-f|--freescout)
|
||||||
|
FREESCOUT_HOST="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
-l|--litellm)
|
||||||
|
LITELLM_HOST="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
-n|--n8n)
|
||||||
|
N8N_HOST="$2"
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Unknown option: $1"
|
||||||
|
show_help
|
||||||
|
exit 1
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
# Run main test suite
|
||||||
|
main
|
||||||
|
|
||||||
|
# Exit with appropriate code
|
||||||
|
if [ $FAILED -gt 0 ]; then
|
||||||
|
exit 1
|
||||||
|
else
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
527
tests/e2e-test-scenario.md
Normal file
527
tests/e2e-test-scenario.md
Normal file
@@ -0,0 +1,527 @@
|
|||||||
|
# E2E Test: Full AI Support Automation Workflow
|
||||||
|
|
||||||
|
## System Setup Prerequisites
|
||||||
|
|
||||||
|
### Services Health Check
|
||||||
|
- **Milvus Vector DB**: Accessible on port 9091
|
||||||
|
- **PostgreSQL**: Running with KB schema and audit tables
|
||||||
|
- **n8n**: Workflow engine operational
|
||||||
|
- **Freescout**: Help desk system with custom fields configured
|
||||||
|
- **LiteLLM**: LLM proxy service accessible
|
||||||
|
- **Baramundi**: Remote execution system (optional)
|
||||||
|
|
||||||
|
### Test Environment Variables
|
||||||
|
```bash
|
||||||
|
export FREESCOUT_API_KEY="your-api-key"
|
||||||
|
export LITELLM_API_KEY="your-api-key"
|
||||||
|
export N8N_AUTH_TOKEN="your-auth-token"
|
||||||
|
export POSTGRES_PASSWORD="your-password"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## E2E Test Scenario: Complete Workflow
|
||||||
|
|
||||||
|
### Test Case ID: E2E-001
|
||||||
|
**Objective**: Full workflow from ticket creation through knowledge base update
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 1. Setup Phase
|
||||||
|
|
||||||
|
### Pre-Test Validation
|
||||||
|
```bash
|
||||||
|
# Verify all services are running
|
||||||
|
./tests/curl-test-collection.sh
|
||||||
|
|
||||||
|
# Clear test data from previous runs (optional)
|
||||||
|
docker-compose exec postgres psql -U kb_user -d n8n_kb -c \
|
||||||
|
"DELETE FROM knowledge_base_updates WHERE created_at > NOW() - INTERVAL '1 hour';"
|
||||||
|
|
||||||
|
docker-compose exec postgres psql -U kb_user -d n8n_kb -c \
|
||||||
|
"DELETE FROM ticket_audit WHERE ticket_id LIKE 'TEST_%';"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Test Data Preparation
|
||||||
|
- Create test customer: `test@example.com` in Freescout (if not exists)
|
||||||
|
- Verify custom fields exist in Freescout:
|
||||||
|
- `AI_SUGGESTION` (text field)
|
||||||
|
- `AI_SUGGESTION_STATUS` (enum: PENDING, APPROVED, REJECTED, EXECUTED)
|
||||||
|
- `AI_CONFIDENCE` (number field)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 2. Workflow A: Ticket Analysis & AI Suggestion
|
||||||
|
|
||||||
|
### Test Step 1: Create Test Ticket in Freescout
|
||||||
|
|
||||||
|
**Action**: Create new ticket via Freescout UI or API
|
||||||
|
```bash
|
||||||
|
curl -X POST https://ekshelpdesk.fft-it.de/api/v1/mailboxes/1/conversations \
|
||||||
|
-H "Authorization: Bearer $FREESCOUT_API_KEY" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{
|
||||||
|
"subject": "TEST_E2E_001: Drucker funktioniert nicht",
|
||||||
|
"body": "Jeder Druck-Befehl wird abgelehnt. Fehlercode 5. Bitte schnell lösen!",
|
||||||
|
"customer_email": "test@example.com",
|
||||||
|
"mailbox_id": 1
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
**Expected Outcome**:
|
||||||
|
- HTTP Status: 201 (Created)
|
||||||
|
- Response contains `conversation_id`
|
||||||
|
- Ticket visible in Freescout dashboard
|
||||||
|
|
||||||
|
**Validation**:
|
||||||
|
```bash
|
||||||
|
# Get the created ticket ID from response
|
||||||
|
TICKET_ID="<conversation_id_from_response>"
|
||||||
|
echo "Created Ticket: $TICKET_ID"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Test Step 2: Wait for Workflow A Cycle (5 minutes)
|
||||||
|
|
||||||
|
**Process Flow**:
|
||||||
|
1. n8n Workflow A triggers every 5 minutes
|
||||||
|
2. Fetches new tickets from Freescout
|
||||||
|
3. Sends ticket text to LiteLLM for analysis
|
||||||
|
4. Updates custom fields with AI suggestion
|
||||||
|
|
||||||
|
**Wait Time**: 5 minutes (plus 1 min buffer = 6 minutes total)
|
||||||
|
|
||||||
|
**During Wait - Monitor Logs**:
|
||||||
|
```bash
|
||||||
|
# Monitor n8n logs for workflow execution
|
||||||
|
docker-compose logs -f n8n | grep -i "workflow_a\|ticket\|analysis"
|
||||||
|
|
||||||
|
# Check PostgreSQL audit log
|
||||||
|
docker-compose exec postgres psql -U kb_user -d n8n_kb -c \
|
||||||
|
"SELECT * FROM ticket_audit WHERE ticket_id = '$TICKET_ID' ORDER BY created_at DESC;"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Expected n8n Logs**:
|
||||||
|
- "Processing ticket: TEST_E2E_001"
|
||||||
|
- "Calling LiteLLM API for analysis"
|
||||||
|
- "Analysis complete: category=Hardware, confidence=0.92"
|
||||||
|
- "Updated custom fields in Freescout"
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Test Step 3: Verify AI Suggestion in Freescout
|
||||||
|
|
||||||
|
**Action**: Check ticket custom fields
|
||||||
|
```bash
|
||||||
|
curl -H "Authorization: Bearer $FREESCOUT_API_KEY" \
|
||||||
|
https://ekshelpdesk.fft-it.de/api/v1/conversations/$TICKET_ID
|
||||||
|
```
|
||||||
|
|
||||||
|
**Expected Response Fields**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"conversation": {
|
||||||
|
"id": "TICKET_ID",
|
||||||
|
"subject": "TEST_E2E_001: Drucker funktioniert nicht",
|
||||||
|
"custom_fields": {
|
||||||
|
"AI_SUGGESTION": "Hardware Problem: Drucker-Treiber fehlerhaft oder beschädigt. Empfohlene Lösung: 1) Drucker neustarten, 2) Treiber neu installieren",
|
||||||
|
"AI_SUGGESTION_STATUS": "PENDING",
|
||||||
|
"AI_CONFIDENCE": 0.92
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Validation Checklist**:
|
||||||
|
- ✅ `AI_SUGGESTION` is not empty
|
||||||
|
- ✅ `AI_SUGGESTION_STATUS` = "PENDING"
|
||||||
|
- ✅ `AI_CONFIDENCE` between 0.7 and 1.0
|
||||||
|
- ✅ Suggestion text contains problem category and solution
|
||||||
|
|
||||||
|
**Alternative: Manual Check in UI**:
|
||||||
|
- Open ticket in Freescout
|
||||||
|
- Scroll to custom fields section
|
||||||
|
- Verify all three fields populated with expected values
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 3. Workflow B: Approval & Execution
|
||||||
|
|
||||||
|
### Test Step 4: Approve AI Suggestion
|
||||||
|
|
||||||
|
**Action**: Update custom field via API
|
||||||
|
```bash
|
||||||
|
curl -X PUT https://ekshelpdesk.fft-it.de/api/v1/conversations/$TICKET_ID \
|
||||||
|
-H "Authorization: Bearer $FREESCOUT_API_KEY" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{
|
||||||
|
"custom_fields": {
|
||||||
|
"AI_SUGGESTION_STATUS": "APPROVED"
|
||||||
|
}
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
**Expected Outcome**:
|
||||||
|
- HTTP Status: 200 (OK)
|
||||||
|
- Custom field updated in Freescout
|
||||||
|
|
||||||
|
**Validation**:
|
||||||
|
```bash
|
||||||
|
# Verify field was updated
|
||||||
|
curl -H "Authorization: Bearer $FREESCOUT_API_KEY" \
|
||||||
|
https://ekshelpdesk.fft-it.de/api/v1/conversations/$TICKET_ID | \
|
||||||
|
jq '.conversation.custom_fields.AI_SUGGESTION_STATUS'
|
||||||
|
# Expected output: "APPROVED"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Test Step 5: Wait for Workflow B Cycle (2 minutes)
|
||||||
|
|
||||||
|
**Process Flow**:
|
||||||
|
1. n8n Workflow B triggers every 2 minutes
|
||||||
|
2. Fetches tickets with `AI_SUGGESTION_STATUS = APPROVED`
|
||||||
|
3. Executes action based on category:
|
||||||
|
- **Hardware/Remote**: Create Baramundi job
|
||||||
|
- **Software/Config**: Send support email
|
||||||
|
- **Knowledge**: Update KB directly
|
||||||
|
4. Updates status to `EXECUTED`
|
||||||
|
|
||||||
|
**Wait Time**: 2 minutes (plus 1 min buffer = 3 minutes total)
|
||||||
|
|
||||||
|
**During Wait - Monitor Logs**:
|
||||||
|
```bash
|
||||||
|
# Check n8n workflow B execution
|
||||||
|
docker-compose logs -f n8n | grep -i "workflow_b\|approved\|executing"
|
||||||
|
|
||||||
|
# Check for Baramundi job creation (if applicable)
|
||||||
|
curl https://baramundi-api.example.com/jobs \
|
||||||
|
-H "Authorization: Bearer $BARAMUNDI_TOKEN" | \
|
||||||
|
jq '.jobs[] | select(.ticket_id == "'"$TICKET_ID"'")'
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Test Step 6: Verify Execution Status
|
||||||
|
|
||||||
|
**Action**: Check ticket status
|
||||||
|
```bash
|
||||||
|
curl -H "Authorization: Bearer $FREESCOUT_API_KEY" \
|
||||||
|
https://ekshelpdesk.fft-it.de/api/v1/conversations/$TICKET_ID
|
||||||
|
```
|
||||||
|
|
||||||
|
**Expected Response**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"conversation": {
|
||||||
|
"custom_fields": {
|
||||||
|
"AI_SUGGESTION_STATUS": "EXECUTED",
|
||||||
|
"EXECUTION_TIMESTAMP": "2026-03-16T14:35:00Z"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Validation Checklist**:
|
||||||
|
- ✅ `AI_SUGGESTION_STATUS` = "EXECUTED"
|
||||||
|
- ✅ `EXECUTION_TIMESTAMP` is recent
|
||||||
|
- ✅ No errors in n8n logs
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 4. Workflow C: Knowledge Base Update
|
||||||
|
|
||||||
|
### Test Step 7: Wait for Workflow C Cycle (1 minute)
|
||||||
|
|
||||||
|
**Process Flow**:
|
||||||
|
1. n8n Workflow C triggers every 1 minute
|
||||||
|
2. Fetches executed tickets
|
||||||
|
3. Extracts: Problem, Solution, Category
|
||||||
|
4. Inserts into PostgreSQL `knowledge_base_updates` table
|
||||||
|
5. Triggers Milvus vector DB embedding and indexing
|
||||||
|
|
||||||
|
**Wait Time**: 1 minute (plus 1 min buffer = 2 minutes total)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Test Step 8: Verify Knowledge Base Entry
|
||||||
|
|
||||||
|
**Action 1**: Check PostgreSQL insert
|
||||||
|
```bash
|
||||||
|
docker-compose exec postgres psql -U kb_user -d n8n_kb -c \
|
||||||
|
"SELECT id, ticket_id, problem, solution, category, frequency, created_at
|
||||||
|
FROM knowledge_base_updates
|
||||||
|
WHERE ticket_id = '$TICKET_ID'
|
||||||
|
ORDER BY created_at DESC LIMIT 1;"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Expected Output**:
|
||||||
|
```
|
||||||
|
id | ticket_id | problem | solution | category | frequency | created_at
|
||||||
|
----+-----------+---------+----------+----------+-----------+---------------------
|
||||||
|
42 | TEST... | Drucker | Treiber | Hardware | 1 | 2026-03-16 14:35:00
|
||||||
|
```
|
||||||
|
|
||||||
|
**Action 2**: Check Milvus vector DB
|
||||||
|
```bash
|
||||||
|
# Query Milvus for the new KB entry
|
||||||
|
curl -X POST http://127.0.0.1:19530/v1/search \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{
|
||||||
|
"collection_name": "knowledge_base",
|
||||||
|
"vectors": [
|
||||||
|
"vector_embedding_of_problem_text"
|
||||||
|
],
|
||||||
|
"top_k": 10,
|
||||||
|
"output_fields": ["id", "ticket_id", "problem", "solution", "similarity"]
|
||||||
|
}' | jq '.'
|
||||||
|
```
|
||||||
|
|
||||||
|
**Expected Response**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"id": 42,
|
||||||
|
"ticket_id": "TEST_E2E_001",
|
||||||
|
"problem": "Drucker funktioniert nicht - Fehlercode 5",
|
||||||
|
"solution": "Drucker neustarten und Treiber neu installieren",
|
||||||
|
"similarity": 0.98
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Validation Checklist**:
|
||||||
|
- ✅ Record exists in `knowledge_base_updates` table
|
||||||
|
- ✅ Fields populated: problem, solution, category, frequency
|
||||||
|
- ✅ Record appears in Milvus search results
|
||||||
|
- ✅ Similarity score >= 0.95 for exact match
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 5. Vector DB Search Test
|
||||||
|
|
||||||
|
### Test Step 9: Search Similar Problem
|
||||||
|
|
||||||
|
**Objective**: Test that similar problems can be found via vector similarity
|
||||||
|
|
||||||
|
**Action**: Query Milvus with similar but different text
|
||||||
|
```bash
|
||||||
|
# Prepare embedding for similar problem
|
||||||
|
curl -X POST http://127.0.0.1:19530/v1/search \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{
|
||||||
|
"collection_name": "knowledge_base",
|
||||||
|
"vectors": [
|
||||||
|
"vector_for_query: Druckerprobleme beim Ausdrucken mit Fehler"
|
||||||
|
],
|
||||||
|
"top_k": 5,
|
||||||
|
"output_fields": ["id", "ticket_id", "problem", "solution", "category"]
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
**Expected Outcome**:
|
||||||
|
- Top result is our test KB entry
|
||||||
|
- Similarity score > 0.85
|
||||||
|
- Same category returned (Hardware)
|
||||||
|
|
||||||
|
**Expected Result**:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"rank": 1,
|
||||||
|
"similarity": 0.91,
|
||||||
|
"ticket_id": "TEST_E2E_001",
|
||||||
|
"problem": "Drucker funktioniert nicht - Fehlercode 5",
|
||||||
|
"solution": "Drucker neustarten und Treiber neu installieren",
|
||||||
|
"category": "Hardware"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"rank": 2,
|
||||||
|
"similarity": 0.78,
|
||||||
|
"ticket_id": "OTHER_TICKET",
|
||||||
|
"problem": "Netzwerkdrucker nicht erreichbar",
|
||||||
|
"solution": "IP-Konfiguration prüfen"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Validation**:
|
||||||
|
- ✅ Test entry ranks in top 3
|
||||||
|
- ✅ Similarity > 0.85
|
||||||
|
- ✅ Relevant results returned
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 6. Failure Scenarios
|
||||||
|
|
||||||
|
### Scenario F1: Service Unavailable
|
||||||
|
|
||||||
|
**Test**: What happens if LiteLLM is unreachable?
|
||||||
|
|
||||||
|
**Action**: Stop LiteLLM service
|
||||||
|
```bash
|
||||||
|
docker-compose stop litellm
|
||||||
|
```
|
||||||
|
|
||||||
|
**Expected Behavior**:
|
||||||
|
- n8n Workflow A fails gracefully
|
||||||
|
- Error logged in PostgreSQL error_log table
|
||||||
|
- Ticket status remains PENDING
|
||||||
|
- After service recovery, retry happens automatically
|
||||||
|
|
||||||
|
**Verify**:
|
||||||
|
```bash
|
||||||
|
docker-compose exec postgres psql -U kb_user -d n8n_kb -c \
|
||||||
|
"SELECT error_message, retry_count FROM error_log WHERE ticket_id = '$TICKET_ID';"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Cleanup**: Restart service
|
||||||
|
```bash
|
||||||
|
docker-compose up -d litellm
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
### Scenario F2: Invalid Custom Field
|
||||||
|
|
||||||
|
**Test**: What if custom field value is invalid?
|
||||||
|
|
||||||
|
**Action**: Set invalid status value
|
||||||
|
```bash
|
||||||
|
curl -X PUT https://ekshelpdesk.fft-it.de/api/v1/conversations/$TICKET_ID \
|
||||||
|
-H "Authorization: Bearer $FREESCOUT_API_KEY" \
|
||||||
|
-d '{
|
||||||
|
"custom_fields": {
|
||||||
|
"AI_SUGGESTION_STATUS": "INVALID_VALUE"
|
||||||
|
}
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
**Expected Behavior**:
|
||||||
|
- Workflow B ignores ticket
|
||||||
|
- Error logged
|
||||||
|
- Manual intervention required
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 7. Test Cleanup
|
||||||
|
|
||||||
|
### Post-Test Actions
|
||||||
|
```bash
|
||||||
|
# Archive test data
|
||||||
|
docker-compose exec postgres psql -U kb_user -d n8n_kb -c \
|
||||||
|
"UPDATE ticket_audit
|
||||||
|
SET archived = true
|
||||||
|
WHERE ticket_id LIKE 'TEST_%';"
|
||||||
|
|
||||||
|
# Optional: Delete test ticket from Freescout
|
||||||
|
curl -X DELETE https://ekshelpdesk.fft-it.de/api/v1/conversations/$TICKET_ID \
|
||||||
|
-H "Authorization: Bearer $FREESCOUT_API_KEY"
|
||||||
|
|
||||||
|
# Verify cleanup
|
||||||
|
docker-compose exec postgres psql -U kb_user -d n8n_kb -c \
|
||||||
|
"SELECT COUNT(*) as active_test_tickets FROM ticket_audit
|
||||||
|
WHERE ticket_id LIKE 'TEST_%' AND archived = false;"
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 8. Test Metrics & Success Criteria
|
||||||
|
|
||||||
|
### Timing Metrics
|
||||||
|
| Phase | Expected Duration | Tolerance |
|
||||||
|
|-------|------------------|-----------|
|
||||||
|
| Setup | - | - |
|
||||||
|
| Workflow A (Analysis) | 5 min | ±1 min |
|
||||||
|
| Workflow B (Execution) | 2 min | ±30 sec |
|
||||||
|
| Workflow C (KB Update) | 1 min | ±30 sec |
|
||||||
|
| **Total End-to-End** | **~8 min** | **±2 min** |
|
||||||
|
|
||||||
|
### Success Criteria
|
||||||
|
- ✅ All services respond to health checks
|
||||||
|
- ✅ Ticket created successfully in Freescout
|
||||||
|
- ✅ AI analysis completes within 5 min
|
||||||
|
- ✅ Confidence score >= 0.7
|
||||||
|
- ✅ Approval triggers execution within 2 min
|
||||||
|
- ✅ KB entry created in PostgreSQL
|
||||||
|
- ✅ KB entry indexed in Milvus
|
||||||
|
- ✅ Vector search returns relevant results (similarity > 0.85)
|
||||||
|
- ✅ All audit logs recorded correctly
|
||||||
|
- ✅ No unhandled errors in logs
|
||||||
|
|
||||||
|
### Performance Targets
|
||||||
|
- API response time: < 2 seconds
|
||||||
|
- LiteLLM inference: < 10 seconds
|
||||||
|
- Milvus embedding + indexing: < 5 seconds
|
||||||
|
- PostgreSQL inserts: < 1 second
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 9. Test Execution Checklist
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Start here:
|
||||||
|
[ ] Verify all services running: ./tests/curl-test-collection.sh
|
||||||
|
[ ] Create test ticket (capture TICKET_ID)
|
||||||
|
[ ] Wait 6 minutes for Workflow A
|
||||||
|
[ ] Verify AI_SUGGESTION populated
|
||||||
|
[ ] Approve ticket (update AI_SUGGESTION_STATUS)
|
||||||
|
[ ] Wait 3 minutes for Workflow B
|
||||||
|
[ ] Verify AI_SUGGESTION_STATUS = EXECUTED
|
||||||
|
[ ] Wait 2 minutes for Workflow C
|
||||||
|
[ ] Verify PostgreSQL kb entry exists
|
||||||
|
[ ] Verify Milvus vector search works
|
||||||
|
[ ] Review all audit logs
|
||||||
|
[ ] Clean up test data
|
||||||
|
[ ] Document any issues found
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## 10. Troubleshooting Guide
|
||||||
|
|
||||||
|
### Issue: AI_SUGGESTION not populated after 5 min
|
||||||
|
|
||||||
|
**Check**:
|
||||||
|
1. n8n logs: `docker-compose logs n8n | grep -i error`
|
||||||
|
2. Freescout API connectivity: `curl https://ekshelpdesk.fft-it.de/healthz`
|
||||||
|
3. LiteLLM service: `curl http://llm.eks-ai.apps.asgard.eks-lnx.fft-it.de/health`
|
||||||
|
4. Custom field exists: Check Freescout admin panel
|
||||||
|
|
||||||
|
### Issue: Workflow B not executing
|
||||||
|
|
||||||
|
**Check**:
|
||||||
|
1. Ticket status field correct: `curl -H "Auth: Bearer $KEY" https://ekshelpdesk.fft-it.de/api/v1/conversations/$TICKET_ID | jq '.custom_fields.AI_SUGGESTION_STATUS'`
|
||||||
|
2. n8n Workflow B enabled: Check n8n UI
|
||||||
|
3. Error logs: `docker-compose exec postgres psql -U kb_user -d n8n_kb -c "SELECT * FROM error_log ORDER BY created_at DESC LIMIT 5;"`
|
||||||
|
|
||||||
|
### Issue: Milvus search returns no results
|
||||||
|
|
||||||
|
**Check**:
|
||||||
|
1. Milvus running: `curl http://127.0.0.1:19530/v1/healthz`
|
||||||
|
2. KB collection exists: See Milvus documentation for collection listing
|
||||||
|
3. Vector embedding generated: Check PostgreSQL `knowledge_base_updates.vector_embedding`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Appendix A: API Endpoints Reference
|
||||||
|
|
||||||
|
| Service | Endpoint | Purpose |
|
||||||
|
|---------|----------|---------|
|
||||||
|
| Freescout | `https://ekshelpdesk.fft-it.de/api/v1/conversations` | Ticket management |
|
||||||
|
| LiteLLM | `http://llm.eks-ai.apps.asgard.eks-lnx.fft-it.de/v1/chat/completions` | AI analysis |
|
||||||
|
| Milvus | `http://127.0.0.1:19530/v1/search` | Vector DB search |
|
||||||
|
| PostgreSQL | `localhost:5432` | Data persistence |
|
||||||
|
| n8n | `http://localhost:5678` | Workflow orchestration |
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**Document Version**: 1.0
|
||||||
|
**Last Updated**: 2026-03-16
|
||||||
|
**Author**: QA/Testing Agent
|
||||||
|
**Status**: Ready for Testing
|
||||||
Reference in New Issue
Block a user