Skip to content

Conversation

@andrewjschuang
Copy link
Contributor

@andrewjschuang andrewjschuang commented Oct 2, 2025

WHY

Summary by CodeRabbit

  • Bug Fixes

    • Prevents reprocessing previously seen items by skipping older IDs during pagination.
    • Ensures events are emitted in proper chronological order (newest-first preserved, emitted oldest-first).
  • Performance

    • Increases page size for faster syncing and fewer API calls.
  • Improvements

    • More reliable incremental sync by tracking and updating the latest processed item.
  • Chores

    • Bumped component/action/package versions for release.

@vercel
Copy link

vercel bot commented Oct 2, 2025

The latest updates on your projects. Learn more about Vercel for GitHub.

2 Skipped Deployments
Project Deployment Preview Comments Updated (UTC)
pipedream-docs Ignored Ignored Oct 2, 2025 8:10pm
pipedream-docs-redirect-do-not-edit Ignored Ignored Oct 2, 2025 8:10pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Oct 2, 2025

Caution

Review failed

The pull request is closed.

Walkthrough

Adds lastId-aware pagination to components/connectwise_psa/connectwise_psa.app.mjs and updates components/connectwise_psa/sources/common/base.mjs to use the new iterator: it requests pages ordered by id desc, skips items with id <= lastId, captures the newest id, updates stored lastId, and emits collected items in reverse order. Several component versions bumped.

Changes

Cohort / File(s) Summary
Pagination logic update
components/connectwise_psa/connectwise_psa.app.mjs
paginate signature changed to accept lastId (async *paginate({ resourceFn, params, max, lastId })). The paginator skips items with id <= lastId before yielding, preserves existing max-based termination, and includes a comment that results are ordered by id desc.
Source processing & paging params
components/connectwise_psa/sources/common/base.mjs
getParams now returns { pageSize: 500, orderBy: "id desc" }. processEvent uses the new connectwise.paginate iterator with lastId, records firstNewId from the first yielded item, collects items, calls _setLastId(firstNewId) when new items exist, and emits the collected items reversed via this.generateMeta(item). Removed prior early return and in-place slicing by max.
Version bumps — actions & sources
components/connectwise_psa/actions/create-company/create-company.mjs, components/connectwise_psa/actions/create-contact/create-contact.mjs, components/connectwise_psa/actions/create-ticket/create-ticket.mjs, components/connectwise_psa/sources/new-contact-created/new-contact-created.mjs, components/connectwise_psa/sources/new-project-created/new-project-created.mjs, components/connectwise_psa/sources/new-ticket-created/new-ticket-created.mjs, components/connectwise_psa/package.json
Updated version fields: package bumped 0.2.10.2.2; several actions/sources had their version strings incremented (e.g., 0.0.20.0.3, 0.1.10.1.2, etc.). No functional logic changes in these files.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor Trigger as Source Trigger
  participant Source as Base Source
  participant App as connectwise_psa.app.mjs
  participant API as ConnectWise PSA API

  Trigger->>Source: processEvent()
  Source->>Source: getParams() → { pageSize:500, orderBy:"id desc" }
  Source->>App: paginate({ resourceFn, params, max, lastId })
  loop fetch pages
    App->>API: resourceFn(params + paging)
    API-->>App: items (id desc)
    App->>App: for each item: if item.id > lastId → yield
    App-->>Source: yielded newer items
  end
  Source->>Source: firstNewId = id of first yielded item
  Source->>Source: collect items
  alt any new items
    Source->>Source: _setLastId(firstNewId)
  end
  Source->>Trigger: emit collected items reversed with generateMeta
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

I hop through pages, counting each new find,
Skipping the old burrows I left behind.
I stash the first carrot—lastId in store,
Flip the pile back, send fresh treats out the door. 🥕

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Description Check ⚠️ Warning The pull request description only contains the template placeholder for the WHY section and provides no actual rationale or explanation of the change. Please complete the WHY section with a clear explanation of the motivation and context for introducing efficient pagination, describing the problem being solved and how this change addresses it.
✅ Passed checks (2 passed)
Check name Status Explanation
Title Check ✅ Passed The title clearly conveys the primary change of improving pagination efficiency for ConnectWise PSA without extraneous detail or noise.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between fc186bf and d98247b.

📒 Files selected for processing (7)
  • components/connectwise_psa/actions/create-company/create-company.mjs (1 hunks)
  • components/connectwise_psa/actions/create-contact/create-contact.mjs (1 hunks)
  • components/connectwise_psa/actions/create-ticket/create-ticket.mjs (1 hunks)
  • components/connectwise_psa/package.json (1 hunks)
  • components/connectwise_psa/sources/new-contact-created/new-contact-created.mjs (1 hunks)
  • components/connectwise_psa/sources/new-project-created/new-project-created.mjs (1 hunks)
  • components/connectwise_psa/sources/new-ticket-created/new-ticket-created.mjs (1 hunks)

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

Comment @coderabbitai help to get the list of available commands and usage tips.

@andrewjschuang andrewjschuang merged commit 3eafcf9 into master Oct 2, 2025
9 checks passed
@andrewjschuang andrewjschuang deleted the connectwise-fix-pagination branch October 2, 2025 20:12
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 (1)
components/connectwise_psa/connectwise_psa.app.mjs (1)

342-342: Add a default value for the lastId parameter.

The lastId parameter lacks a default value. If paginate is called without lastId, the comparison item.id <= lastId (line 359) will evaluate to item.id <= undefined, which is always false, causing all items to pass through. While base.mjs ensures lastId is at least 0, other callers might not.

Apply this diff to provide a sensible default:

-    async *paginate({
-      resourceFn,
-      params,
-      max,
-      lastId,
-    }) {
+    async *paginate({
+      resourceFn,
+      params,
+      max,
+      lastId = 0,
+    }) {
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 57c0956 and fc186bf.

📒 Files selected for processing (2)
  • components/connectwise_psa/connectwise_psa.app.mjs (2 hunks)
  • components/connectwise_psa/sources/common/base.mjs (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
components/connectwise_psa/connectwise_psa.app.mjs (1)
components/connectwise_psa/sources/common/base.mjs (1)
  • lastId (41-41)
components/connectwise_psa/sources/common/base.mjs (1)
components/connectwise_psa/connectwise_psa.app.mjs (1)
  • items (350-352)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (4)
  • GitHub Check: pnpm publish
  • GitHub Check: Lint Code Base
  • GitHub Check: Publish TypeScript components
  • GitHub Check: Verify TypeScript components
🔇 Additional comments (5)
components/connectwise_psa/sources/common/base.mjs (4)

44-49: LGTM!

The iterator creation correctly passes all required parameters (resourceFn, params, max, lastId) to the paginate function. The use of an iterator pattern is appropriate for handling potentially large result sets.


61-63: LGTM!

The conditional update of lastId correctly ensures that the stored value is only updated when new items are found. This prevents overwriting the last known id with an undefined or null value.


65-67: LGTM!

Reversing the items before emission ensures they are emitted in chronological order (oldest first), which aligns with typical event source patterns. The use of generateMeta provides consistent metadata for each emitted item.


28-31: pageSize of 500 is within API limits
500 is under the ConnectWise PSA API’s maximum of 1,000 records per request. No change required.

components/connectwise_psa/connectwise_psa.app.mjs (1)

357-364: Guard against missing or invalid item.id and verify result ordering

  • Change if (item.id <= lastId) to if (item.id == null || item.id <= lastId) to skip items without a valid id.
  • Confirm the PSA API request uses orderBy: "id desc" (or sort client-side) so the early return correctly stops pagination.

Comment on lines +51 to 59
const items = [];
let firstNewId;

for await (const item of iterator) {
if (!firstNewId) {
firstNewId = item.id;
}
items.push(item);
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Consider memory usage when max is undefined.

The code collects all items in memory before emitting them in reverse order. When max is not provided (e.g., in the run method), this could consume significant memory for large result sets. The paginate function has a lastId early-termination mechanism, but for sources with many new items, the in-memory collection could grow large.

Consider one of the following:

  1. Add a reasonable default max value in the run method to cap memory usage.
  2. Document the memory implications for integrators who extend this base class.
  3. Stream items without collecting them if reverse order is not strictly necessary (though this would require design changes).

If the current behavior is intentional and memory usage is not a concern for typical use cases, consider adding a comment explaining the trade-off.

🤖 Prompt for AI Agents
In components/connectwise_psa/sources/common/base.mjs around lines 51-59 the
code collects all iterator items into memory before reversing and emitting them,
which can cause unbounded memory growth when max is undefined; update the
run/paginate usage to enforce a sensible default cap (e.g., default max = 1000)
when callers don't provide max, or if changing callers is undesirable, add an
explicit comment in this file explaining the memory trade-off and that callers
must supply max for large result sets; implement the default by checking for
undefined max at the entry point and limiting iteration or early-terminating
when the cap is reached, and document the behavior in the method docstring.

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