rdev/cookbooks/scripts/aeries-daeya-test.sh
jordan e42c18a9a3 feat: add session web UI mode + aeries-daeya cookbook tree
Session WebUI:
- Add `web_ui` flag to session create — launches claude-code-ui in pod on port 3001
- Install @siteboon/claude-code-ui in claudebox Dockerfile, expose port 3001
- Migration 027: add web_ui column to sessions table
- startWebUI/stopWebUI fire-and-forget helpers in SessionsHandler
- Service selects preview port 3001 (web UI) vs 8080 (sidecar) based on flag

Aeries Daeya cookbook:
- Add cookbooks/trees/aeries-daeya.yaml: privacy-first avatar social platform
  (infra → avatar data model → AI generation pipeline → studio UI)
- Add cookbooks/scripts/aeries-daeya-test.sh: run/status/diagnose/teardown harness
- Fix race condition in common.sh wait_for_pipeline: detect already-running pipelines
  at startup and track directly instead of waiting for a newer one

Docs/tooling:
- Add SDK Update Workflow section to CLAUDE.md
- Add `make sdk` and `make sdk-check` targets for OpenAPI spec management

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-02-26 23:14:08 -07:00

148 lines
5.3 KiB
Bash
Executable File

#!/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 <command> <project-name>
# 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 <command> <project-name>"
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, looks, albums, posts, mutations)"
echo " Phase 3 — AI Generation Pipeline (portrait gen, outfit styling, mutation explorer)"
echo " Phase 4 — Studio UI (creation wizard, mutation explorer, look panel, albums)"
echo ""
"$SCRIPT_DIR/tree-runner.sh" run aeries-daeya \
--project-name "$PROJECT_NAME" \
${AUTO_TEARDOWN:+--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 " Studio: https://$DOMAIN"
echo " API health: https://$DOMAIN/api/daeya-api/health"
echo " Characters: https://$DOMAIN/api/daeya-api/characters (requires auth)"
echo ""
echo " Flow:"
echo " 1. Open https://$DOMAIN → login with OTP"
echo " 2. Create Character → 4-step wizard (describe, shape, soul, generate)"
echo " 3. Open Character → use Mutation Explorer to adjust skin tone, background, lighting"
echo " 4. 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 "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 <token>' 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"
}
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