Skip to content

Commit 68f4c69

Browse files
authored
fix(monaco): reject a stage key and a stage ID together on opportunity writes (#10020)
1 parent b5b8ec3 commit 68f4c69

6 files changed

Lines changed: 22 additions & 6 deletions

File tree

‎apps/docs/content/docs/integrations/monaco.mdx‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -794,7 +794,7 @@ Create a Monaco opportunity on an existing account, optionally setting its pipel
794794
| `accountId` | string | Yes | ID of the account to associate the opportunity with |
795795
| `pipelineId` | string | No | Pipeline to create the opportunity in \(see List Pipelines\). If omitted, the organization's default pipeline is used. |
796796
| `stage` | string | No | Stage key for the opportunity within its pipeline \(up to 64 characters; see List Pipelines\). If omitted, the opportunity is placed in the first stage of that pipeline. |
797-
| `stageId` | string | No | Stage ID \(from List Pipelines\), instead of a stage key. It names the pipeline too, so a pipeline ID, if given, must be that stage's pipeline. |
797+
| `stageId` | string | No | Stage ID \(from List Pipelines\), instead of a stage key; provide either stage or stageId, not both. It names the pipeline too, so a pipeline ID, if given, must be that stage's pipeline. |
798798
| `ownerUserId` | string | No | User ID to assign as the opportunity owner |
799799
| `amount` | number | No | Estimated value as a decimal amount of the currency \(e.g. 50000.25\). Set together with currencyCode. |
800800
| `currencyCode` | string | No | ISO 4217 currency code of the estimated value \(e.g. USD\), up to 8 characters. Set together with amount. |
@@ -852,7 +852,7 @@ Update a Monaco opportunity: rename it, change its owner, move it to another sta
852852
| `name` | string | No | New name of the opportunity |
853853
| `pipelineId` | string | No | Pipeline to move the opportunity to \(see List Pipelines\). The stage key then names a stage in that pipeline; if no stage is given, an open opportunity lands on the pipeline's first active stage and a closed one on its first closed stage with the same outcome. If omitted, the opportunity stays in its pipeline. |
854854
| `stage` | string | No | Stage key for the opportunity within its pipeline \(up to 64 characters; see List Pipelines\) |
855-
| `stageId` | string | No | Stage ID \(from List Pipelines\), instead of a stage key. A stage of the opportunity's own pipeline changes its stage; a stage of another pipeline moves the opportunity there. |
855+
| `stageId` | string | No | Stage ID \(from List Pipelines\), instead of a stage key; provide either stage or stageId, not both. A stage of the opportunity's own pipeline changes its stage; a stage of another pipeline moves the opportunity there. |
856856
| `ownerUserId` | string | No | User ID to assign as the opportunity owner |
857857
| `amount` | number | No | Estimated value as a decimal amount of the currency \(e.g. 50000.25\). Set together with currencyCode. |
858858
| `currencyCode` | string | No | ISO 4217 currency code of the estimated value \(e.g. USD\), up to 8 characters. Set together with amount. |

‎apps/sim/tools/generated/tool-metadata.ts‎

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

‎apps/sim/tools/monaco/create_opportunity.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ export const monacoCreateOpportunityTool: ToolConfig<
6060
required: false,
6161
visibility: 'user-or-llm',
6262
description:
63-
"Stage ID (from List Pipelines), instead of a stage key. It names the pipeline too, so a pipeline ID, if given, must be that stage's pipeline.",
63+
"Stage ID (from List Pipelines), instead of a stage key; provide either stage or stageId, not both. It names the pipeline too, so a pipeline ID, if given, must be that stage's pipeline.",
6464
},
6565
ownerUserId: {
6666
type: 'string',

‎apps/sim/tools/monaco/update_opportunity.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ export const monacoUpdateOpportunityTool: ToolConfig<
6161
required: false,
6262
visibility: 'user-or-llm',
6363
description:
64-
"Stage ID (from List Pipelines), instead of a stage key. A stage of the opportunity's own pipeline changes its stage; a stage of another pipeline moves the opportunity there.",
64+
"Stage ID (from List Pipelines), instead of a stage key; provide either stage or stageId, not both. A stage of the opportunity's own pipeline changes its stage; a stage of another pipeline moves the opportunity there.",
6565
},
6666
ownerUserId: {
6767
type: 'string',

‎apps/sim/tools/monaco/utils.ts‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -747,6 +747,9 @@ export function buildMonacoOpportunityWriteBody(params: {
747747
const trimmed = value?.trim()
748748
if (trimmed) body[key] = trimmed
749749
}
750+
if (body.stage && body.stage_id) {
751+
throw new Error('Provide either stage or stageId, not both')
752+
}
750753
if (params.notes?.trim()) body.notes = params.notes
751754

752755
const currencyCode = params.currencyCode?.trim()

‎apps/sim/tools/monaco/write_bodies.test.ts‎

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
/**
22
* Request bodies whose shape decides what Monaco changes: an empty filter group seeds an
3-
* audience with every contact, and an empty tag list on PATCH clears a record's tags.
3+
* audience with every contact, an empty tag list on PATCH clears a record's tags, and an
4+
* opportunity takes a stage key or a stage ID, never both.
45
*/
56
import { describe, expect, it } from 'vitest'
67
import { monacoCreateAudienceTool } from '@/tools/monaco/create_audience'
@@ -50,3 +51,15 @@ describe('Monaco PATCH tags', () => {
5051
})
5152
})
5253
})
54+
55+
describe('Monaco opportunity stage', () => {
56+
it('rejects a stage key and a stage ID together', () => {
57+
expect(() =>
58+
requestBody(monacoUpdateOpportunityTool, {
59+
opportunityId: 'o-1',
60+
stage: 'proposal',
61+
stageId: 's-1',
62+
})
63+
).toThrow('Provide either stage or stageId, not both')
64+
})
65+
})

0 commit comments

Comments
 (0)