Files
ai-stack-deployer/docs/TESTING.md
Oussama Douhou 8b1556c034 docs: add Gitea Actions workflow status checking documentation
- Add API endpoint and curl commands to check CI status
- Document authentication with Authorization: token header
- Add response field descriptions (status, conclusion)
- Reference BWS key for GITEA_API_TOKEN
2026-01-10 14:38:53 +01:00

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

Gitea Actions CI/CD Status

Check Workflow Status

The oh-my-opencode-free Docker image is built via Gitea Actions. To check CI status:

Web UI:

https://git.app.flexinit.nl/oussamadouhou/oh-my-opencode-free/actions

API (requires token):

# Get GITEA_API_TOKEN from BWS (key: GITEA_API_TOKEN)
GITEA_TOKEN="<your-token>"

# List recent workflow runs
curl -s -H "Authorization: token $GITEA_TOKEN" \
  "https://git.app.flexinit.nl/api/v1/repos/oussamadouhou/oh-my-opencode-free/actions/runs?limit=5" | \
  jq '.workflow_runs[] | {id, run_number, status, conclusion, display_title, head_sha: .head_sha[0:7]}'

# Get specific run details
curl -s -H "Authorization: token $GITEA_TOKEN" \
  "https://git.app.flexinit.nl/api/v1/repos/oussamadouhou/oh-my-opencode-free/actions/runs/<RUN_ID>" | jq .

# Get jobs for a specific run
curl -s -H "Authorization: token $GITEA_TOKEN" \
  "https://git.app.flexinit.nl/api/v1/repos/oussamadouhou/oh-my-opencode-free/actions/runs/<RUN_ID>/jobs" | jq .

API Response Fields

Field Description
status queued, in_progress, completed
conclusion success, failure, cancelled, skipped (only when status=completed)
head_sha Commit SHA that triggered the run
run_number Sequential run number
display_title Commit message or PR title

Gitea API Authentication

From Gitea docs:

# Header format
Authorization: token <your-api-token>

# Alternative: query parameter
?token=<your-api-token>

BWS Token Reference

Key Purpose
GITEA_API_TOKEN Gitea API access for workflow status
DOKPLOY_API_TOKEN Dokploy deployment API (BWS ID: 6b3618fc-ba02-49bc-bdc8-b3c9004087bc)