main
rb 21 lines 1004 Bytes
Raw
1 # frozen_string_literal: true
2
3 # Posts comments on issues or pull requests. Routing all comment creation through
4 # here keeps authorization and validation consistent across callers.
5 class CommentService
6 class Error < StandardError; end
7 class NotFound < Error; end
8
9 # Posts a comment authored by +author+ on the issue or pull request numbered
10 # +number+ in +repository+. Issues and PRs share a number space, so the number
11 # resolves to exactly one. Raises NotFound when nothing matches and
12 # ActiveRecord::RecordInvalid on validation failure. Read access to the repo is
13 # enforced by the caller (the MCP layer only resolves repos the user can read).
14 def self.create(repository:, author:, number:, body:)
15 target = repository.issues.find_by(number: number) ||
16 repository.pull_requests.find_by(number: number)
17 raise NotFound, "No issue or pull request ##{number} in #{repository.full_name}." unless target
18
19 target.comments.create!(user: author, body: body)
20 end
21 end