# Run a local development workspace

Use this guide to test the public API with synthetic customer and deal records. It requires access to the private Terramine source repository.

Building a customer integration? Start with the [API quickstart](https://docs.terraminedesk.ai/docs/quickstart.html) using your workspace URL and service key. The downloadable customer kit offers a Python standard-library rehearsal without repository access or PostgreSQL; this developer launcher runs the actual hosted API against a disposable local database.

## Get the scripts

The launcher imports application code and test fixtures. Clone the complete repository; the script cannot run on its own.

For developers who already have repository access:

```sh
git clone git@github.com:dmitriisorokin88/spareparts-sales-agent.git
cd spareparts-sales-agent
python3.12 -m venv .venv
. .venv/bin/activate
python -m pip install -r requirements-dev.txt
```

The launcher is [scripts/integration_pilot.py](https://github.com/dmitriisorokin88/spareparts-sales-agent/blob/main/scripts/integration_pilot.py). Its fixtures are in `tests/`, and its application dependencies are in `server/`. GitHub requires repository access to open the source link.

## Start the local workspace

Start a local PostgreSQL 16 server with permission to create a database and roles. From the repository root with the virtual environment active, run:

```sh
TEST_DESK_POSTGRES_DSN=postgresql://postgres@127.0.0.1:5432/postgres \
  python scripts/integration_pilot.py --port 8765
```

The launcher creates an isolated database and two roles using the CloudDesk test fixtures. It prints a fresh loopback base URL, service key, synthetic customer ID and deal ID. Copy the service key
into your local credential store; it is not saved in the repository. Only
machine API paths are exposed. Browser owner controls and background jobs are
disabled. Stop with Ctrl-C to delete the unique database and roles; after a
forced kill, use the printed database name to clean them manually.

Set the workflow's base URL to the printed `http://127.0.0.1:8765` when n8n runs
on the host. With Docker Desktop, try `http://host.docker.internal:8765` from
n8n instead. Connectivity to a host loopback listener depends on your Docker
configuration; this address was verified on one development Mac, and is not a
guarantee for other hosts. If it is unreachable, run n8n on the host. Keep the
launcher bound to loopback; it is not a production server.
The synthetic customer name already matches the template. Set `crm_deal_id`
to the printed deal ID so the draft references the synthetic deal; the template
value is only a placeholder. Use `--smoke` to
verify lookup, draft creation and idempotent retry without starting the listener.

Run the workflow twice with the same service key, `quote_request_id` and payload. Both runs should return the same draft ID and order number. Use a new `quote_request_id` for a new quotation request. The local workspace has no business-event delivery; use a configured tenant to test signed webhooks.

For a host curl check, set `PILOT_API_KEY` to the printed key and `PILOT_DEAL_ID`
to the printed deal ID locally, then run:

```sh
curl --fail-with-body \
  -H "Authorization: Bearer $PILOT_API_KEY" \
  "http://127.0.0.1:8765/api/v1/crm/deals/$PILOT_DEAL_ID"
```
