Files
ai-stack-deployer/docs/TESTING.md
Oussama Douhou 67069f3bda fix: resolve 4 UI/UX issues
1. Fix typewriter double-letter bug (race condition)
2. Replace flag emojis with text labels (NL/AR/EN)
3. Fix health check TLS options for Bun compatibility
4. Translate 'yourname' placeholder per language
2026-01-10 11:39:14 +01:00

5.4 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 - SSL errors treated as "alive" during cert provisioning

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}'