Simplify donation receipts

This commit is contained in:
Scott Nonnenberg
2025-07-02 06:33:36 +10:00
committed by GitHub
parent 199dbaf49d
commit 6db7bedc8c
8 changed files with 91 additions and 209 deletions

View File

@@ -1,60 +1,17 @@
// Copyright 2025 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import { omit } from 'lodash';
import * as Errors from '../../types/errors';
import { safeParseLoose } from '../../util/schemas';
import { sql } from '../util';
import { sqlLogger } from '../sqlLogger';
import { donationReceiptSchema } from '../../types/Donations';
import type { DonationReceipt } from '../../types/Donations';
import type { ReadableDB, WritableDB } from '../Interface';
type DonationReceiptForDatabase = Readonly<
{
paymentDetailJson: string;
paymentType: string;
} & Omit<DonationReceipt, 'paymentType' | 'paymentDetail'>
>;
function hydrateDonationReceipt(
receipt: DonationReceiptForDatabase
): DonationReceipt {
const readyForParse = {
...omit(receipt, ['paymentDetailJson']),
paymentDetail: JSON.parse(receipt.paymentDetailJson),
};
const result = safeParseLoose(donationReceiptSchema, readyForParse);
if (result.success) {
return result.data;
}
sqlLogger.error(
`hydrateDonationReceipt: Parse failed for payment type ${readyForParse.paymentType}:`,
Errors.toLogFormat(result.error)
);
const toFix = readyForParse as unknown as DonationReceipt;
toFix.paymentDetail = null;
return toFix;
}
export function freezeDonationReceipt(
receipt: DonationReceipt
): DonationReceiptForDatabase {
return {
...omit(receipt, ['paymentDetail']),
paymentDetailJson: JSON.stringify(receipt.paymentDetail),
};
}
export function getAllDonationReceipts(db: ReadableDB): Array<DonationReceipt> {
const donationReceipts = db
.prepare('SELECT * FROM donationReceipts ORDER BY timestamp DESC;')
.all<DonationReceiptForDatabase>();
.all<DonationReceipt>();
return donationReceipts.map(hydrateDonationReceipt);
return donationReceipts;
}
export function getDonationReceiptById(
db: ReadableDB,
@@ -62,15 +19,7 @@ export function getDonationReceiptById(
): DonationReceipt | undefined {
const [query, parameters] =
sql`SELECT * FROM donationReceipts WHERE id = ${id}`;
const fromDatabase = db
.prepare(query)
.get<DonationReceiptForDatabase>(parameters);
if (fromDatabase) {
return hydrateDonationReceipt(fromDatabase);
}
return undefined;
return db.prepare(query).get<DonationReceipt>(parameters);
}
export function _deleteAllDonationReceipts(db: WritableDB): void {
db.prepare('DELETE FROM donationReceipts;').run();
@@ -84,25 +33,19 @@ export function createDonationReceipt(
db: WritableDB,
receipt: DonationReceipt
): void {
const forDatabase = freezeDonationReceipt(receipt);
db.prepare(
`
INSERT INTO donationReceipts(
id,
currencyType,
paymentAmount,
paymentDetailJson,
paymentType,
timestamp
) VALUES (
$id,
$currencyType,
$paymentAmount,
$paymentDetailJson,
$paymentType,
$timestamp
);
`
).run(forDatabase);
).run(receipt);
}