RejectPending transitions a pending_review message to rejected, records the reviewer's reason (empty string allowed), and scrubs body_text / body_html / attachments_json. Ownership checked; missing rows return ErrMessageNotFound. Non-pending rows return ErrNotPendingApproval.
(ctx context.Context, messageID, userID, reason string)
| 2267 | // body_text / body_html / attachments_json. Ownership checked; missing |
| 2268 | // rows return ErrMessageNotFound. Non-pending rows return ErrNotPendingApproval. |
| 2269 | func (s *Store) RejectPending(ctx context.Context, messageID, userID, reason string) (*Message, error) { |
| 2270 | // Single atomic UPDATE with status guard. We distinguish "not found" from |
| 2271 | // "not pending" with a follow-up existence check only when rows-affected |
| 2272 | // is 0. |
| 2273 | tag, err := s.pool.Exec(ctx, |
| 2274 | `UPDATE messages |
| 2275 | SET status = $3, |
| 2276 | rejection_reason = $4, |
| 2277 | reviewed_at = now(), |
| 2278 | reviewed_by_user_id = $2, |
| 2279 | body_text = NULL, |
| 2280 | body_html = NULL, |
| 2281 | attachments_json = NULL |
| 2282 | WHERE id = $1 |
| 2283 | AND status = 'pending_review' |
| 2284 | AND direction = 'outbound' |
| 2285 | AND agent_id IN (SELECT id FROM agent_identities WHERE user_id = $2)`, |
| 2286 | messageID, userID, MessageStatusReviewRejected, reason, |
| 2287 | ) |
| 2288 | if err != nil { |
| 2289 | return nil, err |
| 2290 | } |
| 2291 | if tag.RowsAffected() == 0 { |
| 2292 | // Figure out why: missing, not owned, or not pending. |
| 2293 | var status string |
| 2294 | err := s.pool.QueryRow(ctx, |
| 2295 | `SELECT m.status |
| 2296 | FROM messages m |
| 2297 | JOIN agent_identities a ON a.id = m.agent_id |
| 2298 | WHERE m.id = $1 AND a.user_id = $2`, |
| 2299 | messageID, userID, |
| 2300 | ).Scan(&status) |
| 2301 | if err != nil { |
| 2302 | return nil, ErrMessageNotFound |
| 2303 | } |
| 2304 | return nil, ErrNotPendingApproval |
| 2305 | } |
| 2306 | return s.GetOutboundMessageForUser(ctx, messageID, userID) |
| 2307 | } |
| 2308 | |
| 2309 | func (s *Store) ListActivityByAgent(ctx context.Context, agentID string, limit int) ([]Message, error) { |
| 2310 | rows, err := s.pool.Query(ctx, |