Skip to content

feat: architecture separation initial commit - #113

Merged
pramodnarayana merged 6 commits into
developmentfrom
feat/architecture-separation
Apr 2, 2026
Merged

pramodnarayana merged 6 commits into
developmentfrom
feat/architecture-separation

Conversation

@pramodnarayana

@pramodnarayana pramodnarayana commented Apr 1, 2026 •

Copy link
Copy Markdown
Owner

Summary by CodeRabbit

  • Documentation

    • Added Phase 8 architecture section for fleet-sharded custom logic and worker sync.
  • Chores

    • Added a new shared framework package and migrated packages/tests/types to use it.
    • Updated pre-commit hook script to streamline checks.
  • Refactor

    • Centralized HTTP client initialization and improved response parsing and idempotent startup.
    • Hardened piece validation during load.
  • Bug Fixes

    • Treat whitespace-only query limits as default instead of failing.

@coderabbitai

coderabbitai Bot commented Apr 1, 2026 •

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds a new package @nexiom/piece-framework, migrates numerous framework imports across the monorepo to it, removes the ./framework export from @nexiom/connectors, refactors HostHttpClient to implement HttpClient/OnModuleInit and enhanced response parsing, updates tests and package dependencies, and adds docs/tasks and Husky pre-commit header removal.

Changes

Cohort / File(s) Summary
New piece-framework package
packages/piece-framework/package.json, packages/piece-framework/src/http-client.ts, packages/piece-framework/src/index.ts, packages/piece-framework/src/piece.ts, packages/piece-framework/tsconfig.json, packages/piece-framework/tsconfig.spec.json, packages/piece-framework/vitest.config.ts
Introduce @nexiom/piece-framework with HTTP client abstractions (HttpMethod/HttpRequest/HttpResponse/HttpClient), initialization proxy, Piece helpers/errors, types, and build/test configs.
Connectors package surface & host HTTP client
packages/connectors/package.json, packages/connectors/src/index.ts, packages/connectors/src/http-client/host-http-client.ts, packages/connectors/src/http-client/host-http-client.spec.ts
Remove ./framework export; HostHttpClient now implements HttpClient, OnModuleInit, calls initializeHttpClient(this) in onModuleInit, expands responseType parsing (json/text/arraybuffer/stream), and removes the module-level httpClient Proxy/initializer; tests adjusted accordingly.
Monorepo-wide import migrations
apps/*, packages/*, packages/pieces/* (e.g., apps/api/..., apps/worker/..., packages/engine/..., packages/pieces/*/...)
Replace imports of types/values from @nexiom/connectors or @nexiom/connectors/framework to @nexiom/piece-framework for symbols such as Piece, Trigger, TriggerStore, TriggerStrategy, HttpMethod, httpClient, PropertyType, resolveOAuth2Url, etc.
HostHttpClient tests & response parsing tests
packages/connectors/src/http-client/host-http-client.spec.ts
Test setup moved to suite-level initialization; added response parsing tests covering json/text/arraybuffer/stream; adjusted mocks and cleanup.
Query & QuickBooks adapter changes
packages/pieces/quickbooks/src/triggers/quickbooks-query.adapter.ts, packages/pieces/quickbooks/src/triggers/quickbooks-polling.helper.ts, packages/pieces/quickbooks/src/triggers/quickbooks-query.adapter.spec.ts
Redefined QBOQuerySpec shape; parseLimit treats whitespace-only strings as undefined/100; removed objectName arg in one call; tests updated.
Piece loader & registry tightening
packages/engine/src/pieces/piece-loader.service.ts, packages/engine/src/pieces/piece-registry.service.ts, packages/engine/src/pieces/pieces.module.ts
Tightened runtime piece validation (require auth object and categories array of strings); migrate Piece/Trigger types to @nexiom/piece-framework.
Promise mock adjustments in specs
apps/worker/src/modules/pipeline/*, packages/connectors/src/http-client/host-http-client.spec.ts
Standardize mocked query-builder .then() signatures to accept optional onfulfilled handlers; updated several tests to match Promise semantics.
Package dependency updates
apps/api/package.json, apps/worker/package.json, packages/connectors/package.json, packages/engine/package.json, packages/pieces/*/package.json
Add @nexiom/piece-framework: "workspace:*" to multiple packages and remove ./framework export from connectors package.
Docs & hooks
docs/architecture/master/tasks.md, .husky/pre-commit
Add Phase 8 tasks T053–T054 to docs; remove Husky pre-commit script bootstrap header (shebang/source lines removed).

Sequence Diagram(s)

sequenceDiagram
    participant NestApp as NestJS App
    participant HostClient as HostHttpClient
    participant Framework as Piece Framework
    participant Proxy as httpClient Proxy
    rect rgba(200,200,255,0.5)
    NestApp->>HostClient: module init -> onModuleInit()
    HostClient->>Framework: initializeHttpClient(this)
    Framework->>Proxy: set internal client instance
    end
    rect rgba(200,255,200,0.5)
    participant PieceCode as Piece consumer
    PieceCode->>Proxy: httpClient.sendRequest(request)
    Proxy->>Framework: forward bound call -> client.sendRequest(...)
    Framework->>HostClient: delegated sendRequest call
    HostClient-->>PieceCode: response (parsed per responseType)
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

Poem

🐰 I hopped through exports and ports anew,

I planted a proxy where requests flew.
Types migrated, tests adjusted their tune,
A tiny framework sprouted like a moon.
🥕 Build green, dear devs — a carrot-shaped boon!

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 25.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main change: creating a new @nexiom/piece-framework package and migrating framework types/exports from @nexiom/connectors to this new dedicated package, establishing clear architectural separation.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/architecture-separation

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.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 11

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
packages/pieces/salesforce/src/lib/trigger/universal-trigger.ts (1)

4-8: ⚠️ Potential issue | 🔴 Critical

Critical: Broken dependency across multiple pieces — intelligence module imports will fail at runtime.

Multiple files across at least 2 pieces import from @nexiom/connectors/intelligence, but their respective package.json files remove @nexiom/connectors as a dependency:

  • Salesforce piece: 5 files affected (universal-trigger.ts, salesforce-query.adapter.ts, salesforce-query.adapter.spec.ts, salesforce-discovery.adapter.ts, salesforce-bulk.adapter.ts)
  • Quickbooks piece: 3 files affected (universal-trigger.ts, quickbooks-query.adapter.ts, quickbooks-polling.helper.ts)

The @nexiom/piece-framework replacement does not re-export UniversalTriggerEngine, optimizationService, IgtLogger, QuerySpec, ObjectHint, or ObjectSchema from the intelligence module. This will cause module resolution failures at runtime.

Required resolution:

  • Retain @nexiom/connectors as a dependency in affected package.json files (alongside @nexiom/piece-framework), OR
  • Move intelligence module exports to @nexiom/piece-framework, OR
  • Create a separate @nexiom/connectors-intelligence package
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/pieces/salesforce/src/lib/trigger/universal-trigger.ts` around lines
4 - 8, The imports of UniversalTriggerEngine, optimizationService, IgtLogger,
QuerySpec, ObjectHint, and ObjectSchema from '@nexiom/connectors/intelligence'
will fail because '@nexiom/connectors' was removed from package.json; restore
runtime resolution by re-adding '@nexiom/connectors' as a dependency to the
affected package.json files (at least the Salesforce and Quickbooks pieces) and
run install/build; search for files importing those symbols (e.g.,
universal-trigger.ts, salesforce-query.adapter.ts,
salesforce-discovery.adapter.ts, salesforce-bulk.adapter.ts, quickbooks
universal-trigger.ts/quickbooks-query.adapter.ts/quickbooks-polling.helper.ts)
to verify imports are unchanged, or alternatively implement one of the other
approved resolutions (re-export these symbols from `@nexiom/piece-framework` or
create a new `@nexiom/connectors-intelligence` package) and update import paths
accordingly before running tests.
packages/engine/src/pieces/piece-loader.service.ts (1)

116-128: ⚠️ Potential issue | 🟠 Major

Strengthen isPiece to enforce required Piece fields.

The runtime validator at lines 116-128 does not check for auth (required) and categories (required) fields defined in the Piece interface. Invalid pieces lacking these fields will pass the guard and cause failures downstream when code assumes the full contract.

Proposed fix
   private isPiece(value: unknown): value is Piece {
     if (typeof value !== 'object' || value === null) return false;
     const v = value as Record<string, unknown>;
     return (
       typeof v['name'] === 'string' &&
       typeof v['displayName'] === 'string' &&
       typeof v['description'] === 'string' &&
       typeof v['logoUrl'] === 'string' &&
+      typeof v['auth'] === 'object' &&
+      v['auth'] !== null &&
+      Array.isArray(v['categories']) &&
       typeof v['actions'] === 'object' &&
       v['actions'] !== null &&
       typeof v['triggers'] === 'object' &&
       v['triggers'] !== null
     );
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/engine/src/pieces/piece-loader.service.ts` around lines 116 - 128,
The isPiece type guard currently misses validating two required Piece fields so
invalid objects slip through; update the isPiece(value: unknown): value is Piece
function to also check that v['auth'] is an object (and not null) and that
v['categories'] is an array (and has at least one string or is an array of
strings per your Piece contract), and ensure both checks use
typeof/Array.isArray validations consistent with the existing pattern so the
guard only returns true when name, displayName, description, logoUrl, actions,
triggers, auth, and categories all meet their expected shapes.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/architecture/master/tasks.md`:
- Line 627: The task description contains a duplicated word "disk disk"; update
the checklist item text that currently reads "pulls/fetches mapped Git Shard
repositories (e.g. `fluxnex-shard-001`) onto the local disk disk every 5
minutes." to remove the extra "disk" so it reads "onto the local disk every 5
minutes." Locate the string in the docs/architecture/master/tasks.md content
(the checklist entry) and correct the typo, preserving the rest of the phrasing
and the 5-minute interval.
- Around line 615-633: The Phase summary table and totals in the docs are stale
after adding new tasks T053 and T054 (Phase 8); update the summary section to
add a "Phase 8" row (reflecting the new T053 · engine and T054 · worker entries)
and recalculate the overall totals so the phase table and totals match the
current task list (ensure references to T053 and T054 appear in the new row and
any aggregate counts/percentages are adjusted accordingly).

In `@packages/connectors/src/http-client/host-http-client.spec.ts`:
- Around line 10-12: Replace the value import of NormalizedRecord and
VendorResponse with a type-only import: change the existing import that brings
those symbols from '@nexiom/piece-framework' into a single type import (import
type { NormalizedRecord, VendorResponse } from '@nexiom/piece-framework') while
leaving any other value imports intact; this ensures NormalizedRecord and
VendorResponse are treated as type-only (they are only used as annotations in
the tests).

In `@packages/connectors/src/http-client/host-http-client.ts`:
- Line 12: The import groups should separate type-only imports from runtime
imports: change the single import that brings in HttpClient, HttpRequest,
HttpResponse, and HttpMethod into two imports so that HttpClient, HttpRequest,
and HttpResponse are imported with "import type" (type-only) and HttpMethod is
imported as a normal runtime import; update the import statement that currently
references HttpClient/HttpRequest/HttpResponse/HttpMethod to use "import type {
HttpClient, HttpRequest, HttpResponse } from '@nexiom/piece-framework';" and
"import { HttpMethod } from '@nexiom/piece-framework';" so runtime usage of
HttpMethod remains available while the other symbols are treated as types.

In `@packages/piece-framework/package.json`:
- Around line 1-27: The package manifest is missing a declared dependency for
`@nestjs/common` while src/piece.ts imports InternalServerErrorException; either
add "@nestjs/common" to the package.json dependencies (so consumers/installers
get it) or replace InternalServerErrorException in src/piece.ts with a local
error type/utility to decouple from Nest; update
packages/piece-framework/package.json "dependencies" to include `@nestjs/common`
with an appropriate semver OR modify the symbol InternalServerErrorException
usage in src/piece.ts to throw a package-local Error subclass (e.g.,
PieceInternalServerError) and remove the external import.

In `@packages/piece-framework/src/http-client.ts`:
- Around line 35-37: initializeHttpClient currently allows overwriting the
singleton _httpClientInstance; change it to guard against re-assignment by
checking _httpClientInstance before setting it and failing fast (throw an
informative error) if it's already initialized. Locate the initializeHttpClient
function and the _httpClientInstance symbol and modify the function to validate
that _httpClientInstance is unset (or null/undefined) before assigning the
provided HttpClient; if already set, throw an Error like "HttpClient already
initialized" to prevent silent mid-process transport swaps.
- Around line 39-43: The httpClient Proxy throws if accessed before
initialization because initializeHttpClient(...) is never called in production;
to fix, call initializeHttpClient(new HostHttpClient(...)) during application
bootstrap so the singleton is set before any piece uses
httpClient.sendRequest(); add this call in the NestJS startup path (e.g., in
PiecesModule onModuleInit / module bootstrap or a dedicated HTTP integration
module that runs before triggers/actions) and ensure HostHttpClient is
constructed with the platform host/context used in production.

In `@packages/piece-framework/tsconfig.json`:
- Around line 14-17: The tsconfig.json contains an invalid trailing comma after
the "include" array which breaks JSON parsing; open the tsconfig.json file and
remove the comma immediately following the closing bracket of the "include"
array so the file is valid JSON (ensure the "include": ["src/**/*"] entry ends
without a trailing comma).

In `@packages/piece-framework/tsconfig.spec.json`:
- Around line 3-7: The tsconfig.spec.json currently sets compilerOptions.types
to only ["vitest/globals"], which overrides the base and drops "node"; update
the types array to include "node" alongside "vitest/globals" so Node globals
remain available for tests (i.e., change compilerOptions.types to include both
"vitest/globals" and "node").

In `@packages/pieces/quickbooks/src/triggers/quickbooks-polling.helper.ts`:
- Around line 1-3: The package is missing the `@nexiom/connectors` dependency
referenced by the import of ObjectHint in quickbooks-polling.helper.ts; add
"@nexiom/connectors" to the dependencies in the quickbooks package.json
(matching the version used across the monorepo), run the package manager to
update lockfiles, and ensure TypeScript can resolve the import so the import of
ObjectHint (and any other symbols from `@nexiom/connectors`) in
quickbooks-polling.helper.ts compiles successfully.

In `@packages/pieces/salesforce/package.json`:
- Line 28: The package.json change removed `@nexiom/connectors` which breaks
imports in packages/pieces/salesforce/src/lib/trigger/universal-trigger.ts (it
imports UniversalTriggerEngine, optimizationService, and IgtLogger from
`@nexiom/connectors/intelligence`); restore `@nexiom/connectors` as a dependency in
packages/pieces/salesforce/package.json (alongside `@nexiom/piece-framework`) so
those symbols remain resolvable, then run install to verify the imports in
UniversalTriggerEngine/optimizationService/IgtLogger resolve.

---

Outside diff comments:
In `@packages/engine/src/pieces/piece-loader.service.ts`:
- Around line 116-128: The isPiece type guard currently misses validating two
required Piece fields so invalid objects slip through; update the isPiece(value:
unknown): value is Piece function to also check that v['auth'] is an object (and
not null) and that v['categories'] is an array (and has at least one string or
is an array of strings per your Piece contract), and ensure both checks use
typeof/Array.isArray validations consistent with the existing pattern so the
guard only returns true when name, displayName, description, logoUrl, actions,
triggers, auth, and categories all meet their expected shapes.

In `@packages/pieces/salesforce/src/lib/trigger/universal-trigger.ts`:
- Around line 4-8: The imports of UniversalTriggerEngine, optimizationService,
IgtLogger, QuerySpec, ObjectHint, and ObjectSchema from
'@nexiom/connectors/intelligence' will fail because '@nexiom/connectors' was
removed from package.json; restore runtime resolution by re-adding
'@nexiom/connectors' as a dependency to the affected package.json files (at
least the Salesforce and Quickbooks pieces) and run install/build; search for
files importing those symbols (e.g., universal-trigger.ts,
salesforce-query.adapter.ts, salesforce-discovery.adapter.ts,
salesforce-bulk.adapter.ts, quickbooks
universal-trigger.ts/quickbooks-query.adapter.ts/quickbooks-polling.helper.ts)
to verify imports are unchanged, or alternatively implement one of the other
approved resolutions (re-export these symbols from `@nexiom/piece-framework` or
create a new `@nexiom/connectors-intelligence` package) and update import paths
accordingly before running tests.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 13dfb78c-29b1-4658-a351-6475e298fff4

📥 Commits

Reviewing files that changed from the base of the PR and between 4d573be and f1a5e25.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (64)
  • .husky/pre-commit
  • apps/api/package.json
  • apps/api/src/modules/connections/connections/callback.controller.spec.ts
  • apps/api/src/modules/connections/connections/connectors.controller.spec.ts
  • apps/api/src/modules/connections/connections/connectors.controller.ts
  • apps/api/src/modules/connections/connections/token-refresh.service.spec.ts
  • apps/api/src/modules/connections/connections/token-refresh.service.ts
  • apps/api/src/modules/connections/connectors.service.spec.ts
  • apps/api/src/modules/connections/connectors.service.ts
  • apps/api/src/modules/scheduler/poll-sync-runner.ts
  • apps/api/src/modules/stitches/metadata-discovery.service.ts
  • apps/api/src/modules/trigger/dlq-processor.service.spec.ts
  • apps/api/src/modules/trigger/poller.service.spec.ts
  • apps/api/src/modules/trigger/redis-trigger-store.ts
  • apps/api/src/modules/trigger/trigger-executor.service.spec.ts
  • apps/api/src/modules/trigger/trigger-executor.service.ts
  • apps/api/src/modules/trigger/webhooks.controller.spec.ts
  • apps/worker/package.json
  • apps/worker/src/modules/pipeline/delivery.service.spec.ts
  • apps/worker/src/modules/pipeline/delivery.service.ts
  • docs/architecture/master/tasks.md
  • packages/connectors/package.json
  • packages/connectors/src/http-client/host-http-client.spec.ts
  • packages/connectors/src/http-client/host-http-client.ts
  • packages/connectors/src/index.ts
  • packages/connectors/src/intelligence/interfaces.ts
  • packages/connectors/src/intelligence/universal-trigger-engine.spec.ts
  • packages/engine/package.json
  • packages/engine/src/pieces/piece-loader.service.ts
  • packages/engine/src/pieces/piece-registry.service.spec.ts
  • packages/engine/src/pieces/piece-registry.service.ts
  • packages/engine/src/pieces/pieces.module.ts
  • packages/engine/src/state/cursor-manager.service.spec.ts
  • packages/engine/src/state/cursor-manager.service.ts
  • packages/engine/src/state/cursor-manager.types.ts
  • packages/piece-framework/package.json
  • packages/piece-framework/src/action.ts
  • packages/piece-framework/src/auth.spec.ts
  • packages/piece-framework/src/auth.ts
  • packages/piece-framework/src/canonical/index.ts
  • packages/piece-framework/src/http-client.ts
  • packages/piece-framework/src/index.ts
  • packages/piece-framework/src/piece.ts
  • packages/piece-framework/src/property.ts
  • packages/piece-framework/src/retryable-exception.ts
  • packages/piece-framework/src/trigger.ts
  • packages/piece-framework/tsconfig.json
  • packages/piece-framework/tsconfig.spec.json
  • packages/pieces/quickbooks/package.json
  • packages/pieces/quickbooks/src/index.ts
  • packages/pieces/quickbooks/src/lib/auth.ts
  • packages/pieces/quickbooks/src/triggers/quickbooks-polling.helper.ts
  • packages/pieces/quickbooks/src/triggers/universal-trigger.ts
  • packages/pieces/salesforce/package.json
  • packages/pieces/salesforce/src/index.ts
  • packages/pieces/salesforce/src/lib/auth.ts
  • packages/pieces/salesforce/src/lib/common/index.ts
  • packages/pieces/salesforce/src/lib/intelligence/salesforce-bulk.adapter.spec.ts
  • packages/pieces/salesforce/src/lib/intelligence/salesforce-bulk.adapter.ts
  • packages/pieces/salesforce/src/lib/intelligence/salesforce-discovery.adapter.spec.ts
  • packages/pieces/salesforce/src/lib/intelligence/salesforce-discovery.adapter.ts
  • packages/pieces/salesforce/src/lib/sf-fetch.ts
  • packages/pieces/salesforce/src/lib/trigger/salesforce-polling.helper.ts
  • packages/pieces/salesforce/src/lib/trigger/universal-trigger.ts

Comment thread docs/architecture/master/tasks.md Outdated
Comment thread docs/architecture/master/tasks.md Outdated
Comment thread packages/connectors/src/http-client/host-http-client.spec.ts Outdated
Comment thread packages/connectors/src/http-client/host-http-client.ts Outdated
Comment thread packages/piece-framework/package.json
Comment thread packages/piece-framework/src/http-client.ts
Comment thread packages/piece-framework/tsconfig.json
Comment thread packages/piece-framework/tsconfig.spec.json
Comment thread packages/pieces/salesforce/package.json

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 7

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/piece-framework/src/piece.ts (1)

304-313: ⚠️ Potential issue | 🟠 Major

Prototype keys can break duplicate detection here.

These reducers build lookup maps on {} and check acc[name] by truthiness. A first action/trigger named toString, constructor, or __proto__ will already look “present” via Object.prototype, and __proto__ can mutate the returned map. Use Object.create(null) plus an own-property check.

🛠️ Suggested change
     const actionsMap = params.actions.reduce(
         (acc, action) => {
-            if (acc[action.name]) {
+            if (Object.prototype.hasOwnProperty.call(acc, action.name)) {
                 throw new PieceInternalServerError(`Duplicate action name: ${action.name}`);
             }
             acc[action.name] = action;
             return acc;
         },
-        {} as Record<string, Action>,
+        Object.create(null) as Record<string, Action>,
     );
     const triggersMap = (params.triggers || []).reduce(
         (acc, trigger: Trigger) => {
             // Guard: skip entries that are not valid objects with a non-empty name
             if (
                 typeof trigger !== 'object' ||
@@
-            if (acc[trigger.name]) {
+            if (Object.prototype.hasOwnProperty.call(acc, trigger.name)) {
                 throw new PieceInternalServerError(`Duplicate trigger name: ${trigger.name}`);
             }
             acc[trigger.name] = trigger;
             return acc;
         },
-        {} as Record<string, Trigger>,
+        Object.create(null) as Record<string, Trigger>,
     );

Also applies to: 315-334

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/piece-framework/src/piece.ts` around lines 304 - 313, The
duplicate-name detection in the actions map reducer uses a plain {} and checks
acc[action.name] by truthiness, which breaks for inherited prototype keys like
"toString" or "__proto__" (and allows __proto__ to mutate the map); change the
accumulator initial value to Object.create(null) and use an own-property check
such as Object.prototype.hasOwnProperty.call(acc, action.name) (or
acc.hasOwnProperty if you first ensure a plain object) before throwing the
PieceInternalServerError; apply the same Object.create(null) + own-property
check fix to the analogous reducer that builds the triggers map (the other map
in the same file).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/architecture/master/tasks.md`:
- Line 615: Rename the Phase 8 heading to use a single consistent label across
sections by standardizing both occurrences to the same string (e.g., change
"Phase 8 — Fleet Sharded Custom Logic" and "Fleet Sharding" to the unified label
"Phase 8 — Fleet Sharding"); locate the two headings by their current text and
update them to the chosen phrase so all references and planning sections use the
identical Phase 8 name.

In `@packages/connectors/src/http-client/host-http-client.ts`:
- Around line 42-47: The onModuleInit in HostHttpClient currently swallows all
errors from initializeHttpClient; change it to only ignore an explicitly
idempotent re-init and rethrow any other failures: call
initializeHttpClient(this) inside try/catch, inspect the caught error (by error
type or message) and if it indicates "already initialized" (or a dedicated
IdempotentInitError from initializeHttpClient) return silently, otherwise
rethrow the error so real initialization failures (tokenManager/db/redis not set
up) are not hidden.

In `@packages/engine/src/pieces/piece-loader.service.ts`:
- Around line 130-132: The type guard isPiece currently only verifies the first
element of v['categories'], allowing mixed-type arrays; update the condition in
the isPiece guard to ensure v['categories'] is an array with length > 0 and that
every element is a string (e.g., replace the single-element typeof check with an
all-elements check using Array.prototype.every) so the guard truly narrows
categories to PieceCategory[].

In `@packages/piece-framework/src/http-client.ts`:
- Around line 10-20: The HttpRequest.interface exposes responseType but the host
implementation currently always calls response.text() and JSON.parse (in the
host HTTP client read/parse response code), so callers asking for binary/stream
will get wrong data; update the host client (the response handling function in
packages/connectors/src/http-client/host-http-client.ts that reads the fetch
Response) to respect HttpRequest.responseType by switching on its value (e.g.,
'json' -> response.json(), 'text' -> response.text(), 'arraybuffer'|'binary' ->
response.arrayBuffer(), 'stream' -> response.body) and return the
appropriately-typed payload, or if you prefer to remove the feature, delete
responseType from the HttpRequest interface and any usages; ensure the chosen
approach updates types/signatures where response is returned and add tests
covering json/text/binary/stream paths.

In `@packages/piece-framework/tsconfig.json`:
- Around line 9-16: The package build tsconfig currently includes
"vitest/globals" in "types" and "src/**/*" in "include", which pulls tests into
the production build; remove the vitest type reference from the "types" array
and restrict "include" to production source (e.g., "src/**/*.ts" or a dedicated
src folder excluding spec files), and rely on tsconfig.spec.json for test
typing; update the tsconfig.json's "types" and "include" entries accordingly so
spec files and vitest types are not part of the emitted dist.

In `@packages/piece-framework/tsconfig.spec.json`:
- Around line 2-8: The spec tsconfig currently inherits outDir and
tsBuildInfoFile from the package tsconfig which causes tsc -p
packages/piece-framework/tsconfig.spec.json to write into the package build
outputs; update packages/piece-framework/tsconfig.spec.json to set "noEmit":
true and override "tsBuildInfoFile" to a dedicated file (e.g.
"./dist/tsconfig.spec.tsbuildinfo") under the "compilerOptions" so the spec
build won’t clobber the package dist and will use an isolated build-info file.

In `@packages/pieces/quickbooks/src/triggers/quickbooks-query.adapter.ts`:
- Line 6: The parseLimit function currently coerces blank strings to 0 via
Number(), creating unbounded queries; fix it by validating the incoming limit
(the limit?: number | string param) before coercion: if typeof limit ===
'string' then if limit.trim() === '' treat it as invalid (either return
undefined to omit MAXRESULTS or throw a validation error) and only call Number()
on non-empty strings, then keep the existing NaN and negative checks; update
parseLimit so blank/whitespace-only strings do not fall through into a numeric 0
and thereby suppress the MAXRESULTS clause.

---

Outside diff comments:
In `@packages/piece-framework/src/piece.ts`:
- Around line 304-313: The duplicate-name detection in the actions map reducer
uses a plain {} and checks acc[action.name] by truthiness, which breaks for
inherited prototype keys like "toString" or "__proto__" (and allows __proto__ to
mutate the map); change the accumulator initial value to Object.create(null) and
use an own-property check such as Object.prototype.hasOwnProperty.call(acc,
action.name) (or acc.hasOwnProperty if you first ensure a plain object) before
throwing the PieceInternalServerError; apply the same Object.create(null) +
own-property check fix to the analogous reducer that builds the triggers map
(the other map in the same file).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 661520ba-fd1d-433e-905d-51e124db8e32

📥 Commits

Reviewing files that changed from the base of the PR and between f1a5e25 and 6ca601a.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (15)
  • apps/worker/src/modules/pipeline/fanout.service.spec.ts
  • apps/worker/src/modules/pipeline/normalization.service.spec.ts
  • apps/worker/src/modules/pipeline/replica.service.spec.ts
  • docs/architecture/master/tasks.md
  • packages/connectors/src/http-client/host-http-client.spec.ts
  • packages/connectors/src/http-client/host-http-client.ts
  • packages/engine/src/pieces/piece-loader.service.ts
  • packages/piece-framework/src/http-client.ts
  • packages/piece-framework/src/piece.ts
  • packages/piece-framework/tsconfig.json
  • packages/piece-framework/tsconfig.spec.json
  • packages/pieces/quickbooks/package.json
  • packages/pieces/quickbooks/src/triggers/quickbooks-polling.helper.ts
  • packages/pieces/quickbooks/src/triggers/quickbooks-query.adapter.ts
  • packages/pieces/salesforce/package.json

Comment thread docs/architecture/master/tasks.md Outdated

---

## Phase 8 — Fleet Sharded Custom Logic

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🧹 Nitpick | 🔵 Trivial

Use a single Phase 8 label across sections for consistency.

Line 615 uses “Fleet Sharded Custom Logic” while Line 648 uses “Fleet Sharding.” Consider standardizing to one name to avoid ambiguity in planning references.

Also applies to: 648-648

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/architecture/master/tasks.md` at line 615, Rename the Phase 8 heading to
use a single consistent label across sections by standardizing both occurrences
to the same string (e.g., change "Phase 8 — Fleet Sharded Custom Logic" and
"Fleet Sharding" to the unified label "Phase 8 — Fleet Sharding"); locate the
two headings by their current text and update them to the chosen phrase so all
references and planning sections use the identical Phase 8 name.

Comment thread packages/connectors/src/http-client/host-http-client.ts
Comment thread packages/engine/src/pieces/piece-loader.service.ts Outdated
Comment thread packages/piece-framework/src/http-client.ts
Comment thread packages/piece-framework/tsconfig.json
Comment thread packages/piece-framework/tsconfig.spec.json
Comment thread packages/pieces/quickbooks/src/triggers/quickbooks-query.adapter.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

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 (1)
packages/pieces/quickbooks/src/triggers/quickbooks-query.adapter.ts (1)

55-60: ⚠️ Potential issue | 🟠 Major

Blank string limits still drop the adapter’s default page size.

parseLimit(undefined) still returns 100, but '' / whitespace now returns undefined, so Line 24 omits MAXRESULTS entirely instead of using the existing default. A cleared input therefore behaves differently from an omitted one and can unexpectedly expand the query. Normalize blank strings to the default branch, or reject them, rather than returning undefined here.

Proposed fix
-    private static parseLimit(limit?: number | string): number | undefined {
-        if (limit === undefined) return 100;
-        if (limit === 0) return 0;
-
-        if (typeof limit === 'string' && limit.trim() === '') {
-            return undefined;
-        }
+    private static parseLimit(limit?: number | string): number {
+        if (typeof limit === 'string') {
+            limit = limit.trim();
+            if (limit === '') return 100;
+        }
+        if (limit === undefined) return 100;
+        if (limit === 0) return 0;

         const parsed = Number(limit);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@packages/pieces/quickbooks/src/triggers/quickbooks-query.adapter.ts` around
lines 55 - 60, The parseLimit function treats blank/whitespace strings as
undefined which causes MAXRESULTS to be omitted; change parseLimit (in
quickbooks-query.adapter.ts) so that empty or whitespace-only string inputs are
normalized to the same default as undefined (return 100) instead of returning
undefined (or alternatively throw for invalid input), ensuring cleared input
behaves like omitted input and preserves the adapter's default page size.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/connectors/src/http-client/host-http-client.spec.ts`:
- Line 1: The test file imports Vitest helpers but omits afterEach, causing a
ReferenceError where afterEach is used; update the import line that currently
lists "describe, expect, it, vi, beforeAll" to also include "afterEach" so the
teardown hook is defined (ensure the import statement includes afterEach
alongside describe, expect, it, vi, beforeAll to match usage later in the file).

In `@packages/engine/src/pieces/piece-loader.service.ts`:
- Around line 130-132: The runtime type guard in piece-loader.service.ts is
erroneously rejecting valid pieces by requiring v['categories'].length > 0;
update the check used by isPiece() (or the local validator around
v['categories']) to allow an empty array (i.e., remove the length > 0
requirement) and only assert Array.isArray(v['categories']) &&
v['categories'].every(c => typeof c === 'string'), so pieces defaulted to [] by
createPiece() are accepted during loading.

In `@packages/piece-framework/tsconfig.spec.json`:
- Around line 6-9: Add a vitest.config.ts that enables Vitest globals to match
the tsconfig.spec.json declaration: create a vitest.config.ts exporting
defineConfig(...) and set test.globals: true, environment: 'node', include to
'src/**/*.spec.ts', and coverage settings (provider 'v8', reporters,
include/exclude patterns) so runtime globals align with the "vitest/globals"
types declared in tsconfig.spec.json; ensure the file exports the configuration
as default using defineConfig from 'vitest/config'.

In `@packages/pieces/quickbooks/src/triggers/quickbooks-query.adapter.ts`:
- Around line 1-6: Several tests pass an extra objectName property that no
longer exists on the QBOQuerySpec type; open the spec that constructs
QBOQuerySpec literals and remove the objectName field from each of the eight
failing test cases (the object literals that are passed where QBOQuerySpec is
expected), ensuring each test object only uses cursorField, cursorValue,
cursorIdField, cursorIdValue, and limit; alternatively revert the QBOQuerySpec
narrowing if you prefer to keep objectName.

---

Duplicate comments:
In `@packages/pieces/quickbooks/src/triggers/quickbooks-query.adapter.ts`:
- Around line 55-60: The parseLimit function treats blank/whitespace strings as
undefined which causes MAXRESULTS to be omitted; change parseLimit (in
quickbooks-query.adapter.ts) so that empty or whitespace-only string inputs are
normalized to the same default as undefined (return 100) instead of returning
undefined (or alternatively throw for invalid input), ensuring cleared input
behaves like omitted input and preserves the adapter's default page size.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: e18dbf16-d05c-4ddb-b034-78aed7cdf6b4

📥 Commits

Reviewing files that changed from the base of the PR and between 6ca601a and bb4a57f.

📒 Files selected for processing (9)
  • docs/architecture/master/tasks.md
  • packages/connectors/src/http-client/host-http-client.spec.ts
  • packages/connectors/src/http-client/host-http-client.ts
  • packages/engine/src/pieces/piece-loader.service.ts
  • packages/piece-framework/src/http-client.ts
  • packages/piece-framework/src/piece.ts
  • packages/piece-framework/tsconfig.json
  • packages/piece-framework/tsconfig.spec.json
  • packages/pieces/quickbooks/src/triggers/quickbooks-query.adapter.ts

Comment thread packages/connectors/src/http-client/host-http-client.spec.ts Outdated
Comment thread packages/engine/src/pieces/piece-loader.service.ts
Comment thread packages/piece-framework/tsconfig.spec.json
Comment thread packages/pieces/quickbooks/src/triggers/quickbooks-query.adapter.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/connectors/src/http-client/host-http-client.spec.ts`:
- Around line 18-25: The test's prototype spy sendRequestSpy is only restored at
the end of individual test flows, which can leak across tests if an assertion
fails; add a suite-level cleanup in the outer describe (paired with the existing
beforeAll initializeHttpClient call) that always restores sendRequestSpy (and
any other spies set in the suite) in an afterAll/afterEach hook so restoration
runs regardless of test failures; locate where sendRequestSpy is created in the
spec (and where initializeHttpClient/HostHttpClient are used) and move or add
the spy restoration to a top-level afterAll (or afterEach) to guarantee cleanup
on failure paths.

In `@packages/piece-framework/vitest.config.ts`:
- Line 7: The Vitest config's include pattern (the include array in
vitest.config.ts) only matches '*.spec.ts' and will miss tests named
'*.test.ts'; update the include value to cover both patterns (e.g., include
'*.spec.*' and '*.test.*' or explicit patterns like 'src/**/*.spec.ts' and
'src/**/*.test.ts') so that functions/tests discovered by Vitest (defined by the
include array) do not get silently skipped.

In `@packages/pieces/quickbooks/src/triggers/quickbooks-query.adapter.ts`:
- Line 24: The parseLimit function currently types its return as number |
undefined but never returns undefined; change its signature to return number,
ensure all code paths return a number (e.g., 100, 0, or parsed value) and remove
any unreachable undefined returns; then simplify the consumer check in
quickbooks-query.adapter.ts (the block using safeLimit, e.g., the if currently
written as if (safeLimit !== 0 && safeLimit !== undefined)) to just check if
(safeLimit !== 0). Update any other callers/types that rely on parseLimit to
reflect the new number return type.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: bb930ed4-e578-4c7b-bb2d-107573ccf4df

📥 Commits

Reviewing files that changed from the base of the PR and between bb4a57f and 9af267e.

📒 Files selected for processing (5)
  • packages/connectors/src/http-client/host-http-client.spec.ts
  • packages/engine/src/pieces/piece-loader.service.ts
  • packages/piece-framework/vitest.config.ts
  • packages/pieces/quickbooks/src/triggers/quickbooks-query.adapter.spec.ts
  • packages/pieces/quickbooks/src/triggers/quickbooks-query.adapter.ts
💤 Files with no reviewable changes (1)
  • packages/pieces/quickbooks/src/triggers/quickbooks-query.adapter.spec.ts

Comment thread packages/connectors/src/http-client/host-http-client.spec.ts
Comment thread packages/piece-framework/vitest.config.ts Outdated
Comment thread packages/pieces/quickbooks/src/triggers/quickbooks-query.adapter.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@packages/connectors/src/http-client/host-http-client.spec.ts`:
- Around line 199-209: Add a test that covers non-ok HTTP responses for
HostHttpClient.sendRequest: spy on global fetch to return ok: false (e.g.,
status 404) with a JSON body and assert the client's behavior (either that
client.sendRequest rejects with an error or returns the expected error
structure). Update host-http-client.spec.ts to include this case using the same
client instance and HttpMethod.GET so we validate how sendRequest handles non-ok
responses.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 58fd3180-cb6a-4031-ad81-3a95a52c69d0

📥 Commits

Reviewing files that changed from the base of the PR and between 9af267e and eedc706.

📒 Files selected for processing (3)
  • packages/connectors/src/http-client/host-http-client.spec.ts
  • packages/piece-framework/vitest.config.ts
  • packages/pieces/quickbooks/src/triggers/quickbooks-query.adapter.ts

Comment thread packages/connectors/src/http-client/host-http-client.spec.ts
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.

1 participant