@@ -121,6 +121,88 @@ defmodule Algora.Bounties do
121
121
|> Oban . insert ( )
122
122
end
123
123
124
+ @ spec do_claim_bounty ( % { user: User . t ( ) , ticket: Ticket . t ( ) , pull_request: map ( ) } ) ::
125
+ { :ok , Claim . t ( ) } | { :error , atom ( ) }
126
+ defp do_claim_bounty ( % { user: user , ticket: ticket , pull_request: pull_request } ) do
127
+ # TODO: ensure user is pull request author
128
+ id = Nanoid . generate ( )
129
+
130
+ changeset =
131
+ Claim . changeset ( % Claim { } , % {
132
+ ticket_id: ticket . id ,
133
+ user_id: user . id ,
134
+ provider: "github" ,
135
+ provider_id: pull_request [ "id" ] ,
136
+ provider_meta: pull_request ,
137
+ title: pull_request [ "title" ] ,
138
+ url: pull_request [ "html_url" ] ,
139
+ group_id: id ,
140
+ merged_at: Util . to_date ( pull_request [ "merged_at" ] )
141
+ } )
142
+
143
+ case Repo . insert ( changeset ) do
144
+ { :ok , claim } ->
145
+ { :ok , claim }
146
+
147
+ { :error , % { errors: [ ticket_id: { _ , [ constraint: :unique , constraint_name: _ ] } ] } } ->
148
+ { :error , :already_exists }
149
+
150
+ { :error , _changeset } ->
151
+ { :error , :internal_server_error }
152
+ end
153
+ end
154
+
155
+ @ spec claim_bounty (
156
+ % {
157
+ user: User . t ( ) ,
158
+ ticket_ref: % { owner: String . t ( ) , repo: String . t ( ) , number: integer ( ) } ,
159
+ pull_request: map ( )
160
+ } ,
161
+ opts :: [ installation_id: integer ( ) ]
162
+ ) ::
163
+ { :ok , Bounty . t ( ) } | { :error , atom ( ) }
164
+ def claim_bounty (
165
+ % {
166
+ user: user ,
167
+ ticket_ref: % { owner: repo_owner , repo: repo_name , number: number } = ticket_ref ,
168
+ pull_request: pull_request
169
+ } ,
170
+ opts \\ [ ]
171
+ ) do
172
+ installation_id = opts [ :installation_id ]
173
+
174
+ token_res =
175
+ if installation_id ,
176
+ do: Github . get_installation_token ( installation_id ) ,
177
+ else: Accounts . get_access_token ( user )
178
+
179
+ Repo . transact ( fn ->
180
+ with { :ok , token } <- token_res ,
181
+ { :ok , ticket } <- Workspace . ensure_ticket ( token , repo_owner , repo_name , number ) ,
182
+ { :ok , claim } <- do_claim_bounty ( % { user: user , ticket: ticket , pull_request: pull_request } ) ,
183
+ { :ok , _job } <- notify_claim ( % { ticket_ref: ticket_ref } , installation_id: installation_id ) do
184
+ broadcast ( )
185
+ { :ok , claim }
186
+ else
187
+ { :error , _reason } = error -> error
188
+ end
189
+ end )
190
+ end
191
+
192
+ @ spec notify_claim (
193
+ % { ticket_ref: % { owner: String . t ( ) , repo: String . t ( ) , number: integer ( ) } } ,
194
+ opts :: [ installation_id: integer ( ) ]
195
+ ) ::
196
+ { :ok , Oban.Job . t ( ) } | { :error , atom ( ) }
197
+ def notify_claim ( % { ticket_ref: ticket_ref } , opts \\ [ ] ) do
198
+ % {
199
+ ticket_ref: % { owner: ticket_ref . owner , repo: ticket_ref . repo , number: ticket_ref . number } ,
200
+ installation_id: opts [ :installation_id ]
201
+ }
202
+ |> Jobs.NotifyClaim . new ( )
203
+ |> Oban . insert ( )
204
+ end
205
+
124
206
@ spec create_tip_intent (
125
207
% {
126
208
recipient: String . t ( ) ,
0 commit comments