Files
ai-stack-deployer/docs/TESTING.md
2026-01-10 12:00:14 +01:00

6.5 KiB

Testing Guide

Quick Verification

# 1. Start server
bun run dev

# 2. Health check
curl http://localhost:3000/health

# 3. Open browser
open http://localhost:3000

API Endpoints

Endpoint Method Purpose
/health GET Server status
/api/check/:name GET Name availability
/api/deploy POST Start deployment
/api/status/:id GET SSE progress stream
/api/stack/:name DELETE Delete stack and cleanup

Test Checklist

Backend

Test Command Expected
Server starts bun run dev "starting on http://0.0.0.0:3000"
Health endpoint curl localhost:3000/health {"status":"healthy"...}
TypeScript bun run typecheck No errors
Dokploy connection Check /api/check/test-name Returns availability

Frontend

Test Action Expected
Page loads Open localhost:3000 Dark theme, centered content
Typewriter Wait 2s "Choose Your Stack Name" animates
Language switch Click 🇲🇦 Arabic text, RTL layout
Name validation Type "ab" Error: too short
Reserved name Type "admin" Error: reserved
Valid name Type "my-stack" "✓ Name is available!"

Deployment Flow

Step Indicator
Submit form Progress bar appears
SSE updates Log entries animate in
Success Typewriter: "Deployment Complete"
Error Typewriter: "Deployment Failed"

Infrastructure

Service URL Purpose
Dokploy https://app.flexinit.nl Container orchestration
Traefik 144.76.116.169 SSL termination
Stacks *.ai.flexinit.nl Deployed AI assistants

Full Deployment Test

# 1. Generate unique name
NAME="test-$(date +%s | tail -c 5)"

# 2. Check availability
curl -s http://localhost:3000/api/check/$NAME

# 3. Deploy
curl -s -X POST http://localhost:3000/api/deploy \
  -H "Content-Type: application/json" \
  -d "{\"name\": \"$NAME\"}"

# 4. Monitor SSE (wait ~2-3 min)
curl -N http://localhost:3000/api/status/<deployment-id>

# 5. Verify stack accessible
curl -s https://$NAME.ai.flexinit.nl

# 6. Cleanup
curl -s -X DELETE http://localhost:3000/api/stack/$NAME

Cleanup Commands

# Delete specific stack
curl -s -X DELETE http://localhost:3000/api/stack/my-stack

# List all projects (direct Dokploy)
source .env && curl -s -H "x-api-key: $DOKPLOY_API_TOKEN" \
  "$DOKPLOY_URL/api/project.all" | jq '.[].name'

Common Issues

Issue Solution
CSS not loading Check /style.css returns CSS, not HTML
401 on Dokploy Regenerate API token in Dokploy dashboard
Typewriter not running Check browser console for JS errors
RTL not working Verify dir="rtl" on <html> element
Health check timeout Container startup can take 1-2 min, timeout is 3 min
SSL cert errors Health check treats SSL errors as "alive" during provisioning
SSE disconnects idleTimeout set to 255s (max), long deployments should complete

Production Verification (2026-01-10)

Verified Working

Component Status Notes
Portal Health https://portal.ai.flexinit.nl/health returns healthy
Name Validation /api/check/:name validates correctly
Frontend UI 3 languages (NL, AR, EN), RTL support, typewriter animation
Stack Deployment Full flow: project → app → domain → deploy → health check
Stack Cleanup DELETE /api/stack/:name removes all resources
SSL/HTTPS Wildcard cert working for all *.ai.flexinit.nl

Critical Configuration

# These settings are REQUIRED for deployment to work
DOKPLOY_URL=https://app.flexinit.nl          # Public URL, NOT internal 10.100.0.20
STACK_IMAGE=git.app.flexinit.nl/oussamadouhou/oh-my-opencode-free:latest
STACK_REGISTRY_ID=bKDYM5X7NN34x_lRDjWbz      # Registry ID for Docker auth

Known Gotchas (Fixed)

  1. Registry URL format - Use git.app.flexinit.nl, NOT https://git.app.flexinit.nl
  2. Username in image path - Must be oussamadouhou, not odouhou
  3. Dokploy URL - Must use public URL for container-to-container communication
  4. Health check - Now uses Dokploy API status check (not HTTP fetch)
  5. Resource limits - Removed temporarily (Dokploy API format issues with CPU/memory values)
  6. Typewriter race condition - Fixed by tracking active instances and canceling previous

UI/UX Fixes (2026-01-10 v2)

Issue Fix Status
Double letters in typewriter Track active instances, cancel before starting new Verified
Flag emojis not showing Replaced with text labels (NL/AR/EN) Verified
SSE disconnects during deployment Use Dokploy API status instead of HTTP health check Verified
'yourname' not translated Added translation key per language Verified

Health Check Change

The health check was changed from HTTP fetch (which failed from inside Docker) to Dokploy API status check:

// Before: HTTP fetch (failed - container can't reach external URL)
const response = await fetch(`${state.url}/`);

// After: Dokploy API status check (works)
const app = await this.client.getApplication(applicationId);
if (app.applicationStatus === 'done') { /* success */ }

Test Commands

# Quick health check
curl -s https://portal.ai.flexinit.nl/health | jq .

# Full deployment test
NAME="test-$(date +%s | tail -c 5)"
RESULT=$(curl -s -X POST https://portal.ai.flexinit.nl/api/deploy \
  -H "Content-Type: application/json" \
  -d "{\"name\": \"$NAME\"}")
echo $RESULT | jq .

# Monitor deployment (use deploymentId from above)
curl -N "https://portal.ai.flexinit.nl/api/status/$(echo $RESULT | jq -r .deploymentId)"

# Verify stack accessible (after deployment completes)
curl -s -k https://$NAME.ai.flexinit.nl | head -5

# Cleanup
curl -s -X DELETE https://portal.ai.flexinit.nl/api/stack/$NAME | jq .

Dokploy Direct Commands

# List all ai-stack projects
source .env && curl -s -H "x-api-key: $DOKPLOY_API_TOKEN" \
  https://app.flexinit.nl/api/project.all | \
  jq '[.[] | select(.name | startswith("ai-stack-")) | {name: .name, id: .projectId}]'

# Get application status
source .env && curl -s -H "x-api-key: $DOKPLOY_API_TOKEN" \
  "https://app.flexinit.nl/api/project.one?projectId=<PROJECT_ID>" | \
  jq '.environments[0].applications[0] | {name: .name, status: .applicationStatus}'