[INFRA-395] feat: add Workflows and ProjectTemplates API resources#45
[INFRA-395] feat: add Workflows and ProjectTemplates API resources#45mguptahub wants to merge 2 commits into
Conversation
Adds project-level Workflows (with WorkflowStates and WorkflowTransitions sub-resources) and ProjectTemplates (WorkItem and Page templates) to the Node SDK, matching INFRA-395 parity with the Python SDK. - src/api/Workflows/ — list, create, update; states attach/detach; transitions list, create, update, del - src/api/ProjectTemplates/ — work item templates and page templates CRUD - src/models/Workflow.ts, ProjectTemplate.ts — TypeScript interfaces and DTOs - Registered on PlaneClient and exported from index - Unit tests for both resources - README API resources section updated Co-authored-by: Plane AI <noreply@plane.so>
📝 WalkthroughWalkthroughThis PR introduces two new API resource modules—Workflows and ProjectTemplates—to the Plane Node SDK. It defines TypeScript models for both resources, implements CRUD-style API clients with typed methods and sub-resources, integrates them into the PlaneClient, and adds comprehensive end-to-end tests and documentation updates. ChangesWorkflows and ProjectTemplates API Resources
🎯 3 (Moderate) | ⏱️ ~25 minutes
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Warning Review ran into problems🔥 ProblemsStopped waiting for pipeline failures after 30000ms. One of your pipelines takes longer than our 30000ms fetch window to run, so review may not consider pipeline-failure results for inline comments if any failures occurred after the fetch window. Increase the timeout if you want to wait longer or run a 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 |
|
Linked to Plane Work Item(s) This comment was auto-generated by Plane |
There was a problem hiding this comment.
Actionable comments posted: 5
🧹 Nitpick comments (1)
src/models/Workflow.ts (1)
1-1: 🏗️ Heavy liftRename this new module to kebab-case to match source file conventions.
src/models/Workflow.tsshould follow kebab-case naming forsrc/**/*.tsfiles to keep module naming consistent across new additions.As per coding guidelines
src/**/*.ts: Use kebab-case for file names.🤖 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 `@src/models/Workflow.ts` at line 1, Rename the module file src/models/Workflow.ts to kebab-case (e.g., src/models/workflow.ts) and update every import that references "Workflow" (for example imports like import { X } from "./models/Workflow" or "src/models/Workflow") to the new path "./models/workflow"; ensure any barrel/index exports or path mappings that re-export the module are updated as well so the exported symbols (the types/classes previously coming from Workflow.ts) continue to resolve.
🤖 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 `@src/api/Workflows/Transitions.ts`:
- Around line 41-43: In the create() error path inside Transitions.ts the code
uses JSON.stringify(error.response) which can throw for non-serializable
responses; instead, defensively extract a string to inspect for "already
exists": check typeof error.response === "string" and use it, else if
error.response?.message is a string use that, else fall back to error.message or
an empty string; call .toLowerCase() only after ensuring you have a string and
then test .includes("already exists"); keep the existing HttpError check and
return null when the duplicate is detected.
In `@src/models/ProjectTemplate.ts`:
- Around line 15-25: CreateWorkItemTemplate and UpdateWorkItemTemplate should be
derived from the WorkItemTemplate model instead of duplicating fields: replace
the explicit property lists by defining CreateWorkItemTemplate =
Pick<WorkItemTemplate, 'name' | 'short_description' | 'template_data'> and
UpdateWorkItemTemplate = Partial<CreateWorkItemTemplate> (or
Partial<Pick<WorkItemTemplate, ...>>) so updates are optional; do the same for
CreatePageTemplate/UpdatePageTemplate by deriving from PageTemplate using Pick
for create DTOs and Partial for update DTOs to keep DTOs in sync with model
changes.
In `@src/models/Workflow.ts`:
- Around line 16-28: The CreateWorkflow and UpdateWorkflow DTOs currently
duplicate slices of the core Workflow model; update them to derive from the
canonical Workflow interface using TypeScript utility types (e.g., export type
CreateWorkflow = Pick<Workflow, 'name' | 'description' | 'work_item_type_ids'> &
{ is_active?: boolean } or export type UpdateWorkflow = Partial<Pick<Workflow,
'name' | 'description' | 'work_item_type_ids' | 'is_active'>>), and apply the
same pattern to CreateWorkflowTransition/UpdateWorkflowTransition so changes to
Workflow/WorkflowTransition don't drift; locate the DTOs named CreateWorkflow
and UpdateWorkflow in this file and replace the standalone interfaces with
derived types using Pick/Partial/Required as appropriate.
In `@tests/unit/project-templates.test.ts`:
- Around line 82-84: The test is using expect(promise).resolves.not.toThrow(),
which is invalid because toThrow applies to functions; replace that assertion on
client.projectTemplates.workItems.del(workspaceSlug, projectId,
workItemTemplate.id!) with a promise-aware matcher such as await
expect(client.projectTemplates.workItems.del(...)).resolves.toBeUndefined() (or
.resolves.toBeDefined() if the API returns a value) to assert the delete
succeeded; make the same change for the identical patterns in
tests/unit/workflows/workflow.test.ts (the assertions around the delete calls at
the referenced locations).
In `@tests/unit/workflows/workflow.test.ts`:
- Around line 102-106: The tests use the invalid Jest matcher
`.resolves.not.toThrow()` for promise-returning calls; update the assertions to
check the resolved value instead (e.g., use `.resolves.toBeUndefined()` for
Promise<void>). Specifically change the assertions for
client.workflows.states.attach(...) (previously at the attach call),
client.workflows.transitions.del(...) (the delete transition call), and
client.workflows.states.detach(...) (the detach call) to assert the promise
resolves to undefined (or another expected resolved value) rather than using
toThrow.
---
Nitpick comments:
In `@src/models/Workflow.ts`:
- Line 1: Rename the module file src/models/Workflow.ts to kebab-case (e.g.,
src/models/workflow.ts) and update every import that references "Workflow" (for
example imports like import { X } from "./models/Workflow" or
"src/models/Workflow") to the new path "./models/workflow"; ensure any
barrel/index exports or path mappings that re-export the module are updated as
well so the exported symbols (the types/classes previously coming from
Workflow.ts) continue to resolve.
🪄 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: defaults
Review profile: CHILL
Plan: Pro
Run ID: 030224fd-dad9-4008-acf5-9407114a12df
📒 Files selected for processing (14)
README.mdsrc/api/ProjectTemplates/Pages.tssrc/api/ProjectTemplates/WorkItems.tssrc/api/ProjectTemplates/index.tssrc/api/Workflows/States.tssrc/api/Workflows/Transitions.tssrc/api/Workflows/index.tssrc/client/plane-client.tssrc/index.tssrc/models/ProjectTemplate.tssrc/models/Workflow.tssrc/models/index.tstests/unit/project-templates.test.tstests/unit/workflows/workflow.test.ts
- Transitions.ts: harden error.response parsing in create() — defensive type check instead of JSON.stringify to avoid throw on non-serializable payloads - Workflow.ts: derive CreateWorkflow/UpdateWorkflow and CreateWorkflowTransition/UpdateWorkflowTransition from model interfaces via Pick/Partial/Required instead of duplicating fields - ProjectTemplate.ts: same — derive Create/Update DTOs from WorkItemTemplate and PageTemplate via Pick/Partial - Tests: replace resolves.not.toThrow() with resolves.toBeUndefined() for Promise<void> assertions (workflow + project-templates) Co-authored-by: Plane AI <noreply@plane.so>
Summary
list,create,update— plusstatessub-resource (attach/detach) andtransitionssub-resource (list,create,update,del)workItems(work item templates CRUD) andpages(page templates CRUD)PlaneClientand exports all classes + types from the package indexWorkflow,WorkflowTransition,WorkItemTemplate,PageTemplateand their Create/Update DTOstests/unit/workflows/workflow.test.ts,tests/unit/project-templates.test.ts)Workflows,ProjectTemplates,Milestones, andAgentRunsNotes
WorkflowTransitions.createreturnsnull(instead of throwing) when the API responds 400 "already exists" — mirrors Python SDK behaviourTest plan
PLANE_API_KEY,PLANE_BASE_URL,TEST_WORKSPACE_SLUG,TEST_PROJECT_IDand runpnpm test tests/unit/workflows/andpnpm test tests/unit/project-templates.test.tspnpm check:lint— 0 errorspnpm check:format— all files correctly formattedpnpm build— compiles cleanlyCo-authored-by: Plane AI noreply@plane.so
Summary by CodeRabbit
New Features
Documentation