fix auction to work as described
This commit is contained in:
parent
cd3125954e
commit
87e4376c10
36
prisma/migrations/20220301201244_auction_fix/migration.sql
Normal file
36
prisma/migrations/20220301201244_auction_fix/migration.sql
Normal file
@ -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 }) {
|
function auction ({ models }) {
|
||||||
return async function ({ name }) {
|
return async function ({ name }) {
|
||||||
console.log('running', 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(
|
const items = await models.item.findMany(
|
||||||
{
|
{
|
||||||
where: {
|
where: {
|
||||||
@ -13,15 +18,33 @@ function auction ({ models }) {
|
|||||||
status: {
|
status: {
|
||||||
not: 'STOPPED'
|
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
|
// for each item, run serialized auction function
|
||||||
items.forEach(async item => {
|
for (const item of items) {
|
||||||
await serialize(models,
|
let bid = lastBid
|
||||||
models.$executeRaw`SELECT run_auction(${item.id})`)
|
// 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)
|
console.log('done', name)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user