fix auction to work as described
This commit is contained in:
parent
cd3125954e
commit
87e4376c10
|
@ -0,0 +1,36 @@
|
|||
-- take a bid and return whether they have enough funds to support it
|
||||
CREATE OR REPLACE FUNCTION run_auction(item_id INTEGER, bid INTEGER) RETURNS BOOLEAN AS $$
|
||||
DECLARE
|
||||
bpm_msats INTEGER;
|
||||
user_id INTEGER;
|
||||
user_msats INTEGER;
|
||||
item_status "Status";
|
||||
BEGIN
|
||||
PERFORM ASSERT_SERIALIZED();
|
||||
|
||||
bpm_msats := (bid * 5) / 216;
|
||||
|
||||
-- extract data we need
|
||||
SELECT "userId", status INTO user_id, item_status FROM "Item" WHERE id = item_id;
|
||||
SELECT msats INTO user_msats FROM users WHERE id = user_id;
|
||||
|
||||
-- check if user wallet has enough sats
|
||||
IF bpm_msats > user_msats THEN
|
||||
-- if not, set status = NOSATS and statusUpdatedAt to now_utc if not already set
|
||||
IF item_status <> 'NOSATS' THEN
|
||||
UPDATE "Item" SET status = 'NOSATS', "statusUpdatedAt" = now_utc() WHERE id = item_id;
|
||||
END IF;
|
||||
|
||||
RETURN false;
|
||||
ELSE
|
||||
-- if so, deduct from user
|
||||
UPDATE users SET msats = msats - bpm_msats WHERE id = user_id;
|
||||
-- update item status = ACTIVE and statusUpdatedAt = null if NOSATS
|
||||
IF item_status = 'NOSATS' THEN
|
||||
UPDATE "Item" SET status = 'ACTIVE', "statusUpdatedAt" = now_utc() WHERE id = item_id;
|
||||
END IF;
|
||||
|
||||
RETURN true;
|
||||
END IF;
|
||||
END;
|
||||
$$ LANGUAGE plpgsql;
|
|
@ -3,7 +3,12 @@ const serialize = require('../api/resolvers/serial')
|
|||
function auction ({ models }) {
|
||||
return async function ({ name }) {
|
||||
console.log('running', name)
|
||||
// get all items we need to check
|
||||
// TODO: do this for each sub with auction ranking
|
||||
// because we only have one auction sub, we don't need to do this
|
||||
const SUB_BASE_COST = 10000
|
||||
const BID_DELTA = 1000
|
||||
|
||||
// get all items we need to check in order of low to high bid
|
||||
const items = await models.item.findMany(
|
||||
{
|
||||
where: {
|
||||
|
@ -13,15 +18,33 @@ function auction ({ models }) {
|
|||
status: {
|
||||
not: 'STOPPED'
|
||||
}
|
||||
},
|
||||
orderBy: {
|
||||
maxBid: 'asc'
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
// we subtract bid delta so that the lowest bidder, pays
|
||||
// the sub base cost
|
||||
let lastBid = SUB_BASE_COST - BID_DELTA
|
||||
// for each item, run serialized auction function
|
||||
items.forEach(async item => {
|
||||
await serialize(models,
|
||||
models.$executeRaw`SELECT run_auction(${item.id})`)
|
||||
})
|
||||
for (const item of items) {
|
||||
let bid = lastBid
|
||||
// if this item's maxBid is great enough, have them pay more
|
||||
// else have them match the last bid
|
||||
if (item.maxBid >= lastBid + BID_DELTA) {
|
||||
bid = lastBid + BID_DELTA
|
||||
}
|
||||
|
||||
const [{ run_auction: succeeded }] = await serialize(models,
|
||||
models.$queryRaw`SELECT run_auction(${item.id}, ${bid})`)
|
||||
|
||||
// if we succeeded update the lastBid
|
||||
if (succeeded) {
|
||||
lastBid = bid
|
||||
}
|
||||
}
|
||||
|
||||
console.log('done', name)
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue