name: foundary
description: "Foundary Studio: Bootstrap a React+API+DB project, design via architect conversation, build with natural language prompts, and verify the live site."
version: 2

vars:
  project_name: ""

steps:
  # ============================================================
  # SECTION 1: INFRASTRUCTURE
  # Create project with React app, API service, and database
  # ============================================================
  create-project:
    description: "Create project with bootstrap build"
    action: api
    method: POST
    endpoint: /project/create-and-build
    body:
      name: "{{ .vars.project_name }}"
      description: "Foundary Studio: Task management with Kanban board"
      template: "skeleton"
      prompt: "Set up the monorepo workspace. Ensure the root README describes a task management studio with Kanban board, REST API, and CockroachDB persistence."
      auto_commit: true
      auto_push: true
    outputs:
      - project_id: .data.project_id
      - domain: .data.domain
      - git_clone_http: .data.git.clone_http
      - bootstrap_task_id: .data.task_id

  wait-bootstrap:
    description: "Wait for bootstrap build to complete"
    depends_on: [create-project]
    action: wait_build
    build_id: "{{ .outputs.create-project.bootstrap_task_id }}"
    max_attempts: 720
    poll_interval: 5

  setup-hooks:
    description: "Configure git hooks in project workspace"
    depends_on: [wait-bootstrap]
    action: api
    method: POST
    endpoint: "/projects/{{ .outputs.create-project.project_id }}/builds"
    body:
      prompt: "Run ./scripts/setup-hooks.sh to configure git hooks. Then verify with: git config core.hooksPath"
      auto_commit: false
      auto_push: false
      git_clone_url: "{{ .outputs.create-project.git_clone_http }}"
    outputs:
      - build_id: .data.task_id

  wait-setup-hooks:
    description: "Wait for git hooks setup to complete"
    depends_on: [setup-hooks]
    action: wait_build
    build_id: "{{ .outputs.setup-hooks.build_id }}"
    max_attempts: 120
    poll_interval: 5

  add-components:
    description: "Add React frontend, API service, and CockroachDB database"
    depends_on: [wait-setup-hooks]
    action: api
    method: POST
    endpoint: "/projects/{{ .outputs.create-project.project_id }}/components/batch"
    body:
      components:
        - type: app-react
          name: studio-ui
        - type: service
          name: studio-api
        - type: postgres
          name: studio-db

  wait-components:
    description: "Wait for component scaffolding pipeline"
    depends_on: [add-components]
    action: wait_pipeline
    project_id: "{{ .outputs.create-project.project_id }}"
    max_attempts: 720
    on_error: continue

  verify-site:
    description: "Verify site is live (may 503 until first build pushes component images)"
    depends_on: [wait-components]
    action: wait_site
    domain: "{{ .outputs.create-project.domain }}"
    max_attempts: 120
    on_error: continue

  # ============================================================
  # SECTION 2: DESIGN & BUILD
  # Architect conversation flow, then 3 iterative builds with
  # natural language prompts (no slash commands).
  # ============================================================
  architect-start:
    description: "Start architect conversation about product goals"
    depends_on: [verify-site]
    action: api
    method: POST
    endpoint: "/projects/{{ .outputs.create-project.project_id }}/architect/start"
    body:
      prompt: "I want to build a task management studio. The product needs: 1) Core data models for Task, Project, Label, and Assignment entities with full CRUD stored in CockroachDB via studio-db, exposed as REST endpoints on studio-api. 2) A React frontend in studio-ui with a Kanban board (drag-and-drop columns: To Do, In Progress, Done), task creation/edit modals, and filtering by label and assignee. Propose the architecture and identify the two MVP features we should build."
    outputs:
      - conversation_id: .data.id

  architect-refine:
    description: "Refine architecture with component details"
    depends_on: [architect-start]
    action: api
    method: POST
    endpoint: "/projects/{{ .outputs.create-project.project_id }}/architect/continue/{{ .outputs.architect-start.conversation_id }}"
    body:
      message: "Good. Let's define exactly two features for the MVP: Feature 1 covers the persistence layer (Task, Project, Label, Assignment entities, migrations, repository layer, service layer, handler tests). Feature 2 covers the React frontend (Kanban board, task CRUD modals, label/assignee filters). Feature 2 depends on Feature 1 being complete since it consumes the API. Please confirm this breakdown and note any architectural considerations."

  architect-generate-blueprint:
    description: "Generate structured blueprint from conversation"
    depends_on: [architect-refine]
    action: api
    method: POST
    endpoint: "/projects/{{ .outputs.create-project.project_id }}/architect/generate-blueprint/{{ .outputs.architect-start.conversation_id }}"
    body:
      name: "foundary-studio-mvp"
    outputs:
      - blueprint_id: .data.blueprint.id

  # --- Build 1: Data models, migrations, repository, handlers on studio-api ---
  build-api:
    description: "Build studio-api: data models, migrations, repository, handlers"
    depends_on: [architect-generate-blueprint]
    action: api
    method: POST
    endpoint: "/projects/{{ .outputs.create-project.project_id }}/builds"
    body:
      prompt: |
        Build the studio-api service with these requirements:

        1. Data models: Define Task, Project, Label, and Assignment entities.
           - Task: id, title, description, status (todo/in_progress/done), project_id, assignee_id, created_at, updated_at
           - Project: id, name, description, created_at
           - Label: id, name, color, project_id
           - Assignment: id, task_id, label_id (many-to-many join)

        2. Database: Create SQL migrations for all tables with foreign keys and indexes.
           Use the studio-db CockroachDB connection (DATABASE_URL env var).

        3. Repository layer: Implement CRUD operations for each entity using sqlx.

        4. Service layer: Business logic for task lifecycle (create, update status, assign labels).

        5. HTTP handlers: RESTful endpoints mounted at /api/:
           - GET/POST /api/projects, GET/PUT/DELETE /api/projects/:id
           - GET/POST /api/tasks, GET/PUT/DELETE /api/tasks/:id
           - GET/POST /api/labels, GET/PUT/DELETE /api/labels/:id
           - POST/DELETE /api/tasks/:id/labels/:label_id

        6. Tests: Add handler tests for the task CRUD endpoints.

        Work in the components/studio-api/ directory.
      auto_commit: true
      auto_push: true
      git_clone_url: "{{ .outputs.create-project.git_clone_http }}"
    outputs:
      - build_id: .data.task_id

  wait-build-api:
    description: "Wait for API build to complete"
    depends_on: [build-api]
    action: wait_build
    build_id: "{{ .outputs.build-api.build_id }}"
    max_attempts: 720
    poll_interval: 5

  wait-deploy-api:
    description: "Wait for API deployment pipeline"
    depends_on: [wait-build-api]
    action: wait_pipeline
    project_id: "{{ .outputs.create-project.project_id }}"
    max_attempts: 720

  # --- Build 2: React Kanban UI, API client, task CRUD modals on studio-ui ---
  build-ui:
    description: "Build studio-ui: Kanban board, API client, task modals"
    depends_on: [wait-deploy-api]
    action: api
    method: POST
    endpoint: "/projects/{{ .outputs.create-project.project_id }}/builds"
    body:
      prompt: |
        Build the studio-ui React frontend with these requirements:

        1. API client: Create a typed fetch wrapper that calls the studio-api endpoints.
           Base URL should be configurable via VITE_API_URL env var, defaulting to /api.

        2. Kanban board: Three columns (To Do, In Progress, Done).
           - Display tasks as cards with title, description preview, and labels.
           - Implement drag-and-drop between columns using @dnd-kit/core.
           - Moving a card between columns calls PUT /api/tasks/:id to update status.

        3. Task modals: Create/Edit modal with fields for title, description, and label selection.
           - Create: POST /api/tasks
           - Edit: PUT /api/tasks/:id
           - Delete: confirmation dialog, then DELETE /api/tasks/:id

        4. Project selector: Dropdown to switch between projects (GET /api/projects).

        5. Label/assignee filters: Filter bar above the Kanban board.

        6. Layout: Clean dashboard layout with header, project selector, filter bar, and board.

        Work in the components/studio-ui/ directory. Use Tailwind CSS for styling.
      auto_commit: true
      auto_push: true
      git_clone_url: "{{ .outputs.create-project.git_clone_http }}"
    outputs:
      - build_id: .data.task_id

  wait-build-ui:
    description: "Wait for UI build to complete"
    depends_on: [build-ui]
    action: wait_build
    build_id: "{{ .outputs.build-ui.build_id }}"
    max_attempts: 720
    poll_interval: 5

  wait-deploy-ui:
    description: "Wait for UI deployment pipeline"
    depends_on: [wait-build-ui]
    action: wait_pipeline
    project_id: "{{ .outputs.create-project.project_id }}"
    max_attempts: 720

  # --- Build 3: Polish — CORS, error handling, health check, README ---
  build-polish:
    description: "Polish: CORS, error handling, health check, README"
    depends_on: [wait-deploy-ui]
    action: api
    method: POST
    endpoint: "/projects/{{ .outputs.create-project.project_id }}/builds"
    body:
      prompt: |
        Polish the Foundary Studio application:

        1. CORS: Ensure studio-api allows requests from the studio-ui origin.
           Add CORS middleware that allows GET, POST, PUT, DELETE, OPTIONS with credentials.

        2. Error handling: Add proper error responses (400, 404, 500) with JSON error bodies
           from studio-api handlers. Add error toast notifications in studio-ui.

        3. Health check: Add GET /api/health endpoint on studio-api that checks database
           connectivity and returns {"status": "ok", "service": "studio-api"}.

        4. README: Update the root README.md with:
           - Project description (task management studio)
           - Architecture overview (monorepo with studio-ui, studio-api, studio-db)
           - API endpoint reference
           - Local development instructions
      auto_commit: true
      auto_push: true
      git_clone_url: "{{ .outputs.create-project.git_clone_http }}"
    outputs:
      - build_id: .data.task_id

  wait-build-polish:
    description: "Wait for polish build to complete"
    depends_on: [build-polish]
    action: wait_build
    build_id: "{{ .outputs.build-polish.build_id }}"
    max_attempts: 720
    poll_interval: 5

  wait-deploy-polish:
    description: "Wait for polish deployment pipeline"
    depends_on: [wait-build-polish]
    action: wait_pipeline
    project_id: "{{ .outputs.create-project.project_id }}"
    max_attempts: 720

  # --- Commit QA artifacts and validate pre-merge hooks ---
  commit-after-qa:
    description: "Commit any remaining changes after QA"
    depends_on: [wait-deploy-polish]
    action: api
    method: POST
    endpoint: "/projects/{{ .outputs.create-project.project_id }}/builds"
    body:
      prompt: '/commit-all "chore: commit QA artifacts and fixes"'
      auto_commit: false
      auto_push: false
      git_clone_url: "{{ .outputs.create-project.git_clone_http }}"
    outputs:
      - build_id: .data.task_id

  wait-commit-after-qa:
    description: "Wait for QA commit to complete"
    depends_on: [commit-after-qa]
    action: wait_build
    build_id: "{{ .outputs.commit-after-qa.build_id }}"
    max_attempts: 120
    poll_interval: 5

  pre-merge-validate:
    description: "Run pre-commit hooks and fix any failures"
    depends_on: [wait-commit-after-qa]
    action: api
    method: POST
    endpoint: "/projects/{{ .outputs.create-project.project_id }}/builds"
    body:
      prompt: |
        Run ./.githooks/pre-commit to check code quality.
        If it fails, run /fix-all to fix all issues, then re-run
        ./.githooks/pre-commit. Repeat until it passes.
      auto_commit: true
      auto_push: true
      git_clone_url: "{{ .outputs.create-project.git_clone_http }}"
    outputs:
      - build_id: .data.task_id

  wait-pre-merge-validate:
    description: "Wait for pre-merge validation to complete"
    depends_on: [pre-merge-validate]
    action: wait_build
    build_id: "{{ .outputs.pre-merge-validate.build_id }}"
    max_attempts: 720
    poll_interval: 5

  wait-deploy-final:
    description: "Wait for final deployment pipeline after validation fixes"
    depends_on: [wait-pre-merge-validate]
    action: wait_pipeline
    project_id: "{{ .outputs.create-project.project_id }}"
    max_attempts: 720

  # ============================================================
  # SECTION 3: VERIFY
  # Confirm site is live and API responds
  # ============================================================
  verify-site-live:
    description: "Verify site is live after all builds"
    depends_on: [wait-deploy-final]
    action: wait_site
    domain: "{{ .outputs.create-project.domain }}"
    max_attempts: 120

  verify-api-health:
    description: "Verify API health endpoint responds"
    depends_on: [verify-site-live]
    on_error: continue
    action: shell
    command: |
      DOMAIN="{{ .outputs.create-project.domain }}"

      # Check API health
      HEALTH=$(curl -sf "https://$DOMAIN/api/studio-api/health" 2>/dev/null || echo '{}')
      echo "API health response: $HEALTH"

      STATUS=$(echo "$HEALTH" | grep -o '"status":"ok"' || true)
      if [ -n "$STATUS" ]; then
        echo "API health check passed"
        exit 0
      else
        echo "API health check failed (may not have health endpoint yet)"
        exit 1
      fi

  verify-complete:
    description: "Print success summary"
    depends_on: [verify-api-health]
    action: shell
    command: |
      echo ""
      echo "============================================================"
      echo "SUCCESS: Foundary Studio build complete"
      echo "============================================================"
      echo ""
      echo "Domain: {{ .outputs.create-project.domain }}"
      echo "Project ID: {{ .outputs.create-project.project_id }}"
      echo ""
      echo "Architecture:"
      echo "  studio-ui   — React Kanban board frontend"
      echo "  studio-api  — REST API with Task/Project/Label CRUD"
      echo "  studio-db   — PostgreSQL persistence"
      echo ""
      echo "Builds completed:"
      echo "  1. API: data models, migrations, repository, handlers"
      echo "  2. UI: Kanban board, drag-and-drop, task modals"
      echo "  3. Polish: CORS, error handling, health check, README"
      echo "============================================================"
      exit 0

teardown:
  - action: api
    method: DELETE
    endpoint: "/project/{{ .outputs.create-project.project_id }}"
