14 KiB
BUILD_AND_TEST_PLAN.md
Conductor — Build and Test Plan
This document defines the incremental build steps for the Conductor MVP. Each step is self-contained and verifiable before the next begins.
Step 1 — Project Scaffold
Goal: Create the repository structure with placeholder files for frontend, backend, and docs.
Deliverables
frontend/— React + TypeScript project scaffold (no UI logic yet)backend/— Node.js + Express + TypeScript project scaffold (no logic yet)docs/— Documentation directory containing all spec filesdocker-compose.yml— Root compose file wiring frontend and backend servicesREADME.md— Root readme with project overview and local dev instructions.gitignore— Ignores node_modules, build artifacts, SQLite files, .env files
Verification
# Confirm directory structure
ls -1
# Confirm docs
ls docs/
# Install dependencies
cd frontend && npm install
cd ../backend && npm install
# Confirm TypeScript compiles without errors
cd frontend && npx tsc --noEmit
cd ../backend && npx tsc --noEmit
Does not include
- Backend health check endpoint
- Frontend UI components
- SQLite setup
- REST proxy
- Authentication
- AI features
Step 2 — Backend Foundation
Goal: Stand up a running Express server with a health check endpoint and SQLite connection.
Deliverables
GET /api/healthreturns{ status: "ok" }- SQLite database initialised on startup
- Basic project table created in SQLite
- Structured request logging (morgan or pino)
Verification
cd backend && npm run dev
curl http://localhost:4000/api/health
# Expected: { "status": "ok" }
Step 3 — Project API (CRUD)
Goal: Implement create, read, update, delete for projects.
Deliverables
POST /api/projects— create a projectGET /api/projects— list all projectsGET /api/projects/:id— get a single projectPUT /api/projects/:id— update a projectDELETE /api/projects/:id— delete a project
Verification
# Create
curl -X POST http://localhost:4000/api/projects \
-H "Content-Type: application/json" \
-d '{"name":"Test Project","description":"My first project"}'
# List
curl http://localhost:4000/api/projects
# Get by ID
curl http://localhost:4000/api/projects/1
# Update
curl -X PUT http://localhost:4000/api/projects/1 \
-H "Content-Type: application/json" \
-d '{"name":"Renamed Project"}'
# Delete
curl -X DELETE http://localhost:4000/api/projects/1
Step 4 — Frontend Shell
Goal: React app loads, renders a basic shell layout, and communicates with the backend.
Deliverables
- App shell with header and placeholder content area
- API client calling
GET /api/projects - Projects listed in the UI (names only)
- Development proxy configured so
/api/*routes to backend
Verification
cd frontend && npm start
# Open http://localhost:3000
# Confirm project list renders (or empty state message)
Step 5 — Canvas and Component Palette
Goal: Drag-and-drop canvas renders and components can be placed.
Deliverables
- Canvas area renders in the editor view
- Component palette with: Button, Text Input, Text Area, Dropdown, Label, Table, JSON Viewer, Status Panel
- Drag a component from the palette onto the canvas
- Dropped component renders on canvas at drop position
- Selected component shows a visual selection indicator
Verification
- Open editor view
- Drag Button onto canvas — button appears
- Drag Text Input onto canvas — input appears
- Click a component — selection indicator shows
Step 6 — Project JSON Definition
Goal: Canvas state is represented as a canonical JSON project definition and persisted to the backend.
Deliverables
- Canvas state serialises to project JSON on every change
- JSON Editor panel displays live project JSON
- Edits in JSON Editor update the canvas
- Save button persists JSON to
PUT /api/projects/:id - Load project from API on page load
Verification
- Add a button to canvas
- JSON Editor panel shows button in JSON
- Manually edit button label in JSON Editor — canvas label updates
- Click Save — reload page — project restores
Step 7 — Component Properties Panel
Goal: Selecting a component opens a properties panel for editing its configuration.
Deliverables
- Properties panel opens when a component is selected
- Editable fields: name, label, placeholder, default value, visibility, disabled state
- Changes in properties panel update canvas and project JSON
Verification
- Place a Text Input
- Select it — properties panel opens
- Change label — canvas updates immediately
- JSON Editor shows updated label
Step 8 — REST Action Configuration
Goal: Users can define REST API actions on a project.
Deliverables
- Actions panel lists defined REST actions
- Create action form: name, method, URL, headers, query params, body template, auth type
- Actions saved as part of project JSON
- Auth types: Anonymous, Basic, Bearer token, API key (header or query param)
Verification
- Create a GET action pointing to
https://httpbin.org/get - Save project
- Reload — action persists
Step 9 — Backend REST Proxy
Goal: Backend proxies REST API calls on behalf of the frontend.
Deliverables
POST /api/proxy/executeaccepts action ID + runtime values- Backend resolves action definition from project JSON
- Backend executes HTTP request to target endpoint
- Response returned to frontend
- Secrets/auth headers injected server-side, never exposed to browser
- Basic execution log saved to SQLite
Verification
curl -X POST http://localhost:4000/api/proxy/execute \
-H "Content-Type: application/json" \
-d '{"projectId":"1","actionId":"action-1","inputs":{}}'
# Expected: proxied response from target
Step 10 — Bindings and Preview Mode
Goal: Components are bound to actions; Preview mode allows end-to-end interaction.
Deliverables
- Button can be bound to a REST action
- Dropdown can populate options from an API response
- Response mapping:
apiResponse.fieldPath -> component.property - Preview mode renders project as end-user view
- API calls fire in preview mode; responses update target components
Verification
- Bind Button to a GET action
- In Preview: click button — API fires — JSON Viewer updates with response
- Bind Dropdown to GET action returning list — dropdown populates on page load
Step 10.5 — Project Persistence
Goal: Connect the Visual Editor to the backend Project CRUD API via a React Project Context.
Deliverables
ProjectProviderwraps the entire app; all editor views share one contextProjectContextholds: currentProjectDocument, backend row ID, project name, dirty state, loading/saving state, project list, and all persistence operationsProjectToolbarrenders: project name (click-to-rename), New, Save / Update, Load buttons- Load picker lists all backend projects and loads the selected one
- Saving serialises the full canonical project JSON and calls
PUT /api/projects/:id(orPOSTon first save) - Loading calls
GET /api/projects/:idand fully replaces context state - Toast notifications for: save succeeded, save failed, load succeeded, load failed, network error
- Visual Editor renders from
ProjectContext— no independent state
Verification
# Start backend
cd backend && npm run dev
# Start frontend
cd frontend && npm start
- Open http://localhost:3000 → Visual Editor
- Add components → click Save → toast confirms save; project appears in backend DB
- Reload page → click Load → select project → canvas restores
- Edit project name in toolbar → click Update → backend reflects new name
- Click New → fresh canvas; previous project unaffected on backend
Step 11 — Validation and Error Handling
Goal: Schema validation, user-facing error states, and proxy error normalisation.
Deliverables
- Project JSON validated against schema on save
- JSON Editor shows schema errors inline
- Preview mode shows error state on failed API call
- Proxy normalises and returns structured error responses
Step 12 — Docker Compose Integration Test
Goal: Full stack runs via docker-compose up.
Deliverables
docker-compose upstarts frontend and backend- Frontend accessible at
http://localhost:3000 - Backend accessible at
http://localhost:4000 - Full Step 10 verification passes against Docker stack
Step 13 — REST Action Model
Goal: Add support for defining REST actions inside the canonical Conductor project JSON. This step is model-only — no execution, no backend proxy, no binding.
Deliverables
- JSON schema (
shared/schemas/conductor-project.schema.json) fully defines theAction$def with all required and optional fields, all five authentication types, and correct validation rules - TypeScript type
RestActioninfrontend/src/types/project.tsmirrors the schema with JSDoc comments Projecttype includesactions: RestAction[]- JSON Editor allows REST actions to be added or edited through the canonical project JSON (apply + validate flow)
POST /api/projects/validatevalidates REST actions against the schema- Example files:
examples/project-definitions/valid-rest-actions.json— seven actions covering all fiveauthenticationTypevaluesexamples/project-definitions/valid-full.json— includes two REST actions with path parameters, query parameters, and body templates
docs/SCHEMA.mddocuments the correctActionshape (withauthenticationType), field table, and validation commands for all example files
REST Action Model
Each REST action supports the following fields:
| Field | Required | Description |
|---|---|---|
id |
✅ | Unique identifier within the project. |
name |
✅ | Human-readable name shown in the UI. |
description |
— | Optional description of the action's purpose. |
method |
✅ | HTTP method:GET · POST · PUT · PATCH · DELETE |
url |
✅ | Target URL template;{{paramName}} marks path parameter slots. |
headers |
— | Static request headers. Values may use{{variableName}} syntax. |
queryParameters |
— | URL query parameters. Values may use{{variableName}} syntax. |
pathParameters |
— | Path segment substitutions for{{paramName}} URL placeholders. |
bodyTemplate |
— | Request body template with{{variableName}} substitution slots. |
authenticationType |
✅ | One of:anonymous · bearerToken · basicAuth · apiKeyHeader · apiKeyQueryParameter |
Does not include
- Backend REST proxy
- REST action execution
- Button-to-REST binding
- Input-to-request binding
- Response mapping execution
- Secret storage
- Authentication credential execution
- AI features
Verification
# Install ajv-cli if not already installed
npm install -g ajv-cli ajv-formats
# Validate the minimal example
ajv validate \
-s shared/schemas/conductor-project.schema.json \
-d examples/project-definitions/valid-minimal.json \
--spec=draft2020
# Validate the full example (includes REST actions)
ajv validate \
-s shared/schemas/conductor-project.schema.json \
-d examples/project-definitions/valid-full.json \
--spec=draft2020
# Validate the REST actions showcase (all five auth types)
ajv validate \
-s shared/schemas/conductor-project.schema.json \
-d examples/project-definitions/valid-rest-actions.json \
--spec=draft2020
# TypeScript type check (frontend)
cd frontend && npx tsc --noEmit
# TypeScript type check (backend)
cd backend && npx tsc --noEmit
Manual verification checklist
- Open the JSON Editor in the browser
- Add a REST action to
project.actionsin the textarea:{ "id": "action_test", "name": "Test Action", "method": "GET", "url": "https://httpbin.org/get", "headers": { "Accept": "application/json" }, "queryParameters": {}, "pathParameters": {}, "bodyTemplate": "", "authenticationType": "anonymous" } - Click Apply — validation passes, action count in sidebar increments
- Click Save — project persists to backend
- Reload page → Load project → REST action is present in JSON
Validation Gate
Before proceeding from any step that changes the project JSON model, JSON schema, component model, REST action model, binding model, or persistence behavior, the change must be validated.
Validation must include:
- Running schema validation against valid examples.
- Running schema validation against invalid examples.
- Testing at least one realistic project document that uses the newly added feature.
- Confirming that the frontend JSON Editor accepts the document.
- Confirming that save/load preserves the document.
- Confirming that the runtime consumes the same model that the schema validates.
A step is not complete until the schema, frontend editor, backend validator, and runtime agree on the same JSON shape.
Do not proceed to the next step if:
- Example JSON fails validation.
- The JSON Editor reports a validation error.
- The runtime expects a different structure than the schema allows.
- The backend validation endpoint returns HTTP 500.
- A new model field is accepted by the frontend but rejected by the backend.