MCPcopy Create free account
hub / github.com/PerpetualSoftware/pad / handleCreateComment

Method handleCreateComment

internal/server/handlers_comments.go:65–133  ·  view source on GitHub ↗

handleCreateComment adds a new comment to an item.

(w http.ResponseWriter, r *http.Request)

Source from the content-addressed store, hash-verified

63
64// handleCreateComment adds a new comment to an item.
65func (s *Server) handleCreateComment(w http.ResponseWriter, r *http.Request) {
66 workspaceID, ok := s.getWorkspaceID(w, r)
67 if !ok {
68 return
69 }
70
71 itemSlug := chi.URLParam(r, "itemSlug")
72 item, err := s.store.ResolveItem(workspaceID, itemSlug)
73 if err != nil {
74 writeInternalError(w, err)
75 return
76 }
77 if item == nil {
78 s.writeItemResolveError(w, r, workspaceID, itemSlug)
79 return
80 }
81 if !s.requireItemVisible(w, r, workspaceID, item) {
82 return
83 }
84 // Check edit permission (grant-aware for guests)
85 if !s.requireEditPermission(w, r, workspaceID, item.ID, item.CollectionID) {
86 return
87 }
88
89 var input models.CommentCreate
90 if err := decodeJSON(r, &input); err != nil {
91 writeError(w, http.StatusBadRequest, "bad_request", err.Error())
92 return
93 }
94
95 if input.Body == "" {
96 writeError(w, http.StatusBadRequest, "bad_request", "body is required")
97 return
98 }
99
100 // Set author from authenticated user if available
101 if u := currentUser(r); u != nil && input.Author == "" {
102 input.Author = u.Name
103 }
104
105 // Derive actor/source from auth context
106 actor, source := actorFromRequest(r)
107 if input.CreatedBy == "" {
108 input.CreatedBy = actor
109 }
110 if input.Source == "" {
111 input.Source = source
112 }
113
114 // Log activity first so we can link the comment to the activity record.
115 // This prevents duplicate timeline entries (one for the comment, one for the activity).
116 // Only set ActivityID on success — comments.activity_id has a FK constraint,
117 // and CreateActivity returns an ID even on insert failure.
118 if activityID, err := s.logActivityWithMetaReturningID(workspaceID, item.ID, "commented", r, ""); err == nil && activityID != "" {
119 input.ActivityID = activityID
120 }
121
122 comment, err := s.store.CreateComment(workspaceID, item.ID, currentUserID(r), input)

Callers

nothing calls this directly

Calls 15

getWorkspaceIDMethod · 0.95
writeItemResolveErrorMethod · 0.95
requireItemVisibleMethod · 0.95
requireEditPermissionMethod · 0.95
publishCommentEventMethod · 0.95
dispatchWebhookMethod · 0.95
writeInternalErrorFunction · 0.85
decodeJSONFunction · 0.85
writeErrorFunction · 0.85
currentUserFunction · 0.85
actorFromRequestFunction · 0.85

Tested by

no test coverage detected