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

Feat/Endaoment project update feature #1892

Merged
merged 10 commits into from
Jan 10, 2025

Conversation

kkatusic
Copy link
Collaborator

@kkatusic kkatusic commented Dec 11, 2024

@CarlosQ96, to bi noticed here, this will use cronJob to fetch all Endaoments projects inside our database and check using Endaoment API is there any changes in title or description and script will update that attributes. Also if project has been deprecated on Endaoment on our side it will be marked as canceled

Summary by CodeRabbit

  • New Features

    • Added endaomentId field to projects to link with the Endaoment platform.
    • Implemented a monthly cron job to check and update Endaoment-related projects.
    • Enhanced functionality to track and update project status based on external organization data.
  • Chores

    • Created migration script to insert Endaoment project IDs.
    • Updated project data model to support the new identifier.

@kkatusic kkatusic self-assigned this Dec 11, 2024
@kkatusic kkatusic marked this pull request as ready for review January 9, 2025 13:20
Copy link
Contributor

coderabbitai bot commented Jan 9, 2025

Walkthrough

This pull request introduces a migration script that adds an endaomentId column to the project table, linking local projects with the Endaoment platform. The Project and ProjectUpdate classes are updated to include this new identifier, which is nullable and unique. Additionally, a cron job service is implemented to periodically check and update project details associated with Endaoment, including handling organization status changes and potential offboarding scenarios.

Changes

File Change Summary
migration/1735909243926-insertEndaomentProjectsIds.ts Added migration script to insert endaomentId into project table and implement up/down methods
src/entities/project.ts Added nullable, unique endaomentId property to Project and ProjectUpdate classes
src/services/cronJobs/checkAndUpdateEndaomentProject.ts Implemented monthly cron job to check and update Endaoment projects with error handling; added EndaomentService class with relevant methods

Sequence Diagram

sequenceDiagram
    participant CronJob as Monthly Cron Job
    participant ProjectService as Project Service
    participant EndaomentAPI as Endaoment API
    
    CronJob->>ProjectService: Retrieve Endaoment Projects
    ProjectService->>EndaomentAPI: Fetch Organization Details
    alt Organization Active
        EndaomentAPI-->>ProjectService: Return Project Data
        ProjectService->>ProjectService: Update Project Details
    else Organization Offboarded
        EndaomentAPI-->>ProjectService: Return 404
        ProjectService->>ProjectService: Mark Project as Cancelled
    end
Loading

Poem

🐰 Hopping through projects with glee,
Endaoment links, now we can see!
Monthly checks, data precise,
Rabbit's magic, systems slice!
Tech hops forward, smooth and bright 🚀

Finishing Touches

  • 📝 Generate Docstrings (Beta)

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 generate docstrings to generate docstrings for this PR. (Beta)
  • @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: 5

🧹 Nitpick comments (2)
src/services/cronJobs/checkAndUpdateEndaomentProject.ts (1)

42-79: Consider refactoring EndaomentService to use simple functions

The EndaomentService class contains only static methods and does not maintain any internal state. It's preferable to use simple functions instead of a class with only static members to reduce complexity and improve readability.

You could refactor the code by exporting the functions directly:

export const fetchOrgDetails = async (orgId: string): Promise<any> => {
  // function body
};

export const updateProjectDetails = async (project: Project, orgData: any): Promise<void> => {
  // function body
};
🧰 Tools
🪛 Biome (1.9.4)

[error] 42-79: Avoid classes that contain only static members.

Prefer using simple functions instead of classes with only static members.

(lint/complexity/noStaticOnlyClass)

migration/1735909243926-insertEndaomentProjectsIds.ts (1)

16-19: Use TypeORM methods instead of raw SQL for schema changes

Using TypeORM's schema builder methods, such as queryRunner.addColumn(), is recommended over executing raw SQL queries. This ensures better portability and consistency across different database systems supported by TypeORM.

Here's how you can modify the code:

await queryRunner.addColumn('project', new TableColumn({
  name: 'endaomentId',
  type: 'uuid',
  isNullable: true,
  isUnique: true,
}));
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between b558266 and ed8e7da.

📒 Files selected for processing (3)
  • migration/1735909243926-insertEndaomentProjectsIds.ts (1 hunks)
  • src/entities/project.ts (2 hunks)
  • src/services/cronJobs/checkAndUpdateEndaomentProject.ts (1 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
src/services/cronJobs/checkAndUpdateEndaomentProject.ts

[error] 42-79: Avoid classes that contain only static members.

Prefer using simple functions instead of classes with only static members.

(lint/complexity/noStaticOnlyClass)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: test
🔇 Additional comments (2)
src/services/cronJobs/checkAndUpdateEndaomentProject.ts (2)

61-61: ⚠️ Potential issue

Review logging of potentially sensitive data

The line logger.debug('Fetched org data:', orgData); logs the entire orgData object. Ensure that this data does not contain any sensitive information before logging it to prevent potential PII leakage.

Consider logging only necessary information or sanitizing the data before logging.


8-8: ⚠️ Potential issue

Ensure runCheckAndUpdateEndaomentProject is invoked to schedule the cron job

The runCheckAndUpdateEndaomentProject function schedules the cron job when it is called. Please ensure that this function is invoked during the application initialization; otherwise, the cron job will not be scheduled, and the task will not run.

You can run the following script to verify if runCheckAndUpdateEndaomentProject is being called in the codebase:

migration/1735909243926-insertEndaomentProjectsIds.ts Outdated Show resolved Hide resolved
src/entities/project.ts Outdated Show resolved Hide resolved
src/entities/project.ts Outdated Show resolved Hide resolved
Copy link
Collaborator

@CarlosQ96 CarlosQ96 left a comment

Choose a reason for hiding this comment

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

Please make the cronjob time editable by env var

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

♻️ Duplicate comments (2)
src/services/cronJobs/checkAndUpdateEndaomentProject.ts (2)

45-45: ⚠️ Potential issue

Validate API_URL before making requests

API_URL is retrieved from the environment variables without validation. If it's undefined, making requests will cause errors.

-const API_URL = process.env.ENDAOMENT_API_URL;
+const API_URL = process.env.ENDAOMENT_API_URL;
+if (!API_URL) {
+  throw new Error('ENDAOMENT_API_URL environment variable is not defined');
+}

82-82: 🛠️ Refactor suggestion

Remove redundant await project.save();

The await project.save(); call is redundant as the project is already saved in both the if and else blocks above.

-    await project.save();
🧹 Nitpick comments (5)
src/services/cronJobs/checkAndUpdateEndaomentProject.ts (5)

23-23: Consider making organizationId configurable

The organizationId is hardcoded to 5. Consider making this configurable through environment variables for better maintainability.

-      const projects = await Project.find({ where: { organizationId: 5 } });
+      const ENDAOMENT_ORG_ID = config.get('ENDAOMENT_ORGANIZATION_ID') || 5;
+      const projects = await Project.find({ where: { organizationId: ENDAOMENT_ORG_ID } });

34-36: Enhance error handling specificity

The catch block could be more specific about the type of error and provide better error context for debugging.

-        } catch (error) {
-          logger.error(`Failed to update project ID ${project.id}`, error);
+        } catch (error: unknown) {
+          const errorMessage = error instanceof Error ? error.message : 'Unknown error';
+          logger.error(
+            `Failed to update project ID ${project.id}: ${errorMessage}`,
+            { projectId: project.id, error }
+          );

23-23: Add logging for empty project results

Consider adding a log when no projects are found to help with monitoring and debugging.

       const projects = await Project.find({ where: { organizationId: 5 } });
+      if (projects.length === 0) {
+        logger.info('No Endaoment projects found to update');
+        return;
+      }

47-84: Convert class to module with standalone functions

The EndaomentService class contains only static methods. Consider converting it to a module with standalone functions for better maintainability.

-export class EndaomentService {
-  static async fetchOrgDetails(orgId: string): Promise<any> {
+export const fetchOrgDetails = async (orgId: string): Promise<OrgDetails> => {
   // ... rest of the code
-  }
+};

-  static async updateProjectDetails(
+export const updateProjectDetails = async (
   // ... rest of the code
-  }
+};
-}

+interface OrgDetails {
+  name?: string;
+  description?: string;
+  // Add other relevant fields
+}
🧰 Tools
🪛 Biome (1.9.4)

[error] 47-84: Avoid classes that contain only static members.

Prefer using simple functions instead of classes with only static members.

(lint/complexity/noStaticOnlyClass)


48-48: Replace 'any' type with proper interface

Using 'any' type reduces type safety. Define a proper interface for the organization details.

-  static async fetchOrgDetails(orgId: string): Promise<any> {
+  static async fetchOrgDetails(orgId: string): Promise<OrgDetails> {
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ed8e7da and 60f30ad.

📒 Files selected for processing (3)
  • migration/1735909243926-insertEndaomentProjectsIds.ts (1 hunks)
  • src/entities/project.ts (2 hunks)
  • src/services/cronJobs/checkAndUpdateEndaomentProject.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/entities/project.ts
  • migration/1735909243926-insertEndaomentProjectsIds.ts
🧰 Additional context used
🪛 Biome (1.9.4)
src/services/cronJobs/checkAndUpdateEndaomentProject.ts

[error] 47-84: Avoid classes that contain only static members.

Prefer using simple functions instead of classes with only static members.

(lint/complexity/noStaticOnlyClass)

🔇 Additional comments (1)
src/services/cronJobs/checkAndUpdateEndaomentProject.ts (1)

8-11: LGTM! Well-structured configuration with fallback.

The cron job configuration is properly implemented with an environment variable override and a sensible default value that runs monthly.

@Giveth Giveth deleted a comment from coderabbitai bot Jan 10, 2025
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: 3

🧹 Nitpick comments (1)
src/services/cronJobs/checkAndUpdateEndaomentProject.ts (1)

25-43: Implement batch processing and timeout handling

For better scalability and reliability:

  1. Process projects in batches to avoid memory issues with large datasets
  2. Add timeout handling for API calls
  3. Consider implementing retry logic for failed API calls

Example implementation:

const BATCH_SIZE = 100;
const API_TIMEOUT = 5000; // 5 seconds

async function processBatch(projects: Project[]) {
  for (const project of projects) {
    try {
      if (!project.endaomentId) {
        logger.warn(`Project ID ${project.id} does not have an endaomentId.`);
        continue;
      }

      const orgData = await Promise.race([
        EndaomentService.fetchOrgDetails(project.endaomentId),
        new Promise((_, reject) => 
          setTimeout(() => reject(new Error('API Timeout')), API_TIMEOUT)
        )
      ]);

      await EndaomentService.updateProjectDetails(project, orgData);
    } catch (error) {
      if (error.message === 'API Timeout') {
        logger.error(`API timeout for project ID ${project.id}`);
      } else {
        logger.error(`Failed to update project ID ${project.id}`, error);
      }
    }
  }
}

// In the main function:
const allProjects = await Project.find({ where: { organizationId: ENDAOMENT_ORGANIZATION_ID } });
for (let i = 0; i < allProjects.length; i += BATCH_SIZE) {
  const batch = allProjects.slice(i, i + BATCH_SIZE);
  await processBatch(batch);
}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 60f30ad and baa7450.

📒 Files selected for processing (1)
  • src/services/cronJobs/checkAndUpdateEndaomentProject.ts (1 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
src/services/cronJobs/checkAndUpdateEndaomentProject.ts

[error] 53-88: Avoid classes that contain only static members.

Prefer using simple functions instead of classes with only static members.

(lint/complexity/noStaticOnlyClass)

🔇 Additional comments (1)
src/services/cronJobs/checkAndUpdateEndaomentProject.ts (1)

1-11: LGTM! Well-structured configuration setup.

The configuration is properly implemented with environment variable support and a sensible default cron schedule.

Copy link
Collaborator

@CarlosQ96 CarlosQ96 left a comment

Choose a reason for hiding this comment

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

Thanks Kechy

@kkatusic kkatusic merged commit 448da9e into staging Jan 10, 2025
5 checks passed
@kkatusic kkatusic deleted the feat/check_periodically_endaoment branch January 10, 2025 12:09
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