Skip to content

Commit 4f8b5f9

Browse files
Merge branch 'main' into feat/issue-152-pr
2 parents b1e73e3 + 81dbd2b commit 4f8b5f9

5 files changed

Lines changed: 107 additions & 228 deletions

File tree

backend/src/routes/donations.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -239,6 +239,8 @@ async function recordDonation(req, res, next) {
239239
await client.query("COMMIT");
240240
inTransaction = false;
241241

242+
// Fire-and-forget: enqueue profile update + donation matching.
243+
// Neither failure should roll back the donation itself.
242244
enqueueProfileUpdate(donorAddress).catch((err) => {
243245
logger.error(
244246
{ event: "profile_update_enqueue_failed", err, donorAddress },

backend/src/routes/donations.socket.test.js

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ jest.mock("../services/stellar", () => ({
99
}));
1010

1111
jest.mock("../services/matchQueue", () => ({
12-
enqueueDonationMatching: jest.fn().mockResolvedValue("job-id"),
12+
enqueueMatchDonation: jest.fn().mockResolvedValue(undefined),
1313
}));
1414

1515
const http = require("http");
@@ -528,15 +528,17 @@ describe("POST /api/donations → broadcast hardening", () => {
528528
}
529529
}, 3000);
530530

531-
test("emits a single primary event when donation is recorded (matching is now async)", async () => {
531+
test("emits only one event per donation (matching is now async via matchQueue)", async () => {
532532
const donorAddress = makePublicKey("K");
533533
const transactionHash = makeTxHash("f");
534+
// Matching is handled asynchronously by matchQueue, so recordDonation
535+
// no longer queries donation_matches or inserts match donations inline.
536+
// Only 6 queries remain: SELECT project, dedup, BEGIN, INSERT, UPDATE, COMMIT.
534537
createMockClient(
535538
queryResult([{ id: "project-match" }]), // SELECT project
536539
queryResult([]), // dedup check
537540
queryResult(), // BEGIN
538541
queryResult([
539-
// INSERT primary donation
540542
{
541543
id: "match-primary",
542544
project_id: "project-match",
@@ -548,7 +550,7 @@ describe("POST /api/donations → broadcast hardening", () => {
548550
transaction_hash: transactionHash,
549551
created_at: new Date().toISOString(),
550552
},
551-
]),
553+
]), // INSERT donation
552554
queryResult(), // UPDATE projects
553555
queryResult(), // COMMIT
554556
);

backend/src/routes/donations.test.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -597,7 +597,7 @@ describe("profile upsert on first donation", () => {
597597
queryResult([]),
598598
queryResult(),
599599
queryResult([donationRow]),
600-
// no donation_matches query for non-XLM
600+
// no donation_matches query for non-XLM — matching is now async via matchQueue
601601
queryResult(), // UPDATE projects (raises_xlm += 0)
602602
queryResult(), // COMMIT
603603
);

backend/src/server.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -451,6 +451,7 @@ async function startServer() {
451451
await runMigrations();
452452
await startSummaryQueue(io);
453453
await startProfileQueue(io);
454+
await startMatchQueue();
454455
await startWebhookQueue();
455456
await startPushQueue();
456457
await startIdempotencyCleanup();
@@ -620,6 +621,7 @@ async function startServer() {
620621
for (const queue of [
621622
"./services/summaryQueue",
622623
"./services/profileQueue",
624+
"./services/matchQueue",
623625
"./services/digestQueue",
624626
"./services/webhookQueue",
625627
"./services/pushQueue",

0 commit comments

Comments
 (0)