remove extra migrations, refine jobs
This commit is contained in:
parent
3fb7ab9cd7
commit
022c72b95b
|
@ -78,7 +78,7 @@ export default {
|
||||||
let items; let user; let pins; let subFull
|
let items; let user; let pins; let subFull
|
||||||
|
|
||||||
const subClause = (num) => {
|
const subClause = (num) => {
|
||||||
return sub ? ` AND "subName" = $${num} ` : ` AND ("subName" IS NULL OR "subName" = $${3}) `
|
return sub ? ` AND "subName" = $${num} ` : ` AND ("subName" IS NULL OR "subName" = $${num}) `
|
||||||
}
|
}
|
||||||
|
|
||||||
const activeOrMine = () => {
|
const activeOrMine = () => {
|
||||||
|
@ -165,9 +165,10 @@ export default {
|
||||||
${timedLeftJoinWeightedSats(1)}
|
${timedLeftJoinWeightedSats(1)}
|
||||||
WHERE "parentId" IS NULL AND created_at <= $1 AND created_at > $3
|
WHERE "parentId" IS NULL AND created_at <= $1 AND created_at > $3
|
||||||
AND "pinId" IS NULL
|
AND "pinId" IS NULL
|
||||||
|
${subClause(4)}
|
||||||
${timedOrderBySats(1)}
|
${timedOrderBySats(1)}
|
||||||
OFFSET $2
|
OFFSET $2
|
||||||
LIMIT ${LIMIT}`, decodedCursor.time, decodedCursor.offset, new Date(new Date() - 7))
|
LIMIT ${LIMIT}`, decodedCursor.time, decodedCursor.offset, new Date(new Date() - 7), sub || 'NULL')
|
||||||
}
|
}
|
||||||
|
|
||||||
if (decodedCursor.offset !== 0 || items?.length < LIMIT) {
|
if (decodedCursor.offset !== 0 || items?.length < LIMIT) {
|
||||||
|
@ -177,9 +178,10 @@ export default {
|
||||||
${timedLeftJoinWeightedSats(1)}
|
${timedLeftJoinWeightedSats(1)}
|
||||||
WHERE "parentId" IS NULL AND created_at <= $1
|
WHERE "parentId" IS NULL AND created_at <= $1
|
||||||
AND "pinId" IS NULL
|
AND "pinId" IS NULL
|
||||||
|
${subClause(3)}
|
||||||
${timedOrderBySats(1)}
|
${timedOrderBySats(1)}
|
||||||
OFFSET $2
|
OFFSET $2
|
||||||
LIMIT ${LIMIT}`, decodedCursor.time, decodedCursor.offset)
|
LIMIT ${LIMIT}`, decodedCursor.time, decodedCursor.offset, sub || 'NULL')
|
||||||
}
|
}
|
||||||
|
|
||||||
if (decodedCursor.offset === 0) {
|
if (decodedCursor.offset === 0) {
|
||||||
|
@ -532,8 +534,9 @@ export default {
|
||||||
|
|
||||||
const checkSats = async () => {
|
const checkSats = async () => {
|
||||||
// check if the user has the funds to run for the first minute
|
// check if the user has the funds to run for the first minute
|
||||||
const minuteMsats = maxBid / 1296
|
const minuteMsats = maxBid * 5 / 216
|
||||||
const user = models.user.findUnique({ where: { id: me.id } })
|
const user = await models.user.findUnique({ where: { id: me.id } })
|
||||||
|
console.log(user, user.msats, minuteMsats)
|
||||||
if (user.msats < minuteMsats) {
|
if (user.msats < minuteMsats) {
|
||||||
throw new UserInputError('insufficient funds')
|
throw new UserInputError('insufficient funds')
|
||||||
}
|
}
|
||||||
|
|
|
@ -104,6 +104,14 @@ export default {
|
||||||
WHERE "Invite"."userId" = $1
|
WHERE "Invite"."userId" = $1
|
||||||
AND users.created_at <= $2
|
AND users.created_at <= $2
|
||||||
GROUP BY "Invite".id)
|
GROUP BY "Invite".id)
|
||||||
|
UNION ALL
|
||||||
|
(SELECT "Item".id::text, "Item"."statusUpdatedAt" AS "sortTime", NULL as "earnedSats",
|
||||||
|
'JobChanged' AS type
|
||||||
|
FROM "Item"
|
||||||
|
WHERE "Item"."userId" = $1
|
||||||
|
AND "maxBid" IS NOT NULL
|
||||||
|
AND status <> 'STOPPED'
|
||||||
|
AND "statusUpdatedAt" <= $2)
|
||||||
ORDER BY "sortTime" DESC
|
ORDER BY "sortTime" DESC
|
||||||
OFFSET $3
|
OFFSET $3
|
||||||
LIMIT ${LIMIT}`, me.id, decodedCursor.time, decodedCursor.offset)
|
LIMIT ${LIMIT}`, me.id, decodedCursor.time, decodedCursor.offset)
|
||||||
|
@ -129,6 +137,9 @@ export default {
|
||||||
Reply: {
|
Reply: {
|
||||||
item: async (n, args, { models }) => getItem(n, { id: n.id }, { models })
|
item: async (n, args, { models }) => getItem(n, { id: n.id }, { models })
|
||||||
},
|
},
|
||||||
|
JobChanged: {
|
||||||
|
item: async (n, args, { models }) => getItem(n, { id: n.id }, { models })
|
||||||
|
},
|
||||||
Mention: {
|
Mention: {
|
||||||
mention: async (n, args, { models }) => true,
|
mention: async (n, args, { models }) => true,
|
||||||
item: async (n, args, { models }) => getItem(n, { id: n.id }, { models })
|
item: async (n, args, { models }) => getItem(n, { id: n.id }, { models })
|
||||||
|
|
|
@ -210,6 +210,23 @@ export default {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const job = await models.item.findFirst({
|
||||||
|
where: {
|
||||||
|
status: {
|
||||||
|
not: 'STOPPED'
|
||||||
|
},
|
||||||
|
maxBid: {
|
||||||
|
not: null
|
||||||
|
},
|
||||||
|
statusUpdatedAt: {
|
||||||
|
gt: user.checkedNotesAt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
if (job) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
// check if new invites have been redeemed
|
// check if new invites have been redeemed
|
||||||
const newInvitees = await models.$queryRaw(`
|
const newInvitees = await models.$queryRaw(`
|
||||||
SELECT "Invite".id
|
SELECT "Invite".id
|
||||||
|
|
|
@ -27,7 +27,12 @@ export default gql`
|
||||||
sortTime: String!
|
sortTime: String!
|
||||||
}
|
}
|
||||||
|
|
||||||
union Notification = Reply | Votification | Mention | Invitification
|
type JobChanged {
|
||||||
|
item: Item!
|
||||||
|
sortTime: String!
|
||||||
|
}
|
||||||
|
|
||||||
|
union Notification = Reply | Votification | Mention | Invitification | JobChanged
|
||||||
|
|
||||||
type Notifications {
|
type Notifications {
|
||||||
lastChecked: String
|
lastChecked: String
|
||||||
|
|
|
@ -92,7 +92,7 @@ export default function JobForm ({ item, sub }) {
|
||||||
<div>
|
<div>
|
||||||
<ol>
|
<ol>
|
||||||
<li>You only pay as many sats/mo as required to maintain your position relative to other
|
<li>You only pay as many sats/mo as required to maintain your position relative to other
|
||||||
posts and only up to your max bid.
|
posts (or {sub.baseCost} sats/mo) and only up to your max bid.
|
||||||
</li>
|
</li>
|
||||||
<li>Your sats/mo must be a multiple of 1000 sats</li>
|
<li>Your sats/mo must be a multiple of 1000 sats</li>
|
||||||
</ol>
|
</ol>
|
||||||
|
@ -147,7 +147,7 @@ export default function JobForm ({ item, sub }) {
|
||||||
if (item) {
|
if (item) {
|
||||||
router.push(`/items/${item.id}`)
|
router.push(`/items/${item.id}`)
|
||||||
} else {
|
} else {
|
||||||
router.push(`/$${sub.name}/recent`)
|
router.push(`/~${sub.name}/recent`)
|
||||||
}
|
}
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
|
@ -198,21 +198,24 @@ export default function JobForm ({ item, sub }) {
|
||||||
function StatusControl ({ item }) {
|
function StatusControl ({ item }) {
|
||||||
let StatusComp
|
let StatusComp
|
||||||
|
|
||||||
if (item.status === 'ACTIVE') {
|
if (item.status !== 'STOPPED') {
|
||||||
StatusComp = () => {
|
StatusComp = () => {
|
||||||
return (
|
return (
|
||||||
<AccordianItem
|
<>
|
||||||
header={<div style={{ fontWeight: 'bold', fontSize: '92%' }}>I want to stop my job</div>}
|
|
||||||
headerColor='var(--danger)'
|
<AccordianItem
|
||||||
body={
|
header={<div style={{ fontWeight: 'bold', fontSize: '92%' }}>I want to stop my job</div>}
|
||||||
<Checkbox
|
headerColor='var(--danger)'
|
||||||
label={<div className='font-weight-bold text-danger'>stop my job</div>} name='stop' inline
|
body={
|
||||||
/>
|
<Checkbox
|
||||||
|
label={<div className='font-weight-bold text-danger'>stop my job</div>} name='stop' inline
|
||||||
|
/>
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else if (item.status === 'STOPPED') {
|
} else {
|
||||||
StatusComp = () => {
|
StatusComp = () => {
|
||||||
return (
|
return (
|
||||||
<AccordianItem
|
<AccordianItem
|
||||||
|
@ -226,18 +229,14 @@ function StatusControl ({ item }) {
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
StatusComp = () => {
|
|
||||||
return (
|
|
||||||
<div style={{ fontWeight: 'bold', color: 'var(--danger)' }}>
|
|
||||||
you have no sats! <Link href='/wallet?type=fund' passHref><a className='text-reset text-underline'>fund your wallet</a></Link> to resume your job
|
|
||||||
</div>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='my-2'>
|
<div className='my-2'>
|
||||||
|
{item.status === 'NOSATS' &&
|
||||||
|
<div className='text-danger font-weight-bold my-1'>
|
||||||
|
you have no sats! <Link href='/wallet?type=fund' passHref><a className='text-reset text-underline'>fund your wallet</a></Link> to resume your job
|
||||||
|
</div>}
|
||||||
<StatusComp />
|
<StatusComp />
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import { useQuery } from '@apollo/client'
|
import { useQuery } from '@apollo/client'
|
||||||
import Comment, { CommentSkeleton } from './comment'
|
import Comment, { CommentSkeleton } from './comment'
|
||||||
import Item from './item'
|
import Item, { ItemJob } from './item'
|
||||||
import { NOTIFICATIONS } from '../fragments/notifications'
|
import { NOTIFICATIONS } from '../fragments/notifications'
|
||||||
import { useRouter } from 'next/router'
|
import { useRouter } from 'next/router'
|
||||||
import MoreFooter from './more-footer'
|
import MoreFooter from './more-footer'
|
||||||
|
@ -58,13 +58,21 @@ function Notification ({ n }) {
|
||||||
<small className='font-weight-bold text-info ml-2'>
|
<small className='font-weight-bold text-info ml-2'>
|
||||||
you were mentioned in
|
you were mentioned in
|
||||||
</small>}
|
</small>}
|
||||||
<div className={n.__typename === 'Votification' || n.__typename === 'Mention' ? '' : 'py-2'}>
|
{n.__typename === 'JobChanged' &&
|
||||||
{n.item.title
|
<small className={`font-weight-bold text-${n.item.status === 'NOSATS' ? 'danger' : 'success'} ml-1`}>
|
||||||
? <Item item={n.item} />
|
{n.item.status === 'NOSATS'
|
||||||
: (
|
? 'your job ran out of sats'
|
||||||
<div className='pb-2'>
|
: 'your job is active again'}
|
||||||
<Comment item={n.item} noReply includeParent rootText={n.__typename === 'Reply' ? 'replying on:' : undefined} clickToContext />
|
</small>}
|
||||||
</div>)}
|
<div className={n.__typename === 'Votification' || n.__typename === 'Mention' || n.__typename === 'JobChanged' ? '' : 'py-2'}>
|
||||||
|
{n.item.maxBid
|
||||||
|
? <ItemJob item={n.item} />
|
||||||
|
: n.item.title
|
||||||
|
? <Item item={n.item} />
|
||||||
|
: (
|
||||||
|
<div className='pb-2'>
|
||||||
|
<Comment item={n.item} noReply includeParent rootText={n.__typename === 'Reply' ? 'replying on:' : undefined} clickToContext />
|
||||||
|
</div>)}
|
||||||
</div>
|
</div>
|
||||||
</>)}
|
</>)}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -41,6 +41,12 @@ export const NOTIFICATIONS = gql`
|
||||||
...InviteFields
|
...InviteFields
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
... on JobChanged {
|
||||||
|
sortTime
|
||||||
|
item {
|
||||||
|
...ItemFields
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} `
|
} `
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
ALTER TABLE "Item" RENAME COLUMN "noSatsAt" TO "statusUpdatedAt";
|
||||||
|
|
||||||
-- charge the user for the auction item
|
-- charge the user for the auction item
|
||||||
CREATE OR REPLACE FUNCTION run_auction(item_id INTEGER) RETURNS void AS $$
|
CREATE OR REPLACE FUNCTION run_auction(item_id INTEGER) RETURNS void AS $$
|
||||||
DECLARE
|
DECLARE
|
||||||
|
@ -9,21 +11,21 @@ CREATE OR REPLACE FUNCTION run_auction(item_id INTEGER) RETURNS void AS $$
|
||||||
PERFORM ASSERT_SERIALIZED();
|
PERFORM ASSERT_SERIALIZED();
|
||||||
|
|
||||||
-- extract data we need
|
-- extract data we need
|
||||||
SELECT ("maxBid" * 1000 / 30 / 24 / 60), "userId", status INTO bid, user_id, item_status FROM "Item" WHERE id = item_id;
|
SELECT ("maxBid" * 5 / 216), "userId", status INTO bid, user_id, item_status FROM "Item" WHERE id = item_id;
|
||||||
SELECT msats INTO user_msats FROM users WHERE id = user_id;
|
SELECT msats INTO user_msats FROM users WHERE id = user_id;
|
||||||
|
|
||||||
-- check if user wallet has enough sats
|
-- check if user wallet has enough sats
|
||||||
IF bid > user_msats THEN
|
IF bid > user_msats THEN
|
||||||
-- if not, set status = NOSATS and noSatsAt to now_utc if not already set
|
-- if not, set status = NOSATS and statusUpdatedAt to now_utc if not already set
|
||||||
IF item_status <> 'NOSATS' THEN
|
IF item_status <> 'NOSATS' THEN
|
||||||
UPDATE "Item" SET status = 'NOSATS', "noSatsAt" = now_utc() WHERE id = item_id;
|
UPDATE "Item" SET status = 'NOSATS', "statusUpdatedAt" = now_utc() WHERE id = item_id;
|
||||||
END IF;
|
END IF;
|
||||||
ELSE
|
ELSE
|
||||||
-- if so, deduct from user
|
-- if so, deduct from user
|
||||||
UPDATE users SET msats = msats - bid WHERE id = user_id;
|
UPDATE users SET msats = msats - bid WHERE id = user_id;
|
||||||
-- update item status = ACTIVE and noSatsAt = null if NOSATS
|
-- update item status = ACTIVE and statusUpdatedAt = null if NOSATS
|
||||||
IF item_status = 'NOSATS' THEN
|
IF item_status = 'NOSATS' THEN
|
||||||
UPDATE "Item" SET status = 'ACTIVE', "noSatsAt" = null WHERE id = item_id;
|
UPDATE "Item" SET status = 'ACTIVE', "statusUpdatedAt" = now_utc() WHERE id = item_id;
|
||||||
END IF;
|
END IF;
|
||||||
END IF;
|
END IF;
|
||||||
END;
|
END;
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
-- AlterTable
|
|
||||||
ALTER TABLE "Item" RENAME COLUMN "noSatsAt" TO "statusUpdatedAt";
|
|
||||||
|
|
||||||
-- charge the user for the auction item
|
|
||||||
CREATE OR REPLACE FUNCTION run_auction(item_id INTEGER) RETURNS void AS $$
|
|
||||||
DECLARE
|
|
||||||
bid INTEGER;
|
|
||||||
user_id INTEGER;
|
|
||||||
user_msats INTEGER;
|
|
||||||
item_status "Status";
|
|
||||||
BEGIN
|
|
||||||
PERFORM ASSERT_SERIALIZED();
|
|
||||||
|
|
||||||
-- extract data we need
|
|
||||||
SELECT ("maxBid" * 1000 / 30 / 24 / 60), "userId", status INTO bid, 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 bid > 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;
|
|
||||||
ELSE
|
|
||||||
-- if so, deduct from user
|
|
||||||
UPDATE users SET msats = msats - bid 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;
|
|
||||||
END IF;
|
|
||||||
END;
|
|
||||||
$$ LANGUAGE plpgsql;
|
|
|
@ -1,3 +0,0 @@
|
||||||
-- AlterTable
|
|
||||||
ALTER TABLE "users" ALTER COLUMN "msats" SET DEFAULT 0,
|
|
||||||
ALTER COLUMN "msats" SET DATA TYPE BIGINT;
|
|
|
@ -1,41 +0,0 @@
|
||||||
/*
|
|
||||||
Warnings:
|
|
||||||
|
|
||||||
- You are about to alter the column `msats` on the `users` table. The data in that column could be lost. The data in that column will be cast from `BigInt` to `Integer`.
|
|
||||||
|
|
||||||
*/
|
|
||||||
-- AlterTable
|
|
||||||
ALTER TABLE "users" ALTER COLUMN "msats" SET DEFAULT 0,
|
|
||||||
ALTER COLUMN "msats" SET DATA TYPE INTEGER;
|
|
||||||
|
|
||||||
|
|
||||||
-- charge the user for the auction item
|
|
||||||
CREATE OR REPLACE FUNCTION run_auction(item_id INTEGER) RETURNS void AS $$
|
|
||||||
DECLARE
|
|
||||||
bid INTEGER;
|
|
||||||
user_id INTEGER;
|
|
||||||
user_msats INTEGER;
|
|
||||||
item_status "Status";
|
|
||||||
BEGIN
|
|
||||||
PERFORM ASSERT_SERIALIZED();
|
|
||||||
|
|
||||||
-- extract data we need
|
|
||||||
SELECT ("maxBid" * 5 / 216), "userId", status INTO bid, 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 bid > 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;
|
|
||||||
ELSE
|
|
||||||
-- if so, deduct from user
|
|
||||||
UPDATE users SET msats = msats - bid 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;
|
|
||||||
END IF;
|
|
||||||
END;
|
|
||||||
$$ LANGUAGE plpgsql;
|
|
Loading…
Reference in New Issue