approveHeld is the shared approve dispatch (used by the agent-path messages/{id}/approve and the account-path /reviews/{id}/approve). The caller MUST have proven account scope + ownership of agentEmail. Branches on direction: inbound holds release to the inbox; outbound holds send via SES (with send
(ctx context.Context, userID, msgID, agentEmail string, body agent.ApproveOverrides, idemKey string, rawBody []byte)
| 108 | // direction: inbound holds release to the inbox; outbound holds send via SES |
| 109 | // (with send-limit + idempotency). |
| 110 | func (s *Server) approveHeld(ctx context.Context, userID, msgID, agentEmail string, body agent.ApproveOverrides, idemKey string, rawBody []byte) (SendResultView, error) { |
| 111 | meta, inbound, err := s.resolveHeldDirection(ctx, msgID, agentEmail) |
| 112 | if err != nil { |
| 113 | return SendResultView{}, err |
| 114 | } |
| 115 | if inbound { |
| 116 | if s.deps.ApproveInboundReview == nil { |
| 117 | return SendResultView{}, NewError(http.StatusInternalServerError, "internal_error", "approve unavailable") |
| 118 | } |
| 119 | if derr := s.deps.ApproveInboundReview(ctx, userID, meta); derr != nil { |
| 120 | return SendResultView{}, NewError(derr.Status, derr.Code, derr.Msg) |
| 121 | } |
| 122 | return SendResultView{Status: identity.MessageStatusReviewApproved, MessageID: meta.ID}, nil |
| 123 | } |
| 124 | if env := s.checkSendLimit(agentEmail); env != nil { |
| 125 | return SendResultView{}, env |
| 126 | } |
| 127 | if s.deps.ApprovePending == nil { |
| 128 | return SendResultView{}, NewError(http.StatusInternalServerError, "internal_error", "approve unavailable") |
| 129 | } |
| 130 | _, view, err := runIdempotent(s, ctx, userID, idemKey, "/v1/approve/"+msgID, rawBody, func() (int, SendResultView, error) { |
| 131 | sent, derr := s.deps.ApprovePending(ctx, userID, msgID, agentEmail, body) |
| 132 | if derr != nil { |
| 133 | return 0, SendResultView{}, NewError(derr.Status, derr.Code, derr.Msg) |
| 134 | } |
| 135 | edited := sent.Edited |
| 136 | return http.StatusOK, SendResultView{ |
| 137 | Status: "sent", MessageID: sent.ID, ProviderMessageID: sent.ProviderMessageID, |
| 138 | SentAs: sent.SentAs, Method: sent.Method, Edited: &edited, |
| 139 | }, nil |
| 140 | }) |
| 141 | if err != nil { |
| 142 | return SendResultView{}, err |
| 143 | } |
| 144 | return view, nil |
| 145 | } |
| 146 | |
| 147 | func (s *Server) handleReject(ctx context.Context, in *rejectInput) (*rejectOutput, error) { |
| 148 | // Account-owner action — see handleApprove. Rejecting (discarding) a held |
no test coverage detected