UNPKG

wisdom-sdk

Version:

Core business logic and data access layer for prediction markets

390 lines (388 loc) 13.2 kB
import { generateUUID } from './chunk-7CBIP22I.js'; import { userBalanceStore } from './chunk-SL5BKWK6.js'; import { getSetMembers, getEntity, startTransaction, storeEntity, deleteEntity, removeFromSet } from './chunk-FIJAO3BQ.js'; import { logger, AppError } from './chunk-2OHF4QSJ.js'; // src/bug-report-store.ts var bugReportLogger = logger.child({ context: "bug-report-store" }); var DEFAULT_INITIAL_REWARD = 10; var DEFAULT_CONFIRMATION_REWARD = 90; var BugReportStore = class { /** * Get all bug reports */ async getAllBugReports() { try { const reportIds = await getSetMembers("BUG_REPORT_IDS", ""); if (!reportIds || reportIds.length === 0) { return []; } const reports = await Promise.all( reportIds.map(async (id) => { const report = await getEntity("BUG_REPORT", id); return report; }) ); return reports.filter((report) => report !== null); } catch (error) { throw new AppError({ message: "Failed to retrieve bug reports", context: "bug-report-store", code: "BUG_REPORT_FETCH_ERROR", originalError: error instanceof Error ? error : new Error(String(error)) }).log(); } } /** * Get specific bug report by ID */ async getBugReport(id) { if (!id) { bugReportLogger.warn({}, "Attempted to get bug report with empty ID"); return null; } const report = await getEntity("BUG_REPORT", id); if (!report) { bugReportLogger.debug({ reportId: id }, `Bug report ${id} not found`); } return report; } /** * Get all bug reports for a specific user */ async getUserBugReports(userId) { try { if (!userId) { return []; } const reportIds = await getSetMembers("USER_BUG_REPORTS", userId); if (reportIds.length === 0) { return []; } const reports = await Promise.all( reportIds.map((id) => this.getBugReport(id)) ); return reports.filter((report) => report !== null); } catch (error) { throw new AppError({ message: `Failed to retrieve bug reports for user ${userId}`, context: "bug-report-store", code: "USER_BUG_REPORTS_ERROR", originalError: error instanceof Error ? error : new Error(String(error)), data: { userId } }).log(); } } /** * Create a new bug report */ async createBugReport(data) { try { if (!data.title || !data.description || !data.createdBy) { throw new AppError({ message: "Missing required bug report data", context: "bug-report-store", code: "BUG_REPORT_VALIDATION_ERROR", data: { hasTitle: !!data.title, hasDescription: !!data.description, hasCreatedBy: !!data.createdBy } }).log(); } const id = generateUUID(); const now = (/* @__PURE__ */ new Date()).toISOString(); const bugReport = { id, title: data.title, description: data.description, severity: data.severity, url: data.url, createdBy: data.createdBy, createdAt: now, status: "open" }; const tx = await startTransaction(); try { await tx.addEntity("BUG_REPORT", id, bugReport); await tx.addToSetInTransaction("BUG_REPORT_IDS", "", id); await tx.addToSetInTransaction("USER_BUG_REPORTS", data.createdBy, id); const success = await tx.execute(); if (!success) { throw new AppError({ message: "Failed to create bug report - transaction failed", context: "bug-report-store", code: "BUG_REPORT_TRANSACTION_ERROR", data: { reportId: id } }).log(); } bugReportLogger.info( { reportId: id, userId: data.createdBy }, `Bug report created: ${data.title}` ); return bugReport; } catch (error) { if (error instanceof AppError) { throw error; } else { throw new AppError({ message: "Error during bug report creation transaction", context: "bug-report-store", code: "BUG_REPORT_CREATE_TRANSACTION_ERROR", originalError: error instanceof Error ? error : new Error(String(error)), data: { title: data.title } }).log(); } } } catch (error) { if (error instanceof AppError) { throw error; } else { throw new AppError({ message: "Failed to create bug report", context: "bug-report-store", code: "BUG_REPORT_CREATE_ERROR", originalError: error instanceof Error ? error : new Error(String(error)), data: { title: data.title } }).log(); } } } /** * Update an existing bug report */ async updateBugReport(id, data) { try { const existingReport = await this.getBugReport(id); if (!existingReport) { bugReportLogger.warn({ reportId: id }, `Cannot update non-existent bug report with ID ${id}`); return null; } const safeData = { ...data }; if (safeData.id && safeData.id !== id) { delete safeData.id; bugReportLogger.warn( { reportId: id, attemptedId: data.id }, "Attempted to change bug report ID during update - ignoring" ); } const updatedReport = { ...existingReport, ...safeData, updatedAt: (/* @__PURE__ */ new Date()).toISOString() }; await storeEntity("BUG_REPORT", id, updatedReport); bugReportLogger.debug( { reportId: id }, `Bug report updated: ${existingReport.title}` ); return updatedReport; } catch (error) { throw new AppError({ message: `Failed to update bug report ${id}`, context: "bug-report-store", code: "BUG_REPORT_UPDATE_ERROR", originalError: error instanceof Error ? error : new Error(String(error)), data: { reportId: id } }).log(); } } async deleteBugReport(id) { try { const report = await this.getBugReport(id); if (!report) { throw new Error(`Bug report ${id} not found`); } await deleteEntity("BUG_REPORT", id); await removeFromSet("BUG_REPORT_IDS", "", id); await removeFromSet("USER_BUG_REPORTS", report.createdBy, id); return true; } catch (error) { console.error(`Error deleting bug report ${id}:`, error); return false; } } /** * Process a reward payment for a bug report * This handles giving the initial or confirmation reward to a user * * @param reportId Bug report ID * @param userId User ID to receive the reward * @param rewardType Type of reward (initial or confirmation) * @param customAmount Optional custom amount (overrides defaults) * @returns Result object with success/error status */ /** * Confirm a bug report (mark as verified by admin) * @param id Bug report ID * @param adminId ID of the admin confirming the report */ async confirmBugReport(id, adminId) { try { const report = await this.getBugReport(id); if (!report) { bugReportLogger.warn({ reportId: id }, `Cannot confirm non-existent bug report: ${id}`); return null; } if (report.status === "resolved") { bugReportLogger.warn({ reportId: id }, `Bug report ${id} is already resolved`); return report; } const now = (/* @__PURE__ */ new Date()).toISOString(); const updatedReport = await this.updateBugReport(id, { status: "resolved", confirmedBy: adminId, confirmedAt: now, updatedBy: adminId, updatedAt: now }); bugReportLogger.info( { reportId: id, adminId }, `Bug report confirmed: ${report.title}` ); return updatedReport; } catch (error) { throw new AppError({ message: `Failed to confirm bug report ${id}`, context: "bug-report-store", code: "BUG_REPORT_CONFIRM_ERROR", originalError: error instanceof Error ? error : new Error(String(error)), data: { reportId: id, adminId } }).log(); } } /** * Pay a reward for a bug report * @param id Bug report ID * @param isInitialReward Whether to pay the initial (true) or confirmation (false) reward */ async payReward(id, isInitialReward) { try { const report = await this.getBugReport(id); if (!report) { bugReportLogger.warn({ reportId: id }, `Cannot pay reward for non-existent bug report: ${id}`); return null; } const recipientId = report.createdBy; const rewardType = isInitialReward ? "initial" : "confirmation"; const result = await this.processRewardPayment(id, recipientId, rewardType); if (!result.success) { throw new AppError({ message: result.error || "Failed to pay reward", context: "bug-report-store", code: "REWARD_PAYMENT_FAILED", data: { reportId: id, userId: recipientId, rewardType, error: result.error } }); } return result.report || null; } catch (error) { if (error instanceof AppError) { throw error; } else { throw new AppError({ message: `Failed to pay ${isInitialReward ? "initial" : "confirmation"} reward for bug report ${id}`, context: "bug-report-store", code: "REWARD_PAYMENT_ERROR", originalError: error instanceof Error ? error : new Error(String(error)), data: { reportId: id, isInitialReward } }).log(); } } } /** * Internal helper method to process reward payments * This handles giving the initial or confirmation reward to a user */ async processRewardPayment(reportId, userId, rewardType, customAmount) { try { const opLogger = bugReportLogger.child({ operation: "processRewardPayment", reportId, userId, rewardType }); opLogger.info({}, `Processing ${rewardType} reward payment`); const report = await this.getBugReport(reportId); if (!report) { return { success: false, error: "Bug report not found" }; } const amount = customAmount || (rewardType === "initial" ? DEFAULT_INITIAL_REWARD : DEFAULT_CONFIRMATION_REWARD); if (rewardType === "initial" && report.initialRewardPaid) { opLogger.warn({}, "Initial reward already paid for this report"); return { success: false, error: "Initial reward already paid for this report", report }; } if (rewardType === "confirmation" && report.confirmationRewardPaid) { opLogger.warn({}, "Confirmation reward already paid for this report"); return { success: false, error: "Confirmation reward already paid for this report", report }; } opLogger.debug({ amount }, `Processing payment of ${amount} tokens`); const updatedBalance = await userBalanceStore.addFunds(userId, amount); if (!updatedBalance) { throw new AppError({ message: "Failed to update user balance", context: "bug-report-store", code: "BALANCE_UPDATE_FAILED", data: { userId, amount, reportId } }); } const updateData = {}; if (rewardType === "initial") { updateData.initialRewardPaid = true; } else { updateData.confirmationRewardPaid = true; if (report.status !== "resolved") { updateData.status = "resolved"; updateData.confirmedAt = (/* @__PURE__ */ new Date()).toISOString(); } } const updatedReport = await this.updateBugReport(reportId, updateData); if (!updatedReport) { throw new AppError({ message: "Failed to update bug report after payment", context: "bug-report-store", code: "REPORT_UPDATE_FAILED", data: { reportId, rewardType } }); } opLogger.info( { amount, reportId, userId }, `Successfully processed ${rewardType} reward payment` ); return { success: true, amount, report: updatedReport }; } catch (error) { if (error instanceof AppError) { error.log(); return { success: false, error: error.message }; } else { const appError = new AppError({ message: `Error processing reward payment for report ${reportId}`, context: "bug-report-store", code: "REWARD_PROCESS_ERROR", originalError: error instanceof Error ? error : new Error(String(error)), data: { reportId, userId, rewardType } }).log(); return { success: false, error: appError.message }; } } } }; var bugReportStore = new BugReportStore(); export { BugReportStore, bugReportStore }; //# sourceMappingURL=chunk-NNOTRTHN.js.map //# sourceMappingURL=chunk-NNOTRTHN.js.map