Skip to content
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

Add organization sort #133

Merged
merged 17 commits into from
Oct 15, 2024
Merged

Add organization sort #133

merged 17 commits into from
Oct 15, 2024

Conversation

MohammadPCh
Copy link
Collaborator

@MohammadPCh MohammadPCh commented Oct 14, 2024

Summary by CodeRabbit

  • New Features

    • Introduced a new ProjectResolver for handling project-related queries.
    • Added sorting functionality for projects based on "vouch" or "flag" criteria.
    • New GraphQL object types: OrganisationType, OrganisationProjectType, ProjectType, and ProjectsSortedByVouchOrFlagType.
    • Added a function to extract selected fields from GraphQL queries.
  • Bug Fixes

    • Improved error handling during database query execution.
  • Documentation

    • Enhanced accessibility of ProjectResolver through exports for easier integration.

@MohammadPCh
Copy link
Collaborator Author

@aminlatifi can you review it? It's not finished but I really appreciate if you take a look and approve the way that I handle it. thanks

Copy link
Contributor

coderabbitai bot commented Oct 14, 2024

Caution

Review failed

The head commit changed during the review from 6908b75 to f9a1c1c.

Walkthrough

The changes introduce a new function getSelectedFields to extract selected field names from GraphQL queries and a ProjectResolver class for handling project-related queries. This resolver includes a method for retrieving projects sorted by specific criteria through a dynamic SQL query. Additionally, new GraphQL object types are defined to structure the data returned by the resolver, and the ProjectResolver is exported for broader accessibility within the application.

Changes

File Change Summary
src/server-extension/helper.ts Added function getSelectedFields(info: GraphQLResolveInfo): string[] to extract selected field names.
src/server-extension/resolver.ts Introduced class ProjectResolver with method async getProjectsSortedByVouchOrFlag(...) for project queries. Added enum EProjectSort. Updated return type for project queries.
src/server-extension/resolvers/index.ts Added export for ProjectResolver from the ../resolver module.
src/server-extension/types.ts Added new classes: OrganisationType, OrganisationProjectType, ProjectType, and ProjectsSortedByVouchOrFlagType with respective fields.

Possibly related PRs

  • Feat/handle attestors with no organization #111: The changes in this PR involve handling attestors without an organization, which may relate to the getSelectedFields function's ability to extract relevant fields from GraphQL queries, potentially including organization-related fields.

Poem

In the garden of code, new blooms arise,
With fields selected, under bright skies.
Projects sorted, like carrots in rows,
A resolver's dance, where data flows.
Hops of joy, as we celebrate,
In the world of GraphQL, we innovate! 🐇✨


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 6

🧹 Outside diff range and nitpick comments (5)
src/server-extension/helper.ts (1)

1-16: Overall assessment: Useful addition with room for improvement.

The getSelectedFields function provides a valuable utility for extracting selected fields from GraphQL queries. However, to enhance its reliability and maintainability, consider implementing the suggested improvements:

  1. Strengthen type safety by replacing 'any' with more specific types.
  2. Add comprehensive error handling for potential edge cases.
  3. Increase flexibility by making the 'project' prefix configurable.

These enhancements will make the function more robust and easier to use across different contexts in the project.

src/server-extension/types.ts (2)

12-22: LGTM: OrganisationProjectType is well-structured, but needs clarification.

The OrganisationProjectType class is correctly defined with appropriate fields and types. However, the purpose of the vouch field is not immediately clear from the context.

Could you please provide a brief comment or documentation explaining the purpose and usage of the vouch field? This would improve the code's self-documentation and make it easier for other developers to understand and use this type correctly.


24-34: LGTM: ProjectType is well-structured, but consider some improvements.

The ProjectType class is correctly defined. However, there are a couple of points to consider:

  1. The title field is nullable. Is this intentional? If so, it might be helpful to add a brief comment explaining why a project can have a null title.

  2. There's a commented-out field attestedOrganisations. Is this a planned feature? If so, consider adding a TODO comment explaining the intent and any pending work.

These additions would improve the code's self-documentation and make future development easier.

src/server-extension/resolver.ts (2)

16-17: Remove Unnecessary Nullability for limit and offset

The arguments limit and offset are marked as nullable with { nullable: true }, but default values are provided (limit: number = 10, offset: number = 0). This can cause confusion and potential issues if null is explicitly passed, as it would override the default values.

Consider removing the nullable: true option to enforce that these arguments always have numeric values:

- @Arg("limit", () => Number, { nullable: true }) limit: number = 10,
- @Arg("offset", () => Number, { nullable: true }) offset: number = 0,
+ @Arg("limit", () => Number) limit: number = 10,
+ @Arg("offset", () => Number) offset: number = 0,

54-55: Use a Logging Framework for Error Handling

Using console.error is not recommended for production applications. It’s better to use a dedicated logging framework that can handle different log levels and output logs appropriately.

Consider using a logging library like winston or pino:

- console.error("Error fetching and sorting projects:", error);
+ logger.error("Error fetching and sorting projects:", error);

Make sure to import and configure the logger at the beginning of your file:

import { logger } from './logger'; // Assuming you have a logger setup
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 66ee6fa and 308731d.

📒 Files selected for processing (4)
  • src/server-extension/helper.ts (1 hunks)
  • src/server-extension/resolver.ts (1 hunks)
  • src/server-extension/resolvers/index.ts (1 hunks)
  • src/server-extension/types.ts (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • src/server-extension/resolvers/index.ts
🧰 Additional context used
🪛 Biome
src/server-extension/resolver.ts

[error] 23-23: Unnecessary use of boolean literals in conditional expression.

Simplify your code by directly assigning the result without using a ternary operator.
If your goal is negation, you may use the logical NOT (!) or double NOT (!!) operator for clearer and concise code.
Check for more details about NOT operator.
Unsafe fix: Remove the conditional expression with

(lint/complexity/noUselessTernary)

🔇 Additional comments (5)
src/server-extension/helper.ts (1)

1-1: LGTM: Import statement is correct.

The import of GraphQLResolveInfo from the 'graphql' package is appropriate for the function's parameter type.

src/server-extension/types.ts (3)

1-1: LGTM: Imports are appropriate and concise.

The import statement correctly includes all necessary decorators and types from 'type-graphql' that are used in the file.


3-10: LGTM: OrganisationType is well-structured.

The OrganisationType class is correctly defined with appropriate fields:

  • id as a non-nullable ID type
  • name as a non-nullable string

This structure provides a clear and concise representation of an organization in the GraphQL schema.


1-34: Overall, the GraphQL types are well-defined and structured.

This file introduces clear and concise GraphQL object types using the type-graphql library. The types are well-structured and follow good practices. The suggested improvements are minor and mainly relate to enhancing documentation for better clarity and maintainability.

Great job on implementing these GraphQL types!

src/server-extension/resolver.ts (1)

50-52: Map Raw Query Results to ProjectType Instances

The manager.query() method returns raw results that may not automatically conform to the ProjectType. This can lead to issues if the data types or field names don't match exactly.

Consider mapping the raw results to instances of ProjectType:

return rawProjects.map(raw => Object.assign(new ProjectType(), raw));

Ensure that the field names in the raw results match the properties of ProjectType.

src/server-extension/helper.ts Outdated Show resolved Hide resolved
src/server-extension/resolver.ts Outdated Show resolved Hide resolved
src/server-extension/resolver.ts Outdated Show resolved Hide resolved
src/server-extension/resolver.ts Outdated Show resolved Hide resolved
src/server-extension/resolver.ts Outdated Show resolved Hide resolved
src/server-extension/resolver.ts Outdated Show resolved Hide resolved
src/server-extension/resolver.ts Outdated Show resolved Hide resolved
src/server-extension/resolver.ts Outdated Show resolved Hide resolved
@MohammadPCh
Copy link
Collaborator Author

@aminlatifi Thanks for your great suggestions!

I agree with you, and I'll limit it to just the projects' IDs. My initial goal was to make the resolver dynamic, but I realized it’s more efficient to retrieve only the projects' IDs from this endpoint and then make a separate request for the project details.

Thanks again for your input!

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Outside diff range and nitpick comments (1)
src/server-extension/resolver.ts (1)

49-52: Enhance error handling for better debugging

When re-throwing the error, including the original error message can provide more context and aid in debugging. This ensures that the calling function receives detailed information about what went wrong.

Apply this change to include the original error message:

catch (error) {
  console.error("Error fetching and sorting projects:", error);
- throw new Error("Failed to fetch and sort projects");
+ throw new Error(`Failed to fetch and sort projects: ${error.message}`);
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 308731d and 523fa9d.

📒 Files selected for processing (2)
  • src/server-extension/resolver.ts (1 hunks)
  • src/server-extension/types.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/server-extension/types.ts
🧰 Additional context used

src/server-extension/resolver.ts Outdated Show resolved Hide resolved
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Outside diff range and nitpick comments (2)
src/server-extension/resolver.ts (2)

14-27: LGTM: getSortBy function is well-structured

The getSortBy function effectively maps EProjectSort values to sorting criteria. It covers all enum cases and provides a default, which is good practice.

Consider adding a return type annotation to enhance type safety:

const getSortBy = (sortBy: EProjectSort): { sortBy: string; order: 'ASC' | 'DESC' } => {
  // ... existing implementation ...
}

33-40: LGTM: Query method declaration is well-structured, but contains an unused parameter

The getProjectsSortedByVouchOrFlag method is properly decorated and has a well-structured signature for a GraphQL query. The default values for limit and offset are a nice touch.

The @Info() info: GraphQLResolveInfo parameter is not used in the method implementation. Consider removing it if it's not needed:

async getProjectsSortedByVouchOrFlag(
  @Arg("orgIds", () => [String]) orgIds: string[],
  @Arg("sortBy", () => String) sortBy: EProjectSort,
  @Arg("limit", () => Number, { nullable: true }) limit: number = 10,
  @Arg("offset", () => Number, { nullable: true }) offset: number = 0
): Promise<ProjectsSortedByVouchOrFlagType[]> {
  // ... existing implementation ...
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 523fa9d and b2344ad.

📒 Files selected for processing (1)
  • src/server-extension/resolver.ts (1 hunks)
🧰 Additional context used
🔇 Additional comments (3)
src/server-extension/resolver.ts (3)

1-12: LGTM: Imports and enum declaration look good

The imports are appropriate for a GraphQL resolver, and the EProjectSort enum provides a clear set of sorting options for projects. This structure enhances code readability and maintainability.


29-31: LGTM: ProjectResolver class declaration is well-structured

The ProjectResolver class is properly decorated with @Resolver() for use with TypeGraphQL. The constructor's use of a transaction function is a good practice for managing database connections, promoting better control over database operations.


41-80: LGTM: Method implementation is secure and functional, with room for minor improvements

The getProjectsSortedByVouchOrFlag method implementation uses a parameterized SQL query, which addresses previous SQL injection concerns. The query logic appears correct, joining the necessary tables and applying sorting based on the input.

Consider the following improvements:

  1. Error handling: Provide more specific error messages to aid in debugging.

    catch (error) {
      console.error("Error in getProjectsSortedByVouchOrFlag:", error);
      throw new Error(`Failed to fetch and sort projects: ${error.message}`);
    }
  2. Type safety: Consider mapping the raw query results to ProjectsSortedByVouchOrFlagType objects before returning.

    return rawProjects.map(project => ({
      id: project.id,
      totalCount: parseInt(project.total_count, 10)
    }));
  3. Performance: If ProjectsSortedByVouchOrFlagType includes more fields than just id and totalCount, consider fetching those fields in the SQL query to avoid N+1 query issues.

To ensure the SQL query is correctly constructed for different sort orders, run the following verification script:

Copy link
Member

@aminlatifi aminlatifi left a comment

Choose a reason for hiding this comment

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

Thanks @MohammadPCh

@MohammadPCh MohammadPCh merged commit 72f9e10 into develop Oct 15, 2024
@MohammadPCh MohammadPCh deleted the add-organization-sort branch October 15, 2024 15:55
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.

2 participants