rdev/cookbooks/fullstack-app.md
jordan c59d348040 chore: prepare for composable monorepo template implementation
This commit captures the current state before implementing the composable
monorepo template system. Key changes included:

Infrastructure:
- Add CockroachDB provisioner adapter for database provisioning
- Add Redis provisioner adapter for cache provisioning
- Add build events system with PostgreSQL storage
- Add WebSocket endpoint for real-time build progress

Code agent improvements:
- Fix Claude Code adapter to use default allowed tools instead of dangerously-skip-permissions
- Add context-aware stream closing for cancellation support
- Improve parser tests for edge cases

Build system:
- Add build event constants and metrics
- Remove deprecated git_operations.go (replaced by pod_git_operations.go)
- Add rollback logic for multi-step provisioning operations

Documentation:
- Add composable-monorepo feature documentation
- Add DNS/Cloudflare service documentation
- Update deployment and troubleshooting guides

Cookbooks:
- Add fullstack-app cookbook
- Refactor landing-test with shared library

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-31 11:39:28 -07:00

13 KiB

Full-Stack App Cookbook

Deploy a full-stack application (Next.js + Go backend) built entirely by Claude through the threesix.ai infrastructure.

Overview

This cookbook creates and deploys a complete full-stack application using agent-driven development:

POST /project/create-and-build
    ↓
Creates: Gitea repo + DNS + Woodpecker CI + K8s deployment
    ↓
Enqueues build task with comprehensive prompt
    ↓
Worker picks up task → Claude builds the entire stack
    ↓
Agent commits + pushes
    ↓
CI builds and deploys
    ↓
Live full-stack app

Claude builds everything from scratch: Next.js frontend with shadcn/ui, Go backend API, Docker configs, and CI pipeline.


Prerequisites

API Access

export RDEV_API_URL="https://rdev.masq-ops.orchard9.ai"
export RDEV_API_KEY="<your-api-key>"

Infrastructure Required


Step 1: Create Project and Build Full-Stack App

Single API call that creates infrastructure AND enqueues the full-stack build:

curl -X POST "$RDEV_API_URL/project/create-and-build" \
  -H "X-API-Key: $RDEV_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my-fullstack-app",
    "description": "Full-stack app with Next.js frontend and Go backend",
    "build": {
      "prompt": "Build a full-stack task management application with the following structure:\n\nFRONTEND (Next.js 14 + shadcn/ui):\n- Create a Next.js 14 app with App Router in /frontend\n- Use shadcn/ui for all components (install with npx shadcn-ui@latest init)\n- Dark theme with modern aesthetic\n- Pages: Dashboard showing tasks, Add Task form, Task detail view\n- Use Tailwind CSS for styling\n- Connect to backend API at /api proxy\n\nBACKEND (Go):\n- Create a Go HTTP server in /backend using chi router\n- Endpoints: GET /api/tasks, POST /api/tasks, GET /api/tasks/{id}, DELETE /api/tasks/{id}\n- In-memory task storage (no database needed)\n- Structured JSON responses\n- CORS middleware for frontend\n\nDOCKER:\n- /frontend/Dockerfile: Multi-stage build for Next.js (node:20-alpine)\n- /backend/Dockerfile: Multi-stage build for Go (golang:1.22-alpine)\n- /docker-compose.yml: Run both services, frontend proxies to backend\n\nCI/CD:\n- /.woodpecker.yml: Build both images, push to registry, deploy to k8s\n\nCreate all necessary files including package.json, go.mod, and configuration files.",
      "auto_commit": true,
      "auto_push": true
    }
  }'

Response:

{
  "project": {
    "project_id": "my-fullstack-app",
    "domain": "xyz789ab.threesix.ai",
    "git": {
      "html_url": "https://git.threesix.ai/jordan/my-fullstack-app"
    }
  },
  "build": {
    "task_id": "task-uuid",
    "status": "pending",
    "status_url": "/builds/task-uuid"
  }
}

Step 2: Monitor Build Progress

Poll the build status:

curl -s "$RDEV_API_URL/builds/{task_id}" \
  -H "X-API-Key: $RDEV_API_KEY" | jq .

Status progression: pendingrunningcompleted (or failed)

Full-stack builds take longer than simple landing pages. Expect 2-5 minutes.

When completed:

{
  "task_id": "task-uuid",
  "status": "completed",
  "result": {
    "success": true,
    "commit_sha": "def456",
    "files_changed": [
      "frontend/package.json",
      "frontend/app/page.tsx",
      "frontend/app/layout.tsx",
      "frontend/components/task-list.tsx",
      "frontend/components/add-task-form.tsx",
      "frontend/Dockerfile",
      "backend/main.go",
      "backend/go.mod",
      "backend/Dockerfile",
      "docker-compose.yml",
      ".woodpecker.yml"
    ],
    "duration_ms": 180000
  }
}

Step 3: Monitor CI Pipeline

The agent's push triggers Woodpecker CI to build both services:

curl -s "$RDEV_API_URL/projects/my-fullstack-app/pipelines" \
  -H "X-API-Key: $RDEV_API_KEY" | jq '.data[0]'

Pipeline stages:

  1. Build frontend Docker image
  2. Build backend Docker image
  3. Push both to registry
  4. Deploy to Kubernetes

Wait for status: "success".


Step 4: Verify Deployment

# Check site is live
curl -I https://xyz789ab.threesix.ai

# Test frontend loads
curl -s https://xyz789ab.threesix.ai | head -20

# Test backend API
curl -s https://xyz789ab.threesix.ai/api/tasks | jq .

# Open in browser
open https://xyz789ab.threesix.ai

Iterating on the App

Add a Feature

curl -X POST "$RDEV_API_URL/projects/my-fullstack-app/builds" \
  -H "X-API-Key: $RDEV_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "Add task priority levels (low, medium, high) with color-coded badges in the UI. Update the backend Task struct and frontend components to support priorities. Add a priority filter dropdown on the dashboard.",
    "auto_commit": true,
    "auto_push": true
  }'

Fix a Bug

curl -X POST "$RDEV_API_URL/projects/my-fullstack-app/builds" \
  -H "X-API-Key: $RDEV_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "Fix the task deletion - ensure the DELETE endpoint returns 204 No Content and the frontend removes the task from the list immediately without requiring a page refresh.",
    "auto_commit": true,
    "auto_push": true
  }'

Add Authentication

curl -X POST "$RDEV_API_URL/projects/my-fullstack-app/builds" \
  -H "X-API-Key: $RDEV_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "Add simple JWT authentication:\n- Backend: Add /api/auth/login endpoint that accepts username/password and returns JWT\n- Backend: Add auth middleware to protect /api/tasks endpoints\n- Frontend: Add login page with shadcn form components\n- Frontend: Store JWT in localStorage, include in API requests\n- Create a demo user (admin/admin123) for testing",
    "auto_commit": true,
    "auto_push": true
  }'

Each build:

  1. Claude clones the existing repo
  2. Makes the requested changes
  3. Commits and pushes
  4. CI deploys automatically

Alternative Prompts

E-commerce Storefront

curl -X POST "$RDEV_API_URL/project/create-and-build" \
  -H "X-API-Key: $RDEV_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my-store",
    "description": "E-commerce storefront",
    "build": {
      "prompt": "Build an e-commerce storefront:\n\nFRONTEND: Next.js 14 with shadcn/ui, dark theme\n- Product grid with images, prices, descriptions\n- Product detail page\n- Shopping cart (localStorage)\n- Checkout form (no payment processing)\n\nBACKEND: Go with chi router\n- GET /api/products - list products\n- GET /api/products/{id} - product detail\n- POST /api/orders - create order (log to console)\n- Seed with 6 sample products\n\nInclude Dockerfiles and .woodpecker.yml for CI/CD.",
      "auto_commit": true,
      "auto_push": true
    }
  }'

Dashboard App

curl -X POST "$RDEV_API_URL/project/create-and-build" \
  -H "X-API-Key: $RDEV_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my-dashboard",
    "description": "Analytics dashboard",
    "build": {
      "prompt": "Build an analytics dashboard:\n\nFRONTEND: Next.js 14 with shadcn/ui + recharts\n- Dashboard with 4 stat cards (users, revenue, orders, growth)\n- Line chart showing weekly trends\n- Bar chart showing top products\n- Recent activity table\n- Dark theme, responsive grid layout\n\nBACKEND: Go with chi router\n- GET /api/stats - return dashboard statistics\n- GET /api/trends - return weekly trend data\n- GET /api/activity - return recent activity\n- Generate realistic sample data\n\nInclude Dockerfiles and .woodpecker.yml for CI/CD.",
      "auto_commit": true,
      "auto_push": true
    }
  }'

Adding Custom Domains

# Add custom domain
curl -X POST "$RDEV_API_URL/projects/my-fullstack-app/domains" \
  -H "X-API-Key: $RDEV_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"domain": "app.mycompany.com"}'

# List all domains
curl -s "$RDEV_API_URL/projects/my-fullstack-app/domains" \
  -H "X-API-Key: $RDEV_API_KEY" | jq '.data.domains'

Teardown

curl -X DELETE "$RDEV_API_URL/project/my-fullstack-app" \
  -H "X-API-Key: $RDEV_API_KEY"

Removes: DNS records, K8s deployment, project metadata. Gitea repo preserved for safety.


E2E Test Script

Run the full flow:

./cookbooks/scripts/fullstack-test.sh run my-test-fullstack

Check status:

./cookbooks/scripts/fullstack-test.sh status my-test-fullstack

Cleanup:

./cookbooks/scripts/fullstack-test.sh teardown my-test-fullstack

Architecture

┌─────────────────────────────────────────────────────────────────────┐
│                  Agent-Driven Full-Stack App                        │
│                                                                     │
│  POST /project/create-and-build                                     │
│       │                                                             │
│       ├──► Gitea: creates repo                                      │
│       ├──► Cloudflare: creates DNS                                  │
│       ├──► Woodpecker: activates CI                                 │
│       ├──► K8s: creates Deployment/Service/Ingress                  │
│       └──► Work Queue: enqueues build task                          │
│                 │                                                   │
│                 ▼                                                   │
│       Worker polls queue, claims task                               │
│                 │                                                   │
│                 ▼                                                   │
│       Claude Code executes in claudebox-0:                          │
│         - Clones repo                                               │
│         - Creates Next.js frontend with shadcn/ui                   │
│         - Creates Go backend with chi router                        │
│         - Writes Dockerfiles and CI config                          │
│         - Commits and pushes                                        │
│                 │                                                   │
│                 ▼                                                   │
│       Woodpecker CI triggered by push:                              │
│         - Builds frontend Docker image                              │
│         - Builds backend Docker image                               │
│         - Pushes to registry                                        │
│         - Deploys to K8s                                            │
│                 │                                                   │
│                 ▼                                                   │
│       Full-stack app live at https://{slug}.threesix.ai             │
│         - Frontend: Next.js + shadcn/ui                             │
│         - Backend: Go API                                           │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

Troubleshooting

Build stuck in pending

# Check worker status
curl -s "$RDEV_API_URL/workers" -H "X-API-Key: $RDEV_API_KEY" | jq '.data.summary'

# Should show at least 1 idle worker

Build failed

# Get build details with full output
curl -s "$RDEV_API_URL/builds/{task_id}" -H "X-API-Key: $RDEV_API_KEY" | jq '.result'

# Check rdev-api logs for worker errors
./scripts/logs.sh -e

Pipeline not triggering

# Check if commit was pushed
curl -s "https://git.threesix.ai/api/v1/repos/jordan/my-fullstack-app/commits" | jq '.[0]'

# Check Woodpecker
open https://ci.threesix.ai/jordan/my-fullstack-app

Frontend/Backend connection issues

# Check both containers are running
kubectl get pods -n projects -l app=my-fullstack-app

# Check frontend logs
kubectl logs -n projects -l app=my-fullstack-app -c frontend

# Check backend logs
kubectl logs -n projects -l app=my-fullstack-app -c backend