# Continuous Control: notes for coding agents

This project uses **Continuous Control**, which connects Salesforce Revenue Cloud to NetSuite.
Copy this file to the root of your repository as `AGENTS.md` (or `CLAUDE.md` for Claude Code)
and fill in the values marked `<...>`.

## Where the docs are

- Index of every docs page in Markdown: https://taggalongtech.github.io/continuous-control/llms.txt
- All pages in one file: https://taggalongtech.github.io/continuous-control/llms-full.txt
- Start with `quickstart.md`, `connection-wizard.md` and `monitoring-troubleshooting.md`.
- Read the `.md` pages, not the `.html` ones. The `.md` pages carry the exact API names,
  script ids and payload shapes.

## This project's environments

| | Value |
|---|---|
| Salesforce org alias (sf CLI) | `<org alias>` |
| Salesforce org type | `<production / sandbox / scratch>` |
| NetSuite account id | `<account id>` |
| NetSuite SDF auth id (suitecloud CLI) | `<auth id, e.g. continuous>` |
| Continuous Control package version | `<e.g. 3.4.1>`; check with `sf package installed list -o <org alias>` |
| NetSuite release | `<e.g. ns-v3.3.0>`; the Connection wizard's step 4 shows the installed version |

## Rules

- **Never commit credentials.** NetSuite consumer key/secret, token id/secret, certificate
  private keys (`*.pem`) and `.env` files stay out of the repository.
- **Never commit account-specific internal ids** (NetSuite internal ids, Salesforce record ids).
  They differ in every environment.
- **NetSuite deploys never delete.** SDF adds and updates components but never removes them.
  Removing a component means deleting its source *and* deleting the record in the NetSuite UI.
- **Don't edit the Continuous Control package's own metadata** in the org (objects, fields,
  classes prefixed `CC_` / `CcNs`). Package upgrades overwrite it. Extend with your own
  calls, mappings and Flows instead; see `configurable-calls.md`.
- **Change mappings and calls in the app** (Calls & Mappings tab), then Validate and Activate.
  Edits are drafts until activated; live syncs keep using the active version.
- **Ask a person before running anything against production**: installs, deploys, activating a
  call, or triggering a sync. Syncs create real records in NetSuite.

## Common commands

```bash
# Install or update the Salesforce package (version id from ref-versions.md)
sf package install --package <package version id> -o <org alias> --wait 20

# Install or update the NetSuite components (from the unzipped release folder)
NS_ACCOUNT=<account id> NS_CERT_ID=<certificate id> NS_KEY_PATH=./continuous-key.pem ./install.sh
./install.sh --validate-only        # dry run

# Look at recent sync runs
sf data query -o <org alias> -q "SELECT Name, Type__c, Status__c, Error__c, CreatedDate FROM CC_NetSuite_Sync_Run__c ORDER BY CreatedDate DESC LIMIT 20"
```

## When a sync fails

1. Open the run on the **Sync Runs** tab, or query `CC_NetSuite_Sync_Run__c`. It has the status,
   the error, and the exact JSON sent and received.
2. Look the error up in `monitoring-troubleshooting.md`.
3. Fix the cause (usually a mapping, a missing NetSuite item, or a setting) and re-run the sync.
   Re-running is safe: records match on their Salesforce id, so nothing duplicates.
