feat(comments): edit your own comments#149
Conversation
- Add updatedAt column to comments table (migration 0047) - Surface isEdited flag through the full data pipeline to clients - Inline edit form in comment thread: textarea, Save/Cancel, Escape/Cmd+Enter - (edited) marker shown in comment header after any edit - REST PATCH and MCP update_comment now use userEditComment (writes history)
Cover: edit button visibility, form open/close, Cancel, Escape, Save, Cmd+Enter, disabled Save on empty content, unauth not shown.
- Wrap history insert + comment update in a db.transaction so a failed update doesn't leave a dangling history record - Use comment.content.length in the focus effect (correct dep array) - Change onKeyDown to else-if so branches are mutually exclusive - Tighten e2e waitForFunction to wait for this comment's specific ID to resolve, and replace non-null assertion with an explicit throw
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: c3098f4a4c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const result = await userEditComment(commentId, parsed.data.content, { | ||
| principalId, | ||
| role: (principalRecord?.role as 'admin' | 'member' | 'user') ?? 'user', | ||
| }) |
There was a problem hiding this comment.
Restore comment.updated dispatch for REST edits
Switching PATCH /api/v1/comments/:commentId to userEditComment here bypasses the only path that emits dispatchCommentUpdated (updateComment in comment.service.ts), so comment edits through this API no longer generate comment.updated webhook/integration events. Any automation that depends on update events will silently stop firing for REST-driven edits unless event dispatch is added to the new edit path.
Useful? React with 👍 / 👎.
| parentId: c.parentId as CommentId | null, | ||
| isTeamMember: c.isTeamMember, | ||
| isPrivate: c.isPrivate, | ||
| isEdited: false, |
There was a problem hiding this comment.
Derive isEdited from updatedAt in admin comment mapping
Hardcoding isEdited: false discards edit state even though PostDetails.comments carries timestamp data, so edited comments rendered through this adapter never show the (edited) marker in admin comment threads. This makes admin views inconsistent with portal behavior and hides whether a comment was modified; compute this flag from c.updatedAt instead of a constant.
Useful? React with 👍 / 👎.
…ler test The MCP update_comment tool now calls userEditComment from comment.permissions instead of updateComment from comment.service; update the test mock to match.
- Add dispatchCommentUpdated to userEditComment so REST PATCH and MCP edits emit the comment.updated webhook/integration event - Fix isEdited: false hardcoded in admin comment mappers (post-utils, roadmap-modal, merge-preview-modal) to use !!c.updatedAt
…s code - roadmap-modal: replace inline comment mapping with toPortalComments(), fixing missing statusChange on replies and removing duplicate logic - comment.permissions: remove "what" comment, inline post/board access in dispatchCommentUpdated call
- comment-edit.test.ts: 15 tests covering canEditComment (author allowed, team member allowed, non-author denied, deleted denied, not found, team-reply blocked) and userEditComment (success, transaction atomicity, event dispatch, forbidden, validation, length limit, concurrent deletion) - \$commentId.test.ts: 13 tests covering PATCH 200/400/401/403/404 cases, GET 200/404, and DELETE 204/403
Client code must only import from lib/server/functions/ — no other lib/server/ paths are permitted in client bundles. This prevents node:crypto, ioredis, bullmq, and other server-only modules from leaking into the browser bundle (root cause: PR #149 introduced a static import chain to crypto.createHmac via dispatch.ts). - Convert static imports to dynamic await import() inside handler bodies in functions/widget, settings, api-keys, subscriptions, integrations, and dispatch.ts - Add lib/shared/integration-catalog.ts, storage-config.ts, webhook-events.ts, integration-types.ts, auth-providers.ts, help-center-tree.ts and lib/client/auth-client.ts as client-safe re-export bridges - Add lib/shared/types/ domain type files (posts, users, settings, boards, roadmaps, webhooks, api-keys, subscriptions, principals, activity, notifications, import) - Redirect ~115 component/route/hook imports from lib/server/ to the appropriate lib/shared/ or lib/client/ bridge - Add bullmq, ioredis, openai to Vite importProtection specifiers
Summary
Test plan
Comment editingdescribe block incomments.spec.ts)