name: async-worker-pipeline description: "Slack Path 2: Background Workers. Implements Producer/Consumer pattern with Redis." version: 1 vars: project_name: "" feature_slug: "async-jobs" steps: # --- Infrastructure --- create-project: action: api method: POST endpoint: /project body: name: "{{ .vars.project_name }}" description: "Slack Path 2: Async Workers" outputs: - project_id: .data.name - domain: .data.domain add-redis: description: Add Redis for job queue (may already exist from skeleton) depends_on: [create-project] on_error: continue action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/components" body: type: redis name: "job-queue" add-components: description: Add API + Worker atomically (single git commit) depends_on: [create-project, add-redis] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/components/batch" body: components: - type: service name: "api" - type: worker name: "background-processor" wait-infra: depends_on: [create-project, add-components] action: wait_pipeline project_id: "{{ .outputs.create-project.project_id }}" # --- Implementation --- implement-queue: description: "Agent implements Job Queue logic in API and Worker" depends_on: [create-project, wait-infra] action: api method: POST endpoint: "/projects/{{ .outputs.create-project.project_id }}/builds" body: prompt: "/implement-feature {{ .vars.feature_slug }} --requirements 'API: POST /jobs pushes JSON to Redis. Worker: Pops from Redis, simulates work, updates status. API: GET /jobs/{id} returns status.'" auto_commit: true auto_push: true git_clone_url: "https://git.threesix.ai/jordan/{{ .outputs.create-project.project_id }}.git" outputs: - build_id: .data.task_id wait-code: description: Wait for agent code generation depends_on: [implement-queue] action: wait_build build_id: "{{ .outputs.implement-queue.build_id }}" max_attempts: 120 poll_interval: 5 wait-deploy: depends_on: [create-project, wait-code] action: wait_pipeline project_id: "{{ .outputs.create-project.project_id }}" # --- Verification --- verify-service-running: description: "Verify API service is running" depends_on: [create-project, wait-deploy] action: shell command: | DOMAIN="{{ .outputs.create-project.domain }}" HEALTH=$(curl -s "https://$DOMAIN/api/api/health" | jq -r '.data.status // empty') if [ "$HEALTH" == "healthy" ]; then echo "API service healthy" exit 0 else echo "Fail: API service not healthy" exit 1 fi verify-async: description: "Create Job -> Verify Acceptance -> Poll for Completion (optional)" depends_on: [create-project, verify-service-running] on_error: continue action: shell command: | DOMAIN="{{ .outputs.create-project.domain }}" # 1. Enqueue JOB_ID=$(curl -s -X POST "https://$DOMAIN/api/jobs" -d '{"type":"image_resize"}' | jq -r .id) echo "Job enqueued: $JOB_ID" # 2. Poll for completion (Worker should pick it up) for i in {1..10}; do STATUS=$(curl -s "https://$DOMAIN/api/jobs/$JOB_ID" | jq -r .status) echo "Job status: $STATUS" if [ "$STATUS" == "completed" ]; then exit 0; fi sleep 2 done echo "Job never completed" exit 1 teardown: - action: api method: DELETE endpoint: "/project/{{ .outputs.create-project.project_id }}"