#!/bin/bash set -euo pipefail # Aeries Daeya E2E Test Script # Privacy-first avatar social platform: character creation, AI styling from photos, # mutation explorer, album management. # # Usage: ./cookbooks/scripts/aeries-daeya-test.sh # Commands: run, status, diagnose, teardown # # Examples: # ./cookbooks/scripts/aeries-daeya-test.sh run my-daeya # ./cookbooks/scripts/aeries-daeya-test.sh run my-daeya --auto-teardown # AUTO_TEARDOWN=true ./cookbooks/scripts/aeries-daeya-test.sh run my-daeya SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" source "$SCRIPT_DIR/common.sh" # Parse --auto-teardown flag from args ARGS=("$@") for i in "${!ARGS[@]}"; do if [[ "${ARGS[$i]}" == "--auto-teardown" ]]; then AUTO_TEARDOWN="true" unset 'ARGS[$i]' fi done ARGS=("${ARGS[@]}") COMMAND="${ARGS[0]:-}" PROJECT_NAME="${ARGS[1]:-}" register_cleanup_trap if [[ -z "$COMMAND" || -z "$PROJECT_NAME" ]]; then echo "Usage: $0 " echo "Commands:" echo " run - Deploy full aeries-daeya platform via tree runner" echo " status - Check project and component status" echo " diagnose - Deep diagnostic of pipeline and site issues" echo " teardown - Delete the project and all resources" exit 1 fi run_flow() { print_header "Aeries Daeya: Privacy-First Avatar Platform" echo "Running tree: aeries-daeya for project: $PROJECT_NAME" echo "" echo " Phase 1 — Infrastructure (DB + Redis + service + worker + app)" echo " Phase 2 — Avatar & Look Data Model (characters + public discovery endpoints)" echo " Phase 3 — AI Generation Pipeline (portrait gen, outfit styling, mutation explorer)" echo " Phase 4 — Studio UI (public feed + character profiles + studio + dark pink theme)" echo "" "$SCRIPT_DIR/tree-runner.sh" run aeries-daeya \ --project-name "$PROJECT_NAME" \ $([[ "$AUTO_TEARDOWN" == "true" ]] && echo "--auto-teardown") DOMAIN=$(api_call GET "/project/$PROJECT_NAME" | jq -r '.data.domain // empty') if [[ -n "$DOMAIN" ]]; then print_success "Aeries Daeya is live at https://$DOMAIN" echo "" echo " Discovery: https://$DOMAIN (public — no login)" echo " Studio: https://$DOMAIN/studio (requires login)" echo " API health: https://$DOMAIN/api/daeya-api/health" echo " Public feed: https://$DOMAIN/api/daeya-api/characters/public" echo "" echo " Flow:" echo " 1. Open https://$DOMAIN → browse published characters (no login needed)" echo " 2. Click 'Create Your Character' → OTP login → /studio" echo " 3. Create Character → 4-step wizard (describe, shape, soul, generate)" echo " 4. In studio: toggle 'Public' → character appears on discovery feed" echo " 5. Open Character → Mutation Explorer (skin tone, background, lighting, style)" echo " 6. Add Look → upload a photo of an outfit to style on your character" fi } check_status() { print_header "Project Status: $PROJECT_NAME" local project project=$(api_call GET "/project/$PROJECT_NAME") local domain domain=$(echo "$project" | jq -r '.data.domain // "unknown"') local status status=$(echo "$project" | jq -r '.data.status // "unknown"') echo " Domain: $domain" echo " Status: $status" echo "" print_header "Components" api_call GET "/projects/$PROJECT_NAME/components" | jq -r '.data[] | " \(.name) (\(.type)): \(.status)"' 2>/dev/null || echo " (no components)" echo "" print_header "Recent Pipelines" api_call GET "/projects/$PROJECT_NAME/pipelines" | jq -r '.data[0:3][] | " [\(.status)] \(.number) — \(.created_at)"' 2>/dev/null || echo " (no pipelines)" echo "" if [[ "$domain" != "unknown" ]]; then local health_status health_status=$(curl -sf "https://$domain/api/daeya-api/health" 2>/dev/null | jq -r '.data.status // "unreachable"' || echo "unreachable") echo " daeya-api health: $health_status" fi } diagnose() { print_header "Diagnostic: $PROJECT_NAME" local domain domain=$(api_call GET "/project/$PROJECT_NAME" | jq -r '.data.domain // empty') diagnose_pipeline_failure "$PROJECT_NAME" if [[ -n "$domain" ]]; then diagnose_site_failure "$domain" "$PROJECT_NAME" fi print_diagnostic_header "Notify / Email Checks" echo "" echo " If OTP email never arrives:" print_fix "Check NOTIFY_API_KEY is injected into the daeya-api pod" print_cmd "kubectl exec -n projects deploy/$PROJECT_NAME-daeya-api -- env | grep NOTIFY" echo "" print_fix "If NOTIFY_API_KEY is empty, notify provisioning failed during project creation" print_cmd "curl -s -H 'X-API-Key: \$RDEV_API_KEY' \$RDEV_API_URL/projects/$PROJECT_NAME/notify/status | jq" echo "" print_fix "Test OTP endpoint directly (200/202/429 = notify working; 404/500 = broken)" print_cmd "curl -s -o /dev/null -w '%{http_code}' -X POST https://$domain/api/daeya-api/auth/otp/send -H 'Content-Type: application/json' -d '{\"email\":\"test@example.com\"}'" print_diagnostic_header "AI Generation Checks" echo "" echo " If characters are stuck in 'pending' status:" print_fix "media-worker may not be running or Redis connection may be broken" print_cmd "kubectl logs -n projects -l project=$PROJECT_NAME,component=media-worker --tail=50" echo "" echo " If mutation explorer generates but never shows result:" print_fix "SSE channel:daeya subscription may not be connected" print_cmd "curl -N -H 'Authorization: Bearer ' https://$domain/api/daeya-api/events/channel:daeya" echo "" echo " If look generation fails with photo upload:" print_fix "GEMINI_API_KEY may not be injected or vision endpoint unreachable" print_cmd "kubectl exec -n projects deploy/$PROJECT_NAME-media-worker -- env | grep GEMINI" print_diagnostic_header "Public Discovery Checks" echo "" echo " If /characters/public returns 404:" print_fix "implement-avatar-model build may not have created public endpoints" print_cmd "curl -s https://$domain/api/daeya-api/characters/public | jq" echo "" echo " If published characters don't show on the discovery feed:" print_fix "Character may not be toggled to published=true in the studio" print_cmd "curl -s -H 'Authorization: Bearer ' https://$domain/api/daeya-api/characters | jq '.[].published'" } teardown() { print_header "Tearing down: $PROJECT_NAME" local result result=$(api_call DELETE "/project/$PROJECT_NAME") print_success "Project $PROJECT_NAME deleted" echo "$result" | jq -r '.message // empty' 2>/dev/null || true } case "$COMMAND" in run) run_flow ;; status) check_status ;; diagnose) diagnose ;; teardown) teardown ;; *) echo "Unknown command: $COMMAND"; exit 1 ;; esac