invites_repo.rb

 1# frozen_string_literal: true
 2
 3class InvitesRepo
 4	class Invalid < StandardError; end
 5
 6	def initialize(db=DB)
 7		@db = db
 8	end
 9
10	def unused_invites(customer_id)
11		promise = @db.query_defer(<<~SQL, [customer_id])
12			SELECT code FROM unused_invites WHERE creator_id=$1
13		SQL
14		promise.then { |result| result.map { |row| row["code"] } }
15	end
16
17	def claim_code(customer_id, code, &blk)
18		EMPromise.resolve(nil).then do
19			@db.transaction do
20				valid = @db.exec(<<~SQL, [customer_id, code]).cmd_tuples.positive?
21					UPDATE invites SET used_by_id=$1, used_at=LOCALTIMESTAMP
22					WHERE code=$2 AND used_by_id IS NULL
23				SQL
24				raise Invalid, "Not a valid invite code: #{code}" unless valid
25
26				blk.call
27			end
28		end
29	end
30end