Skip to content

feat(save-user-data): extend user data abstract class for api backend COMPASS-9558 #7114

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 20 commits into
base: main
Choose a base branch
from

Conversation

myang1220
Copy link
Contributor

@myang1220 myang1220 commented Jul 15, 2025

Description

Extend the IUserData abstract class to create an AtlasUserData class that uses the endpoints created in CCS. Contains unit testing.

Checklist

  • New tests and/or benchmarks are included
  • Documentation is changed or added
  • If this change updates the UI, screenshots/videos are added and a design review is requested
  • I have signed the MongoDB Contributor License Agreement (https://www.mongodb.com/legal/contributor-agreement)

Motivation and Context

  • Bugfix
  • New feature
  • Dependency update
  • Misc

Open Questions

See comments

Dependents

Types of changes

  • Backport Needed
  • Patch (non-breaking change which fixes an issue)
  • Minor (non-breaking change which adds functionality)
  • Major (fix or feature that would cause existing functionality to change)

@github-actions github-actions bot added the feat label Jul 15, 2025
@myang1220 myang1220 added the no release notes Fix or feature not for release notes label Jul 15, 2025
}

return true;
} catch (error) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

How does the logging look? Are there any changes that I should make to make this more consistent with Compass behavior?

) => Promise<Response>,
orgId: string,
groupId: string,
type: string,
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Should type be more strictly typed? I originally created a AtlasUserDataType enum so that the inputted type would be more strictly limited to the declared values in the enum, but I thought this might pose issues later on when importing — could be totally wrong about this.

const json = await response.json();
const data = Array.isArray(json)
? json.map((item) =>
this.validator.parse(this.deserialize(item.data as string))
Copy link
Contributor Author

@myang1220 myang1220 Jul 18, 2025

Choose a reason for hiding this comment

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

I wonder whether it should parse one by one.

For example, suppose 3 queries in the output are well-formatted, and 1 isn't. As it currently stands, readAll would not return any values in data, and simply returns an error in the errors array. If we put the try-catch inside the loop, then we could add to data and errors as necessary. In theory, the data should always be well-formatted, though, because we also parse when we call write (?) — maybe updateAttributes should also parse as well?

async updateAttributes(
id: string,
data: Partial<z.input<T>>
): Promise<z.output<T>> {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Why does the file system have updateAttributes as returning the whole data item? From a look through the code, I didn't see any instances of where the output of updateAttributes was actually used. Would the backend endpoint need to change to reflect the file system, or the other way around?

@myang1220 myang1220 requested review from Anemy and gribnoysup July 18, 2025 21:21
@myang1220 myang1220 marked this pull request as ready for review July 18, 2025 21:21
@Copilot Copilot AI review requested due to automatic review settings July 18, 2025 21:21
@myang1220 myang1220 requested a review from a team as a code owner July 18, 2025 21:21
Copy link

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR extends the user data abstract class system by implementing a new AtlasUserData class that communicates with Atlas backend API endpoints for cloud-based user data storage, as an alternative to the existing file-based storage.

  • Adds AtlasUserData class implementing the IUserData interface for API-based storage
  • Includes comprehensive test coverage for all CRUD operations and URL construction
  • Updates exports to make the new class available to consumers

Reviewed Changes

Copilot reviewed 3 out of 4 changed files in this pull request and generated 4 comments.

File Description
packages/compass-user-data/src/user-data.ts Implements AtlasUserData class with HTTP-based CRUD operations
packages/compass-user-data/src/user-data.spec.ts Adds comprehensive test suite for AtlasUserData functionality
packages/compass-user-data/src/index.ts Exports the new AtlasUserData class

private orgId: string = '';
private groupId: string = '';
private readonly type: string;
private readonly BASE_URL = 'cluster-connection.cloud-local.mongodb.com';
Copy link
Preview

Copilot AI Jul 18, 2025

Choose a reason for hiding this comment

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

The hardcoded BASE_URL should be configurable through constructor parameters or environment variables to support different deployment environments (development, staging, production).

Suggested change
private readonly BASE_URL = 'cluster-connection.cloud-local.mongodb.com';
private readonly BASE_URL: string;

Copilot uses AI. Check for mistakes.

`Failed to update data: ${response.status} ${response.statusText}`
);
}
return this.validator.parse(data);
Copy link
Preview

Copilot AI Jul 18, 2025

Choose a reason for hiding this comment

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

The method returns the parsed input data instead of the actual updated data from the server response. This could lead to inconsistencies if the server modifies the data during update.

Suggested change
return this.validator.parse(data);
const responseData = await response.json();
return this.validator.parse(this.deserialize(responseData));

Copilot uses AI. Check for mistakes.

Comment on lines +479 to +480
return `${this.BASE_URL}/${this.type}/${this.orgId}/${this.groupId}`;
}
Copy link
Preview

Copilot AI Jul 18, 2025

Choose a reason for hiding this comment

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

The URL construction should include protocol (https://) and validate/sanitize the orgId, groupId, and type parameters to prevent URL injection attacks.

Suggested change
return `${this.BASE_URL}/${this.type}/${this.orgId}/${this.groupId}`;
}
const sanitizedType = this.sanitizeInput(this.type);
const sanitizedOrgId = this.sanitizeInput(this.orgId);
const sanitizedGroupId = this.sanitizeInput(this.groupId);
const baseUrl = this.BASE_URL.startsWith('https://') ? this.BASE_URL : `https://${this.BASE_URL}`;
return `${baseUrl}/${sanitizedType}/${sanitizedOrgId}/${sanitizedGroupId}`;
}
private sanitizeInput(input: string): string {
// Basic sanitization: remove any characters that are not alphanumeric, dashes, or underscores
return input.replace(/[^a-zA-Z0-9-_]/g, '');
}

Copilot uses AI. Check for mistakes.

myang1220 and others added 3 commits July 18, 2025 17:25
Co-authored-by: Copilot <[email protected]>
Merge branch 'extend-user-data' of https://github.com/mongodb-js/compass into extend-user-data
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feat no release notes Fix or feature not for release notes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants