98 lines
3.4 KiB
JavaScript
98 lines
3.4 KiB
JavaScript
/// <reference path="../pb_data/types.d.ts" />
|
|
|
|
// ── Credit deduction — fires when a conversion record is created ───────────────
|
|
|
|
onRecordBeforeCreateRequest((e) => {
|
|
const userId = e.record.get('user')
|
|
const fileHash = e.record.get('file_hash')
|
|
|
|
$app.dao().runInTransaction((txDao) => {
|
|
const user = txDao.findRecordById('users', userId)
|
|
const balance = user.getInt('credits_balance')
|
|
const freeUsed = user.getBool('free_used')
|
|
|
|
// Free tier path — first conversion for this account
|
|
if (!freeUsed) {
|
|
user.set('free_used', true)
|
|
txDao.saveRecord(user)
|
|
|
|
const txRecord = new Record(txDao.findCollectionByNameOrId('transactions'))
|
|
txRecord.set('user', userId)
|
|
txRecord.set('type', 'free')
|
|
txRecord.set('credits', 0)
|
|
txRecord.set('balance_after', balance)
|
|
txRecord.set('file_hash', fileHash)
|
|
txDao.saveRecord(txRecord)
|
|
return // allow conversion record to be created
|
|
}
|
|
|
|
// Paid path — check balance
|
|
if (balance < 1) {
|
|
throw new Error('INSUFFICIENT_CREDITS')
|
|
}
|
|
|
|
const newBalance = balance - 1
|
|
user.set('credits_balance', newBalance)
|
|
txDao.saveRecord(user)
|
|
|
|
const txRecord = new Record(txDao.findCollectionByNameOrId('transactions'))
|
|
txRecord.set('user', userId)
|
|
txRecord.set('type', 'conversion')
|
|
txRecord.set('credits', -1)
|
|
txRecord.set('balance_after', newBalance)
|
|
txRecord.set('file_hash', fileHash)
|
|
txDao.saveRecord(txRecord)
|
|
})
|
|
}, 'conversions')
|
|
|
|
|
|
// ── Credit refund — fires when a conversion is marked failed ─────────────────
|
|
|
|
onRecordAfterUpdateRequest((e) => {
|
|
if (e.record.get('status') !== 'failed') return
|
|
|
|
const userId = e.record.get('user')
|
|
|
|
$app.dao().runInTransaction((txDao) => {
|
|
const user = txDao.findRecordById('users', userId)
|
|
|
|
// Only refund paid conversions — free conversions cost nothing
|
|
if (!user.getBool('free_used')) return
|
|
|
|
const newBalance = user.getInt('credits_balance') + 1
|
|
user.set('credits_balance', newBalance)
|
|
txDao.saveRecord(user)
|
|
|
|
const txRecord = new Record(txDao.findCollectionByNameOrId('transactions'))
|
|
txRecord.set('user', userId)
|
|
txRecord.set('type', 'refund')
|
|
txRecord.set('credits', +1)
|
|
txRecord.set('balance_after', newBalance)
|
|
txDao.saveRecord(txRecord)
|
|
})
|
|
}, 'conversions')
|
|
|
|
|
|
// ── Credit top-up — fires when a purchase record is created (from Stripe webhook) ──
|
|
|
|
onRecordBeforeCreateRequest((e) => {
|
|
const userId = e.record.get('user')
|
|
const credits = e.record.getInt('credits')
|
|
const stripeId = e.record.get('stripe_id')
|
|
|
|
$app.dao().runInTransaction((txDao) => {
|
|
const user = txDao.findRecordById('users', userId)
|
|
const newBalance = user.getInt('credits_balance') + credits
|
|
user.set('credits_balance', newBalance)
|
|
txDao.saveRecord(user)
|
|
|
|
const txRecord = new Record(txDao.findCollectionByNameOrId('transactions'))
|
|
txRecord.set('user', userId)
|
|
txRecord.set('type', 'purchase')
|
|
txRecord.set('credits', credits)
|
|
txRecord.set('balance_after', newBalance)
|
|
txRecord.set('stripe_id', stripeId)
|
|
txDao.saveRecord(txRecord)
|
|
})
|
|
}, 'purchases')
|