feat: phase 4 collaboration features (comments, followers, tags)#30
Conversation
The create/list error handlers referenced a workspace variable scoped inside the try block, so any API failure crashed with ReferenceError instead of printing the formatted error.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Code Review
This pull request implements collaboration features (Phase 4) for the Asana CLI, introducing commands and subcommands to manage task comments, followers, and tags, along with corresponding API client integrations, input validators, documentation, and E2E/unit tests. The code review identified three key areas for improvement: correcting a potential runtime error in the Asana client where a singular method name (removeFollowerForTask) was used instead of the plural form, throwing a ValidationError instead of directly calling process.exit(1) when updating a tag with no fields specified, and resolving a case-sensitivity issue when validating the HTML <body> tag in comments.
| removeFollowers: async (taskGid: string, followers: string[]) => { | ||
| const body = { data: { followers } } | ||
| const result = await tasksApiInstance!.removeFollowerForTask(body, taskGid, {}) | ||
| return result.data | ||
| }, |
There was a problem hiding this comment.
[HIGH] removeFollowers 메서드의 API 호출 함수명 오류 가능성
Problem: removeFollowers 메서드에서 tasksApiInstance!.removeFollowerForTask를 호출하고 있습니다. Asana API의 엔드포인트가 /tasks/{task_gid}/removeFollowers이고 addFollowers가 addFollowersForTask를 사용하는 점으로 미루어 볼 때, 올바른 메서드명은 복수형인 removeFollowersForTask일 가능성이 높습니다. 단수형을 사용할 경우 런타임에 함수가 존재하지 않아 에러가 발생할 수 있습니다.
Rationale: Asana 노드 라이브러리의 자동 생성된 메서드명은 OpenAPI 스펙의 operationId를 따르므로 복수형(removeFollowersForTask)이 올바릅니다.
Suggestion: removeFollowerForTask를 removeFollowersForTask로 변경하여 런타임 오류를 방지합니다.
| removeFollowers: async (taskGid: string, followers: string[]) => { | |
| const body = { data: { followers } } | |
| const result = await tasksApiInstance!.removeFollowerForTask(body, taskGid, {}) | |
| return result.data | |
| }, | |
| removeFollowers: async (taskGid: string, followers: string[]) => { | |
| const body = { data: { followers } } | |
| const result = await tasksApiInstance!.removeFollowersForTask(body, taskGid, {}) | |
| return result.data | |
| }, |
References
- 런타임 오류를 방지하기 위해 외부 라이브러리 API 호출 시 올바른 메서드명을 사용해야 합니다. (link)
There was a problem hiding this comment.
[claude] ⏭️ 적용하지 않았습니다 — 제안과 달리 asana SDK v3.1.2에는 removeFollowersForTask가 존재하지 않습니다. 패키지를 직접 확인한 결과 생성된 메서드명은 단수형 removeFollowerForTask뿐이며(node_modules/asana/dist/api/TasksApi.js:1314), 이 메서드가 내부적으로 POST /tasks/{task_gid}/removeFollowers 엔드포인트를 호출합니다. 제안대로 복수형으로 변경하면 오히려 런타임에 함수가 존재하지 않아 에러가 발생합니다. 현재 코드가 올바릅니다. @gemini-code-assist
There was a problem hiding this comment.
확인해주셔서 감사합니다. 말씀하신 대로 Asana SDK의 자동 생성된 메서드명은 OpenAPI 스펙의 operationId를 따르며, 해당 버전에서 removeFollowerForTask가 올바른 메서드명임을 확인했습니다. 런타임 오류를 방지하기 위해 현재 코드를 유지하는 것이 맞습니다. 상세한 확인과 피드백 감사합니다.
…aboration-features # Conflicts: # src/commands/task.ts # src/constants/errorIds.ts # src/index.ts # src/lib/asana-client.ts # test/commands/task-update-validation.test.ts
- tag update: throw ValidationError instead of calling process.exit directly - task comment: case-insensitive <body> detection in ensureHtmlBody
…aboration-features # Conflicts: # src/types/index.ts
Summary
Implements Phase 4 collaboration features: task comments (Stories API), follower management, and tag CRUD with task assignment.
Closes #17
Changes
Comments (
task comment)task comment add <task-gid> <text>— add a comment;--htmlflag sends Asana rich text (auto-wrapped in<body>)task comment list <task-gid>— lists user comments only (system stories filtered byresource_subtype)Followers (
task follower)task follower add|remove <task-gid> <user>— accepts numeric GID, email, ormetask follower list <task-gid>— via taskfollowersopt_fields (Asana has no standalone endpoint)Tags (
tag,task tag)tag list|create|get|update|delete— full CRUD; workspace falls back to the configured defaulttask tag add|remove|list— tag assignment per taskredare rejected by the API; the CLI fails fast with the valid color list)Client
asana-client: newstoriesandtagswrappers plus follower/tag operations ontasks(usesStoriesApi,TagsApi,addFollowersForTask/removeFollowerForTask,addTagForTask/removeTagForTask)Bug fix
task/projectcreate & list error handlers referenced aworkspacevariable scoped insidetry, crashing withReferenceErroron any API failure. Hoisted the declaration so errors are reported properly.Testing
bun test test/) — command structure tests for comment/follower/tag, validator tests for user identifier and tag colortests/e2e/collaboration.test.tscovers comment add/list (plain + rich text), follower add/list/remove, tag CRUD, multi-task tag assignment. Not run locally — the.envPAT returns 401 (expired); pre-existing e2e suites fail the same wayNotes
feat:commits will generate it--color "red"is not accepted by the Asana API — only thedark-*/light-*palette is valid; the CLI validates and lists valid colors