Skip to content

fix(ipa): preserve resource scope in Operations resource operation IDs - #1414

Merged
julius-jogela merged 2 commits into
mainfrom
ipa-104-105-operations-scope-operation-ids
Aug 5, 2026
Merged

julius-jogela merged 2 commits into
mainfrom
ipa-104-105-operations-scope-operation-ids

Conversation

@julius-jogela

@julius-jogela julius-jogela commented Aug 4, 2026 •

Copy link
Copy Markdown
Contributor

Proposed changes

Problem: LRO standardization (IPA-132) nests read-only Operations endpoints under a parent resource at both collection and instance scope. The collection- and instance-scoped pairs generated identical operation IDs:

Path Operation ID (before)
/clusters/operations listGroupClusterOperations
/clusters/{clusterName}/operations listGroupClusterOperations
/clusters/operations/{operationId} getGroupClusterOperation
/clusters/{clusterName}/operations/{operationId} getGroupClusterOperation

generateOperationID strips all path parameters before building the noun list and then singularizes every non-final noun, so both scopes collapse to the same nouns. Note this affects every method on these paths, not just List — the {operationId} parameter does not make Get naturally distinct, because it is discarded along with the other path parameters.

Fix: add an isCollectionScopedOperationsPath check and keep the parent noun in its plural form when the trailing operations section is attached to a resource collection rather than to a single resource. The trailing noun keeps its normal meaning (plural for List, singular for Get), so the existing convention is preserved and all four IDs become distinct:

Path Operation ID (after)
/clusters/operations listGroupClustersOperations
/clusters/{clusterName}/operations listGroupClusterOperations
/clusters/operations/{operationId} getGroupClustersOperation
/clusters/{clusterName}/operations/{operationId} getGroupClusterOperation

This reuses the existing singularize helper and its ignoreSingularizationList opt-out rather than introducing new Collection/Instance suffix conventions.

Documentation: the exception is documented in the xgen-IPA-104-valid-operation-id and xgen-IPA-105-valid-operation-id rule descriptions (the Get and List methods), and the ruleset README.md is regenerated to match.

Verification: unchanged behavior for non-Operations paths, a singular parent (/groups/{groupId}/operations), a non-trailing operations section, an unscoped /api/atlas/v2/operations, and multi-word custom methods — all covered by tests. Full suite passes (705 tests), along with lint-js and format-check.

Because the scope distinction is a property of the path rather than of the method, the Create, Update and Delete shapes are pinned by tests as well:

Path Operation ID
create /clusters/operations createGroupClustersOperation
create /clusters/{clusterName}/operations createGroupClusterOperation
update /clusters/operations/{operationId} updateGroupClustersOperation
update /clusters/{clusterName}/operations/{operationId} updateGroupClusterOperation
delete /clusters/operations/{operationId} deleteGroupClustersOperation
delete /clusters/{clusterName}/operations/{operationId} deleteGroupClusterOperation

These endpoints should not exist — IPA-132 Operations resources are read-only — so the tests are not asserting supported API surface. They are there purely to guarantee the collection-vs-instance distinction stays consistent across every method rather than being special-cased to Get and List, and to catch a silent regression if a mutating method is ever added to an Operations path.

Follows up on #1406, which relaxed xgen-IPA-102-path-alternate-resource-name-path-param to permit these paths.

Jira ticket: CLOUDP-429467

Checklist

  • I have signed the MongoDB CLA
  • I have added tests that prove my fix is effective or that my feature works

Changes to Spectral

  • I have read the README file for Spectral Updates

Further comments

One thing worth flagging for review: there is no operation-ID uniqueness check anywhere in the repo today — each rule only validates that an operation ID matches the one generated from its own path. The collision described above would not have been flagged by validation, only by downstream SDK codegen, where each operation ID becomes a method name.

@julius-jogela julius-jogela self-assigned this Aug 4, 2026
@julius-jogela
julius-jogela marked this pull request as ready for review August 4, 2026 09:24
@julius-jogela
julius-jogela requested a review from a team as a code owner August 4, 2026 09:24
A collection-scoped Operations resource and an instance-scoped Operations
resource under the same parent produced identical operation IDs.
generateOperationID removes path parameters before building the noun list and
then singularizes every non-final noun, so both scopes reduced to the same
nouns.

Keep the parent noun plural when the trailing 'operations' section is attached
to a resource collection, so the two resources get distinct operation IDs:

  /groups/{groupId}/clusters/operations                              -> listGroupClustersOperations
  /groups/{groupId}/clusters/{clusterName}/operations                -> listGroupClusterOperations
  /groups/{groupId}/clusters/operations/{operationId}                -> getGroupClustersOperation
  /groups/{groupId}/clusters/{clusterName}/operations/{operationId}  -> getGroupClusterOperation

The scope distinction applies to every method, so pin the Create, Update and
Delete shapes too. IPA-132 Operations resources are read-only and those methods
should not exist, but the tests guard consistency if they ever do.

Document the exception in the IPA-104 and IPA-105 valid-operation-id
descriptions, which govern the Get and List methods, and regenerate the
ruleset README.

Jira ticket: CLOUDP-429467
@julius-jogela
julius-jogela force-pushed the ipa-104-105-operations-scope-operation-ids branch from e55e479 to 6199074 Compare August 4, 2026 11:20

@andmatei andmatei left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@yelizhenden-mdb yelizhenden-mdb left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Waiting for DevTools team confirmation

The Operation ID must start with the verb “get” and should be followed by a noun or compound noun.
The noun(s) in the Operation ID should be the collection identifiers from the resource identifier in singular form.
If the resource is a singleton resource, the last noun may be the plural form of the collection identifier.
For a collection-scoped Operations resource, such as '/clusters/operations/{operationId}', the parent noun is in plural form, so that the Operation ID differs from the one for the instance-scoped Operations resource, such as '/clusters/{clusterName}/operations/{operationId}'.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Operation IDs for collection-scoped and instance-scoped LRO resources are already expected to be different — as are all operation IDs, since they map to CLI command names. Restating that in an operation-ID validity check doesn't add value, especially since the rule doesn't actually verify cross-path uniqueness. If you want to document the change, it's enough to say what the rule now expects:

For a collection-scoped Operations resource, such as /resources/operations/{operationId}, the parent noun (e.g. resources) stays in its plural form instead of being singularized

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same applies to IPA-105

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed: reworded to describe what the rule expects instead of restating uniqueness.

).toEqual('getGroupClusterOperation');
});

it('should generate distinct operation IDs for collection- and instance-scoped operations resources', () => {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need this test, given that we already have the previous check?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed: removed redundant tests.

});

it('should not preserve the parent plural for other operations paths', () => {
// the parent is a single resource, so the existing singularization applies

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does "the parent is a single resource" mean in this context?
We would expect to see listGroupsOperations for /api/atlas/v2/groups/operations

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed: added a test for /groups/operations (no ID) — confirms it hits the collection-scoped branch and returns listGroupsOperations as expected. Also reworded the adjacent comment to name {groupId} as thats what makes the other case instance-scoped.

…ant test; add collection-scoped coverage

- Reword IPA-104/IPA-105 descriptions per review feedback
- Regenerate README.md
- Remove redundant distinct-operation-ID test (already covered by exact-value assertions)
- Add test for /groups/operations (no ID) and clarify adjacent comment

@yelizhenden-mdb yelizhenden-mdb left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks!

@julius-jogela
julius-jogela merged commit 333b09b into main Aug 5, 2026
9 checks passed
@julius-jogela
julius-jogela deleted the ipa-104-105-operations-scope-operation-ids branch August 5, 2026 13:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants