Skip to content

New Components - planning_center #16625

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

Merged
merged 2 commits into from
May 13, 2025
Merged

New Components - planning_center #16625

merged 2 commits into from
May 13, 2025

Conversation

michelle0927
Copy link
Collaborator

@michelle0927 michelle0927 commented May 9, 2025

Resolves #15143

Summary by CodeRabbit

  • New Features
    • Introduced Planning Center integration, enabling connections to the Planning Center API.
    • Added support for the following event sources:
      • New Calendar Event: Triggers when a new calendar event is created.
      • New Donation Received: Triggers when a new donation is received.
      • New Person Added to List: Triggers when a new person is added to a selected list.
  • Chores
    • Updated package metadata and dependencies for improved compatibility and maintenance.

Copy link

vercel bot commented May 9, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

3 Skipped Deployments
Name Status Preview Comments Updated (UTC)
docs-v2 ⬜️ Ignored (Inspect) May 9, 2025 9:36pm
pipedream-docs ⬜️ Ignored (Inspect) May 9, 2025 9:36pm
pipedream-docs-redirect-do-not-edit ⬜️ Ignored (Inspect) May 9, 2025 9:36pm

Copy link
Contributor

coderabbitai bot commented May 9, 2025

Walkthrough

This change introduces a new Planning Center integration with several polling sources: "New Person Added to List," "New Calendar Event," and "New Donation Received." It includes base components for API interaction, event polling, and state management. Legacy files and configuration are removed or updated to reflect the new structure and dependencies.

Changes

Files/Groups Change Summary
components/planning_center/.gitignore Deleted .gitignore file that previously excluded .js, .mjs, and dist directory from version control.
components/planning_center/app/planning_center.app.ts Removed the old Planning Center app definition, which used defineApp and provided minimal functionality.
components/planning_center/package.json Updated version to 0.1.0, changed entry point, removed "files" field, added dependency on @pipedream/platform, and fixed publishConfig.
components/planning_center/planning_center.app.mjs Added new Planning Center app module with OAuth authentication, API wrappers for lists, donations, calendar events, and a generic pagination utility.
components/planning_center/sources/common/base.mjs Introduced a reusable base source module for polling Planning Center data, with stateful timestamp tracking, event emission, and required subclass methods for resource fetching and summaries.
components/planning_center/sources/new-calendar-event/new-calendar-event.mjs Added a new polling source for "New Calendar Event," extending the base source and emitting events for new calendar events.
components/planning_center/sources/new-donation/new-donation.mjs Added a new polling source for "New Donation Received," extending the base source and emitting events for new donations.
components/planning_center/sources/new-list-result/new-list-result.mjs Added a new polling source for "New Person Added to List," with configurable List ID, extending the base source and emitting events for new list results.

Sequence Diagram(s)

sequenceDiagram
    participant Source as Polling Source (e.g., New Donation)
    participant App as Planning Center App
    participant API as Planning Center API
    participant DB as Database

    Source->>DB: Get last processed timestamp
    Source->>App: Call paginated API method (e.g., listDonations)
    loop For each page of results
        App->>API: GET /giving/v2/donations (with OAuth)
        API-->>App: Return donation data
        App-->>Source: Return donation data
        Source->>Source: Filter new items by timestamp
        Source->>DB: Update last processed timestamp
        Source->>Source: Emit event for each new item
    end
Loading

Assessment against linked issues

Objective Addressed Explanation
Implement Planning Center integration with polling sources: new-list-result, new-calendar-event, new-donation (#15143)
Each source emits an event when a new relevant item is created (person added to list, calendar event, donation) (#15143)
new-list-result source includes required List ID prop (#15143)

Suggested reviewers

  • lcaresia

Poem

In burrows deep, I code and hop,
Now Planning Center’s live—nonstop!
New lists, events, and gifts appear,
Each one polled and crystal clear.
With every change, I thump with glee—
🐇 Code and carrots, harmony!
—Your rabbit dev, so proud to see!

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

components/planning_center/planning_center.app.mjs

Oops! Something went wrong! :(

ESLint: 8.57.1

Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'jsonc-eslint-parser' imported from /eslint.config.mjs
at packageResolve (node:internal/modules/esm/resolve:839:9)
at moduleResolve (node:internal/modules/esm/resolve:908:18)
at defaultResolve (node:internal/modules/esm/resolve:1038:11)
at ModuleLoader.defaultResolve (node:internal/modules/esm/loader:557:12)
at ModuleLoader.resolve (node:internal/modules/esm/loader:525:25)
at ModuleLoader.getModuleJob (node:internal/modules/esm/loader:246:38)
at ModuleJob._link (node:internal/modules/esm/module_job:126:49)

components/planning_center/sources/common/base.mjs

Oops! Something went wrong! :(

ESLint: 8.57.1

Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'jsonc-eslint-parser' imported from /eslint.config.mjs
at packageResolve (node:internal/modules/esm/resolve:839:9)
at moduleResolve (node:internal/modules/esm/resolve:908:18)
at defaultResolve (node:internal/modules/esm/resolve:1038:11)
at ModuleLoader.defaultResolve (node:internal/modules/esm/loader:557:12)
at ModuleLoader.resolve (node:internal/modules/esm/loader:525:25)
at ModuleLoader.getModuleJob (node:internal/modules/esm/loader:246:38)
at ModuleJob._link (node:internal/modules/esm/module_job:126:49)

components/planning_center/sources/new-donation/new-donation.mjs

Oops! Something went wrong! :(

ESLint: 8.57.1

Error [ERR_MODULE_NOT_FOUND]: Cannot find package 'jsonc-eslint-parser' imported from /eslint.config.mjs
at packageResolve (node:internal/modules/esm/resolve:839:9)
at moduleResolve (node:internal/modules/esm/resolve:908:18)
at defaultResolve (node:internal/modules/esm/resolve:1038:11)
at ModuleLoader.defaultResolve (node:internal/modules/esm/loader:557:12)
at ModuleLoader.resolve (node:internal/modules/esm/loader:525:25)
at ModuleLoader.getModuleJob (node:internal/modules/esm/loader:246:38)
at ModuleJob._link (node:internal/modules/esm/module_job:126:49)

  • 2 others
✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ 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.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

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.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this 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: 1

🧹 Nitpick comments (6)
components/planning_center/sources/new-donation/new-donation.mjs (1)

1-27: Consider implementing the isSorted method

The component correctly extends the common base and specifies ordering by creation date descending. However, unlike the calendar event source, this component doesn't explicitly implement isSorted(). Since you're explicitly ordering by creation date descending, consider adding an isSorted() method that returns true to optimize event processing.

+    isSorted() {
+      return true;
+    },
components/planning_center/sources/new-list-result/new-list-result.mjs (1)

1-37: Consider implementing the isSorted method

The component correctly extends the common base, adds the necessary listId prop, and specifies ordering by creation date descending. Similar to the donation source, consider adding an isSorted() method that returns true since you're explicitly ordering results by creation date.

+    isSorted() {
+      return true;
+    },
components/planning_center/planning_center.app.mjs (1)

72-96: Consider adding error handling to the paginate method

The paginate method is well-implemented using the async generator pattern. However, consider adding error handling to gracefully handle API failures:

do {
-  const { data } = await fn(args);
+  try {
+    const { data } = await fn(args);
+    for (const item of data) {
+      yield item;
+      if (max && ++count >= max) {
+        return;
+      }
+    }
+    total = data?.length;
+    args.params.offset += args.params.per_page;
+  } catch (error) {
+    console.error("Error while paginating Planning Center API:", error);
+    throw error;
+  }
} while (total);

Also consider adding rate limiting handling if the Planning Center API has rate limits.

components/planning_center/sources/common/base.mjs (3)

22-30: Consider adding JSDoc comments for these overridable methods.

These methods are designed to be overridden by subclasses. Adding JSDoc comments would make it clearer for developers extending this base component.

+/**
+ * Override to provide custom arguments for API calls
+ * @returns {Object} Arguments to pass to the resource function
+ */
 getArgs() {
   return {};
 },
+/**
+ * Extract timestamp from an item
+ * @param {Object} item - The item to extract timestamp from
+ * @returns {number} Timestamp in milliseconds
+ */
 getTs(item) {
   return Date.parse(item.attributes.created_at);
 },
+/**
+ * Whether the data is sorted by timestamp
+ * @returns {boolean} True if data is sorted by timestamp
+ */
 isSorted() {
   return true;
 },

1-82: Add fallback for timestamp extraction.

The getTs method assumes items always have a created_at attribute. Consider adding a fallback mechanism for items without this attribute.

 getTs(item) {
-  return Date.parse(item.attributes.created_at);
+  if (item.attributes && item.attributes.created_at) {
+    return Date.parse(item.attributes.created_at);
+  }
+  // Fallback to current time if created_at is not available
+  console.warn("Item missing created_at attribute:", item);
+  return Date.now();
 },

1-82: Consider adding class-level JSDoc description.

Adding a description at the top of the component would help developers understand its purpose and how to extend it.

+/**
+ * Base component for Planning Center sources.
+ * 
+ * This component provides the foundation for incremental event processing with stateful tracking.
+ * Subclasses must implement the following methods:
+ * - getResourceFn(): Returns the API function to call
+ * - getSummary(item): Returns a summary string for an event
+ * 
+ * Optional methods to override:
+ * - getArgs(): Returns arguments for the API call
+ * - getTs(item): Extracts timestamp from an item
+ * - isSorted(): Whether the data is sorted by timestamp
+ */
 export default {
   props: {
     planningCenter,
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 4957795 and 8a60b94.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (8)
  • components/planning_center/.gitignore (0 hunks)
  • components/planning_center/app/planning_center.app.ts (0 hunks)
  • components/planning_center/package.json (1 hunks)
  • components/planning_center/planning_center.app.mjs (1 hunks)
  • components/planning_center/sources/common/base.mjs (1 hunks)
  • components/planning_center/sources/new-calendar-event/new-calendar-event.mjs (1 hunks)
  • components/planning_center/sources/new-donation/new-donation.mjs (1 hunks)
  • components/planning_center/sources/new-list-result/new-list-result.mjs (1 hunks)
💤 Files with no reviewable changes (2)
  • components/planning_center/.gitignore
  • components/planning_center/app/planning_center.app.ts
⏰ Context from checks skipped due to timeout of 90000ms (4)
  • GitHub Check: Verify TypeScript components
  • GitHub Check: pnpm publish
  • GitHub Check: Publish TypeScript components
  • GitHub Check: Lint Code Base
🔇 Additional comments (12)
components/planning_center/package.json (1)

3-17: Package.json updates support the new component architecture

The updates to version, main entry point, and dependencies correctly align with the new Planning Center integration. The version bump from 0.0.2 to 0.1.0 is appropriate given the substantial changes to the component structure.

components/planning_center/sources/new-calendar-event/new-calendar-event.mjs (1)

1-23: Implementation follows good component patterns

The source component properly extends the common base and implements the necessary methods for detecting new calendar events. Good job including the documentation link in the description.

Note that isSorted() returning false indicates the API doesn't return data in a consistent order, which could affect how events are processed chronologically.

components/planning_center/planning_center.app.mjs (4)

1-4: Constants are appropriately defined

The constants for default and maximum limits are well-defined at the top of the file for easy reference and modification.


5-28: Prop definition for listId is well-implemented

The listId prop definition with its async options loader is well-structured. It correctly uses pagination and maps the API response to the expected options format.


29-71: API methods are well-organized

The base URL, request helper, and API-specific methods are well-organized and follow good practices. Each endpoint has its own dedicated method, making the code modular and maintainable.


1-98:

✅ Verification successful

Verify the MAX_LIMIT constant aligns with Planning Center's API

The code sets MAX_LIMIT to 100 items per page. Verify this is consistent with Planning Center's API documentation to avoid potential issues with pagination.


🌐 Web query:

What is the maximum page size for Planning Center API endpoints?

💡 Result:

The maximum page size for Planning Center API endpoints is 100 items per page when using the per_page parameter. This information is referenced in community discussions about API integrations, where it is stated: “the default number of orders per page is 15 and it is possible to configure it up to 100 using the per_page parameter”[3].

Official Planning Center API documentation does not directly specify this value, but third-party integration and developer experiences consistently report 100 as the upper limit per page for paginated requests to Planning Center’s endpoints[3].

Citations:


MAX_LIMIT constant is correct
Verified that Planning Center’s API supports a maximum per_page value of 100 items per page. No changes needed.

components/planning_center/sources/common/base.mjs (6)

1-3: Imports look good.

The file correctly imports the Planning Center app and default polling interval constant.


4-14: Props structure looks well-organized.

The component properly defines the Planning Center app, database service for state persistence, and timer interface with appropriate default polling interval.


16-21: State management methods are implemented correctly.

The implementation for getting and setting the last timestamp in the database looks good.


31-41: Event emission and metadata generation look good.

The methods properly handle event emission with appropriate metadata.


67-72: Abstract methods are correctly implemented.

The base component correctly throws errors for methods that must be implemented by subclasses.


74-81: Lifecycle hooks look good.

The deploy hook correctly processes a limited number of events initially, and the run method processes events continuously.

Copy link
Collaborator

@luancazarine luancazarine left a comment

Choose a reason for hiding this comment

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

Hi @michelle0927, LGTM! Ready for QA!

@michelle0927 michelle0927 merged commit 016a21a into master May 13, 2025
11 checks passed
@michelle0927 michelle0927 deleted the issue-15143 branch May 13, 2025 14:50
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.

[Components] planning_center
2 participants