/** * Points management utilities */ import { Transaction, TransactionType } from './types'; import { createTransaction, getUserTransactions, getUserBalance } from './db/store'; /** * Add points to a user's account */ export function addPoints( userId: string, amount: number, source: string ): Transaction { if (amount <= 0) { throw new Error('Amount must be positive'); } return createTransaction(userId, amount, TransactionType.EARNED, source); } /** * Deduct points from a user's account */ export function deductPoints( userId: string, amount: number, source: string ): Transaction { if (amount <= 0) { throw new Error('Amount must be positive'); } const currentBalance = getBalance(userId); if (currentBalance < amount) { throw new Error('Insufficient balance'); } return createTransaction(userId, amount, TransactionType.SPENT, source); } /** * Get user's current points balance */ export function getBalance(userId: string): number { return getUserBalance(userId); } /** * Get all transactions for a user */ export function getTransactions(userId: string): Transaction[] { return getUserTransactions(userId).sort( (a, b) => b.createdAt.getTime() - a.createdAt.getTime() ); } /** * Get recent transactions (last N) */ export function getRecentTransactions( userId: string, limit: number = 10 ): Transaction[] { const allTransactions = getTransactions(userId); return allTransactions.slice(0, limit); } /** * Get transaction statistics for a user */ export function getTransactionStats(userId: string): { totalEarned: number; totalSpent: number; balance: number; transactionCount: number; } { const transactions = getUserTransactions(userId); const totalEarned = transactions .filter(t => t.type === TransactionType.EARNED) .reduce((sum, t) => sum + t.amount, 0); const totalSpent = transactions .filter(t => t.type === TransactionType.SPENT) .reduce((sum, t) => sum + t.amount, 0); return { totalEarned, totalSpent, balance: totalEarned - totalSpent, transactionCount: transactions.length }; } /** * Get points earned from specific source */ export function getPointsBySource( userId: string, source: string ): number { const transactions = getUserTransactions(userId); return transactions .filter(t => t.type === TransactionType.EARNED && t.source === source) .reduce((sum, t) => sum + t.amount, 0); } /** * Get breakdown of points by source */ export function getPointsBreakdown(userId: string): Record { const transactions = getUserTransactions(userId); const breakdown: Record = {}; transactions .filter(t => t.type === TransactionType.EARNED) .forEach(t => { breakdown[t.source] = (breakdown[t.source] || 0) + t.amount; }); return breakdown; } /** * Check if user can afford a purchase */ export function canAfford(userId: string, amount: number): boolean { return getBalance(userId) >= amount; } /** * Award task completion points */ export function awardTaskPoints( userId: string, taskId: string, amount: number ): Transaction { return addPoints(userId, amount, `task:${taskId}`); } /** * Award referral bonus points */ export function awardReferralBonus( userId: string, referralId: string, amount: number ): Transaction { return addPoints(userId, amount, `referral:${referralId}`); } /** * Award daily streak bonus */ export function awardStreakBonus( userId: string, streakDays: number ): Transaction { const bonusAmount = Math.min(streakDays * 5, 50); // Max 50 points return addPoints(userId, bonusAmount, `streak:${streakDays}days`); }