Skip to content

Commit 00c1f56

Browse files
authored
Merge pull request #42 from superfluid-org/feat/point-balance-delete-hook
feat(cms): add afterDelete hook to adjust point balances
2 parents 1c1c749 + 459d989 commit 00c1f56

File tree

1 file changed

+48
-1
lines changed

1 file changed

+48
-1
lines changed

cms/src/domains/points/collections/PointEvents.ts

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { CollectionAfterChangeHook, CollectionConfig } from "payload"
1+
import type { CollectionAfterChangeHook, CollectionAfterDeleteHook, CollectionConfig } from "payload"
22
import { z } from "zod"
33
import type { PointEvent } from "../../../payload-types"
44
import { AccessControl } from "../../../utils/AccessControl"
@@ -70,6 +70,52 @@ const updatePointBalance: CollectionAfterChangeHook<PointEvent> = async ({ doc,
7070
return doc
7171
}
7272

73+
/**
74+
* After deleting a PointEvent, adjust the corresponding PointBalance.
75+
* This reverses the effect of the original event on the balance.
76+
*/
77+
const adjustPointBalanceOnDelete: CollectionAfterDeleteHook<PointEvent> = async ({ doc, req }) => {
78+
// Skip balance adjustment for informational events
79+
if (doc.informational) return doc
80+
81+
const { campaign, account, points, id: eventId } = doc
82+
const campaignId = typeof campaign === "object" ? campaign.id : campaign
83+
const balanceId = `${campaignId}:${account}`
84+
85+
// Find existing balance
86+
const existing = await req.payload.find({
87+
req,
88+
collection: "point-balances",
89+
where: { id: { equals: balanceId } },
90+
limit: 1,
91+
depth: 0,
92+
})
93+
94+
if (existing.docs.length > 0) {
95+
const balance = existing.docs[0]
96+
const existingEventIds = (balance.events as number[]) || []
97+
98+
// Remove the deleted event from the events array
99+
const updatedEventIds = existingEventIds.filter((id) => id !== eventId)
100+
101+
await req.payload.update({
102+
req,
103+
collection: "point-balances",
104+
id: balance.id,
105+
data: {
106+
// NOTE: Deleting a large negative event from an account that was capped at 0
107+
// may grant unintended points. E.g., if -1000 points brought balance from 100 to 0
108+
// (capped), deleting that event would set balance to 0 - (-1000) = 1000, not 100.
109+
totalPoints: Math.max(0, balance.totalPoints - points),
110+
eventCount: Math.max(0, balance.eventCount - 1),
111+
events: updatedEventIds,
112+
},
113+
})
114+
}
115+
116+
return doc
117+
}
118+
73119
export const PointEvents: CollectionConfig = {
74120
slug: "point-events",
75121
admin: {
@@ -87,6 +133,7 @@ export const PointEvents: CollectionConfig = {
87133
},
88134
hooks: {
89135
afterChange: [updatePointBalance],
136+
afterDelete: [adjustPointBalanceOnDelete],
90137
},
91138
fields: [
92139
{

0 commit comments

Comments
 (0)