Skip to content

Commit d906afa

Browse files
authored
Merge branch 'master' into custom_domain
2 parents 1d04948 + 4be7f12 commit d906afa

File tree

15 files changed

+743
-300
lines changed

15 files changed

+743
-300
lines changed

api/paidAction/downZap.js

Lines changed: 31 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { PAID_ACTION_PAYMENT_METHODS } from '@/lib/constants'
22
import { msatsToSats, satsToMsats } from '@/lib/format'
3+
import { Prisma } from '@prisma/client'
34

45
export const anonable = false
56

@@ -48,9 +49,9 @@ export async function onPaid ({ invoice, actId }, { tx }) {
4849
let itemAct
4950
if (invoice) {
5051
await tx.itemAct.updateMany({ where: { invoiceId: invoice.id }, data: { invoiceActionState: 'PAID' } })
51-
itemAct = await tx.itemAct.findFirst({ where: { invoiceId: invoice.id } })
52+
itemAct = await tx.itemAct.findFirst({ where: { invoiceId: invoice.id }, include: { item: true } })
5253
} else if (actId) {
53-
itemAct = await tx.itemAct.findUnique({ where: { id: actId } })
54+
itemAct = await tx.itemAct.findUnique({ where: { id: actId }, include: { item: true } })
5455
} else {
5556
throw new Error('No invoice or actId')
5657
}
@@ -60,19 +61,34 @@ export async function onPaid ({ invoice, actId }, { tx }) {
6061

6162
// denormalize downzaps
6263
await tx.$executeRaw`
63-
WITH zapper AS (
64-
SELECT trust FROM users WHERE id = ${itemAct.userId}::INTEGER
65-
), zap AS (
66-
INSERT INTO "ItemUserAgg" ("userId", "itemId", "downZapSats")
67-
VALUES (${itemAct.userId}::INTEGER, ${itemAct.itemId}::INTEGER, ${sats}::INTEGER)
68-
ON CONFLICT ("itemId", "userId") DO UPDATE
69-
SET "downZapSats" = "ItemUserAgg"."downZapSats" + ${sats}::INTEGER, updated_at = now()
70-
RETURNING LOG("downZapSats" / GREATEST("downZapSats" - ${sats}::INTEGER, 1)::FLOAT) AS log_sats
71-
)
72-
UPDATE "Item"
73-
SET "weightedDownVotes" = "weightedDownVotes" + (zapper.trust * zap.log_sats)
74-
FROM zap, zapper
75-
WHERE "Item".id = ${itemAct.itemId}::INTEGER`
64+
WITH territory AS (
65+
SELECT COALESCE(r."subName", i."subName", 'meta')::TEXT as "subName"
66+
FROM "Item" i
67+
LEFT JOIN "Item" r ON r.id = i."rootId"
68+
WHERE i.id = ${itemAct.itemId}::INTEGER
69+
), zapper AS (
70+
SELECT
71+
COALESCE(${itemAct.item.parentId
72+
? Prisma.sql`"zapCommentTrust"`
73+
: Prisma.sql`"zapPostTrust"`}, 0) as "zapTrust",
74+
COALESCE(${itemAct.item.parentId
75+
? Prisma.sql`"subZapCommentTrust"`
76+
: Prisma.sql`"subZapPostTrust"`}, 0) as "subZapTrust"
77+
FROM territory
78+
LEFT JOIN "UserSubTrust" ust ON ust."subName" = territory."subName"
79+
AND ust."userId" = ${itemAct.userId}::INTEGER
80+
), zap AS (
81+
INSERT INTO "ItemUserAgg" ("userId", "itemId", "downZapSats")
82+
VALUES (${itemAct.userId}::INTEGER, ${itemAct.itemId}::INTEGER, ${sats}::INTEGER)
83+
ON CONFLICT ("itemId", "userId") DO UPDATE
84+
SET "downZapSats" = "ItemUserAgg"."downZapSats" + ${sats}::INTEGER, updated_at = now()
85+
RETURNING LOG("downZapSats" / GREATEST("downZapSats" - ${sats}::INTEGER, 1)::FLOAT) AS log_sats
86+
)
87+
UPDATE "Item"
88+
SET "weightedDownVotes" = "weightedDownVotes" + zapper."zapTrust" * zap.log_sats,
89+
"subWeightedDownVotes" = "subWeightedDownVotes" + zapper."subZapTrust" * zap.log_sats
90+
FROM zap, zapper
91+
WHERE "Item".id = ${itemAct.itemId}::INTEGER`
7692
}
7793

7894
export async function onFail ({ invoice }, { tx }) {

api/paidAction/itemCreate.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -252,15 +252,18 @@ export async function onPaid ({ invoice, id }, context) {
252252
JOIN users ON "Item"."userId" = users.id
253253
WHERE "Item".id = ${item.id}::INTEGER
254254
), ancestors AS (
255+
SELECT "Item".*
256+
FROM "Item", comment
257+
WHERE "Item".path @> comment.path AND "Item".id <> comment.id
258+
ORDER BY "Item".id
259+
), updated_ancestors AS (
255260
UPDATE "Item"
256261
SET ncomments = "Item".ncomments + 1,
257262
"lastCommentAt" = GREATEST("Item"."lastCommentAt", comment.created_at),
258-
"weightedComments" = "Item"."weightedComments" +
259-
CASE WHEN comment."userId" = "Item"."userId" THEN 0 ELSE comment.trust END,
260263
"nDirectComments" = "Item"."nDirectComments" +
261264
CASE WHEN comment."parentId" = "Item".id THEN 1 ELSE 0 END
262-
FROM comment
263-
WHERE "Item".path @> comment.path AND "Item".id <> comment.id
265+
FROM comment, ancestors
266+
WHERE "Item".id = ancestors.id
264267
RETURNING "Item".*
265268
)
266269
INSERT INTO "Reply" (created_at, updated_at, "ancestorId", "ancestorUserId", "itemId", "userId", level)

api/paidAction/lib/territory.js

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import { USER_ID } from '@/lib/constants'
2+
3+
export const GLOBAL_SEEDS = [USER_ID.k00b, USER_ID.ek]
4+
5+
export function initialTrust ({ name, userId }) {
6+
const results = GLOBAL_SEEDS.map(id => ({
7+
subName: name,
8+
userId: id,
9+
zapPostTrust: 1,
10+
subZapPostTrust: 1,
11+
zapCommentTrust: 1,
12+
subZapCommentTrust: 1
13+
}))
14+
15+
if (!GLOBAL_SEEDS.includes(userId)) {
16+
results.push({
17+
subName: name,
18+
userId,
19+
zapPostTrust: 0,
20+
subZapPostTrust: 1,
21+
zapCommentTrust: 0,
22+
subZapCommentTrust: 1
23+
})
24+
}
25+
26+
return results
27+
}

api/paidAction/territoryCreate.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { PAID_ACTION_PAYMENT_METHODS, TERRITORY_PERIOD_COST } from '@/lib/constants'
22
import { satsToMsats } from '@/lib/format'
33
import { nextBilling } from '@/lib/territory'
4+
import { initialTrust } from './lib/territory'
45

56
export const anonable = false
67

@@ -20,7 +21,7 @@ export async function perform ({ invoiceId, ...data }, { me, cost, tx }) {
2021
const billedLastAt = new Date()
2122
const billPaidUntil = nextBilling(billedLastAt, billingType)
2223

23-
return await tx.sub.create({
24+
const sub = await tx.sub.create({
2425
data: {
2526
...data,
2627
billedLastAt,
@@ -42,6 +43,12 @@ export async function perform ({ invoiceId, ...data }, { me, cost, tx }) {
4243
}
4344
}
4445
})
46+
47+
await tx.userSubTrust.createMany({
48+
data: initialTrust({ name: sub.name, userId: sub.userId })
49+
})
50+
51+
return sub
4552
}
4653

4754
export async function describe ({ name }) {

api/paidAction/territoryUnarchive.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { PAID_ACTION_PAYMENT_METHODS, TERRITORY_PERIOD_COST } from '@/lib/constants'
22
import { satsToMsats } from '@/lib/format'
33
import { nextBilling } from '@/lib/territory'
4+
import { initialTrust } from './lib/territory'
45

56
export const anonable = false
67

@@ -65,7 +66,7 @@ export async function perform ({ name, invoiceId, ...data }, { me, cost, tx }) {
6566
}
6667
})
6768

68-
return await tx.sub.update({
69+
const updatedSub = await tx.sub.update({
6970
data,
7071
// optimistic concurrency control
7172
// make sure none of the relevant fields have changed since we fetched the sub
@@ -76,6 +77,12 @@ export async function perform ({ name, invoiceId, ...data }, { me, cost, tx }) {
7677
}
7778
}
7879
})
80+
81+
await tx.userSubTrust.createMany({
82+
data: initialTrust({ name: updatedSub.name, userId: updatedSub.userId })
83+
})
84+
85+
return updatedSub
7986
}
8087

8188
export async function describe ({ name }, context) {

api/paidAction/zap.js

Lines changed: 39 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { PAID_ACTION_PAYMENT_METHODS, USER_ID } from '@/lib/constants'
22
import { msatsToSats, satsToMsats } from '@/lib/format'
33
import { notifyZapped } from '@/lib/webPush'
44
import { getInvoiceableWallets } from '@/wallets/server'
5+
import { Prisma } from '@prisma/client'
56

67
export const anonable = true
78

@@ -149,26 +150,53 @@ export async function onPaid ({ invoice, actIds }, { tx }) {
149150
// perform denomormalized aggregates: weighted votes, upvotes, msats, lastZapAt
150151
// NOTE: for the rows that might be updated by a concurrent zap, we use UPDATE for implicit locking
151152
await tx.$queryRaw`
152-
WITH zapper AS (
153-
SELECT trust FROM users WHERE id = ${itemAct.userId}::INTEGER
153+
WITH territory AS (
154+
SELECT COALESCE(r."subName", i."subName", 'meta')::TEXT as "subName"
155+
FROM "Item" i
156+
LEFT JOIN "Item" r ON r.id = i."rootId"
157+
WHERE i.id = ${itemAct.itemId}::INTEGER
158+
), zapper AS (
159+
SELECT
160+
COALESCE(${itemAct.item.parentId
161+
? Prisma.sql`"zapCommentTrust"`
162+
: Prisma.sql`"zapPostTrust"`}, 0) as "zapTrust",
163+
COALESCE(${itemAct.item.parentId
164+
? Prisma.sql`"subZapCommentTrust"`
165+
: Prisma.sql`"subZapPostTrust"`}, 0) as "subZapTrust"
166+
FROM territory
167+
LEFT JOIN "UserSubTrust" ust ON ust."subName" = territory."subName"
168+
AND ust."userId" = ${itemAct.userId}::INTEGER
154169
), zap AS (
155170
INSERT INTO "ItemUserAgg" ("userId", "itemId", "zapSats")
156171
VALUES (${itemAct.userId}::INTEGER, ${itemAct.itemId}::INTEGER, ${sats}::INTEGER)
157172
ON CONFLICT ("itemId", "userId") DO UPDATE
158173
SET "zapSats" = "ItemUserAgg"."zapSats" + ${sats}::INTEGER, updated_at = now()
159174
RETURNING ("zapSats" = ${sats}::INTEGER)::INTEGER as first_vote,
160175
LOG("zapSats" / GREATEST("zapSats" - ${sats}::INTEGER, 1)::FLOAT) AS log_sats
176+
), item_zapped AS (
177+
UPDATE "Item"
178+
SET
179+
"weightedVotes" = "weightedVotes" + zapper."zapTrust" * zap.log_sats,
180+
"subWeightedVotes" = "subWeightedVotes" + zapper."subZapTrust" * zap.log_sats,
181+
upvotes = upvotes + zap.first_vote,
182+
msats = "Item".msats + ${msats}::BIGINT,
183+
mcredits = "Item".mcredits + ${invoice?.invoiceForward ? 0n : msats}::BIGINT,
184+
"lastZapAt" = now()
185+
FROM zap, zapper
186+
WHERE "Item".id = ${itemAct.itemId}::INTEGER
187+
RETURNING "Item".*, zapper."zapTrust" * zap.log_sats as "weightedVote"
188+
), ancestors AS (
189+
SELECT "Item".*
190+
FROM "Item", item_zapped
191+
WHERE "Item".path @> item_zapped.path AND "Item".id <> item_zapped.id
192+
ORDER BY "Item".id
161193
)
162194
UPDATE "Item"
163-
SET
164-
"weightedVotes" = "weightedVotes" + (zapper.trust * zap.log_sats),
165-
upvotes = upvotes + zap.first_vote,
166-
msats = "Item".msats + ${msats}::BIGINT,
167-
mcredits = "Item".mcredits + ${invoice?.invoiceForward ? 0n : msats}::BIGINT,
168-
"lastZapAt" = now()
169-
FROM zap, zapper
170-
WHERE "Item".id = ${itemAct.itemId}::INTEGER
171-
RETURNING "Item".*`
195+
SET "weightedComments" = "Item"."weightedComments" + item_zapped."weightedVote",
196+
"commentMsats" = "Item"."commentMsats" + ${msats}::BIGINT,
197+
"commentMcredits" = "Item"."commentMcredits" + ${invoice?.invoiceForward ? 0n : msats}::BIGINT
198+
FROM item_zapped, ancestors
199+
WHERE "Item".id = ancestors.id`
172200

173201
// record potential bounty payment
174202
// NOTE: we are at least guaranteed that we see the update "ItemUserAgg" from our tx so we can trust
@@ -188,17 +216,6 @@ export async function onPaid ({ invoice, actIds }, { tx }) {
188216
SET "bountyPaidTo" = array_remove(array_append(array_remove("bountyPaidTo", bounty.target), bounty.target), NULL)
189217
FROM bounty
190218
WHERE "Item".id = bounty.id AND bounty.paid`
191-
192-
// update commentMsats on ancestors
193-
await tx.$executeRaw`
194-
WITH zapped AS (
195-
SELECT * FROM "Item" WHERE id = ${itemAct.itemId}::INTEGER
196-
)
197-
UPDATE "Item"
198-
SET "commentMsats" = "Item"."commentMsats" + ${msats}::BIGINT,
199-
"commentMcredits" = "Item"."commentMcredits" + ${invoice?.invoiceForward ? 0n : msats}::BIGINT
200-
FROM zapped
201-
WHERE "Item".path @> zapped.path AND "Item".id <> zapped.id`
202219
}
203220

204221
export async function nonCriticalSideEffects ({ invoice, actIds }, { models }) {

0 commit comments

Comments
 (0)