From 2d8b842290f926e744972185cb07dfc424f81143 Mon Sep 17 00:00:00 2001 From: Nikita Nemirovsky Date: Fri, 20 Feb 2026 14:32:35 +0700 Subject: [PATCH 1/2] fix: use recordings trash endpoint for comment delete --- cmd/comment/delete.go | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/cmd/comment/delete.go b/cmd/comment/delete.go index 24bb34a..d18ce26 100644 --- a/cmd/comment/delete.go +++ b/cmd/comment/delete.go @@ -88,9 +88,9 @@ func newDeleteCmd(f *factory.Factory) *cobra.Command { } } - // Delete the comment - path := fmt.Sprintf("/buckets/%s/comments/%d.json", projectID, commentID) - if err := client.Delete(path); err != nil { + // Trash the comment via Basecamp recordings API + path := fmt.Sprintf("/buckets/%s/recordings/%d/status/trashed.json", projectID, commentID) + if err := client.Put(path, nil, nil); err != nil { return fmt.Errorf("failed to delete comment: %w", err) } From 825c6c6543847c53898dce1b1101387f22294f5d Mon Sep 17 00:00:00 2001 From: Raymond Brigleb Date: Fri, 20 Feb 2026 19:16:58 -0800 Subject: [PATCH 2/2] refactor: extract TrashComment API method and update messaging - Add TrashComment method to CommentOperations interface for consistency with DeleteScheduleEntry pattern - Update user-facing text from "delete" to "trash" to accurately reflect the recoverable nature of Basecamp's trash operation Co-Authored-By: Claude Opus 4.6 --- cmd/comment/delete.go | 13 ++++++------- internal/api/comments.go | 11 +++++++++++ internal/api/modular.go | 1 + 3 files changed, 18 insertions(+), 7 deletions(-) diff --git a/cmd/comment/delete.go b/cmd/comment/delete.go index d18ce26..e882cab 100644 --- a/cmd/comment/delete.go +++ b/cmd/comment/delete.go @@ -20,7 +20,7 @@ func newDeleteCmd(f *factory.Factory) *cobra.Command { cmd := &cobra.Command{ Use: "delete ", Short: "Delete a comment", - Long: `Delete a comment. This operation cannot be undone.`, + Long: `Trash a comment on a recording. Trashed comments can be recovered from the Basecamp trash.`, Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { // Apply overrides if specified @@ -73,9 +73,9 @@ func newDeleteCmd(f *factory.Factory) *cobra.Command { if !skipConfirm { var confirm bool if err := huh.NewConfirm(). - Title(fmt.Sprintf("Delete comment #%d?", commentID)). + Title(fmt.Sprintf("Trash comment #%d?", commentID)). Description(fmt.Sprintf("By %s on %s", comment.Creator.Name, comment.CreatedAt.Format("Jan 2, 2006"))). - Affirmative("Delete"). + Affirmative("Trash"). Negative("Cancel"). Value(&confirm). Run(); err != nil { @@ -89,14 +89,13 @@ func newDeleteCmd(f *factory.Factory) *cobra.Command { } // Trash the comment via Basecamp recordings API - path := fmt.Sprintf("/buckets/%s/recordings/%d/status/trashed.json", projectID, commentID) - if err := client.Put(path, nil, nil); err != nil { - return fmt.Errorf("failed to delete comment: %w", err) + if err := client.TrashComment(f.Context(), projectID, commentID); err != nil { + return err } // Output if ui.IsTerminal(os.Stdout) { - fmt.Printf("✓ Deleted comment #%d\n", commentID) + fmt.Printf("✓ Trashed comment #%d\n", commentID) } return nil diff --git a/internal/api/comments.go b/internal/api/comments.go index 86541ba..57f89c0 100644 --- a/internal/api/comments.go +++ b/internal/api/comments.go @@ -82,3 +82,14 @@ func (c *Client) UpdateComment(ctx context.Context, projectID string, commentID return &comment, nil } + +// TrashComment trashes a comment via the recordings status endpoint +func (c *Client) TrashComment(ctx context.Context, projectID string, commentID int64) error { + path := fmt.Sprintf("/buckets/%s/recordings/%d/status/trashed.json", projectID, commentID) + + if err := c.Put(path, nil, nil); err != nil { + return fmt.Errorf("failed to trash comment: %w", err) + } + + return nil +} diff --git a/internal/api/modular.go b/internal/api/modular.go index 623729e..b72dd10 100644 --- a/internal/api/modular.go +++ b/internal/api/modular.go @@ -106,6 +106,7 @@ type CommentOperations interface { GetComment(ctx context.Context, projectID string, commentID int64) (*Comment, error) CreateComment(ctx context.Context, projectID string, recordingID int64, req CommentCreateRequest) (*Comment, error) UpdateComment(ctx context.Context, projectID string, commentID int64, req CommentUpdateRequest) (*Comment, error) + TrashComment(ctx context.Context, projectID string, commentID int64) error } // ActivityOperations defines activity-specific operations