feat(pipedrive): add Projects, Tasks, and related list actions#21338
feat(pipedrive): add Projects, Tasks, and related list actions#21338michelle0927 wants to merge 7 commits into
Conversation
Adds action coverage for Pipedrive Projects (surfaced in the Pipedrive UI as a project-management add-on) so AI agents can create, update, delete, list, and inspect projects and their tasks — the direct ask in #20984 from the Viktor-in-Slack user. Also expands read coverage on other entities that AI agents commonly need to reach when following project/task flows (persons, organizations, filters), each modeled after the existing `list-deals` shape. New actions: Projects - pipedrive-create-project - pipedrive-get-project - pipedrive-update-project - pipedrive-delete-project - pipedrive-list-projects - pipedrive-list-project-boards - pipedrive-list-project-phases Tasks - pipedrive-create-task - pipedrive-get-task - pipedrive-update-task - pipedrive-delete-task - pipedrive-list-tasks Adjacent lists (used constantly by AI agents while working with projects and tasks) - pipedrive-list-persons - pipedrive-list-organizations - pipedrive-list-filters App-level changes (pipedrive.app.mjs, +82 lines): - New methods wrapping the SDK's ProjectsApi, TasksApi, and the v2 Persons / Organizations endpoints (getPersons and getOrganizations are already used by other options() pickers; the new list actions reuse them). - New propDefinitions where the existing set didn't cover the fields the project/task endpoints need. Constants (common/constants.mjs): - PROJECT_STATUS_OPTIONS, PERSON_SORT_BY_OPTIONS, PERSON_INCLUDE_FIELDS_OPTIONS, ORGANIZATION_SORT_BY_OPTIONS, ORGANIZATION_INCLUDE_FIELDS_OPTIONS, FILTER_TYPE_OPTIONS — enum values pulled directly from Pipedrive's v1 and v2 OpenAPI specs so the option lists don't drift from what the API actually accepts. Closes #20984
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
Coordinated patch bump across the existing pipedrive actions and sources so their published versions advance alongside the app-file changes in this PR (new methods, propDefinitions, and constants used by the new Projects/Tasks/Persons/Organizations/Filters actions).
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (3)
📝 WalkthroughWalkthroughThis PR adds Pipedrive Projects and Tasks support, plus new list actions for organizations, persons, and filters. It also adds shared project-related constants, expands the Pipedrive app methods, and bumps version metadata across existing actions and sources. ChangesPipedrive Projects and Tasks
Existing action/source version bumps
Estimated code review effort: 3 (Moderate) | ~30 minutes Possibly related PRs
🚥 Pre-merge checks | ✅ 3 | ❌ 2❌ Failed checks (2 warnings)
✅ Passed checks (3 passed)
✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 9
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@components/pipedrive/actions/create-project/create-project.mjs`:
- Around line 83-88: The labelIds prop description in createProject should be
updated to explain both the expected value format and where to get valid label
IDs, since it currently only says they are associated with the project. Use the
createProject action’s labelIds field alongside the existing
dealIds/personIds/orgIds descriptions as the reference point, and revise the
description so users are directed to the appropriate list/view or source for
labels, matching the coding guideline for non-obvious IDs.
- Around line 28-34: The create-project action is duplicating shared prop logic
for status and phaseId instead of reusing app-level definitions. Move the common
`status` and `phaseId` setup into `pipedriveApp.propDefinitions`, then update
the action to reference them via `propDefinition` and only override
action-specific `description` text where needed. Use the existing
`createProject` component and the matching `list-projects.mjs` fields as the
places to switch over so both actions share the same options/labels source.
In `@components/pipedrive/actions/create-task/create-task.mjs`:
- Around line 66-71: The assigneeId field is defined as a plain string instead
of reusing the shared userId propDefinition, which makes user selection
inconsistent with ownerId. Update create-task.mjs so assigneeId uses
propDefinition: [pipedriveApp, "userId"] like list-organizations.mjs does for
ownerId, keeping the existing label/description behavior as needed and ensuring
users get the searchable dropdown for valid user IDs.
In `@components/pipedrive/actions/list-projects/list-projects.mjs`:
- Around line 55-62: The limit field validation currently allows values up to
1000 even though the documented API cap is 500. Update the `limit` schema in
`list-projects.mjs` so the `max` matches the API cap, and keep the description
aligned with the validation. Use the `limit` property definition in the action
schema to locate the change.
In `@components/pipedrive/actions/list-tasks/list-tasks.mjs`:
- Around line 22-27: The `assigneeId` field in `list-tasks` should reuse the
shared prop definition used by the Task CRUD actions instead of redefining the
same schema inline. Update the `listTasks` action to reference the existing
`assigneeId` propDefinition from the shared Pipedrive task props so validation,
labels, and help text stay consistent across actions.
- Around line 28-33: The `parentTaskId` filter description in `listTasks` is
misleading because the optional field cannot represent `null`, yet the API
semantics differ between omitted, null, and integer values. Update the
`parentTaskId` schema/description in `list-tasks.mjs` and the `listTasks`
handling so it clearly reflects that omitting the field returns all tasks,
`null` is needed for root-level tasks, and an integer selects subtasks of that
task; if `null` cannot be passed through this action config, adjust the
implementation or wording to match the actual supported behavior.
In `@components/pipedrive/actions/update-task/update-task.mjs`:
- Around line 61-66: The assigneeId field is duplicating the same prop
definition used elsewhere, so reuse the shared propDefinition from
create-task.mjs instead of inlining the string label, description, and optional
settings here. Update the assigneeId definition in update-task.mjs to reference
the existing shared symbol for consistency and easier maintenance.
In `@components/pipedrive/pipedrive.app.mjs`:
- Around line 780-800: The two project API methods still duplicate request setup
instead of using the shared wrapper. Update getProjectBoards and
getProjectPhases to route through the common request helper used elsewhere in
pipedrive.app.mjs, keeping the same endpoint and params behavior but removing
the inline axios call and repeated Authorization header construction.
- Around line 749-752: listProjects currently forwards unsupported filter fields
directly to ProjectsApi.getProjects, so the query can ignore deal_id, person_id,
and org_id and return broader results than expected. Update listProjects in
pipedrive.app.mjs to map only supported project query params and remove or
translate those unsupported filters before calling this.api("ProjectsApi",
"v2"), keeping the method behavior aligned with the List Projects UI.
🪄 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: Organization UI
Review profile: ASSERTIVE
Plan: Pro
Run ID: 45852d55-16da-4b55-821f-018d79c4ac85
📒 Files selected for processing (50)
components/pipedrive/actions/add-activity/add-activity.mjscomponents/pipedrive/actions/add-deal/add-deal.mjscomponents/pipedrive/actions/add-labels/add-labels.mjscomponents/pipedrive/actions/add-lead/add-lead.mjscomponents/pipedrive/actions/add-note/add-note.mjscomponents/pipedrive/actions/add-organization/add-organization.mjscomponents/pipedrive/actions/add-person/add-person.mjscomponents/pipedrive/actions/create-project/create-project.mjscomponents/pipedrive/actions/create-task/create-task.mjscomponents/pipedrive/actions/delete-project/delete-project.mjscomponents/pipedrive/actions/delete-task/delete-task.mjscomponents/pipedrive/actions/get-all-leads/get-all-leads.mjscomponents/pipedrive/actions/get-deal/get-deal.mjscomponents/pipedrive/actions/get-lead-by-id/get-lead-by-id.mjscomponents/pipedrive/actions/get-person-details/get-person-details.mjscomponents/pipedrive/actions/get-project/get-project.mjscomponents/pipedrive/actions/get-task/get-task.mjscomponents/pipedrive/actions/list-deals/list-deals.mjscomponents/pipedrive/actions/list-filters/list-filters.mjscomponents/pipedrive/actions/list-lead-label-ids-options/list-lead-label-ids-options.mjscomponents/pipedrive/actions/list-organization-label-ids-options/list-organization-label-ids-options.mjscomponents/pipedrive/actions/list-organizations/list-organizations.mjscomponents/pipedrive/actions/list-person-label-ids-options/list-person-label-ids-options.mjscomponents/pipedrive/actions/list-persons/list-persons.mjscomponents/pipedrive/actions/list-project-boards/list-project-boards.mjscomponents/pipedrive/actions/list-project-phases/list-project-phases.mjscomponents/pipedrive/actions/list-projects/list-projects.mjscomponents/pipedrive/actions/list-tasks/list-tasks.mjscomponents/pipedrive/actions/list-user-id-options/list-user-id-options.mjscomponents/pipedrive/actions/merge-deals/merge-deals.mjscomponents/pipedrive/actions/merge-persons/merge-persons.mjscomponents/pipedrive/actions/remove-duplicate-notes/remove-duplicate-notes.mjscomponents/pipedrive/actions/remove-labels/remove-labels.mjscomponents/pipedrive/actions/search-leads/search-leads.mjscomponents/pipedrive/actions/search-notes/search-notes.mjscomponents/pipedrive/actions/search-persons/search-persons.mjscomponents/pipedrive/actions/update-deal/update-deal.mjscomponents/pipedrive/actions/update-lead/update-lead.mjscomponents/pipedrive/actions/update-person/update-person.mjscomponents/pipedrive/actions/update-project/update-project.mjscomponents/pipedrive/actions/update-task/update-task.mjscomponents/pipedrive/common/constants.mjscomponents/pipedrive/package.jsoncomponents/pipedrive/pipedrive.app.mjscomponents/pipedrive/sources/new-deal-instant/new-deal-instant.mjscomponents/pipedrive/sources/new-event-instant/new-event-instant.mjscomponents/pipedrive/sources/new-person-instant/new-person-instant.mjscomponents/pipedrive/sources/updated-deal-instant/updated-deal-instant.mjscomponents/pipedrive/sources/updated-lead-instant/updated-lead-instant.mjscomponents/pipedrive/sources/updated-person-instant/updated-person-instant.mjs
* Add `projectStatus` and `projectPhaseId` propDefinitions on pipedriveApp so create-project, list-projects, and update-project can reuse them via propDefinition + per-action description overrides instead of each duplicating the same schema inline. * Have the three task actions (create/list/update-task) reference the existing `userId` propDefinition for `assigneeId`, matching how list-deals/list-organizations reference it for `ownerId`. Gives the agent a searchable user-picker and switches assignee_id to integer (matches the Pipedrive v2 tasks endpoint's declared type). * list-projects: cap `limit.max` at 500 to match the API's server-side cap, and tighten the description to stop advertising a higher ceiling. * list-tasks: rewrite the `parentTaskId` description so it accurately reflects the v2 semantics — omit returns all tasks, an integer returns subtasks; the API also accepts null for root-level-only but this prop can't represent null, so we call that out. * create-project: point users to Pipedrive Settings → Labels for the label IDs `labelIds` expects (there is no dedicated list-project-labels action to reference). Not applied: * Reviewer suggested routing getProjectBoards / getProjectPhases through a shared request helper. No such helper exists in pipedrive.app.mjs — every other method uses the Pipedrive JS SDK (`this.api(...).getX()`); those two use raw axios only because the SDK doesn't cover v2 boards or phases. Introducing a helper is a real cleanup, but the premise (that one already exists) was incorrect, so leaving as-is. * Reviewer suggested listProjects drops `deal_id`, `person_id`, and `org_id` because they're unsupported. Verified against Pipedrive's v2 OpenAPI: all three ARE supported query params on GET /projects, and the action forwards them correctly.
…lasses don't exist
The `pipedrive@^24.1.1` JS SDK does not export ProjectsApi or TasksApi
in its v2 module (v1 has them; v2 only exposes Activities, Beta, Deals,
ItemSearch, Leads, Organizations, Persons, Pipelines, Products, Stages).
Runtime instantiation confirms: `pd.v2.ProjectsApi is not a constructor`.
All ten project/task app methods (`listProjects`, `addProject`, `getProject`,
`updateProject`, `deleteProject`, `listTasks`, `addTask`, `getTask`,
`updateTask`, `deleteTask`) were calling `this.api("ProjectsApi", "v2")` /
`this.api("TasksApi", "v2")` — every one of them would TypeError on first
invocation. Actions publish cleanly but crash on the first eval.
Rewrite the ten methods to use raw axios against `/api/v2/*` — same
pattern boards/phases already needed (the SDK never had those classes
either). Introduce a small `_v2Request` helper on the app so the auth
header + baseURL + method dispatch live in one place, and fold
`getProjectBoards` / `getProjectPhases` through it so they stop
duplicating axios setup (addresses the earlier reviewer note).
Method signatures now take a first-argument object with `$` explicitly
(matching the boards/phases pattern), so update all twelve action
call-sites to pass `$` through for step-trace attribution.
There was a problem hiding this comment.
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
components/pipedrive/actions/create-project/create-project.mjs (1)
33-38: 📐 Maintainability & Code Quality | 🔵 TrivialExtract
boardId/ownerIdinto shared app propDefinitions.
boardIdandownerIdare re-defined inline here and again inupdate-project.mjswith near-identical (but slightly diverging) labels/descriptions — the same pattern already fixed forstatus/phaseId. Consider addingprojectBoardId/projectOwnerIdpropDefinitions onpipedriveAppand referencing them viapropDefinitionin both actions.As per coding guidelines, "Any prop used by more than one component must be defined in the app file's
propDefinitionsand referenced viapropDefinition; do not duplicate its label, description, or options logic in component files."Also applies to: 46-51
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@components/pipedrive/actions/create-project/create-project.mjs` around lines 33 - 38, The `boardId` and `ownerId` props are duplicated in `create-project` and `update-project` with inconsistent labels/descriptions. Move them into shared `propDefinitions` on `pipedriveApp` as `projectBoardId` and `projectOwnerId`, then switch both actions to use `propDefinition` instead of inline definitions. Keep the existing `status`/`phaseId` pattern consistent and remove the duplicated label/description/options logic from the component files.Source: Coding guidelines
♻️ Duplicate comments (1)
components/pipedrive/actions/update-project/update-project.mjs (1)
40-52: 📐 Maintainability & Code Quality | 🔵 TrivialDuplicate
boardId/phaseId-adjacentownerId/boardIdprop definitions withcreate-project.mjs.Same as flagged in
create-project.mjs:boardId(lines 40-45) duplicates the inline definition increate-project.mjswith a slightly different description, and should be pulled into a sharedpropDefinition.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@components/pipedrive/actions/update-project/update-project.mjs` around lines 40 - 52, The `boardId` and related project props in `updateProject` are duplicated instead of being shared with `createProject`, so align them by moving the inline `boardId` definition in `update-project.mjs` to a shared `propDefinition` on `pipedriveApp` like the existing `projectPhaseId` usage. Update `create-project.mjs` and `update-project.mjs` to reference the same unique prop helpers for `ownerId`/`boardId` so both actions stay consistent and only the action-specific fields remain inline.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Outside diff comments:
In `@components/pipedrive/actions/create-project/create-project.mjs`:
- Around line 33-38: The `boardId` and `ownerId` props are duplicated in
`create-project` and `update-project` with inconsistent labels/descriptions.
Move them into shared `propDefinitions` on `pipedriveApp` as `projectBoardId`
and `projectOwnerId`, then switch both actions to use `propDefinition` instead
of inline definitions. Keep the existing `status`/`phaseId` pattern consistent
and remove the duplicated label/description/options logic from the component
files.
---
Duplicate comments:
In `@components/pipedrive/actions/update-project/update-project.mjs`:
- Around line 40-52: The `boardId` and related project props in `updateProject`
are duplicated instead of being shared with `createProject`, so align them by
moving the inline `boardId` definition in `update-project.mjs` to a shared
`propDefinition` on `pipedriveApp` like the existing `projectPhaseId` usage.
Update `create-project.mjs` and `update-project.mjs` to reference the same
unique prop helpers for `ownerId`/`boardId` so both actions stay consistent and
only the action-specific fields remain inline.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 16e137e1-2565-4eea-9718-3fc5eb2c7935
📒 Files selected for processing (11)
components/pipedrive/actions/create-project/create-project.mjscomponents/pipedrive/actions/create-task/create-task.mjscomponents/pipedrive/actions/delete-project/delete-project.mjscomponents/pipedrive/actions/delete-task/delete-task.mjscomponents/pipedrive/actions/get-project/get-project.mjscomponents/pipedrive/actions/get-task/get-task.mjscomponents/pipedrive/actions/list-projects/list-projects.mjscomponents/pipedrive/actions/list-tasks/list-tasks.mjscomponents/pipedrive/actions/update-project/update-project.mjscomponents/pipedrive/actions/update-task/update-task.mjscomponents/pipedrive/pipedrive.app.mjs
…update-project * Add a new `projectBoardId` propDefinition on pipedriveApp; create-project and update-project now reference it via propDefinition and only override their descriptions. Matches the `projectStatus` / `projectPhaseId` pattern. * Point `ownerId` in both actions at the existing `userId` propDef instead of duplicating the inline `string` schema — inherits its integer type (correct per Pipedrive v2) and its searchable user picker. Matches how `assigneeId` in the task actions was resolved in the previous review pass.
Summary
Adds action coverage for Pipedrive Projects (Pipedrive's project-management add-on) so AI agents can work with projects, tasks, and their supporting boards/phases. Directly addresses the ask in #20984 from the Viktor-in-Slack user, whose agent couldn't reach Projects because no components existed for them.
Also expands read coverage on adjacent entities that agents constantly need to hop through when following project/task flows.
New actions
create-project,get-project,update-project,delete-project,list-projects,list-project-boards,list-project-phasescreate-task,get-task,update-task,delete-task,list-taskslist-persons,list-organizations,list-filtersApp-level changes
pipedrive.app.mjs(+82 lines): new methods wrapping the SDK's ProjectsApi and TasksApi.getPersons/getOrganizationswere already used by option pickers on this branch — the new list-* actions reuse them.Constants
Each new option list is pulled directly from Pipedrive's v1 and v2 OpenAPI specs so the enum values in the UI don't drift from what the API accepts:
PROJECT_STATUS_OPTIONSPERSON_SORT_BY_OPTIONS,PERSON_INCLUDE_FIELDS_OPTIONSORGANIZATION_SORT_BY_OPTIONS,ORGANIZATION_INCLUDE_FIELDS_OPTIONSFILTER_TYPE_OPTIONSOne thing not shipped
An earlier version of this branch also had four "instant" sources for new/updated projects and tasks. Removed before this PR opened — Pipedrive's Webhooks v1 API only accepts these
event_objectvalues:Neither
projectnortaskis in the enum, and I confirmed there's no v2 webhook mechanism for them either. Any source subscribing viapipedrive.addWebhook({ event_object: 'project' })would fail at deploy. If we want project/task triggers later, they'd need to be timer-based polling sources (/projects/{id}/changelogin v2 looks like the right feed for that), which is a separate design pass.Closes #20984
Test plan
filters, v2 forprojects/tasks/persons/organizations) — no invented params.🤖 Generated with Claude Code
Summary by CodeRabbit