Skip to content

Conversation

@jcortes
Copy link
Collaborator

@jcortes jcortes commented Sep 4, 2025

WHY

Resolves #18050

Summary by CodeRabbit

  • New Features
    • Full Billbee integration: create, retrieve, list (with filters), update orders; change order state; add shipments; create invoices; list products, stocks, customers, shops, states, carriers, shipments, and shipment types; update stock.
    • Dynamic searchable dropdowns for orders, products, shops, states, tags, stocks, carriers, shipments, and cloud storage.
    • Automatic pagination with configurable max limits for list actions.
  • Chores
    • Package bumped to 0.1.0 and dependency added.

@jcortes jcortes self-assigned this Sep 4, 2025
@vercel
Copy link

vercel bot commented Sep 4, 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 Sep 9, 2025 5:00pm
pipedream-docs-redirect-do-not-edit Ignored Ignored Sep 9, 2025 5:00pm

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Sep 4, 2025

Walkthrough

Adds a Billbee integration: new app client with HTTP helpers, pagination, propDefinitions, constants and utils, many domain methods (orders, products, customers, shipments), plus multiple actions for orders, invoices, customers, and products. Bumps package version and adds @pipedream/platform dependency.

Changes

Cohort / File(s) Summary
App core
components/billbee/billbee.app.mjs
New comprehensive app: propDefinitions populated, HTTP client (axios) and helpers (getBaseUrl, getUrl, getHeaders, getAuth, makeRequest, post/put/delete/patch), pagination generator + paginate, many domain methods (listOrders, getOrder, createOrder, updateOrder, changeOrderState, addShipmentToOrder, createInvoiceForOrder, listProducts, updateStock, listStocks, listCustomers, listShopAccounts, listOrderStates, listCloudStorages, listShippingProviders, listShipments, listShippingCarriers, listShipmentTypes). Removed legacy authKeys().
Common utilities & constants
components/billbee/common/constants.mjs, components/billbee/common/utils.mjs
New constants (BASE_URL, VERSION_PATH, DEFAULT_MAX, DEFAULT_LIMIT) and utilities (emptyStrToUndefined, parse, iterate, getNestedProperty).
Orders actions
components/billbee/actions/list-orders/..., components/billbee/actions/create-order/..., components/billbee/actions/get-order-by-id/..., components/billbee/actions/update-order/..., components/billbee/actions/change-order-state/..., components/billbee/actions/add-shipment-to-order/...
New actions mapping to app methods: list (paginated, filters), create, get by ID, update (patch), change state, add shipment.
Invoices action
components/billbee/actions/create-invoice-for-order/create-invoice-for-order.mjs
New action to create an invoice for an order (template, include PDF, send to cloud options) calling app.createInvoiceForOrder.
Customers action
components/billbee/actions/list-customers/list-customers.mjs
New paginated list customers action using app.paginate and app.listCustomers.
Products actions
components/billbee/actions/list-products/list-products.mjs, components/billbee/actions/update-stock/update-stock.mjs
New list-products action (filters + pagination) and update-stock action (single stock update) mapped to app methods.
Package metadata
components/billbee/package.json
Bumped package version to 0.1.0 and added dependency on @pipedream/platform.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant Action as Pipedream Action
  participant App as Billbee App Client
  participant API as Billbee API

  User->>Action: Trigger action with props
  Action->>App: call app.<method>({ $, ... })
  App->>App: build URL, headers, auth
  App->>API: HTTP request (axios)
  API-->>App: HTTP response
  App-->>Action: return data
  Action-->>User: $.export("$summary") + result
Loading
sequenceDiagram
  autonumber
  participant Action as List Orders Action
  participant App as App.paginate()
  participant API as Billbee Orders API

  Action->>App: paginate(resourcesFn=listOrders, params, resourceName="Data", max)
  loop pages
    App->>API: GET /api/v1/orders?page=N&...
    API-->>App: { Data: [...], Paging: ... }
    App-->>Action: yield page items
  end
  Action-->>User: aggregated items + summary
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Assessment against linked issues

Objective Addressed Explanation
Orders core subset: List, Create, Get by ID, Update (partial), Add shipment, Change state (#18050) Corresponding app methods and actions added.
Orders remaining endpoints: Get by external ref/ID+partner, Patchable fields, Tags, Messages, Parse placeholders, Trigger event (#18050) Those specific endpoints/methods/actions are not present in this diff.
Invoices: Create invoice for order; List invoices (#18050) Partially CreateInvoice implemented; list invoices endpoint not added.
Customers: List customers; other customer endpoints (#18050) Partially List customers implemented; other customer CRUD/address endpoints not present.

Suggested reviewers

  • GTFalcao

Pre-merge checks (1 passed, 3 warnings, 1 inconclusive)

❌ Failed checks (3 warnings, 1 inconclusive)
Check name Status Explanation Resolution
Linked Issues Check ⚠️ Warning The PR implements several endpoints from issue #18050—such as list-orders, create-order, get-order-by-id, update-order, add-shipment-to-order, change-order-state, create-invoice-for-order, list-customers, list-products, and update-stock—but omits many others specified in the linked issue (including external-ref order retrieval, patchable fields, tags management, messaging actions, delivery notes, full customer CRUD and addresses, comprehensive product endpoints, and shipment creation/listing). As a result, the code changes do not fully meet the objectives outlined in #18050. Implement the remaining required actions or update the issue to reflect the subset of endpoints covered; ensure each linked endpoint is either added or explicitly addressed in this PR’s scope.
Description Check ⚠️ Warning The PR description only contains “Resolves #18050” under the WHY header and does not explain the motivation or summarize the key changes, leaving the required WHY section incomplete. Please expand the WHY section to describe the rationale for adding these Billbee components, outline the problems being solved, and summarize the major changes introduced by this PR.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
Title Check ❓ Inconclusive The current title “[APP] Billbee - new components” is overly generic and does not clearly summarize the primary change from the developer’s perspective, since “new components” could refer to any set of additions and does not convey the scope or main purpose of the PR. It is related to Billbee but lacks specificity and does not help a reviewer quickly understand the core update. Please revise the title to be a concise, descriptive sentence that reflects the main objective of the changeset, for example “Add Billbee integration actions for orders, invoices, customers, and products.”
✅ Passed checks (1 passed)
Check name Status Explanation
Out of Scope Changes Check ✅ Passed All modifications are confined to the Billbee integration under components/billbee (action modules, app core, constants, utils, and package metadata) and directly support the linked issue’s requirements, with no unrelated or out-of-scope changes present.

Poem

I thump my paws—deploy day cheer!
New orders hop and invoices near.
Stocks bounce up, customers found,
Endpoints stitched and APIs sound.
Rabbit-coded joy, a tiny cheer—🥕🐇

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch billbee-new-components

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.

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: 15

🧹 Nitpick comments (20)
components/billbee/common/utils.mjs (2)

38-59: Harden parseArray(): handle whitespace, non-strings, and enforce array output
Improve normalization and avoid JSON.parse on non-strings.

Apply:

-function parseArray(value) {
-  try {
-    if (!value) {
-      return [];
-    }
-
-    if (Array.isArray(value)) {
-      return value;
-    }
-
-    const parsedValue = JSON.parse(value);
-
-    if (!Array.isArray(parsedValue)) {
-      throw new Error("Not an array");
-    }
-
-    return parsedValue;
-
-  } catch (e) {
-    throw new ConfigurationError("Make sure the custom expression contains a valid array object");
-  }
-}
+function parseArray(value) {
+  const valueToParse = emptyStrToUndefined(value);
+  try {
+    if (valueToParse == null) return [];
+    if (Array.isArray(valueToParse)) return valueToParse;
+    if (typeof valueToParse === "string") {
+      const parsed = JSON.parse(valueToParse);
+      if (!Array.isArray(parsed)) throw new Error("Not an array");
+      return parsed;
+    }
+    // Any other non-array, non-string input is invalid
+    throw new Error("Not an array");
+  } catch {
+    throw new ConfigurationError("Make sure the custom expression contains a valid array");
+  }
+}

33-36: Optional: guard getNestedProperty against empty path
Handle empty/invalid propertyString to avoid returning obj[""].

Apply:

 function getNestedProperty(obj, propertyString) {
-  const properties = propertyString.split(".");
+  if (!propertyString) return undefined;
+  const properties = propertyString.split(".");
   return properties.reduce((prev, curr) => prev?.[curr], obj);
 }
components/billbee/actions/get-order-by-id/get-order-by-id.mjs (2)

6-6: Fix double slash in docs URL
Minor formatting nit.

-  description: "Retrieve a specific order by its ID from Billbee. [See the documentation](https://app.billbee.io//swagger/ui/index#/Orders/OrderApi_Get)",
+  description: "Retrieve a specific order by its ID from Billbee. [See the documentation](https://app.billbee.io/swagger/ui/index#/Orders/OrderApi_Get)",

29-31: Summary field depends on response shape
Confirm response.Data.BillBeeOrderId exists across environments; otherwise, consider falling back to the requested orderId.

Example:

-    $.export("$summary", `Successfully retrieved order with ID \`${response.Data?.BillBeeOrderId}\``);
+    $.export("$summary", `Successfully retrieved order with ID \`${response.Data?.BillBeeOrderId ?? orderId}\``);
components/billbee/actions/create-order/create-order.mjs (1)

7-7: Fix double slashes in docs URLs
Tidy up links in description.

-  description: "Create a new order. [See the documentation](https://app.billbee.io//swagger/ui/index#/Orders/OrderApi_PostNewOrder)",
+  description: "Create a new order. [See the documentation](https://app.billbee.io/swagger/ui/index#/Orders/OrderApi_PostNewOrder)",
@@
-      description: `The data for the order. [See the documentation](https://app.billbee.io//swagger/ui/index#/Orders/OrderApi_PostNewOrder)
+      description: `The data for the order. [See the documentation](https://app.billbee.io/swagger/ui/index#/Orders/OrderApi_PostNewOrder)

Also applies to: 15-15

components/billbee/actions/update-stock/update-stock.mjs (1)

6-6: Fix docs URL (double slash).

Apply:

-  description: "Update the stock level for a single product. [See the documentation](https://app.billbee.io//swagger/ui/index#/Products/Article_UpdateStock)",
+  description: "Update the stock level for a single product. [See the documentation](https://app.billbee.io/swagger/ui/index#/Products/Article_UpdateStock)",
components/billbee/actions/list-customers/list-customers.mjs (2)

24-32: Remove hardcoded debug: true from pagination args.

Avoid noisy logs by default. Add a separate debug prop if needed.

Apply:

-    const customers = await app.paginate({
-      resourcesFn: app.listCustomers,
-      resourcesFnArgs: {
-        $,
-        debug: true,
-      },
-      resourceName: "Data",
-      max,
-    });
+    const customers = await app.paginate({
+      resourcesFn: app.listCustomers,
+      resourcesFnArgs: { $ },
+      resourceName: "Data",
+      max,
+    });

11-16: Constrain max to positive integers.

Helps prevent accidental zero/negative values.

Apply:

     max: {
       type: "integer",
       label: "Maximum Results",
       description: "Maximum number of customers to return",
       optional: true,
+      min: 1,
     },
components/billbee/actions/change-order-state/change-order-state.mjs (2)

6-6: Fix docs URL (double slash).

Apply:

-  description: "Change the state of an order. [See the documentation](https://app.billbee.io//swagger/ui/index#/Orders/OrderApi_UpdateState)",
+  description: "Change the state of an order. [See the documentation](https://app.billbee.io/swagger/ui/index#/Orders/OrderApi_UpdateState)",

17-26: Use integer prop type and drop parseInt.

Let the UI enforce numeric input and pass through as-is.

Apply:

-    newStateId: {
-      type: "string",
+    newStateId: {
+      type: "integer",
       label: "New Order State",
       description: "The new state for the order",
       optional: false,
       propDefinition: [
         app,
         "orderStateId",
       ],
     },
-        NewStateId: parseInt(newStateId),
+        NewStateId: newStateId,

Also applies to: 39-40

components/billbee/actions/add-shipment-to-order/add-shipment-to-order.mjs (3)

6-6: Fix docs URL (double slash).

Apply:

-  description: "Add a shipment to an existing order. [See the documentation](https://app.billbee.io//swagger/ui/index#/Orders/OrderApi_AddShipment)",
+  description: "Add a shipment to an existing order. [See the documentation](https://app.billbee.io/swagger/ui/index#/Orders/OrderApi_AddShipment)",

23-37: Return { value, label } for better UX in dynamic options.

Returning only the value can lead to unlabeled dropdown entries. Provide readable labels.

Apply:

     shippingProviderProductId: {
       label: "Shipping Provider Product ID",
       description: "The ID of the shipping provider product/service",
       propDefinition: [
         app,
         "shipment",
         ({
           orderId, shippingProviderId,
         }) => ({
           orderId,
           shippingProviderId,
-          mapper: ({ ShippingProviderProductId: value }) => value,
+          mapper: ({ ShippingProviderProductId: value, Name }) => ({
+            value,
+            label: Name ? `${Name} (${value})` : String(value),
+          }),
         }),
       ],
     },

38-52: Ditto for shippingId options mapping.

Apply:

     shippingId: {
       label: "Shipping ID",
       description: "The ID of the shipping",
       propDefinition: [
         app,
         "shipment",
         ({
           orderId, shippingProviderId,
         }) => ({
           orderId,
           shippingProviderId,
-          mapper: ({ ShippingId: value }) => value,
+          mapper: ({ ShippingId: value, Name }) => ({
+            value,
+            label: Name ? `${Name} (${value})` : String(value),
+          }),
         }),
       ],
     },
components/billbee/actions/update-order/update-order.mjs (2)

6-6: Fix docs URL (double slash).

Apply:

-  description: "Partially update an existing order. [See the documentation](https://app.billbee.io//swagger/ui/index#/Orders/OrderApi_PatchOrder)",
+  description: "Partially update an existing order. [See the documentation](https://app.billbee.io/swagger/ui/index#/Orders/OrderApi_PatchOrder)",

117-119: Improve summary fallback.

When the API doesn’t return Data.BillBeeOrderId, show orderId.

Apply:

-    $.export("$summary", `Successfully updated order \`${response.Data?.BillBeeOrderId}\``);
+    $.export("$summary", `Successfully updated order \`${response?.Data?.BillBeeOrderId ?? orderId}\``);
components/billbee/actions/list-products/list-products.mjs (1)

6-6: Fix docs URL (double slash).

Use a single slash in the docs link.

-  description: "Retrieve a list of products. [See the documentation](https://app.billbee.io//swagger/ui/index#/Products/Article_GetList)",
+  description: "Retrieve a list of products. [See the documentation](https://app.billbee.io/swagger/ui/index#/Products/Article_GetList)",
components/billbee/actions/list-orders/list-orders.mjs (1)

6-6: Fix docs URL (double slash).

-  description: "Retrieve a list of orders. [See the documentation](https://app.billbee.io//swagger/ui/index#/Orders/OrderApi_GetList)",
+  description: "Retrieve a list of orders. [See the documentation](https://app.billbee.io/swagger/ui/index#/Orders/OrderApi_GetList)",
components/billbee/billbee.app.mjs (3)

239-254: Add a params serializer for arrays.

Centralize array handling so multi-select props serialize consistently (e.g., CSV).

-    makeRequest({
-      $ = this, path, headers, url, ...args
-    } = {}) {
+    makeRequest({
+      $ = this, path, headers, url, ...args
+    } = {}) {
       const {
         getUrl,
         getHeaders,
         getAuth,
       } = this;
 
-      return axios($, {
+      const params = args.params;
+      const normalize = (o) => Object.fromEntries(
+        Object.entries(o || {}).map(([k, v]) => [k, Array.isArray(v) ? v.join(",") : v]),
+      );
+
+      return axios($, {
         ...(args.debug ? { debug: true } : {}),
         headers: getHeaders(headers),
         url: getUrl(path, url),
         auth: getAuth(),
+        params: normalize(params),
-        ...args,
+        ...args,
       });
     },

267-272: Avoid delete as a method name.

Using the reserved keyword as a method can be confusing. Prefer del.

-    delete(args = {}) {
+    del(args = {}) {
       return this.makeRequest({
         method: "delete",
         ...args,
       });
     },

400-449: Guard date filtering in pagination.

If dateField is missing or unparsable, Date.parse yields NaN and silently drops items. Add a guard.

-          const isDateGreater =
-            lastDateAt
-              && Date.parse(resource[dateField]) >= Date.parse(lastDateAt);
+          const isDateGreater =
+            lastDateAt && dateField
+              && !Number.isNaN(Date.parse(resource?.[dateField]))
+              && Date.parse(resource[dateField]) >= Date.parse(lastDateAt);
 
-          if (!lastDateAt || isDateGreater) {
+          if (!lastDateAt || (dateField && isDateGreater)) {
             yield resource;
             resourcesCount += 1;
           }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between e3d9866 and 42c24b3.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (14)
  • components/billbee/actions/add-shipment-to-order/add-shipment-to-order.mjs (1 hunks)
  • components/billbee/actions/change-order-state/change-order-state.mjs (1 hunks)
  • components/billbee/actions/create-invoice-for-order/create-invoice-for-order.mjs (1 hunks)
  • components/billbee/actions/create-order/create-order.mjs (1 hunks)
  • components/billbee/actions/get-order-by-id/get-order-by-id.mjs (1 hunks)
  • components/billbee/actions/list-customers/list-customers.mjs (1 hunks)
  • components/billbee/actions/list-orders/list-orders.mjs (1 hunks)
  • components/billbee/actions/list-products/list-products.mjs (1 hunks)
  • components/billbee/actions/update-order/update-order.mjs (1 hunks)
  • components/billbee/actions/update-stock/update-stock.mjs (1 hunks)
  • components/billbee/billbee.app.mjs (1 hunks)
  • components/billbee/common/constants.mjs (1 hunks)
  • components/billbee/common/utils.mjs (1 hunks)
  • components/billbee/package.json (2 hunks)
🧰 Additional context used
🧠 Learnings (1)
📚 Learning: 2024-12-12T19:23:09.039Z
Learnt from: jcortes
PR: PipedreamHQ/pipedream#14935
File: components/sailpoint/package.json:15-18
Timestamp: 2024-12-12T19:23:09.039Z
Learning: When developing Pipedream components, do not add built-in Node.js modules like `fs` to `package.json` dependencies, as they are native modules provided by the Node.js runtime.

Applied to files:

  • components/billbee/package.json
🧬 Code graph analysis (8)
components/billbee/actions/update-order/update-order.mjs (2)
components/billbee/actions/get-order-by-id/get-order-by-id.mjs (1)
  • response (24-27)
components/billbee/actions/update-stock/update-stock.mjs (1)
  • response (87-99)
components/billbee/actions/list-customers/list-customers.mjs (1)
components/billbee/billbee.app.mjs (1)
  • customers (28-33)
components/billbee/actions/update-stock/update-stock.mjs (2)
components/billbee/actions/get-order-by-id/get-order-by-id.mjs (1)
  • response (24-27)
components/billbee/actions/update-order/update-order.mjs (1)
  • response (94-115)
components/billbee/actions/list-orders/list-orders.mjs (1)
components/billbee/billbee.app.mjs (1)
  • orders (14-19)
components/billbee/actions/get-order-by-id/get-order-by-id.mjs (3)
components/billbee/actions/update-order/update-order.mjs (1)
  • response (94-115)
components/billbee/actions/update-stock/update-stock.mjs (1)
  • response (87-99)
components/billbee/billbee.app.mjs (1)
  • response (409-417)
components/billbee/common/utils.mjs (1)
components/shortcut/actions/create-story/create-story.mjs (1)
  • iterations (168-168)
components/billbee/actions/list-products/list-products.mjs (1)
components/billbee/billbee.app.mjs (1)
  • products (56-61)
components/billbee/billbee.app.mjs (7)
components/billbee/actions/list-orders/list-orders.mjs (1)
  • orders (114-133)
components/billbee/actions/list-customers/list-customers.mjs (1)
  • customers (24-32)
components/billbee/actions/list-products/list-products.mjs (1)
  • products (45-57)
components/billbee/actions/get-order-by-id/get-order-by-id.mjs (1)
  • response (24-27)
components/billbee/actions/update-order/update-order.mjs (1)
  • response (94-115)
components/billbee/actions/update-stock/update-stock.mjs (1)
  • response (87-99)
components/mews/sources/common/polling.mjs (1)
  • lastDateAt (96-96)
⏰ 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: Publish TypeScript components
  • GitHub Check: Verify TypeScript components
  • GitHub Check: Lint Code Base
🔇 Additional comments (9)
components/billbee/package.json (1)

3-3: Semver bump makes sense for new actions

Minor version bump to 0.1.0 aligns with added functionality. LGTM.

components/billbee/common/constants.mjs (1)

6-7: Confirm pagination defaults with Billbee limits
DEFAULT_MAX=300 and DEFAULT_LIMIT=100 look reasonable; please verify the API’s max page size to avoid server-side clamping or errors.

components/billbee/actions/update-stock/update-stock.mjs (1)

87-98: API field names and requirements confirmed
Field names in the payload match UpdateStockApiModel in the Billbee API (StockId, BillbeeId, Sku, Reason, OldQuantity, NewQuantity, ForceSendStockToShops, AutosubtractReservedAmount) (npm.io). StockId and BillbeeId are optional (multi-stock and alternative identifier), while Sku is required. No changes needed.

components/billbee/actions/list-customers/list-customers.mjs (1)

34-36: LGTM overall.

Pagination pattern and summary are consistent with other actions.

components/billbee/actions/change-order-state/change-order-state.mjs (1)

28-47: LGTM otherwise.

Flow and summary are clear; relies correctly on app.changeOrderState.

components/billbee/actions/update-order/update-order.mjs (1)

78-92: Verify Billbee API field names and casing
The updateOrder call in billbee.app.mjs simply spreads your shippedAt, payedAt, invoiceDate, etc., into the PATCH payload without any internal key mapping. Confirm each property (for example, whether the endpoint expects paidAt rather than payedAt) matches the Billbee /orders/{orderId} Patch schema exactly to avoid silent no-ops.

components/billbee/actions/list-products/list-products.mjs (1)

11-16: Parameters match Billbee API
CamelCase keys minCreatedAt, minimumBillBeeArticleId, and maximumBillBeeArticleId align with the endpoint’s expected query parameters (the API also accepts snake_case variants).

components/billbee/actions/list-orders/list-orders.mjs (1)

23-31: Confirm multi-select compatibility for shopId/orderStateId props. These props reuse definitions in billbee.app.mjs where their base type is "string" (lines 65–67, 85–87), so verify that overriding the type to "string[]" produces a multi-select UI and returns an array.

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

90-103: Dismiss Data‐wrapper check for listOrderStates
listOrderStates targets the /enums/orderstates endpoint, which returns a raw array of states in the response body — Pipedream’s makeRequest unwraps and returns that array directly (pipedream.com). Mapping the array via orderStates.map(...) is correct; no { Data } destructuring needed.

Likely an incorrect or invalid review comment.

@jcortes jcortes force-pushed the billbee-new-components branch from 42c24b3 to 1830dc9 Compare September 4, 2025 22:07
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: 4

♻️ Duplicate comments (2)
components/billbee/actions/create-order/create-order.mjs (1)

41-49: Validate payload before calling the API.

Fail fast if orderData is missing, not an object, or an array. This prevents 400s from the API and clearer user errors.

 import app from "../../billbee.app.mjs";
 import utils from "../../common/utils.mjs";
@@
   async run({ $ }) {
     const {
       app,
       orderData,
     } = this;
 
-    const response = await app.createOrder({
+    const data = utils.parse(orderData);
+    if (!data || typeof data !== "object" || Array.isArray(data)) {
+      throw new (await import("@pipedream/platform")).ConfigurationError(
+        "Order Data must be a valid JSON object."
+      );
+    }
+    const response = await app.createOrder({
       $,
-      data: utils.parse(orderData),
+      data,
     });
components/billbee/billbee.app.mjs (1)

49-54: Nice defensive mapping.

Using title?.[0]?.Text || "Untitled" avoids runtime errors when Title is missing.

🧹 Nitpick comments (9)
components/billbee/common/constants.mjs (1)

3-4: Optional: align defaults with API max page size.

API allows pageSize up to 250; DEFAULT_LIMIT=100 is safe but consider 250 for faster pagination. (simworkflow.com)

components/billbee/common/utils.mjs (1)

37-40: Guard against invalid property paths.

Add a fast path for falsy/empty propertyString to avoid split() errors.

-function getNestedProperty(obj, propertyString) {
-  const properties = propertyString.split(".");
+function getNestedProperty(obj, propertyString) {
+  if (!propertyString) return undefined;
+  const properties = String(propertyString).split(".");
components/billbee/actions/create-order/create-order.mjs (3)

7-7: Fix doc URL (double slash after domain).

-  description: "Create a new order. [See the documentation](https://app.billbee.io//swagger/ui/index#/Orders/OrderApi_PostNewOrder)",
+  description: "Create a new order. [See the documentation](https://app.billbee.io/swagger/ui/index#/Orders/OrderApi_PostNewOrder)",

15-37: Example payload: consider minimal valid fields.

Billbee may reject dates/fields with invalid types; keep example minimal to reduce copy/paste errors. Not blocking. (github.com)


51-53: Summary fallback to avoid “undefined”.

If BillBeeOrderId isn’t present, fall back to a generic message.

-    $.export("$summary", `Successfully created order with ID \`${response.Data?.BillBeeOrderId}\``);
+    const orderId = response?.Data?.BillBeeOrderId;
+    $.export("$summary", orderId
+      ? `Successfully created order with ID \`${orderId}\``
+      : "Successfully created order");
components/billbee/billbee.app.mjs (4)

399-448: Date paging: handle invalid dates and avoid dupes.

  • Skip items with invalid/missing dateField when lastDateAt is provided.
  • Use strict “>” to avoid re-emitting the last processed record.
-          const isDateGreater =
-            lastDateAt
-              && Date.parse(resource[dateField]) >= Date.parse(lastDateAt);
+          const resMs = Date.parse(resource?.[dateField]);
+          const lastMs = lastDateAt ? Date.parse(lastDateAt) : undefined;
+          const isDateGreater = lastMs !== undefined && !Number.isNaN(resMs) && resMs > lastMs;
 
-          if (!lastDateAt || isDateGreater) {
+          if (!lastDateAt || isDateGreater) {
             yield resource;
             resourcesCount += 1;
           }

441-444: Silence noisy logs or gate behind a debug flag.

Console logs can clutter runs. Consider gating via an env/prop or remove.


221-226: Security: consider explicit Accept and JSON Content-Type.

Most requests are JSON; setting Accept plus relying on axios JSON defaults clarifies intent.

   getHeaders(headers) {
     return {
       ...headers,
       "x-billbee-api-key": this.$auth.api_key,
+      Accept: "application/json",
     };
   },

8-213: Minor: some option props represent arrays in API.

Docs show shopId[], orderStateId[], tag[]. Single-value is fine, but consider multi-select for parity. (simworkflow.com)

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 42c24b3 and 1830dc9.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (14)
  • components/billbee/actions/add-shipment-to-order/add-shipment-to-order.mjs (1 hunks)
  • components/billbee/actions/change-order-state/change-order-state.mjs (1 hunks)
  • components/billbee/actions/create-invoice-for-order/create-invoice-for-order.mjs (1 hunks)
  • components/billbee/actions/create-order/create-order.mjs (1 hunks)
  • components/billbee/actions/get-order-by-id/get-order-by-id.mjs (1 hunks)
  • components/billbee/actions/list-customers/list-customers.mjs (1 hunks)
  • components/billbee/actions/list-orders/list-orders.mjs (1 hunks)
  • components/billbee/actions/list-products/list-products.mjs (1 hunks)
  • components/billbee/actions/update-order/update-order.mjs (1 hunks)
  • components/billbee/actions/update-stock/update-stock.mjs (1 hunks)
  • components/billbee/billbee.app.mjs (1 hunks)
  • components/billbee/common/constants.mjs (1 hunks)
  • components/billbee/common/utils.mjs (1 hunks)
  • components/billbee/package.json (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (10)
  • components/billbee/actions/add-shipment-to-order/add-shipment-to-order.mjs
  • components/billbee/package.json
  • components/billbee/actions/update-order/update-order.mjs
  • components/billbee/actions/create-invoice-for-order/create-invoice-for-order.mjs
  • components/billbee/actions/change-order-state/change-order-state.mjs
  • components/billbee/actions/list-products/list-products.mjs
  • components/billbee/actions/get-order-by-id/get-order-by-id.mjs
  • components/billbee/actions/list-orders/list-orders.mjs
  • components/billbee/actions/list-customers/list-customers.mjs
  • components/billbee/actions/update-stock/update-stock.mjs
🧰 Additional context used
🧬 Code graph analysis (3)
components/billbee/actions/create-order/create-order.mjs (3)
components/billbee/actions/get-order-by-id/get-order-by-id.mjs (1)
  • response (24-27)
components/billbee/actions/update-order/update-order.mjs (1)
  • response (94-115)
components/billbee/actions/update-stock/update-stock.mjs (1)
  • response (87-99)
components/billbee/common/utils.mjs (1)
components/shortcut/actions/create-story/create-story.mjs (1)
  • iterations (168-168)
components/billbee/billbee.app.mjs (8)
components/billbee/actions/list-orders/list-orders.mjs (1)
  • orders (114-133)
components/billbee/actions/list-customers/list-customers.mjs (1)
  • customers (24-31)
components/billbee/actions/list-products/list-products.mjs (1)
  • products (45-57)
components/billbee/actions/create-order/create-order.mjs (1)
  • response (46-49)
components/billbee/actions/get-order-by-id/get-order-by-id.mjs (1)
  • response (24-27)
components/billbee/actions/update-order/update-order.mjs (1)
  • response (94-115)
components/billbee/actions/update-stock/update-stock.mjs (1)
  • response (87-99)
components/mews/sources/common/polling.mjs (1)
  • lastDateAt (96-96)
⏰ 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: Lint Code Base
  • GitHub Check: Verify TypeScript components
  • GitHub Check: Publish TypeScript components
  • GitHub Check: pnpm publish
🔇 Additional comments (6)
components/billbee/common/utils.mjs (1)

29-35: LGTM: simple async iterator collector.

components/billbee/billbee.app.mjs (5)

375-398: Shipments endpoints look correct.

Paths match the API: shippingproviders, shippingcarriers, shipments, shipwithlabel available elsewhere. (github.com, unpkg.com)


357-368: Order states path matches docs.


279-330: Orders endpoints align with API (list/get/create/update/state change/invoice). (simworkflow.com)


449-451: LGTM: simple wrapper over iterator.


238-246: Optional: allow caller-provided full URLs safely.

getUrl supports url override; ensure callers can’t bypass auth/header logic unintentionally. If allowing, document it.

Copy link
Collaborator

@michelle0927 michelle0927 left a comment

Choose a reason for hiding this comment

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

Hi @jcortes. This PR didn't have a reviewer assigned, so I reviewed it. Looks good, just a few typos and a question about the @pipedream/platform version.

@michelle0927 michelle0927 removed the request for review from lcaresia September 9, 2025 15:18
@jcortes jcortes force-pushed the billbee-new-components branch from 1830dc9 to 79f20b0 Compare September 9, 2025 16:57
@jcortes jcortes force-pushed the billbee-new-components branch from 79f20b0 to b73fb67 Compare September 9, 2025 17:00
@jcortes jcortes requested a review from michelle0927 September 9, 2025 17:01
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

♻️ Duplicate comments (3)
components/billbee/actions/create-order/create-order.mjs (1)

41-49: Validate and parse orderData before calling the API

Fail fast on non-object, null, or array input; surface a ConfigurationError instead of sending a bad payload. Mirrors earlier feedback.

+import { ConfigurationError } from "@pipedream/platform";
 import app from "../../billbee.app.mjs";
 import utils from "../../common/utils.mjs";
@@
   async run({ $ }) {
     const {
       app,
       orderData,
     } = this;
 
-    const response = await app.createOrder({
+    const data = utils.parse(orderData);
+    if (!data || typeof data !== "object" || Array.isArray(data)) {
+      throw new ConfigurationError("Order Data must be a valid JSON object.");
+    }
+
+    const response = await app.createOrder({
       $,
-      data: utils.parse(orderData),
+      data,
     });
components/billbee/billbee.app.mjs (2)

215-217: Confirm base URL resolves to api.billbee.io

Docs and SDKs use https://api.billbee.io/api/v1. Either set constants accordingly or consolidate into a single API_BASE. (github.com, unpkg.com)

-    getBaseUrl() {
-      return `${constants.BASE_URL}${constants.VERSION_PATH}`;
-    },
+    getBaseUrl() {
+      // e.g., constants.API_BASE = "https://api.billbee.io/api/v1"
+      return constants.API_BASE ?? `${constants.BASE_URL}${constants.VERSION_PATH}`;
+    },

247-253: Add timeouts (and optional 429 backoff) to external calls

Avoid hung requests and handle Billbee throttling gracefully. Mirrors prior feedback. (unpkg.com)

       return axios($, {
         headers: getHeaders(headers),
         url: getUrl(path, url),
         auth: getAuth(),
+        timeout: args.timeout ?? 30000,
+        // Optional: lightweight retry on 429 with exponential backoff
+        // ...(args.retry429 && { /* wire interceptor or custom loop here */ }),
         ...args,
       });
🧹 Nitpick comments (5)
components/billbee/actions/create-order/create-order.mjs (2)

51-53: Harden summary ID extraction

Response shapes vary. Prefer a safe fallback chain so the summary doesn’t print “undefined”. Please verify against a real response.

-    $.export("$summary", `Successfully created order with ID \`${response.Data?.BillBeeOrderId}\``);
+    const orderId =
+      response?.Data?.BillBeeOrderId ??
+      response?.Data?.Id ??
+      response?.BillBeeOrderId ??
+      response?.Id;
+    $.export("$summary", `Successfully created order with ID \`${orderId ?? "unknown"}\``);

7-7: Fix double slashes in docs links (cosmetic)

Ensure a single slash to avoid redirects.

-  description: "Create a new order. [See the documentation](https://app.billbee.io//swagger/ui/index#/Orders/OrderApi_PostNewOrder)",
+  description: "Create a new order. [See the documentation](https://app.billbee.io/swagger/ui/index#/Orders/OrderApi_PostNewOrder)",
@@
-      description: `The data for the order. [See the documentation](https://app.billbee.io//swagger/ui/index#/Orders/OrderApi_PostNewOrder)
+      description: `The data for the order. [See the documentation](https://app.billbee.io/swagger/ui/index#/Orders/OrderApi_PostNewOrder)

Also applies to: 15-15, 17-37

components/billbee/billbee.app.mjs (3)

166-181: Minor: rename local var and verify mapped field

These are shipments, not “shippingProviderProducts”. Also confirm the ID field is BillbeeId (lowercase “b” in BillbeeId) as per schemas. (unpkg.com)

-        const { Data: shippingProviderProducts } = await this.listShipments({
+        const { Data: shipments } = await this.listShipments({
           params: {
             page: page + 1,
             pageSize: constants.DEFAULT_LIMIT,
             orderId,
             shippingProviderId,
           },
         });
-        return shippingProviderProducts?.map(mapper) || [];
+        return shipments?.map(mapper) || [];

221-226: Set safe default headers

Add Accept and default JSON Content-Type; allow overrides via arg headers.

     getHeaders(headers) {
       return {
         ...headers,
-        "x-billbee-api-key": this.$auth.api_key,
+        "X-Billbee-Api-Key": this.$auth.api_key,
+        "Accept": "application/json",
+        ...(headers?.["Content-Type"] ? {} : { "Content-Type": "application/json" }),
       };
     },

399-448: Pagination iterator: guard date parsing and reduce noisy logs

Skip items with invalid dates explicitly and keep logs terse.

-          const isDateGreater =
-            lastDateAt
-              && Date.parse(resource[dateField]) >= Date.parse(lastDateAt);
+          const hasComparableDates =
+            lastDateAt && resource?.[dateField] && !Number.isNaN(Date.parse(resource[dateField]));
+          const isDateGreater = hasComparableDates
+            ? Date.parse(resource[dateField]) >= Date.parse(lastDateAt)
+            : false;
@@
-          console.log("No more resources found");
+          console.log("No more resources");
@@
-          console.log("Reached max resources");
+          console.log("Reached max");
@@
-          console.log("No next page found");
+          console.log("No next page");
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1830dc9 and b73fb67.

📒 Files selected for processing (14)
  • components/billbee/actions/add-shipment-to-order/add-shipment-to-order.mjs (1 hunks)
  • components/billbee/actions/change-order-state/change-order-state.mjs (1 hunks)
  • components/billbee/actions/create-invoice-for-order/create-invoice-for-order.mjs (1 hunks)
  • components/billbee/actions/create-order/create-order.mjs (1 hunks)
  • components/billbee/actions/get-order-by-id/get-order-by-id.mjs (1 hunks)
  • components/billbee/actions/list-customers/list-customers.mjs (1 hunks)
  • components/billbee/actions/list-orders/list-orders.mjs (1 hunks)
  • components/billbee/actions/list-products/list-products.mjs (1 hunks)
  • components/billbee/actions/update-order/update-order.mjs (1 hunks)
  • components/billbee/actions/update-stock/update-stock.mjs (1 hunks)
  • components/billbee/billbee.app.mjs (1 hunks)
  • components/billbee/common/constants.mjs (1 hunks)
  • components/billbee/common/utils.mjs (1 hunks)
  • components/billbee/package.json (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (12)
  • components/billbee/package.json
  • components/billbee/common/constants.mjs
  • components/billbee/actions/change-order-state/change-order-state.mjs
  • components/billbee/actions/update-stock/update-stock.mjs
  • components/billbee/actions/list-customers/list-customers.mjs
  • components/billbee/actions/add-shipment-to-order/add-shipment-to-order.mjs
  • components/billbee/common/utils.mjs
  • components/billbee/actions/list-products/list-products.mjs
  • components/billbee/actions/list-orders/list-orders.mjs
  • components/billbee/actions/create-invoice-for-order/create-invoice-for-order.mjs
  • components/billbee/actions/update-order/update-order.mjs
  • components/billbee/actions/get-order-by-id/get-order-by-id.mjs
🧰 Additional context used
🧬 Code graph analysis (2)
components/billbee/billbee.app.mjs (8)
components/billbee/actions/list-orders/list-orders.mjs (1)
  • orders (114-133)
components/billbee/actions/list-customers/list-customers.mjs (1)
  • customers (24-31)
components/billbee/actions/list-products/list-products.mjs (1)
  • products (45-57)
components/billbee/actions/create-order/create-order.mjs (1)
  • response (46-49)
components/billbee/actions/get-order-by-id/get-order-by-id.mjs (1)
  • response (24-27)
components/billbee/actions/update-order/update-order.mjs (1)
  • response (94-115)
components/billbee/actions/update-stock/update-stock.mjs (1)
  • response (87-99)
components/mews/sources/common/polling.mjs (1)
  • lastDateAt (96-96)
components/billbee/actions/create-order/create-order.mjs (4)
components/billbee/actions/get-order-by-id/get-order-by-id.mjs (1)
  • response (24-27)
components/billbee/actions/update-order/update-order.mjs (1)
  • response (94-115)
components/billbee/actions/update-stock/update-stock.mjs (1)
  • response (87-99)
components/billbee/billbee.app.mjs (1)
  • response (408-416)
⏰ 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 (4)
components/billbee/billbee.app.mjs (4)

49-55: Good null-safety on product Title

title?.[0]?.Text avoids runtime errors when Title is missing. Nice.


66-84: Prop descriptions look good

Descriptions for shopId and orderStateId read clearly.

Also applies to: 86-103


188-197: Confirm .Data wrapper on listShippingCarriers
Ensure the Billbee API response for shipping carriers is wrapped in a Data field (per OpenAPI) before mapping; if so, update the loader to:

- const carriers = await this.listShippingCarriers();
+ const { Data: carriers } = await this.listShippingCarriers();

90-103: Don’t add .DatalistOrderStates returns a raw array like the other /enums endpoints (shippingCarriers, shipmentTypes), so mapping orderStates directly is correct.

Likely an incorrect or invalid review comment.

Copy link
Collaborator

@michelle0927 michelle0927 left a comment

Choose a reason for hiding this comment

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

LGTM! Ready for QA.

@vunguyenhung vunguyenhung merged commit d4a1acb into master Sep 10, 2025
10 checks passed
@vunguyenhung vunguyenhung deleted the billbee-new-components branch September 10, 2025 08:54
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.

Billbee

4 participants