conductor/docs/BUILD_AND_TEST_PLAN.md
2026-07-18 10:23:13 -04:00

436 lines
14 KiB
Markdown

# 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 files
- `docker-compose.yml` — Root compose file wiring frontend and backend services
- `README.md` — Root readme with project overview and local dev instructions
- `.gitignore` — Ignores node_modules, build artifacts, SQLite files, .env files
### Verification
```bash
# 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/health` returns `{ status: "ok" }`
- SQLite database initialised on startup
- Basic project table created in SQLite
- Structured request logging (morgan or pino)
### Verification
```bash
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 project
- `GET /api/projects` — list all projects
- `GET /api/projects/:id` — get a single project
- `PUT /api/projects/:id` — update a project
- `DELETE /api/projects/:id` — delete a project
### Verification
```bash
# 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
```bash
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/execute` accepts 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
```bash
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
- `ProjectProvider` wraps the entire app; all editor views share one context
- `ProjectContext` holds: current `ProjectDocument`, backend row ID, project name, dirty state, loading/saving state, project list, and all persistence operations
- `ProjectToolbar` renders: 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` (or `POST` on first save)
- Loading calls `GET /api/projects/:id` and 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
```bash
# 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 up` starts 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 the `Action` $def with all required and optional fields, all five authentication types, and correct validation rules
- TypeScript type `RestAction` in `frontend/src/types/project.ts` mirrors the schema with JSDoc comments
- `Project` type includes `actions: RestAction[]`
- JSON Editor allows REST actions to be added or edited through the canonical project JSON (apply + validate flow)
- `POST /api/projects/validate` validates REST actions against the schema
- Example files:
- `examples/project-definitions/valid-rest-actions.json` — seven actions covering all five `authenticationType` values
- `examples/project-definitions/valid-full.json` — includes two REST actions with path parameters, query parameters, and body templates
- `docs/SCHEMA.md` documents the correct `Action` shape (with `authenticationType`), 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
```bash
# 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.actions` in the textarea:
```json
{
"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.
---