> ## Documentation Index
> Fetch the complete documentation index at: https://docs.wellapp.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# ConnectorMapping

> A `ConnectorMapping` row is the compiled JSONata expression that the connector sync pipeline uses to transform one MCP tool's response payload into one of twelv

A `ConnectorMapping` row is the compiled JSONata expression that the connector sync pipeline uses to transform one MCP tool's response payload into one of twelve Well financial-graph entity types (company, invoice, transaction, account, etc.). One row is produced per unique `(workspace_connector, target_model, tool_name)` triple; the triple is enforced by a partial unique index on non-deleted rows. The record is entirely pipeline-owned: it is created, regenerated, and soft-deleted by `SyncConfigService` during each MCP sync cycle, and is never written by a user. It is associated upward to a `WorkspaceConnector` (the authenticated provider instance) and to a `Workspace`.

| Naming                          | Value                             |
| ------------------------------- | --------------------------------- |
| Object                          | ConnectorMapping                  |
| Resource type (JSON:API `type`) | `connector_mapping`               |
| Collection / records root       | — <sub>(not a records root)</sub> |
| REST base                       | `/v1/connector-mappings`          |
| Entity class                    | `ConnectorMapping`                |

<Note>
  **Internal object.** Not currently exposed on the public REST API. The operations below describe the intended contract.
</Note>

## API operations

| Operation | Method & path                        | Status     |
| --------- | ------------------------------------ | ---------- |
| List      | `GET /v1/connector-mappings`         | 🟡 Planned |
| Retrieve  | `GET /v1/connector-mappings/{id}`    | 🟡 Planned |
| Create    | `POST /v1/connector-mappings`        | 🟡 Planned |
| Update    | `PATCH /v1/connector-mappings/{id}`  | 🟡 Planned |
| Delete    | `DELETE /v1/connector-mappings/{id}` | 🟡 Planned |

## Data model

### Attributes

| Field                  | Type                                   | Required | Constraints                                                                                                            | Allowed values                                                                                                                                                        | Description                                                                                                                                                                                                                                                                            |
| ---------------------- | -------------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| connector\_mapping\_id | 🔒 system — UUID string                | ✅ Yes    | unique                                                                                                                 | UUID v4                                                                                                                                                               | Public stable identifier for the mapping row. Generated via gen\_random\_uuid() at insert time.                                                                                                                                                                                        |
| target\_model          | 🔒 system — enum (target\_model\_enum) | ✅ Yes    | native Postgres enum type target\_model\_enum; NOT NULL                                                                | company \| people \| invoice \| transaction \| account \| ledger\_account \| journal \| journal\_entry \| email \| payment\_means \| invoice\_transaction \| document | The Well financial-graph entity type this mapping expression produces. Part of the partial-unique triple (workspace\_connector\_pk, target\_model, tool\_name) WHERE deleted\_at IS NULL.                                                                                              |
| expression             | 🔒 system — text                       | ✅ Yes    | NOT NULL; text (unbounded)                                                                                             | —                                                                                                                                                                     | JSONata expression produced by the structured-slot-decision jury pipeline (SyncConfigService). Transforms a single MCP tool response payload into an array of Well entities matching target\_model. Never written directly by a user.                                                  |
| user\_instructions     | 🔒 system — text                       | ⚪ No     | nullable                                                                                                               | —                                                                                                                                                                     | Optional free-text hints stored alongside the mapping at generation time to guide re-generation prompts. Written by the sync pipeline, not directly by end users.                                                                                                                      |
| schema\_fingerprint    | 🔒 system — varchar(128)               | ⚪ No     | nullable; max length 128                                                                                               | —                                                                                                                                                                     | Hash of the provider tool's schema at the time this mapping was generated. Compared on subsequent syncs via compareSchemaFingerprints(); a 'drift' result triggers needs\_regeneration = true.                                                                                         |
| schema\_key\_paths     | 🔒 system — jsonb (string\[])          | ⚪ No     | nullable; jsonb                                                                                                        | —                                                                                                                                                                     | Ordered list of dotted key-paths extracted from the provider schema sample used during jury generation. Used by the panelists for vocab-bound source\_path validation.                                                                                                                 |
| needs\_regeneration    | 🔒 system — boolean                    | ✅ Yes    | NOT NULL; default false                                                                                                | true \| false                                                                                                                                                         | Flag set to true by the sync pipeline when schema drift is detected or last\_persist\_count is 0 after a sync. When true, the next sync attempt regenerates the JSONata expression before executing.                                                                                   |
| tool\_name             | 🔒 system — text                       | ✅ Yes    | NOT NULL; part of partial-unique index (workspace\_connector\_pk, target\_model, tool\_name) WHERE deleted\_at IS NULL | —                                                                                                                                                                     | Name of the MCP tool whose response this mapping expression consumes. Added in Migration20260420100000; rows pre-dating multi-tool support were backfilled with '**legacy**'.                                                                                                          |
| tool\_args             | 🔒 system — jsonb                      | ⚪ No     | nullable; CHECK pg\_column\_size(tool\_args) \< 65536 (64 KB); added in Migration20260420100000                        | —                                                                                                                                                                     | Tool invocation arguments captured at AI tool-selection time. Rehydrated by the sync orchestrator to replay the exact MCP call. Read-only; never mutated post-creation.                                                                                                                |
| selected\_at           | 🔒 system — timestamptz                | ⚪ No     | nullable; timestamptz                                                                                                  | —                                                                                                                                                                     | Timestamp recorded when the AI tool-selection phase picked this tool. Serves as an anchor for TTL-based re-selection logic in the sync pipeline.                                                                                                                                       |
| audit\_trail           | 🔒 system — jsonb                      | ⚪ No     | nullable; jsonb                                                                                                        | —                                                                                                                                                                     | Latest jury-run audit verdict for this mapping row. Written by JuryService after each jury run. Shape: \{ jury\_name, panelists\[], judge\_reasoning, disagreement\_score, duration\_ms, synthesized? }. Null on legacy rows predating the structured pipeline.                        |
| pagination\_spec       | 🔒 system — jsonb (ToolPagination)     | ⚪ No     | nullable; jsonb; added in Migration20260513110000                                                                      | —                                                                                                                                                                     | LLM-discovered pagination specification for the tool. Null means single-page tool (no pagination). Discovered at mapping-generation time using the same schema sample as the JSONata jury. Shape is ToolPagination from services/mcp/pagination.types.                                 |
| last\_persist\_count   | 🔒 system — int                        | ⚪ No     | nullable; int                                                                                                          | —                                                                                                                                                                     | Count of entities successfully persisted in the most recent sync that used this mapping. Stamped by SyncConfigService.recordPersistCount after each sync. Zero triggers auto-regeneration (needs\_regeneration = true) on the next sync. Non-zero enables the regression-revert guard. |
| created\_at            | 🔒 system — timestamptz                | ✅ Yes    | NOT NULL; set by onCreate hook                                                                                         | —                                                                                                                                                                     | Row creation timestamp. Set once by the MikroORM onCreate lifecycle hook; never updated.                                                                                                                                                                                               |
| updated\_at            | 🔒 system — timestamptz                | ⚪ No     | nullable; set by onUpdate hook                                                                                         | —                                                                                                                                                                     | Row last-modification timestamp. Set by the MikroORM onUpdate hook on every flush.                                                                                                                                                                                                     |
| deleted\_at            | 🔒 system — timestamptz                | ⚪ No     | nullable                                                                                                               | —                                                                                                                                                                     | Soft-delete timestamp. When non-null the row is logically deleted and excluded from the partial-unique index on (workspace\_connector\_pk, target\_model, tool\_name). Allows a replacement row to be inserted under the same triple after re-generation.                              |

### Relationships

| Name               | Type               | Required | Description                                                                                                                                                                                                     |
| ------------------ | ------------------ | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| workspaceConnector | to-one (ManyToOne) | ✅ Yes    | The authenticated provider instance (WorkspaceConnector) this mapping belongs to. FK column: workspace\_connector\_pk. All active mappings for a connector are soft-deleted when the connector is disconnected. |
| workspace          | to-one (ManyToOne) | ✅ Yes    | The owning workspace. FK column: workspace\_pk. Used for tenant scoping — every query against connector\_mappings filters by workspace\_pk.                                                                     |

### System-computed

* connector\_mapping\_id — generated via gen\_random\_uuid() at insert; unique constraint enforced at DB level
* created\_at — set once by MikroORM onCreate lifecycle hook
* updated\_at — set on every flush by MikroORM onUpdate lifecycle hook
* deleted\_at — soft-delete; when set, the row is excluded from the partial unique index on (workspace\_connector\_pk, target\_model, tool\_name) WHERE deleted\_at IS NULL, allowing a fresh row to be inserted under the same triple
* needs\_regeneration — auto-flipped to true by SyncConfigService when schema drift ('drift' result from compareSchemaFingerprints) is detected or last\_persist\_count == 0 after a sync
* last\_persist\_count — stamped by SyncConfigService.recordPersistCount after each sync completes; zero value is the signal for automatic re-generation on the next sync cycle
* expression — produced by the structured slot-decision jury pipeline (3-panelist OpenAI strict json\_schema → reconcileJuryDecisions → mergeSlotDecisions with YAML-pinned slots → compileSlotDecisionsToJsonata); regenerated when needs\_regeneration is true; subject to three-tier graceful degradation (reuse prior working expression → legacy jury → hard fail)
* schema\_fingerprint — computed from the provider tool schema sample at generation time; compareSchemaFingerprints returns identical | additive\_only | drift; only 'drift' triggers regeneration
* schema\_key\_paths — extracted from the provider schema sample during jury generation; used for vocab-bound source\_path validation by jury panelists
* audit\_trail — written by JuryService after each jury run; null on rows predating the structured pipeline
* pagination\_spec — discovered by the same schema-sample pass as the JSONata jury at generation time; null means single-page tool
* tool\_args — captured once at AI tool-selection time (selected\_at anchor); never mutated post-creation; bounded to 64 KB by a CHECK constraint (Migration20260420100000)
* Partial-unique index connector\_mappings\_wc\_target\_tool\_unique on (workspace\_connector\_pk, target\_model, tool\_name) WHERE deleted\_at IS NULL — enforces one active mapping per tool-per-target-per-connector; added in Migration20260420100000 replacing the legacy (workspace\_connector\_pk, target\_model) unique index

## Example

```json theme={null}
{
  "data": {
    "type": "connector_mapping",
    "id": "a3f8c1d2-7b4e-4f2a-9c01-3e5d8f2a6b19",
    "attributes": {
      "connector_mapping_id": "a3f8c1d2-7b4e-4f2a-9c01-3e5d8f2a6b19",
      "target_model": "invoice",
      "expression": "$map(result.invoices, function($v) { { 'reference_number': $v.invoice_number, 'grand_total': $number($v.total_amount), 'issue_date': $v.created_at } })",
      "user_instructions": "Map invoice totals from EUR cents to decimal euros.",
      "schema_fingerprint": "sha256:3a9c1e7f2b4d",
      "schema_key_paths": ["result.invoices[].invoice_number", "result.invoices[].total_amount", "result.invoices[].created_at"],
      "needs_regeneration": false,
      "tool_name": "pennylane_list_invoices",
      "tool_args": { "page": 1, "per_page": 100 },
      "selected_at": "2026-05-01T14:32:00.000Z",
      "audit_trail": {
        "jury_name": "slot-decision-v2",
        "panelists": ["gpt-5.4-0.4", "gpt-5.4-0.7", "gpt-5.4-1.0"],
        "disagreement_score": 0.12,
        "duration_ms": 4320,
        "synthesized": false
      },
      "pagination_spec": { "type": "page_number", "page_param": "page", "per_page_param": "per_page", "per_page": 100 },
      "last_persist_count": 87,
      "created_at": "2026-04-20T10:00:00.000Z",
      "updated_at": "2026-05-01T14:32:05.000Z",
      "deleted_at": null
    },
    "relationships": {
      "workspace_connector": {
        "data": { "type": "workspace_connector", "id": "c7d4a2f1-1e3b-4a2c-8f01-9b2e7c3d5a11" }
      },
      "workspace": {
        "data": { "type": "workspace", "id": "9f3e2b1a-4c7d-4f8e-b3a1-2c5d9e7f3b08" }
      }
    }
  }
}
```

<sub>Source: `/Users/maximechampoux/platform/apps/api/src/database/entities/ConnectorMapping.ts` · domain: ingestion · tier: Infrastructure</sub>
